/drivers/net/wireless/bcm4329/bcmsdstd.c
C | 3127 lines | 2414 code | 482 blank | 231 comment | 507 complexity | 5aad232ff8803f66b7b0f3bea186897f MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
Large files files are truncated, but you can click here to view the full file
1/*
2 * 'Standard' SDIO HOST CONTROLLER driver
3 *
4 * Copyright (C) 1999-2010, Broadcom Corporation
5 *
6 * Unless you and Broadcom execute a separate written software license
7 * agreement governing use of this software, this software is licensed to you
8 * under the terms of the GNU General Public License version 2 (the "GPL"),
9 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
10 * following added to such license:
11 *
12 * As a special exception, the copyright holders of this software give you
13 * permission to link this software with independent modules, and to copy and
14 * distribute the resulting executable under terms of your choice, provided that
15 * you also meet, for each linked independent module, the terms and conditions of
16 * the license of that module. An independent module is a module which is not
17 * derived from this software. The special exception does not apply to any
18 * modifications of the software.
19 *
20 * Notwithstanding the above, under no circumstances may you combine this
21 * software in any way with any other Broadcom software provided under a license
22 * other than the GPL, without Broadcom's express prior written consent.
23 *
24 * $Id: bcmsdstd.c,v 1.64.4.1.4.4.2.18 2010/08/17 17:00:48 Exp $
25 */
26
27#include <typedefs.h>
28
29#include <bcmdevs.h>
30#include <bcmendian.h>
31#include <bcmutils.h>
32#include <osl.h>
33#include <siutils.h>
34#include <sdio.h> /* SDIO Device and Protocol Specs */
35#include <sdioh.h> /* SDIO Host Controller Specification */
36#include <bcmsdbus.h> /* bcmsdh to/from specific controller APIs */
37#include <sdiovar.h> /* ioctl/iovars */
38#include <pcicfg.h>
39
40
41#define SD_PAGE_BITS 12
42#define SD_PAGE (1 << SD_PAGE_BITS)
43
44#include <bcmsdstd.h>
45
46/* Globals */
47uint sd_msglevel = SDH_ERROR_VAL;
48uint sd_hiok = TRUE; /* Use hi-speed mode if available? */
49uint sd_sdmode = SDIOH_MODE_SD4; /* Use SD4 mode by default */
50uint sd_f2_blocksize = 64; /* Default blocksize */
51
52#ifdef BCMSDYIELD
53bool sd_yieldcpu = TRUE; /* Allow CPU yielding for buffer requests */
54uint sd_minyield = 0; /* Minimum xfer size to allow CPU yield */
55bool sd_forcerb = FALSE; /* Force sync readback in intrs_on/off */
56#endif
57
58uint sd_divisor = 2; /* Default 48MHz/2 = 24MHz */
59
60uint sd_power = 1; /* Default to SD Slot powered ON */
61uint sd_clock = 1; /* Default to SD Clock turned ON */
62uint sd_pci_slot = 0xFFFFffff; /* Used to force selection of a particular PCI slot */
63uint8 sd_dma_mode = DMA_MODE_SDMA; /* Default to SDMA for now */
64
65uint sd_toctl = 7;
66
67static bool trap_errs = FALSE;
68
69static const char *dma_mode_description[] = { "PIO", "SDMA", "ADMA1", "32b ADMA2", "64b ADMA2" };
70
71/* Prototypes */
72static bool sdstd_start_clock(sdioh_info_t *sd, uint16 divisor);
73static bool sdstd_start_power(sdioh_info_t *sd);
74static bool sdstd_bus_width(sdioh_info_t *sd, int width);
75static int sdstd_set_highspeed_mode(sdioh_info_t *sd, bool HSMode);
76static int sdstd_set_dma_mode(sdioh_info_t *sd, int8 dma_mode);
77static int sdstd_card_enablefuncs(sdioh_info_t *sd);
78static void sdstd_cmd_getrsp(sdioh_info_t *sd, uint32 *rsp_buffer, int count);
79static int sdstd_cmd_issue(sdioh_info_t *sd, bool use_dma, uint32 cmd, uint32 arg);
80static int sdstd_card_regread(sdioh_info_t *sd, int func, uint32 regaddr,
81 int regsize, uint32 *data);
82static int sdstd_card_regwrite(sdioh_info_t *sd, int func, uint32 regaddr,
83 int regsize, uint32 data);
84static int sdstd_driver_init(sdioh_info_t *sd);
85static bool sdstd_reset(sdioh_info_t *sd, bool host_reset, bool client_reset);
86static int sdstd_card_buf(sdioh_info_t *sd, int rw, int func, bool fifo,
87 uint32 addr, int nbytes, uint32 *data);
88static int sdstd_abort(sdioh_info_t *sd, uint func);
89static int sdstd_check_errs(sdioh_info_t *sdioh_info, uint32 cmd, uint32 arg);
90static int set_client_block_size(sdioh_info_t *sd, int func, int blocksize);
91static void sd_map_dma(sdioh_info_t * sd);
92static void sd_unmap_dma(sdioh_info_t * sd);
93static void sd_clear_adma_dscr_buf(sdioh_info_t *sd);
94static void sd_fill_dma_data_buf(sdioh_info_t *sd, uint8 data);
95static void sd_create_adma_descriptor(sdioh_info_t *sd,
96 uint32 index, uint32 addr_phys,
97 uint16 length, uint16 flags);
98static void sd_dump_adma_dscr(sdioh_info_t *sd);
99static void sdstd_dumpregs(sdioh_info_t *sd);
100
101
102/*
103 * Private register access routines.
104 */
105
106/* 16 bit PCI regs */
107
108extern uint16 sdstd_rreg16(sdioh_info_t *sd, uint reg);
109uint16
110sdstd_rreg16(sdioh_info_t *sd, uint reg)
111{
112
113 volatile uint16 data = *(volatile uint16 *)(sd->mem_space + reg);
114 sd_ctrl(("16: R Reg 0x%02x, Data 0x%x\n", reg, data));
115 return data;
116}
117
118extern void sdstd_wreg16(sdioh_info_t *sd, uint reg, uint16 data);
119void
120sdstd_wreg16(sdioh_info_t *sd, uint reg, uint16 data)
121{
122 *(volatile uint16 *)(sd->mem_space + reg) = (uint16)data;
123 sd_ctrl(("16: W Reg 0x%02x, Data 0x%x\n", reg, data));
124}
125
126static void
127sdstd_or_reg16(sdioh_info_t *sd, uint reg, uint16 val)
128{
129 volatile uint16 data = *(volatile uint16 *)(sd->mem_space + reg);
130 sd_ctrl(("16: OR Reg 0x%02x, Val 0x%x\n", reg, val));
131 data |= val;
132 *(volatile uint16 *)(sd->mem_space + reg) = (uint16)data;
133
134}
135static void
136sdstd_mod_reg16(sdioh_info_t *sd, uint reg, int16 mask, uint16 val)
137{
138
139 volatile uint16 data = *(volatile uint16 *)(sd->mem_space + reg);
140 sd_ctrl(("16: MOD Reg 0x%02x, Mask 0x%x, Val 0x%x\n", reg, mask, val));
141 data &= ~mask;
142 data |= (val & mask);
143 *(volatile uint16 *)(sd->mem_space + reg) = (uint16)data;
144}
145
146
147/* 32 bit PCI regs */
148static uint32
149sdstd_rreg(sdioh_info_t *sd, uint reg)
150{
151 volatile uint32 data = *(volatile uint32 *)(sd->mem_space + reg);
152 sd_ctrl(("32: R Reg 0x%02x, Data 0x%x\n", reg, data));
153 return data;
154}
155static inline void
156sdstd_wreg(sdioh_info_t *sd, uint reg, uint32 data)
157{
158 *(volatile uint32 *)(sd->mem_space + reg) = (uint32)data;
159 sd_ctrl(("32: W Reg 0x%02x, Data 0x%x\n", reg, data));
160
161}
162
163/* 8 bit PCI regs */
164static inline void
165sdstd_wreg8(sdioh_info_t *sd, uint reg, uint8 data)
166{
167 *(volatile uint8 *)(sd->mem_space + reg) = (uint8)data;
168 sd_ctrl(("08: W Reg 0x%02x, Data 0x%x\n", reg, data));
169}
170static uint8
171sdstd_rreg8(sdioh_info_t *sd, uint reg)
172{
173 volatile uint8 data = *(volatile uint8 *)(sd->mem_space + reg);
174 sd_ctrl(("08: R Reg 0x%02x, Data 0x%x\n", reg, data));
175 return data;
176}
177
178/*
179 * Private work routines
180 */
181
182sdioh_info_t *glob_sd;
183
184/*
185 * Public entry points & extern's
186 */
187extern sdioh_info_t *
188sdioh_attach(osl_t *osh, void *bar0, uint irq)
189{
190 sdioh_info_t *sd;
191
192 sd_trace(("%s\n", __FUNCTION__));
193 if ((sd = (sdioh_info_t *)MALLOC(osh, sizeof(sdioh_info_t))) == NULL) {
194 sd_err(("sdioh_attach: out of memory, malloced %d bytes\n", MALLOCED(osh)));
195 return NULL;
196 }
197 bzero((char *)sd, sizeof(sdioh_info_t));
198 glob_sd = sd;
199 sd->osh = osh;
200 if (sdstd_osinit(sd) != 0) {
201 sd_err(("%s:sdstd_osinit() failed\n", __FUNCTION__));
202 MFREE(sd->osh, sd, sizeof(sdioh_info_t));
203 return NULL;
204 }
205 sd->mem_space = (volatile char *)sdstd_reg_map(osh, (uintptr)bar0, SDIOH_REG_WINSZ);
206 sd_init_dma(sd);
207 sd->irq = irq;
208 if (sd->mem_space == NULL) {
209 sd_err(("%s:ioremap() failed\n", __FUNCTION__));
210 sdstd_osfree(sd);
211 MFREE(sd->osh, sd, sizeof(sdioh_info_t));
212 return NULL;
213 }
214 sd_info(("%s:sd->mem_space = %p\n", __FUNCTION__, sd->mem_space));
215 sd->intr_handler = NULL;
216 sd->intr_handler_arg = NULL;
217 sd->intr_handler_valid = FALSE;
218
219 /* Set defaults */
220 sd->sd_blockmode = TRUE;
221 sd->use_client_ints = TRUE;
222 sd->sd_dma_mode = sd_dma_mode;
223
224 if (!sd->sd_blockmode)
225 sd->sd_dma_mode = DMA_MODE_NONE;
226
227 if (sdstd_driver_init(sd) != SUCCESS) {
228 /* If host CPU was reset without resetting SD bus or
229 SD device, the device will still have its RCA but
230 driver no longer knows what it is (since driver has been restarted).
231 go through once to clear the RCA and a gain reassign it.
232 */
233 sd_info(("driver_init failed - Reset RCA and try again\n"));
234 if (sdstd_driver_init(sd) != SUCCESS) {
235 sd_err(("%s:driver_init() failed()\n", __FUNCTION__));
236 if (sd->mem_space) {
237 sdstd_reg_unmap(osh, (uintptr)sd->mem_space, SDIOH_REG_WINSZ);
238 sd->mem_space = NULL;
239 }
240 sdstd_osfree(sd);
241 MFREE(sd->osh, sd, sizeof(sdioh_info_t));
242 return (NULL);
243 }
244 }
245
246 OSL_DMADDRWIDTH(osh, 32);
247
248 /* Always map DMA buffers, so we can switch between DMA modes. */
249 sd_map_dma(sd);
250
251 if (sdstd_register_irq(sd, irq) != SUCCESS) {
252 sd_err(("%s: sdstd_register_irq() failed for irq = %d\n", __FUNCTION__, irq));
253 sdstd_free_irq(sd->irq, sd);
254 if (sd->mem_space) {
255 sdstd_reg_unmap(osh, (uintptr)sd->mem_space, SDIOH_REG_WINSZ);
256 sd->mem_space = NULL;
257 }
258
259 sdstd_osfree(sd);
260 MFREE(sd->osh, sd, sizeof(sdioh_info_t));
261 return (NULL);
262 }
263
264 sd_trace(("%s: Done\n", __FUNCTION__));
265 return sd;
266}
267
268extern SDIOH_API_RC
269sdioh_detach(osl_t *osh, sdioh_info_t *sd)
270{
271 sd_trace(("%s\n", __FUNCTION__));
272 if (sd) {
273 sd_unmap_dma(sd);
274 sdstd_wreg16(sd, SD_IntrSignalEnable, 0);
275 sd_trace(("%s: freeing irq %d\n", __FUNCTION__, sd->irq));
276 sdstd_free_irq(sd->irq, sd);
277 if (sd->card_init_done)
278 sdstd_reset(sd, 1, 1);
279 if (sd->mem_space) {
280 sdstd_reg_unmap(osh, (uintptr)sd->mem_space, SDIOH_REG_WINSZ);
281 sd->mem_space = NULL;
282 }
283
284 sdstd_osfree(sd);
285 MFREE(sd->osh, sd, sizeof(sdioh_info_t));
286 }
287 return SDIOH_API_RC_SUCCESS;
288}
289
290/* Configure callback to client when we receive client interrupt */
291extern SDIOH_API_RC
292sdioh_interrupt_register(sdioh_info_t *sd, sdioh_cb_fn_t fn, void *argh)
293{
294 sd_trace(("%s: Entering\n", __FUNCTION__));
295 sd->intr_handler = fn;
296 sd->intr_handler_arg = argh;
297 sd->intr_handler_valid = TRUE;
298 return SDIOH_API_RC_SUCCESS;
299}
300
301extern SDIOH_API_RC
302sdioh_interrupt_deregister(sdioh_info_t *sd)
303{
304 sd_trace(("%s: Entering\n", __FUNCTION__));
305 sd->intr_handler_valid = FALSE;
306 sd->intr_handler = NULL;
307 sd->intr_handler_arg = NULL;
308 return SDIOH_API_RC_SUCCESS;
309}
310
311extern SDIOH_API_RC
312sdioh_interrupt_query(sdioh_info_t *sd, bool *onoff)
313{
314 sd_trace(("%s: Entering\n", __FUNCTION__));
315 *onoff = sd->client_intr_enabled;
316 return SDIOH_API_RC_SUCCESS;
317}
318
319#if defined(DHD_DEBUG)
320extern bool
321sdioh_interrupt_pending(sdioh_info_t *sd)
322{
323 uint16 intrstatus;
324 intrstatus = sdstd_rreg16(sd, SD_IntrStatus);
325 return !!(intrstatus & CLIENT_INTR);
326}
327#endif
328
329uint
330sdioh_query_iofnum(sdioh_info_t *sd)
331{
332 return sd->num_funcs;
333}
334
335/* IOVar table */
336enum {
337 IOV_MSGLEVEL = 1,
338 IOV_BLOCKMODE,
339 IOV_BLOCKSIZE,
340 IOV_DMA,
341 IOV_USEINTS,
342 IOV_NUMINTS,
343 IOV_NUMLOCALINTS,
344 IOV_HOSTREG,
345 IOV_DEVREG,
346 IOV_DIVISOR,
347 IOV_SDMODE,
348 IOV_HISPEED,
349 IOV_HCIREGS,
350 IOV_POWER,
351 IOV_YIELDCPU,
352 IOV_MINYIELD,
353 IOV_FORCERB,
354 IOV_CLOCK
355};
356
357const bcm_iovar_t sdioh_iovars[] = {
358 {"sd_msglevel", IOV_MSGLEVEL, 0, IOVT_UINT32, 0 },
359 {"sd_blockmode", IOV_BLOCKMODE, 0, IOVT_BOOL, 0 },
360 {"sd_blocksize", IOV_BLOCKSIZE, 0, IOVT_UINT32, 0 }, /* ((fn << 16) | size) */
361 {"sd_dma", IOV_DMA, 0, IOVT_UINT32, 0 },
362#ifdef BCMSDYIELD
363 {"sd_yieldcpu", IOV_YIELDCPU, 0, IOVT_BOOL, 0 },
364 {"sd_minyield", IOV_MINYIELD, 0, IOVT_UINT32, 0 },
365 {"sd_forcerb", IOV_FORCERB, 0, IOVT_BOOL, 0 },
366#endif
367 {"sd_ints", IOV_USEINTS, 0, IOVT_BOOL, 0 },
368 {"sd_numints", IOV_NUMINTS, 0, IOVT_UINT32, 0 },
369 {"sd_numlocalints", IOV_NUMLOCALINTS, 0, IOVT_UINT32, 0 },
370 {"sd_hostreg", IOV_HOSTREG, 0, IOVT_BUFFER, sizeof(sdreg_t) },
371 {"sd_devreg", IOV_DEVREG, 0, IOVT_BUFFER, sizeof(sdreg_t) },
372 {"sd_divisor", IOV_DIVISOR, 0, IOVT_UINT32, 0 },
373 {"sd_power", IOV_POWER, 0, IOVT_UINT32, 0 },
374 {"sd_clock", IOV_CLOCK, 0, IOVT_UINT32, 0 },
375 {"sd_mode", IOV_SDMODE, 0, IOVT_UINT32, 100},
376 {"sd_highspeed", IOV_HISPEED, 0, IOVT_UINT32, 0},
377 {NULL, 0, 0, 0, 0 }
378};
379
380int
381sdioh_iovar_op(sdioh_info_t *si, const char *name,
382 void *params, int plen, void *arg, int len, bool set)
383{
384 const bcm_iovar_t *vi = NULL;
385 int bcmerror = 0;
386 int val_size;
387 int32 int_val = 0;
388 bool bool_val;
389 uint32 actionid;
390
391 ASSERT(name);
392 ASSERT(len >= 0);
393
394 /* Get must have return space; Set does not take qualifiers */
395 ASSERT(set || (arg && len));
396 ASSERT(!set || (!params && !plen));
397
398 sd_trace(("%s: Enter (%s %s)\n", __FUNCTION__, (set ? "set" : "get"), name));
399
400 if ((vi = bcm_iovar_lookup(sdioh_iovars, name)) == NULL) {
401 bcmerror = BCME_UNSUPPORTED;
402 goto exit;
403 }
404
405 if ((bcmerror = bcm_iovar_lencheck(vi, arg, len, set)) != 0)
406 goto exit;
407
408 /* Set up params so get and set can share the convenience variables */
409 if (params == NULL) {
410 params = arg;
411 plen = len;
412 }
413
414 if (vi->type == IOVT_VOID)
415 val_size = 0;
416 else if (vi->type == IOVT_BUFFER)
417 val_size = len;
418 else
419 val_size = sizeof(int);
420
421 if (plen >= (int)sizeof(int_val))
422 bcopy(params, &int_val, sizeof(int_val));
423
424 bool_val = (int_val != 0) ? TRUE : FALSE;
425
426 actionid = set ? IOV_SVAL(vi->varid) : IOV_GVAL(vi->varid);
427 switch (actionid) {
428 case IOV_GVAL(IOV_MSGLEVEL):
429 int_val = (int32)sd_msglevel;
430 bcopy(&int_val, arg, val_size);
431 break;
432
433 case IOV_SVAL(IOV_MSGLEVEL):
434 sd_msglevel = int_val;
435 break;
436
437 case IOV_GVAL(IOV_BLOCKMODE):
438 int_val = (int32)si->sd_blockmode;
439 bcopy(&int_val, arg, val_size);
440 break;
441
442 case IOV_SVAL(IOV_BLOCKMODE):
443 si->sd_blockmode = (bool)int_val;
444 /* Haven't figured out how to make non-block mode with DMA */
445 if (!si->sd_blockmode)
446 si->sd_dma_mode = DMA_MODE_NONE;
447 break;
448
449#ifdef BCMSDYIELD
450 case IOV_GVAL(IOV_YIELDCPU):
451 int_val = sd_yieldcpu;
452 bcopy(&int_val, arg, val_size);
453 break;
454
455 case IOV_SVAL(IOV_YIELDCPU):
456 sd_yieldcpu = (bool)int_val;
457 break;
458
459 case IOV_GVAL(IOV_MINYIELD):
460 int_val = sd_minyield;
461 bcopy(&int_val, arg, val_size);
462 break;
463
464 case IOV_SVAL(IOV_MINYIELD):
465 sd_minyield = (bool)int_val;
466 break;
467
468 case IOV_GVAL(IOV_FORCERB):
469 int_val = sd_forcerb;
470 bcopy(&int_val, arg, val_size);
471 break;
472
473 case IOV_SVAL(IOV_FORCERB):
474 sd_forcerb = (bool)int_val;
475 break;
476#endif /* BCMSDYIELD */
477
478 case IOV_GVAL(IOV_BLOCKSIZE):
479 if ((uint32)int_val > si->num_funcs) {
480 bcmerror = BCME_BADARG;
481 break;
482 }
483 int_val = (int32)si->client_block_size[int_val];
484 bcopy(&int_val, arg, val_size);
485 break;
486
487 case IOV_SVAL(IOV_BLOCKSIZE):
488 {
489 uint func = ((uint32)int_val >> 16);
490 uint blksize = (uint16)int_val;
491 uint maxsize;
492
493 if (func > si->num_funcs) {
494 bcmerror = BCME_BADARG;
495 break;
496 }
497
498 switch (func) {
499 case 0: maxsize = 32; break;
500 case 1: maxsize = BLOCK_SIZE_4318; break;
501 case 2: maxsize = BLOCK_SIZE_4328; break;
502 default: maxsize = 0;
503 }
504 if (blksize > maxsize) {
505 bcmerror = BCME_BADARG;
506 break;
507 }
508 if (!blksize) {
509 blksize = maxsize;
510 }
511
512 /* Now set it */
513 sdstd_lock(si);
514 bcmerror = set_client_block_size(si, func, blksize);
515 sdstd_unlock(si);
516 break;
517 }
518
519 case IOV_GVAL(IOV_DMA):
520 int_val = (int32)si->sd_dma_mode;
521 bcopy(&int_val, arg, val_size);
522 break;
523
524 case IOV_SVAL(IOV_DMA):
525 si->sd_dma_mode = (char)int_val;
526 sdstd_set_dma_mode(si, si->sd_dma_mode);
527 break;
528
529 case IOV_GVAL(IOV_USEINTS):
530 int_val = (int32)si->use_client_ints;
531 bcopy(&int_val, arg, val_size);
532 break;
533
534 case IOV_SVAL(IOV_USEINTS):
535 si->use_client_ints = (bool)int_val;
536 if (si->use_client_ints)
537 si->intmask |= CLIENT_INTR;
538 else
539 si->intmask &= ~CLIENT_INTR;
540 break;
541
542 case IOV_GVAL(IOV_DIVISOR):
543 int_val = (uint32)sd_divisor;
544 bcopy(&int_val, arg, val_size);
545 break;
546
547 case IOV_SVAL(IOV_DIVISOR):
548 sd_divisor = int_val;
549 if (!sdstd_start_clock(si, (uint16)sd_divisor)) {
550 sd_err(("set clock failed!\n"));
551 bcmerror = BCME_ERROR;
552 }
553 break;
554
555 case IOV_GVAL(IOV_POWER):
556 int_val = (uint32)sd_power;
557 bcopy(&int_val, arg, val_size);
558 break;
559
560 case IOV_SVAL(IOV_POWER):
561 sd_power = int_val;
562 if (sd_power == 1) {
563 if (sdstd_driver_init(si) != SUCCESS) {
564 sd_err(("set SD Slot power failed!\n"));
565 bcmerror = BCME_ERROR;
566 } else {
567 sd_err(("SD Slot Powered ON.\n"));
568 }
569 } else {
570 uint8 pwr = 0;
571
572 pwr = SFIELD(pwr, PWR_BUS_EN, 0);
573 sdstd_wreg8(si, SD_PwrCntrl, pwr); /* Set Voltage level */
574 sd_err(("SD Slot Powered OFF.\n"));
575 }
576 break;
577
578 case IOV_GVAL(IOV_CLOCK):
579 int_val = (uint32)sd_clock;
580 bcopy(&int_val, arg, val_size);
581 break;
582
583 case IOV_SVAL(IOV_CLOCK):
584 sd_clock = int_val;
585 if (sd_clock == 1) {
586 sd_info(("SD Clock turned ON.\n"));
587 if (!sdstd_start_clock(si, (uint16)sd_divisor)) {
588 sd_err(("sdstd_start_clock failed\n"));
589 bcmerror = BCME_ERROR;
590 }
591 } else {
592 /* turn off HC clock */
593 sdstd_wreg16(si, SD_ClockCntrl,
594 sdstd_rreg16(si, SD_ClockCntrl) & ~((uint16)0x4));
595
596 sd_info(("SD Clock turned OFF.\n"));
597 }
598 break;
599
600 case IOV_GVAL(IOV_SDMODE):
601 int_val = (uint32)sd_sdmode;
602 bcopy(&int_val, arg, val_size);
603 break;
604
605 case IOV_SVAL(IOV_SDMODE):
606 sd_sdmode = int_val;
607
608 if (!sdstd_bus_width(si, sd_sdmode)) {
609 sd_err(("sdstd_bus_width failed\n"));
610 bcmerror = BCME_ERROR;
611 }
612 break;
613
614 case IOV_GVAL(IOV_HISPEED):
615 int_val = (uint32)sd_hiok;
616 bcopy(&int_val, arg, val_size);
617 break;
618
619 case IOV_SVAL(IOV_HISPEED):
620 sd_hiok = int_val;
621 bcmerror = sdstd_set_highspeed_mode(si, (bool)sd_hiok);
622 break;
623
624 case IOV_GVAL(IOV_NUMINTS):
625 int_val = (int32)si->intrcount;
626 bcopy(&int_val, arg, val_size);
627 break;
628
629 case IOV_GVAL(IOV_NUMLOCALINTS):
630 int_val = (int32)si->local_intrcount;
631 bcopy(&int_val, arg, val_size);
632 break;
633
634 case IOV_GVAL(IOV_HOSTREG):
635 {
636 sdreg_t *sd_ptr = (sdreg_t *)params;
637
638 if (sd_ptr->offset < SD_SysAddr || sd_ptr->offset > SD_MaxCurCap) {
639 sd_err(("%s: bad offset 0x%x\n", __FUNCTION__, sd_ptr->offset));
640 bcmerror = BCME_BADARG;
641 break;
642 }
643
644 sd_trace(("%s: rreg%d at offset %d\n", __FUNCTION__,
645 (sd_ptr->offset & 1) ? 8 : ((sd_ptr->offset & 2) ? 16 : 32),
646 sd_ptr->offset));
647 if (sd_ptr->offset & 1)
648 int_val = sdstd_rreg8(si, sd_ptr->offset);
649 else if (sd_ptr->offset & 2)
650 int_val = sdstd_rreg16(si, sd_ptr->offset);
651 else
652 int_val = sdstd_rreg(si, sd_ptr->offset);
653
654 bcopy(&int_val, arg, sizeof(int_val));
655 break;
656 }
657
658 case IOV_SVAL(IOV_HOSTREG):
659 {
660 sdreg_t *sd_ptr = (sdreg_t *)params;
661
662 if (sd_ptr->offset < SD_SysAddr || sd_ptr->offset > SD_MaxCurCap) {
663 sd_err(("%s: bad offset 0x%x\n", __FUNCTION__, sd_ptr->offset));
664 bcmerror = BCME_BADARG;
665 break;
666 }
667
668 sd_trace(("%s: wreg%d value 0x%08x at offset %d\n", __FUNCTION__, sd_ptr->value,
669 (sd_ptr->offset & 1) ? 8 : ((sd_ptr->offset & 2) ? 16 : 32),
670 sd_ptr->offset));
671 if (sd_ptr->offset & 1)
672 sdstd_wreg8(si, sd_ptr->offset, (uint8)sd_ptr->value);
673 else if (sd_ptr->offset & 2)
674 sdstd_wreg16(si, sd_ptr->offset, (uint16)sd_ptr->value);
675 else
676 sdstd_wreg(si, sd_ptr->offset, (uint32)sd_ptr->value);
677
678 break;
679 }
680
681 case IOV_GVAL(IOV_DEVREG):
682 {
683 sdreg_t *sd_ptr = (sdreg_t *)params;
684 uint8 data;
685
686 if (sdioh_cfg_read(si, sd_ptr->func, sd_ptr->offset, &data)) {
687 bcmerror = BCME_SDIO_ERROR;
688 break;
689 }
690
691 int_val = (int)data;
692 bcopy(&int_val, arg, sizeof(int_val));
693 break;
694 }
695
696 case IOV_SVAL(IOV_DEVREG):
697 {
698 sdreg_t *sd_ptr = (sdreg_t *)params;
699 uint8 data = (uint8)sd_ptr->value;
700
701 if (sdioh_cfg_write(si, sd_ptr->func, sd_ptr->offset, &data)) {
702 bcmerror = BCME_SDIO_ERROR;
703 break;
704 }
705 break;
706 }
707
708
709 default:
710 bcmerror = BCME_UNSUPPORTED;
711 break;
712 }
713exit:
714
715 return bcmerror;
716}
717
718extern SDIOH_API_RC
719sdioh_cfg_read(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data)
720{
721 SDIOH_API_RC status;
722 /* No lock needed since sdioh_request_byte does locking */
723 status = sdioh_request_byte(sd, SDIOH_READ, fnc_num, addr, data);
724 return status;
725}
726
727extern SDIOH_API_RC
728sdioh_cfg_write(sdioh_info_t *sd, uint fnc_num, uint32 addr, uint8 *data)
729{
730 /* No lock needed since sdioh_request_byte does locking */
731 SDIOH_API_RC status;
732 status = sdioh_request_byte(sd, SDIOH_WRITE, fnc_num, addr, data);
733 return status;
734}
735
736extern SDIOH_API_RC
737sdioh_cis_read(sdioh_info_t *sd, uint func, uint8 *cisd, uint32 length)
738{
739 uint32 count;
740 int offset;
741 uint32 foo;
742 uint8 *cis = cisd;
743
744 sd_trace(("%s: Func = %d\n", __FUNCTION__, func));
745
746 if (!sd->func_cis_ptr[func]) {
747 bzero(cis, length);
748 return SDIOH_API_RC_FAIL;
749 }
750
751 sdstd_lock(sd);
752 *cis = 0;
753 for (count = 0; count < length; count++) {
754 offset = sd->func_cis_ptr[func] + count;
755 if (sdstd_card_regread(sd, 0, offset, 1, &foo)) {
756 sd_err(("%s: regread failed: Can't read CIS\n", __FUNCTION__));
757 sdstd_unlock(sd);
758 return SDIOH_API_RC_FAIL;
759 }
760 *cis = (uint8)(foo & 0xff);
761 cis++;
762 }
763 sdstd_unlock(sd);
764 return SDIOH_API_RC_SUCCESS;
765}
766
767extern SDIOH_API_RC
768sdioh_request_byte(sdioh_info_t *sd, uint rw, uint func, uint regaddr, uint8 *byte)
769{
770 int status;
771 uint32 cmd_arg;
772 uint32 rsp5;
773
774 sdstd_lock(sd);
775 cmd_arg = 0;
776 cmd_arg = SFIELD(cmd_arg, CMD52_FUNCTION, func);
777 cmd_arg = SFIELD(cmd_arg, CMD52_REG_ADDR, regaddr);
778 cmd_arg = SFIELD(cmd_arg, CMD52_RW_FLAG, rw == SDIOH_READ ? 0 : 1);
779 cmd_arg = SFIELD(cmd_arg, CMD52_RAW, 0);
780 cmd_arg = SFIELD(cmd_arg, CMD52_DATA, rw == SDIOH_READ ? 0 : *byte);
781
782 if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_52, cmd_arg)) != SUCCESS) {
783 sdstd_unlock(sd);
784 return status;
785 }
786
787 sdstd_cmd_getrsp(sd, &rsp5, 1);
788 if (sdstd_rreg16 (sd, SD_ErrorIntrStatus) != 0) {
789 sd_err(("%s: 1: ErrorintrStatus 0x%x\n",
790 __FUNCTION__, sdstd_rreg16(sd, SD_ErrorIntrStatus)));
791 }
792 if (GFIELD(rsp5, RSP5_FLAGS) != 0x10)
793 sd_err(("%s: rsp5 flags is 0x%x\t %d\n",
794 __FUNCTION__, GFIELD(rsp5, RSP5_FLAGS), func));
795
796 if (GFIELD(rsp5, RSP5_STUFF))
797 sd_err(("%s: rsp5 stuff is 0x%x: should be 0\n",
798 __FUNCTION__, GFIELD(rsp5, RSP5_STUFF)));
799
800 if (rw == SDIOH_READ)
801 *byte = GFIELD(rsp5, RSP5_DATA);
802
803 sdstd_unlock(sd);
804 return SDIOH_API_RC_SUCCESS;
805}
806
807extern SDIOH_API_RC
808sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func, uint addr,
809 uint32 *word, uint nbytes)
810{
811 int status;
812 bool swap = FALSE;
813
814 sdstd_lock(sd);
815
816 if (rw == SDIOH_READ) {
817 status = sdstd_card_regread(sd, func, addr, nbytes, word);
818 if (swap)
819 *word = BCMSWAP32(*word);
820 } else {
821 if (swap)
822 *word = BCMSWAP32(*word);
823 status = sdstd_card_regwrite(sd, func, addr, nbytes, *word);
824 }
825
826 sdstd_unlock(sd);
827 return (status == SUCCESS ? SDIOH_API_RC_SUCCESS : SDIOH_API_RC_FAIL);
828}
829
830extern SDIOH_API_RC
831sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint rw, uint func,
832 uint addr, uint reg_width, uint buflen_u, uint8 *buffer, void *pkt)
833{
834 int len;
835 int buflen = (int)buflen_u;
836 bool fifo = (fix_inc == SDIOH_DATA_FIX);
837 uint8 *localbuf = NULL, *tmpbuf = NULL;
838 uint tmplen = 0;
839 bool local_blockmode = sd->sd_blockmode;
840
841 sdstd_lock(sd);
842
843 ASSERT(reg_width == 4);
844 ASSERT(buflen_u < (1 << 30));
845 ASSERT(sd->client_block_size[func]);
846
847 sd_data(("%s: %c len %d r_cnt %d t_cnt %d, pkt @0x%p\n",
848 __FUNCTION__, rw == SDIOH_READ ? 'R' : 'W',
849 buflen_u, sd->r_cnt, sd->t_cnt, pkt));
850
851 /* Break buffer down into blocksize chunks:
852 * Bytemode: 1 block at a time.
853 * Blockmode: Multiples of blocksizes at a time w/ max of SD_PAGE.
854 * Both: leftovers are handled last (will be sent via bytemode).
855 */
856 while (buflen > 0) {
857 if (local_blockmode) {
858 /* Max xfer is Page size */
859 len = MIN(SD_PAGE, buflen);
860
861 /* Round down to a block boundry */
862 if (buflen > sd->client_block_size[func])
863 len = (len/sd->client_block_size[func]) *
864 sd->client_block_size[func];
865 if ((func == SDIO_FUNC_1) && ((len % 4) == 3) && (rw == SDIOH_WRITE)) {
866 tmplen = len;
867 sd_err(("%s: Rounding up buffer to mod4 length.\n", __FUNCTION__));
868 len++;
869 tmpbuf = buffer;
870 if ((localbuf = (uint8 *)MALLOC(sd->osh, len)) == NULL) {
871 sd_err(("out of memory, malloced %d bytes\n",
872 MALLOCED(sd->osh)));
873 sdstd_unlock(sd);
874 return SDIOH_API_RC_FAIL;
875 }
876 bcopy(buffer, localbuf, len);
877 buffer = localbuf;
878 }
879 } else {
880 /* Byte mode: One block at a time */
881 len = MIN(sd->client_block_size[func], buflen);
882 }
883
884 if (sdstd_card_buf(sd, rw, func, fifo, addr, len, (uint32 *)buffer) != SUCCESS) {
885 sdstd_unlock(sd);
886 return SDIOH_API_RC_FAIL;
887 }
888
889 if (local_blockmode) {
890 if ((func == SDIO_FUNC_1) && ((tmplen % 4) == 3) && (rw == SDIOH_WRITE)) {
891 if (localbuf)
892 MFREE(sd->osh, localbuf, len);
893 len--;
894 buffer = tmpbuf;
895 sd_err(("%s: Restoring back buffer ptr and len.\n", __FUNCTION__));
896 }
897 }
898
899 buffer += len;
900 buflen -= len;
901 if (!fifo)
902 addr += len;
903 }
904 sdstd_unlock(sd);
905 return SDIOH_API_RC_SUCCESS;
906}
907
908static
909int sdstd_abort(sdioh_info_t *sd, uint func)
910{
911 int err = 0;
912 int retries;
913
914 uint16 cmd_reg;
915 uint32 cmd_arg;
916 uint32 rsp5;
917 uint8 rflags;
918
919 uint16 int_reg = 0;
920 uint16 plain_intstatus;
921
922 /* Argument is write to F0 (CCCR) IOAbort with function number */
923 cmd_arg = 0;
924 cmd_arg = SFIELD(cmd_arg, CMD52_FUNCTION, SDIO_FUNC_0);
925 cmd_arg = SFIELD(cmd_arg, CMD52_REG_ADDR, SDIOD_CCCR_IOABORT);
926 cmd_arg = SFIELD(cmd_arg, CMD52_RW_FLAG, SD_IO_OP_WRITE);
927 cmd_arg = SFIELD(cmd_arg, CMD52_RAW, 0);
928 cmd_arg = SFIELD(cmd_arg, CMD52_DATA, func);
929
930 /* Command is CMD52 write */
931 cmd_reg = 0;
932 cmd_reg = SFIELD(cmd_reg, CMD_RESP_TYPE, RESP_TYPE_48_BUSY);
933 cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 1);
934 cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 1);
935 cmd_reg = SFIELD(cmd_reg, CMD_DATA_EN, 0);
936 cmd_reg = SFIELD(cmd_reg, CMD_TYPE, CMD_TYPE_ABORT);
937 cmd_reg = SFIELD(cmd_reg, CMD_INDEX, SDIOH_CMD_52);
938
939 if (sd->sd_mode == SDIOH_MODE_SPI) {
940 cmd_reg = SFIELD(cmd_reg, CMD_CRC_EN, 0);
941 cmd_reg = SFIELD(cmd_reg, CMD_INDEX_EN, 0);
942 }
943
944 /* Wait for CMD_INHIBIT to go away as per spec section 3.6.1.1 */
945 retries = RETRIES_SMALL;
946 while (GFIELD(sdstd_rreg(sd, SD_PresentState), PRES_CMD_INHIBIT)) {
947 if (retries == RETRIES_SMALL)
948 sd_err(("%s: Waiting for Command Inhibit, state 0x%08x\n",
949 __FUNCTION__, sdstd_rreg(sd, SD_PresentState)));
950 if (!--retries) {
951 sd_err(("%s: Command Inhibit timeout, state 0x%08x\n",
952 __FUNCTION__, sdstd_rreg(sd, SD_PresentState)));
953 if (trap_errs)
954 ASSERT(0);
955 err = BCME_SDIO_ERROR;
956 goto done;
957 }
958 }
959
960 /* Clear errors from any previous commands */
961 if ((plain_intstatus = sdstd_rreg16(sd, SD_ErrorIntrStatus)) != 0) {
962 sd_err(("abort: clearing errstat 0x%04x\n", plain_intstatus));
963 sdstd_wreg16(sd, SD_ErrorIntrStatus, plain_intstatus);
964 }
965 plain_intstatus = sdstd_rreg16(sd, SD_IntrStatus);
966 if (plain_intstatus & ~(SFIELD(0, INTSTAT_CARD_INT, 1))) {
967 sd_err(("abort: intstatus 0x%04x\n", plain_intstatus));
968 if (GFIELD(plain_intstatus, INTSTAT_CMD_COMPLETE)) {
969 sd_err(("SDSTD_ABORT: CMD COMPLETE SET BEFORE COMMAND GIVEN!!!\n"));
970 }
971 if (GFIELD(plain_intstatus, INTSTAT_CARD_REMOVAL)) {
972 sd_err(("SDSTD_ABORT: INTSTAT_CARD_REMOVAL\n"));
973 err = BCME_NODEVICE;
974 goto done;
975 }
976 }
977
978 /* Issue the command */
979 sdstd_wreg(sd, SD_Arg0, cmd_arg);
980 sdstd_wreg16(sd, SD_Command, cmd_reg);
981
982 /* In interrupt mode return, expect later CMD_COMPLETE interrupt */
983 if (!sd->polled_mode)
984 return err;
985
986 /* Otherwise, wait for the command to complete */
987 retries = RETRIES_LARGE;
988 do {
989 int_reg = sdstd_rreg16(sd, SD_IntrStatus);
990 } while (--retries &&
991 (GFIELD(int_reg, INTSTAT_ERROR_INT) == 0) &&
992 (GFIELD(int_reg, INTSTAT_CMD_COMPLETE) == 0));
993
994 /* If command completion fails, do a cmd reset and note the error */
995 if (!retries) {
996 sd_err(("%s: CMD_COMPLETE timeout: intr 0x%04x err 0x%04x state 0x%08x\n",
997 __FUNCTION__, int_reg,
998 sdstd_rreg16(sd, SD_ErrorIntrStatus),
999 sdstd_rreg(sd, SD_PresentState)));
1000
1001 sdstd_wreg8(sd, SD_SoftwareReset, SFIELD(0, SW_RESET_CMD, 1));
1002 retries = RETRIES_LARGE;
1003 do {
1004 sd_trace(("%s: waiting for CMD line reset\n", __FUNCTION__));
1005 } while ((GFIELD(sdstd_rreg8(sd, SD_SoftwareReset),
1006 SW_RESET_CMD)) && retries--);
1007
1008 if (!retries) {
1009 sd_err(("%s: Timeout waiting for CMD line reset\n", __FUNCTION__));
1010 }
1011
1012 if (trap_errs)
1013 ASSERT(0);
1014
1015 err = BCME_SDIO_ERROR;
1016 }
1017
1018 /* Clear Command Complete interrupt */
1019 int_reg = SFIELD(0, INTSTAT_CMD_COMPLETE, 1);
1020 sdstd_wreg16(sd, SD_IntrStatus, int_reg);
1021
1022 /* Check for Errors */
1023 if ((plain_intstatus = sdstd_rreg16 (sd, SD_ErrorIntrStatus)) != 0) {
1024 sd_err(("%s: ErrorintrStatus: 0x%x, "
1025 "(intrstatus = 0x%x, present state 0x%x) clearing\n",
1026 __FUNCTION__, plain_intstatus,
1027 sdstd_rreg16(sd, SD_IntrStatus),
1028 sdstd_rreg(sd, SD_PresentState)));
1029
1030 sdstd_wreg16(sd, SD_ErrorIntrStatus, plain_intstatus);
1031
1032 sdstd_wreg8(sd, SD_SoftwareReset, SFIELD(0, SW_RESET_DAT, 1));
1033 retries = RETRIES_LARGE;
1034 do {
1035 sd_trace(("%s: waiting for DAT line reset\n", __FUNCTION__));
1036 } while ((GFIELD(sdstd_rreg8(sd, SD_SoftwareReset),
1037 SW_RESET_DAT)) && retries--);
1038
1039 if (!retries) {
1040 sd_err(("%s: Timeout waiting for DAT line reset\n", __FUNCTION__));
1041 }
1042
1043 if (trap_errs)
1044 ASSERT(0);
1045
1046 /* ABORT is dataless, only cmd errs count */
1047 if (plain_intstatus & ERRINT_CMD_ERRS)
1048 err = BCME_SDIO_ERROR;
1049 }
1050
1051 /* If command failed don't bother looking at response */
1052 if (err)
1053 goto done;
1054
1055 /* Otherwise, check the response */
1056 sdstd_cmd_getrsp(sd, &rsp5, 1);
1057 rflags = GFIELD(rsp5, RSP5_FLAGS);
1058
1059 if (rflags & SD_RSP_R5_ERRBITS) {
1060 sd_err(("%s: R5 flags include errbits: 0x%02x\n", __FUNCTION__, rflags));
1061
1062 /* The CRC error flag applies to the previous command */
1063 if (rflags & (SD_RSP_R5_ERRBITS & ~SD_RSP_R5_COM_CRC_ERROR)) {
1064 err = BCME_SDIO_ERROR;
1065 goto done;
1066 }
1067 }
1068
1069 if (((rflags & (SD_RSP_R5_IO_CURRENTSTATE0 | SD_RSP_R5_IO_CURRENTSTATE1)) != 0x10) &&
1070 ((rflags & (SD_RSP_R5_IO_CURRENTSTATE0 | SD_RSP_R5_IO_CURRENTSTATE1)) != 0x20)) {
1071 sd_err(("%s: R5 flags has bad state: 0x%02x\n", __FUNCTION__, rflags));
1072 err = BCME_SDIO_ERROR;
1073 goto done;
1074 }
1075
1076 if (GFIELD(rsp5, RSP5_STUFF)) {
1077 sd_err(("%s: rsp5 stuff is 0x%x: should be 0\n",
1078 __FUNCTION__, GFIELD(rsp5, RSP5_STUFF)));
1079 err = BCME_SDIO_ERROR;
1080 goto done;
1081 }
1082
1083done:
1084 if (err == BCME_NODEVICE)
1085 return err;
1086
1087 sdstd_wreg8(sd, SD_SoftwareReset,
1088 SFIELD(SFIELD(0, SW_RESET_DAT, 1), SW_RESET_CMD, 1));
1089
1090 retries = RETRIES_LARGE;
1091 do {
1092 rflags = sdstd_rreg8(sd, SD_SoftwareReset);
1093 if (!GFIELD(rflags, SW_RESET_DAT) && !GFIELD(rflags, SW_RESET_CMD))
1094 break;
1095 } while (--retries);
1096
1097 if (!retries) {
1098 sd_err(("%s: Timeout waiting for DAT/CMD reset: 0x%02x\n",
1099 __FUNCTION__, rflags));
1100 err = BCME_SDIO_ERROR;
1101 }
1102
1103 return err;
1104}
1105
1106extern int
1107sdioh_abort(sdioh_info_t *sd, uint fnum)
1108{
1109 int ret;
1110
1111 sdstd_lock(sd);
1112 ret = sdstd_abort(sd, fnum);
1113 sdstd_unlock(sd);
1114
1115 return ret;
1116}
1117
1118int
1119sdioh_start(sdioh_info_t *sd, int stage)
1120{
1121 return SUCCESS;
1122}
1123
1124int
1125sdioh_stop(sdioh_info_t *sd)
1126{
1127 return SUCCESS;
1128}
1129
1130static int
1131sdstd_check_errs(sdioh_info_t *sdioh_info, uint32 cmd, uint32 arg)
1132{
1133 uint16 regval;
1134 uint retries;
1135 uint function = 0;
1136
1137 /* If no errors, we're done */
1138 if ((regval = sdstd_rreg16(sdioh_info, SD_ErrorIntrStatus)) == 0)
1139 return SUCCESS;
1140
1141 sd_info(("%s: ErrorIntrStatus 0x%04x (clearing), IntrStatus 0x%04x PresentState 0x%08x\n",
1142 __FUNCTION__, regval, sdstd_rreg16(sdioh_info, SD_IntrStatus),
1143 sdstd_rreg(sdioh_info, SD_PresentState)));
1144 sdstd_wreg16(sdioh_info, SD_ErrorIntrStatus, regval);
1145
1146 /* On command error, issue CMD reset */
1147 if (regval & ERRINT_CMD_ERRS) {
1148 sd_trace(("%s: issuing CMD reset\n", __FUNCTION__));
1149 sdstd_wreg8(sdioh_info, SD_SoftwareReset, SFIELD(0, SW_RESET_CMD, 1));
1150 for (retries = RETRIES_LARGE; retries; retries--)
1151 if (!(GFIELD(sdstd_rreg8(sdioh_info, SD_SoftwareReset), SW_RESET_CMD)))
1152 break;
1153 if (!retries) {
1154 sd_err(("%s: Timeout waiting for CMD line reset\n", __FUNCTION__));
1155 }
1156 }
1157
1158 /* On data error, issue DAT reset */
1159 if (regval & ERRINT_DATA_ERRS) {
1160 sd_trace(("%s: issuing DAT reset\n", __FUNCTION__));
1161 sdstd_wreg8(sdioh_info, SD_SoftwareReset, SFIELD(0, SW_RESET_DAT, 1));
1162 for (retries = RETRIES_LARGE; retries; retries--)
1163 if (!(GFIELD(sdstd_rreg8(sdioh_info, SD_SoftwareReset), SW_RESET_DAT)))
1164 break;
1165 if (!retries) {
1166 sd_err(("%s: Timeout waiting for DAT line reset\n", __FUNCTION__));
1167 }
1168 }
1169
1170 /* For an IO command (CMD52 or CMD53) issue an abort to the appropriate function */
1171 if (cmd == SDIOH_CMD_53)
1172 function = GFIELD(arg, CMD53_FUNCTION);
1173 else if (cmd == SDIOH_CMD_52)
1174 function = GFIELD(arg, CMD52_FUNCTION);
1175 if (function) {
1176 sd_trace(("%s: requesting abort for function %d after cmd %d\n",
1177 __FUNCTION__, function, cmd));
1178 sdstd_abort(sdioh_info, function);
1179 }
1180
1181 if (trap_errs)
1182 ASSERT(0);
1183
1184 return ERROR;
1185}
1186
1187
1188
1189/*
1190 * Private/Static work routines
1191 */
1192static bool
1193sdstd_reset(sdioh_info_t *sd, bool host_reset, bool client_reset)
1194{
1195 int retries = RETRIES_LARGE;
1196 uchar regval;
1197
1198 if (!sd)
1199 return TRUE;
1200
1201 sdstd_lock(sd);
1202 /* Reset client card */
1203 if (client_reset && (sd->adapter_slot != -1)) {
1204 if (sdstd_card_regwrite(sd, 0, SDIOD_CCCR_IOABORT, 1, 0x8) != SUCCESS)
1205 sd_err(("%s: Cannot write to card reg 0x%x\n",
1206 __FUNCTION__, SDIOD_CCCR_IOABORT));
1207 else
1208 sd->card_rca = 0;
1209 }
1210
1211 /* Reset host controller */
1212 if (host_reset) {
1213 regval = SFIELD(0, SW_RESET_ALL, 1);
1214 sdstd_wreg8(sd, SD_SoftwareReset, regval);
1215 do {
1216 sd_trace(("%s: waiting for reset\n", __FUNCTION__));
1217 } while ((sdstd_rreg8(sd, SD_SoftwareReset) & regval) && retries--);
1218
1219 if (!retries) {
1220 sd_err(("%s: Timeout waiting for host reset\n", __FUNCTION__));
1221 sdstd_unlock(sd);
1222 return (FALSE);
1223 }
1224
1225 /* A reset should reset bus back to 1 bit mode */
1226 sd->sd_mode = SDIOH_MODE_SD1;
1227 sdstd_set_dma_mode(sd, sd->sd_dma_mode);
1228 }
1229 sdstd_unlock(sd);
1230 return TRUE;
1231}
1232
1233/* Disable device interrupt */
1234void
1235sdstd_devintr_off(sdioh_info_t *sd)
1236{
1237 sd_trace(("%s: %d\n", __FUNCTION__, sd->use_client_ints));
1238 if (sd->use_client_ints) {
1239 sd->intmask &= ~CLIENT_INTR;
1240 sdstd_wreg16(sd, SD_IntrSignalEnable, sd->intmask);
1241 sdstd_rreg16(sd, SD_IntrSignalEnable); /* Sync readback */
1242 }
1243}
1244
1245/* Enable device interrupt */
1246void
1247sdstd_devintr_on(sdioh_info_t *sd)
1248{
1249 ASSERT(sd->lockcount == 0);
1250 sd_trace(("%s: %d\n", __FUNCTION__, sd->use_client_ints));
1251 if (sd->use_client_ints) {
1252 uint16 status = sdstd_rreg16(sd, SD_IntrStatusEnable);
1253 sdstd_wreg16(sd, SD_IntrStatusEnable, SFIELD(status, INTSTAT_CARD_INT, 0));
1254 sdstd_wreg16(sd, SD_IntrStatusEnable, status);
1255
1256 sd->intmask |= CLIENT_INTR;
1257 sdstd_wreg16(sd, SD_IntrSignalEnable, sd->intmask);
1258 sdstd_rreg16(sd, SD_IntrSignalEnable); /* Sync readback */
1259 }
1260}
1261
1262#ifdef BCMSDYIELD
1263/* Enable/disable other interrupts */
1264void
1265sdstd_intrs_on(sdioh_info_t *sd, uint16 norm, uint16 err)
1266{
1267 if (err) {
1268 norm = SFIELD(norm, INTSTAT_ERROR_INT, 1);
1269 sdstd_wreg16(sd, SD_ErrorIntrSignalEnable, err);
1270 }
1271
1272 sd->intmask |= norm;
1273 sdstd_wreg16(sd, SD_IntrSignalEnable, sd->intmask);
1274 if (sd_forcerb)
1275 sdstd_rreg16(sd, SD_IntrSignalEnable); /* Sync readback */
1276}
1277
1278void
1279sdstd_intrs_off(sdioh_info_t *sd, uint16 norm, uint16 err)
1280{
1281 if (err) {
1282 norm = SFIELD(norm, INTSTAT_ERROR_INT, 1);
1283 sdstd_wreg16(sd, SD_ErrorIntrSignalEnable, 0);
1284 }
1285
1286 sd->intmask &= ~norm;
1287 sdstd_wreg16(sd, SD_IntrSignalEnable, sd->intmask);
1288 if (sd_forcerb)
1289 sdstd_rreg16(sd, SD_IntrSignalEnable); /* Sync readback */
1290}
1291#endif /* BCMSDYIELD */
1292
1293static int
1294sdstd_host_init(sdioh_info_t *sd)
1295{
1296 int num_slots, full_slot;
1297 uint8 reg8;
1298
1299 uint32 card_ins;
1300 int slot, first_bar = 0;
1301 bool detect_slots = FALSE;
1302 uint bar;
1303
1304 /* Check for Arasan ID */
1305 if ((OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) & 0xFFFF) == VENDOR_SI_IMAGE) {
1306 sd_info(("%s: Found Arasan Standard SDIO Host Controller\n", __FUNCTION__));
1307 sd->controller_type = SDIOH_TYPE_ARASAN_HDK;
1308 detect_slots = TRUE;
1309 } else if ((OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) & 0xFFFF) == VENDOR_BROADCOM) {
1310 sd_info(("%s: Found Broadcom 27xx Standard SDIO Host Controller\n", __FUNCTION__));
1311 sd->controller_type = SDIOH_TYPE_BCM27XX;
1312 detect_slots = FALSE;
1313 } else if ((OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) & 0xFFFF) == VENDOR_TI) {
1314 sd_info(("%s: Found TI PCIxx21 Standard SDIO Host Controller\n", __FUNCTION__));
1315 sd->controller_type = SDIOH_TYPE_TI_PCIXX21;
1316 detect_slots = TRUE;
1317 } else if ((OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) & 0xFFFF) == VENDOR_RICOH) {
1318 sd_info(("%s: Ricoh Co Ltd R5C822 SD/SDIO/MMC/MS/MSPro Host Adapter\n",
1319 __FUNCTION__));
1320 sd->controller_type = SDIOH_TYPE_RICOH_R5C822;
1321 detect_slots = TRUE;
1322 } else if ((OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) & 0xFFFF) == VENDOR_JMICRON) {
1323 sd_info(("%s: JMicron Standard SDIO Host Controller\n",
1324 __FUNCTION__));
1325 sd->controller_type = SDIOH_TYPE_JMICRON;
1326 detect_slots = TRUE;
1327 } else {
1328 return ERROR;
1329 }
1330
1331 /*
1332 * Determine num of slots
1333 * Search each slot
1334 */
1335
1336 first_bar = OSL_PCI_READ_CONFIG(sd->osh, SD_SlotInfo, 4) & 0x7;
1337 num_slots = (OSL_PCI_READ_CONFIG(sd->osh, SD_SlotInfo, 4) & 0xff) >> 4;
1338 num_slots &= 7;
1339 num_slots++; /* map bits to num slots according to spec */
1340
1341 if (OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_VID, 4) ==
1342 ((SDIOH_FPGA_ID << 16) | VENDOR_BROADCOM)) {
1343 sd_err(("%s: Found Broadcom Standard SDIO Host Controller FPGA\n", __FUNCTION__));
1344 /* Set BAR0 Window to SDIOSTH core */
1345 OSL_PCI_WRITE_CONFIG(sd->osh, PCI_BAR0_WIN, 4, 0x18001000);
1346
1347 /* Set defaults particular to this controller. */
1348 detect_slots = TRUE;
1349 num_slots = 1;
1350 first_bar = 0;
1351
1352 /* Controller supports ADMA2, so turn it on here. */
1353 sd->sd_dma_mode = DMA_MODE_ADMA2;
1354 }
1355
1356 /* Map in each slot on the board and query it to see if a
1357 * card is inserted. Use the first populated slot found.
1358 */
1359 if (sd->mem_space) {
1360 sdstd_reg_unmap(sd->osh, (uintptr)sd->mem_space, SDIOH_REG_WINSZ);
1361 sd->mem_space = NULL;
1362 }
1363
1364 full_slot = -1;
1365
1366 for (slot = 0; slot < num_slots; slot++) {
1367 bar = OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_BAR0 + (4*(slot + first_bar)), 4);
1368 sd->mem_space = (volatile char *)sdstd_reg_map(sd->osh,
1369 (uintptr)bar, SDIOH_REG_WINSZ);
1370
1371 sd->adapter_slot = -1;
1372
1373 if (detect_slots) {
1374 card_ins = GFIELD(sdstd_rreg(sd, SD_PresentState), PRES_CARD_PRESENT);
1375 } else {
1376 card_ins = TRUE;
1377 }
1378
1379 if (card_ins) {
1380 sd_info(("%s: SDIO slot %d: Full\n", __FUNCTION__, slot));
1381 if (full_slot < 0)
1382 full_slot = slot;
1383 } else {
1384 sd_info(("%s: SDIO slot %d: Empty\n", __FUNCTION__, slot));
1385 }
1386
1387 if (sd->mem_space) {
1388 sdstd_reg_unmap(sd->osh, (uintptr)sd->mem_space, SDIOH_REG_WINSZ);
1389 sd->mem_space = NULL;
1390 }
1391 }
1392
1393 if (full_slot < 0) {
1394 sd_err(("No slots on SDIO controller are populated\n"));
1395 return -1;
1396 }
1397
1398 bar = OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_BAR0 + (4*(full_slot + first_bar)), 4);
1399 sd->mem_space = (volatile char *)sdstd_reg_map(sd->osh, (uintptr)bar, SDIOH_REG_WINSZ);
1400
1401 sd_err(("Using slot %d at BAR%d [0x%08x] mem_space 0x%p\n",
1402 full_slot,
1403 (full_slot + first_bar),
1404 OSL_PCI_READ_CONFIG(sd->osh, PCI_CFG_BAR0 + (4*(full_slot + first_bar)), 4),
1405 sd->mem_space));
1406
1407
1408 sd->adapter_slot = full_slot;
1409
1410 sd->version = sdstd_rreg16(sd, SD_HostControllerVersion) & 0xFF;
1411 switch (sd->version) {
1412 case 0:
1413 sd_err(("Host Controller version 1.0, Vendor Revision: 0x%02x\n",
1414 sdstd_rreg16(sd, SD_HostControllerVersion) >> 8));
1415 break;
1416 case 1:
1417 case 2:
1418 sd_err(("Host Controller version 2.0, Vendor Revision: 0x%02x\n",
1419 sdstd_rreg16(sd, SD_HostControllerVersion) >> 8));
1420 break;
1421 default:
1422 sd_err(("%s: Host Controller version 0x%02x not supported.\n",
1423 __FUNCTION__, sd->version));
1424 break;
1425 }
1426
1427 sd->caps = sdstd_rreg(sd, SD_Capabilities); /* Cache this for later use */
1428 sd->curr_caps = sdstd_rreg(sd, SD_MaxCurCap);
1429
1430 sdstd_set_dma_mode(sd, sd->sd_dma_mode);
1431
1432
1433 sdstd_reset(sd, 1, 0);
1434
1435 /* Read SD4/SD1 mode */
1436 if ((reg8 = sdstd_rreg8(sd, SD_HostCntrl))) {
1437 if (reg8 & SD4_MODE) {
1438 sd_err(("%s: Host cntrlr already in 4 bit mode: 0x%x\n",
1439 __FUNCTION__, reg8));
1440 }
1441 }
1442
1443 /* Default power on mode is SD1 */
1444 sd->sd_mode = SDIOH_MODE_SD1;
1445 sd->polled_mode = TRUE;
1446 sd->host_init_done = TRUE;
1447 sd->card_init_done = FALSE;
1448 sd->adapter_slot = full_slot;
1449
1450 return (SUCCESS);
1451}
1452#define CMD5_RETRIES 200
1453static int
1454get_ocr(sdioh_info_t *sd, uint32 *cmd_arg, uint32 *cmd_rsp)
1455{
1456 int retries, status;
1457
1458 /* Get the Card's Operation Condition. Occasionally the board
1459 * takes a while to become ready
1460 */
1461 retries = CMD5_RETRIES;
1462 do {
1463 *cmd_rsp = 0;
1464 if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_5, *cmd_arg))
1465 != SUCCESS) {
1466 sd_err(("%s: CMD5 failed\n", __FUNCTION__));
1467 return status;
1468 }
1469 sdstd_cmd_getrsp(sd, cmd_rsp, 1);
1470 if (!GFIELD(*cmd_rsp, RSP4_CARD_READY))
1471 sd_trace(("%s: Waiting for card to become ready\n", __FUNCTION__));
1472 } while ((!GFIELD(*cmd_rsp, RSP4_CARD_READY)) && --retries);
1473 if (!retries)
1474 return ERROR;
1475
1476 return (SUCCESS);
1477}
1478
1479static int
1480sdstd_client_init(sdioh_info_t *sd)
1481{
1482 uint32 cmd_arg, cmd_rsp;
1483 int status;
1484 uint8 fn_ints;
1485
1486
1487 sd_trace(("%s: Powering up slot %d\n", __FUNCTION__, sd->adapter_slot));
1488
1489 /* Clear any pending ints */
1490 sdstd_wreg16(sd, SD_IntrStatus, 0x1ff);
1491 sdstd_wreg16(sd, SD_ErrorIntrStatus, 0x0fff);
1492
1493 /* Enable both Normal and Error Status. This does not enable
1494 * interrupts, it only enables the status bits to
1495 * become 'live'
1496 */
1497 sdstd_wreg16(sd, SD_IntrStatusEnable, 0x1ff);
1498 sdstd_wreg16(sd, SD_ErrorIntrStatusEnable, 0xffff);
1499
1500 sdstd_wreg16(sd, SD_IntrSignalEnable, 0); /* Disable ints for now. */
1501
1502 /* Start at ~400KHz clock rate for initialization */
1503 if (!sdstd_start_clock(sd, 128)) {
1504 sd_err(("sdstd_start_clock failed\n"));
1505 return ERROR;
1506 }
1507 if (!sdstd_start_power(sd)) {
1508 sd_err(("sdstd_start_power failed\n"));
1509 return ERROR;
1510 }
1511
1512 if (sd->num_funcs == 0) {
1513 sd_err(("%s: No IO funcs!\n", __FUNCTION__));
1514 return ERROR;
1515 }
1516
1517 /* In SPI mode, issue CMD0 first */
1518 if (sd->sd_mode == SDIOH_MODE_SPI) {
1519 cmd_arg = 0;
1520 if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_0, cmd_arg))
1521 != SUCCESS) {
1522 sd_err(("BCMSDIOH: cardinit: CMD0 failed!\n"));
1523 return status;
1524 }
1525 }
1526
1527 if (sd->sd_mode != SDIOH_MODE_SPI) {
1528 uint16 rsp6_status;
1529
1530 /* Card is operational. Ask it to send an RCA */
1531 cmd_arg = 0;
1532 if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_3, cmd_arg))
1533 != SUCCESS) {
1534 sd_err(("%s: CMD3 failed!\n", __FUNCTION__));
1535 return status;
1536 }
1537
1538 /* Verify the card status returned with the cmd response */
1539 sdstd_cmd_getrsp(sd, &cmd_rsp, 1);
1540 rsp6_status = GFIELD(cmd_rsp, RSP6_STATUS);
1541 if (GFIELD(rsp6_status, RSP6STAT_COM_CRC_ERROR) ||
1542 GFIELD(rsp6_status, RSP6STAT_ILLEGAL_CMD) ||
1543 GFIELD(rsp6_status, RSP6STAT_ERROR)) {
1544 sd_err(("%s: CMD3 response error. Response = 0x%x!\n",
1545 __FUNCTION__, rsp6_status));
1546 return ERROR;
1547 }
1548
1549 /* Save the Card's RCA */
1550 sd->card_rca = GFIELD(cmd_rsp, RSP6_IO_RCA);
1551 sd_info(("RCA is 0x%x\n", sd->card_rca));
1552
1553 if (rsp6_status)
1554 sd_err(("raw status is 0x%x\n", rsp6_status));
1555
1556 /* Select the card */
1557 cmd_arg = SFIELD(0, CMD7_RCA, sd->card_rca);
1558 if ((status = sdstd_cmd_issue(sd, USE_DMA(sd), SDIOH_CMD_7, cmd_arg))
1559 != SUCCESS) {
1560 sd_err(("%s: CMD7 failed!\n", __FUNCTION__));
1561 return status;
1562 }
1563 sdstd_cmd_getrsp(sd, &cmd_rsp, 1);
1564 if (cmd_rsp != SDIOH_CMD7_EXP_STATUS) {
1565 sd_err(("%s: CMD7 response error. Response = 0x%x!\n",
1566 __FUNCTION__, cmd_rsp));
1567 return ERROR;
1568 }
1569 }
1570
1571 sdstd_card_enablefuncs(sd);
1572
1573 if (!sdstd_bus_width(sd, sd_sdmode)) {
1574 sd_err(("sdstd_bus_width failed\n"));
1575 return ERROR;
1576 }
1577
1578 set_client_block_size(sd, 1, BLOCK_SIZE_4318);
1579 fn_ints = INTR_CTL_FUNC1_EN;
1580
1581 if (sd->num_funcs >= 2) {
1582 set_client_block_size(sd, 2, sd_f2_blocksize /* BLOCK_SIZE_4328 */);
1583 fn_ints |= INTR_CTL_FUNC2_EN;
1584 }
1585
1586 /* Enable/Disable Client interrupts */
1587 /* Turn on here but disable at host controller? */
1588 if (sdstd_card_regwrite(sd, 0, SDIOD_CCCR_INTEN, 1,
1589 (fn_ints | INTR_CTL_MASTER_EN)) != SUCCESS) {
1590 sd_err(("%s: Could not enable ints in CCCR\n", __FUNCTION__));
1591 return ERROR;
1592 }
1593
1594 /* Switch to High-speed clocking mode if both host and device support it */
1595 sdstd_set_highspeed_mode(sd, (bool)sd_hiok);
1596
1597 /* After configuring for High-Speed mode, set the desired clock rate. */
1598 if (!sdstd_start_clock(sd, (uint16)sd_divisor)) {
1599 sd_err(("sdstd_start_clock failed\n"));
1600 return ERROR;
1601 }
1602
1603 sd->card_init_done = TRUE;
1604
1605 return SUCCESS;
1606}
1607
1608static int
1609sdstd_set_highspeed_mode(sdioh_info_t *sd, bool HSMode)
1610{
1611 uint32 regdata;
1612 int status;
1613 uint8 reg8;
1614
1615 reg8 = sdstd_rreg8(sd, SD_HostCntrl);
1616
1617
1618 if (HSMode == TRUE) {
1619 if (sd_hiok && (GFIELD(sd->caps, CAP_HIGHSPEED)) == 0) {
1620 sd_err(("Host Controller does not support hi-speed mode.\n"));
1621 return BCME_ERROR;
1622 }
1623
1624 sd_info(("Attempting to enable High-Speed mode.\n"));
1625
1626 if ((status = sdstd_card_regread(sd, 0, SDIOD_CCCR_SPEED_CONTROL,
1627 1, ®data)) != SUCCESS) {
1628 return BCME_SDIO_ERROR;
1629 }
1630 if (regdata & SDIO_SPEED_SHS) {
1631 sd_info(("Device supports High-Speed mode.\n"));
1632
1633 regdata |= SDIO_SPEED_EHS;
1634
1635 sd_info(("Writing %08x to Card at %08x\n",
1636 regdata, SDIOD_CCCR_SPEED_CONTROL));
1637 if ((status = sdstd_card_regwrite(sd, 0, SDIOD_CCCR_SPEED_CONTROL,
1638 1, regdata)) != BCME_OK) {
1639 return BCME_SDIO_ERROR;
1640 }
1641
1642 if ((status = sdstd_card_regread(sd, 0, SDIOD_CCCR_SPEED_CONTROL,
1643 1, ®data)) != BCME_OK) {
1644 return BCME_SDIO_ERROR;
1645 }
1646
1647 sd_info(("Read %08x to Card at %08x\n", regdata, SDIOD_CCCR_SPEED_CONTROL));
1648
1649 reg8 = SFIELD(reg8, HOST_HI_SPEED_EN, 1);
1650
1651 sd_err(("High-speed clocking mode enabled.\n"));
1652 }
1653 else {
1654 sd_err(("Device does not support High-Speed Mode.\n"));
1655 reg8 = SFIELD(reg8, HOST_HI_SPEED_EN, 0);
1656 }
1657 } else {
1658 /* Force off device bit */
1659 if ((status = sdstd_card_regread(sd, 0, SDIOD_CCCR_SPEED_CONTROL,
1660 1, ®data)) != BCME_OK) {
1661 return status;
1662 }
1663 if (regdata & SDIO_SPEED_EHS) {
1664 regdata &= ~SDIO_SPEED_EHS;
1665 if ((status = sdstd_card_regwrite(sd, 0, SDIOD_CCCR_SPEED_CONTROL,
1666 1, regdata)) != BCME_OK) {
1667 return status;
1668 }
1669 }
1670
1671 sd_err(("High-speed clocking mode disabled.\n"));
1672 reg8 = SFIELD(reg8, HOST_HI_SPEED_EN, 0);
1673 }
1674
1675 sdstd_wreg8(sd, SD_HostCntrl, reg8);
1676
1677 return BCME_OK;
1678}
1679
1680/* Select DMA Mode:
1681 * If dma_mode == DMA_MODE_AUTO, pick the "best" mode.
1682 * Otherwise, pick the selected mode if supported.
1683 * If not supported, use PIO mode.
1684 */
1685static int
1686sdstd_set_dma_mode(sdioh_info_t *sd, int8 dma_mode)
1687{
1688 uint8 reg8, dma_sel_bits = SDIOH_SDMA_MODE;
1689 int8 prev_dma_mode = sd->sd_dma_mode;
1690
1691 switch (prev_dma_mode) {
1692 case DMA_MODE_AUTO:
1693 sd_dma(("%s: Selecting best DMA mode supported by controller.\n",
1694 __FUNCTION__));
1695 if (GFIELD(sd->caps, CAP_ADMA2)) {
1696 sd->sd_dma_mode = DMA_MODE_ADMA2;
1697 dma_sel_bits = SDIOH_ADMA2_MODE;
1698 } else if (GFIELD(sd->caps, CAP_ADMA1)) {
1699 sd->sd_dma_mode = DMA_MODE_ADMA1;
1700 dma_sel_bits = SDIOH_ADMA1_MODE;
1701 } else if (GFIELD(sd->caps, CAP_DMA)) {
1702 sd->sd_dma_mode = DMA_MODE_SDMA;
1703 } else {
1704 sd->sd_dma_mode = DMA_MODE_NONE;
1705 }
1706 break;
1707 case DMA_MODE_NONE:
1708 sd->sd_dma_mode = DMA_MODE_NONE;
1709 break;
1710 case DMA_MODE_SDMA:
1711 if (GFIELD(sd->caps, CAP_DMA)) {
1712 sd->sd_dma_mode = DMA_MODE_SDMA;
1713 } else {
1714 sd_err(("%s: SDMA not supported by controller.\n", __FUNCTION__));
1715 sd->sd_dma_mode = DMA_MODE_NONE;
1716 }
1717 break;
1718 case DMA_MODE_ADMA1:
1719 if (GFIELD(sd->caps, CAP_ADMA1)) {
1720 sd->sd_dma_mode = DMA_MODE_ADMA1;
1721 dma_sel_bits = SDIOH_ADMA1_MODE;
1722 } else {
1723 sd_err(("%s: ADMA1 not supported by controller.\n", __FUNCTION__));
1724 sd->sd_dma_mode = DMA_MODE_NONE;
1725 }
1726 break;
1727 case DMA_MODE_ADMA2:
1728 if (GFIELD(sd->caps, CAP_ADMA2)) {
1729 sd->sd_dma_mode = DMA_MODE_ADMA2;
1730 dma_sel_bits = SDIOH_ADMA2_MODE;
1731 } else {
1732 sd_err(("%s: ADMA2 not supported by controller.\n", __FUNCTION__));
1733 sd->sd_dma_mode = DMA_MODE_NONE;
1734 }
1735 break;
1736 case DMA_MODE_ADMA2_64:
1737 sd_err(("%s: 64b ADMA2 not supported by driver.\n", __FUNCTION__));
1738 sd->sd_dma_mode = DMA_MODE_NONE;
1739 break;
1740 default:
1741 sd_err(("%s: Unsupported DMA Mode %d requested.\n", __FUNCTION__,
1742 prev_dma_mode));
1743 sd->sd_dma_mode = DMA_MODE_NONE;
1744 break;
1745 }
1746
1747 /* clear SysAddr, only used for SDMA */
1748 sdstd_wreg(sd, SD_SysAddr, 0);
1749
1750 sd_err(("%s: %s mode selected.\n", __FUNCTION__, dma_mode_description[sd->sd_dma_mode]));
1751
1752 reg8 = sdstd_rreg8(sd, SD_HostCntrl);
1753 reg8 = SFIELD(reg8, HOST_DMA_SEL, dma_sel_bits);
1754 sdstd_wreg8(sd, SD_HostCntrl, reg8);
1755 sd_dma(("%s: SD_HostCntrl=0x%02x\n", __FUNCTION__, reg8));
1756
1757 return BCME_OK;
1758}
1759
1760
1761bool
1762sdstd_start_clock(sdioh_info_t *sd, uint16 new_sd_divisor)
1763{
1764 uint rc, count;
1765 uint16 divisor;
1766
1767 /* turn off HC clock */
1768 sdstd_wreg16(sd, SD_ClockCntrl,
1769 sdstd_rreg16(sd, SD_ClockCntrl) & ~((uint16)0x4)); /* Disable the HC clock */
1770
1771 /* Set divisor */
1772
1773 divisor = (new_sd_divisor >> 1) << 8;
1774
1775 sd_info(("Clock control is 0x%x\n", sdstd_rreg16(sd, SD_ClockCntrl)));
1776 sdstd_mod_reg16(sd, SD_ClockCntrl, 0xff00, divisor);
1777 sd_info(("%s: Using clock divisor of %d (regval 0x%04x)\n", __FUNCTION__,
1778 new_sd_divisor, divisor));
1779
1780 sd_info(("Primary Clock Freq = %d MHz\n", GFIELD(sd->caps, CAP_TO_CLKFREQ)));
1781
1782 if (GFIELD(sd->caps, CAP_TO_CLKFREQ) == 50) {
1783 sd_info(("%s: Resulting SDIO clock is %d %s\n", __FUNCTION__,
1784 ((50 % new_sd_divisor) ? (50000 / new_sd_divisor) : (50 / new_sd_divisor)),
1785 ((50 % new_sd_divisor) ? "KHz" : "MHz")));
1786 } else if (GFIELD(sd->caps, CAP_TO_CLKFREQ) == 48) {
1787 sd_info(("%s: Resulting SDIO clock is %d %s\n", __FUNCTION__,
1788 ((48 % new_sd_divisor) ? (48000 / new_sd_divisor) : (48 / new_sd_divisor)),
1789 ((48 % new_sd_divisor) ? "KHz" : "MHz")));
1790 } else if (GFIELD(sd->caps, CAP_TO_CLKFREQ) == 33) {
1791 sd_info(("%s: Resulting SDIO clock is %d %s\n", __FUNCTION__,
1792 ((33 % new_sd_divisor) ? (33000 / new_sd_divisor) : (33 / new_sd_divisor)),
1793 ((33 % new_sd_divisor) ? "KHz" : "MHz")));
1794
1795 } else if (sd->controller_type == SDIOH_TYPE_BCM27XX) {
1796 } else {
1797 sd_err(("Need to determine divisor for %d MHz clocks\n",
1798 GFIELD(sd->caps, CAP_TO_CLKFREQ)));
1799 sd_err(("Consult SD Host Controller Spec: Clock Control Register\n"));
1800 …
Large files files are truncated, but you can click here to view the full file