2 * Copyright (c) 2011 Broadcom Corporation
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 /* ***** SDIO interface chip backplane handle functions ***** */
18 #include <linux/types.h>
19 #include <linux/netdevice.h>
20 #include <linux/mmc/card.h>
21 #include <linux/mmc/sdio_func.h>
22 #include <linux/mmc/sdio_ids.h>
23 #include <linux/ssb/ssb_regs.h>
24 #include <linux/bcma/bcma.h>
26 #include <chipcommon.h>
27 #include <brcm_hw_ids.h>
28 #include <brcmu_wifi.h>
29 #include <brcmu_utils.h>
32 #include "sdio_host.h"
33 #include "sdio_chip.h"
35 /* chip core base & ramsize */
37 /* SDIO device core, ID 0x829 */
38 #define BCM4329_CORE_BUS_BASE 0x18011000
39 /* internal memory core, ID 0x80e */
40 #define BCM4329_CORE_SOCRAM_BASE 0x18003000
41 /* ARM Cortex M3 core, ID 0x82a */
42 #define BCM4329_CORE_ARM_BASE 0x18002000
43 #define BCM4329_RAMSIZE 0x48000
46 /* SDIO device core */
47 #define BCM43143_CORE_BUS_BASE 0x18002000
48 /* internal memory core */
49 #define BCM43143_CORE_SOCRAM_BASE 0x18004000
50 /* ARM Cortex M3 core, ID 0x82a */
51 #define BCM43143_CORE_ARM_BASE 0x18003000
52 #define BCM43143_RAMSIZE 0x70000
54 #define SBCOREREV(sbidh) \
55 ((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \
56 ((sbidh) & SSB_IDHIGH_RCLO))
58 /* SOC Interconnect types (aka chip types) */
63 #define CIB_REV_MASK 0xff000000
64 #define CIB_REV_SHIFT 24
66 /* ARM CR4 core specific control flag bits */
67 #define ARMCR4_BCMA_IOCTL_CPUHALT 0x0020
69 #define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu))
70 /* SDIO Pad drive strength to select value mappings */
71 struct sdiod_drive_str {
72 u8 strength; /* Pad Drive Strength in mA */
73 u8 sel; /* Chip-specific select value */
75 /* SDIO Drive Strength to sel value table for PMU Rev 11 (1.8V) */
76 static const struct sdiod_drive_str sdiod_drvstr_tab1_1v8[] = {
87 /* SDIO Drive Strength to sel value table for PMU Rev 13 (1.8v) */
88 static const struct sdiod_drive_str sdiod_drive_strength_tab5_1v8[] = {
98 /* SDIO Drive Strength to sel value table for PMU Rev 17 (1.8v) */
99 static const struct sdiod_drive_str sdiod_drvstr_tab6_1v8[] = {
105 /* SDIO Drive Strength to sel value table for 43143 PMU Rev 17 (3.3V) */
106 static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = {
114 brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid)
118 for (idx = 0; idx < BRCMF_MAX_CORENUM; idx++)
119 if (coreid == ci->c_inf[idx].id)
122 return BRCMF_MAX_CORENUM;
126 brcmf_sdio_sb_corerev(struct brcmf_sdio_dev *sdiodev,
127 struct chip_info *ci, u16 coreid)
132 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
134 regdata = brcmf_sdiod_regrl(sdiodev,
135 CORE_SB(ci->c_inf[idx].base, sbidhigh),
137 return SBCOREREV(regdata);
141 brcmf_sdio_ai_corerev(struct brcmf_sdio_dev *sdiodev,
142 struct chip_info *ci, u16 coreid)
146 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
148 return (ci->c_inf[idx].cib & CIB_REV_MASK) >> CIB_REV_SHIFT;
152 brcmf_sdio_sb_iscoreup(struct brcmf_sdio_dev *sdiodev,
153 struct chip_info *ci, u16 coreid)
158 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
159 if (idx == BRCMF_MAX_CORENUM)
162 regdata = brcmf_sdiod_regrl(sdiodev,
163 CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
165 regdata &= (SSB_TMSLOW_RESET | SSB_TMSLOW_REJECT |
166 SSB_IMSTATE_REJECT | SSB_TMSLOW_CLOCK);
167 return (SSB_TMSLOW_CLOCK == regdata);
171 brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev,
172 struct chip_info *ci, u16 coreid)
178 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
179 if (idx == BRCMF_MAX_CORENUM)
182 regdata = brcmf_sdiod_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
184 ret = (regdata & (BCMA_IOCTL_FGC | BCMA_IOCTL_CLK)) == BCMA_IOCTL_CLK;
186 regdata = brcmf_sdiod_regrl(sdiodev,
187 ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
189 ret = ret && ((regdata & BCMA_RESET_CTL_RESET) == 0);
195 brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev,
196 struct chip_info *ci, u16 coreid, u32 core_bits)
201 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
202 base = ci->c_inf[idx].base;
204 regdata = brcmf_sdiod_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL);
205 if (regdata & SSB_TMSLOW_RESET)
208 regdata = brcmf_sdiod_regrl(sdiodev, CORE_SB(base, sbtmstatelow), NULL);
209 if ((regdata & SSB_TMSLOW_CLOCK) != 0) {
211 * set target reject and spin until busy is clear
212 * (preserve core-specific bits)
214 regdata = brcmf_sdiod_regrl(sdiodev,
215 CORE_SB(base, sbtmstatelow), NULL);
216 brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
217 regdata | SSB_TMSLOW_REJECT, NULL);
219 regdata = brcmf_sdiod_regrl(sdiodev,
220 CORE_SB(base, sbtmstatelow), NULL);
222 SPINWAIT((brcmf_sdiod_regrl(sdiodev,
223 CORE_SB(base, sbtmstatehigh),
225 SSB_TMSHIGH_BUSY), 100000);
227 regdata = brcmf_sdiod_regrl(sdiodev,
228 CORE_SB(base, sbtmstatehigh),
230 if (regdata & SSB_TMSHIGH_BUSY)
231 brcmf_err("core state still busy\n");
233 regdata = brcmf_sdiod_regrl(sdiodev, CORE_SB(base, sbidlow),
235 if (regdata & SSB_IDLOW_INITIATOR) {
236 regdata = brcmf_sdiod_regrl(sdiodev,
237 CORE_SB(base, sbimstate),
239 regdata |= SSB_IMSTATE_REJECT;
240 brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbimstate),
242 regdata = brcmf_sdiod_regrl(sdiodev,
243 CORE_SB(base, sbimstate),
246 SPINWAIT((brcmf_sdiod_regrl(sdiodev,
247 CORE_SB(base, sbimstate),
249 SSB_IMSTATE_BUSY), 100000);
252 /* set reset and reject while enabling the clocks */
253 regdata = SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK |
254 SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET;
255 brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
257 regdata = brcmf_sdiod_regrl(sdiodev,
258 CORE_SB(base, sbtmstatelow), NULL);
261 /* clear the initiator reject bit */
262 regdata = brcmf_sdiod_regrl(sdiodev, CORE_SB(base, sbidlow),
264 if (regdata & SSB_IDLOW_INITIATOR) {
265 regdata = brcmf_sdiod_regrl(sdiodev,
266 CORE_SB(base, sbimstate),
268 regdata &= ~SSB_IMSTATE_REJECT;
269 brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbimstate),
274 /* leave reset and reject asserted */
275 brcmf_sdiod_regwl(sdiodev, CORE_SB(base, sbtmstatelow),
276 (SSB_TMSLOW_REJECT | SSB_TMSLOW_RESET), NULL);
281 brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev,
282 struct chip_info *ci, u16 coreid, u32 core_bits)
287 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
288 if (idx == BRCMF_MAX_CORENUM)
291 /* if core is already in reset, just return */
292 regdata = brcmf_sdiod_regrl(sdiodev,
293 ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
295 if ((regdata & BCMA_RESET_CTL_RESET) != 0)
298 /* ensure no pending backplane operation
299 * 300uc should be sufficient for backplane ops to be finish
300 * extra 10ms is taken into account for firmware load stage
301 * after 10300us carry on disabling the core anyway
303 SPINWAIT(brcmf_sdiod_regrl(sdiodev,
304 ci->c_inf[idx].wrapbase+BCMA_RESET_ST,
306 regdata = brcmf_sdiod_regrl(sdiodev,
307 ci->c_inf[idx].wrapbase+BCMA_RESET_ST,
310 brcmf_err("disabling core 0x%x with reset status %x\n",
313 brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
314 BCMA_RESET_CTL_RESET, NULL);
317 brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
319 regdata = brcmf_sdiod_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
321 usleep_range(10, 20);
326 brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev,
327 struct chip_info *ci, u16 coreid, u32 core_bits)
332 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
333 if (idx == BRCMF_MAX_CORENUM)
337 * Must do the disable sequence first to work for
338 * arbitrary current core state.
340 brcmf_sdio_sb_coredisable(sdiodev, ci, coreid, 0);
343 * Now do the initialization sequence.
344 * set reset while enabling the clock and
345 * forcing them on throughout the core
347 brcmf_sdiod_regwl(sdiodev,
348 CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
349 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK | SSB_TMSLOW_RESET,
351 regdata = brcmf_sdiod_regrl(sdiodev,
352 CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
356 /* clear any serror */
357 regdata = brcmf_sdiod_regrl(sdiodev,
358 CORE_SB(ci->c_inf[idx].base, sbtmstatehigh),
360 if (regdata & SSB_TMSHIGH_SERR)
361 brcmf_sdiod_regwl(sdiodev,
362 CORE_SB(ci->c_inf[idx].base, sbtmstatehigh),
365 regdata = brcmf_sdiod_regrl(sdiodev,
366 CORE_SB(ci->c_inf[idx].base, sbimstate),
368 if (regdata & (SSB_IMSTATE_IBE | SSB_IMSTATE_TO))
369 brcmf_sdiod_regwl(sdiodev,
370 CORE_SB(ci->c_inf[idx].base, sbimstate),
371 regdata & ~(SSB_IMSTATE_IBE | SSB_IMSTATE_TO),
374 /* clear reset and allow it to propagate throughout the core */
375 brcmf_sdiod_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
376 SSB_TMSLOW_FGC | SSB_TMSLOW_CLOCK, NULL);
377 regdata = brcmf_sdiod_regrl(sdiodev,
378 CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
382 /* leave clock enabled */
383 brcmf_sdiod_regwl(sdiodev, CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
384 SSB_TMSLOW_CLOCK, NULL);
385 regdata = brcmf_sdiod_regrl(sdiodev,
386 CORE_SB(ci->c_inf[idx].base, sbtmstatelow),
392 brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev,
393 struct chip_info *ci, u16 coreid, u32 core_bits)
398 idx = brcmf_sdio_chip_getinfidx(ci, coreid);
399 if (idx == BRCMF_MAX_CORENUM)
402 /* must disable first to work for arbitrary current core state */
403 brcmf_sdio_ai_coredisable(sdiodev, ci, coreid, core_bits);
405 /* now do initialization sequence */
406 brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
407 core_bits | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL);
408 regdata = brcmf_sdiod_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
410 brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
412 regdata = brcmf_sdiod_regrl(sdiodev,
413 ci->c_inf[idx].wrapbase+BCMA_RESET_CTL,
417 brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
418 core_bits | BCMA_IOCTL_CLK, NULL);
419 regdata = brcmf_sdiod_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL,
425 /* safety check for chipinfo */
426 static int brcmf_sdio_chip_cichk(struct chip_info *ci)
430 /* check RAM core presence for ARM CM3 core */
431 core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3);
432 if (BRCMF_MAX_CORENUM != core_idx) {
433 core_idx = brcmf_sdio_chip_getinfidx(ci,
434 BCMA_CORE_INTERNAL_MEM);
435 if (BRCMF_MAX_CORENUM == core_idx) {
436 brcmf_err("RAM core not provided with ARM CM3 core\n");
441 /* check RAM base for ARM CR4 core */
442 core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CR4);
443 if (BRCMF_MAX_CORENUM != core_idx) {
444 if (ci->rambase == 0) {
445 brcmf_err("RAM base not provided with ARM CR4 core\n");
453 static inline int brcmf_sdio_chip_cichk(struct chip_info *ci)
459 static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
460 struct chip_info *ci)
466 * Chipid is assume to be at offset 0 from regs arg
467 * For different chiptypes or old sdio hosts w/o chipcommon,
468 * other ways of recognition should be added here.
470 ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON;
471 ci->c_inf[0].base = SI_ENUM_BASE;
472 regdata = brcmf_sdiod_regrl(sdiodev,
473 CORE_CC_REG(ci->c_inf[0].base, chipid),
475 ci->chip = regdata & CID_ID_MASK;
476 ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
477 if (sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 &&
479 ci->chip = BCM4339_CHIP_ID;
480 ci->socitype = (regdata & CID_TYPE_MASK) >> CID_TYPE_SHIFT;
482 brcmf_dbg(INFO, "chipid=0x%x chiprev=%d\n", ci->chip, ci->chiprev);
484 /* Address of cores for new chips should be added here */
486 case BCM43143_CHIP_ID:
487 ci->c_inf[0].wrapbase = ci->c_inf[0].base + 0x00100000;
488 ci->c_inf[0].cib = 0x2b000000;
489 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
490 ci->c_inf[1].base = BCM43143_CORE_BUS_BASE;
491 ci->c_inf[1].wrapbase = ci->c_inf[1].base + 0x00100000;
492 ci->c_inf[1].cib = 0x18000000;
493 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
494 ci->c_inf[2].base = BCM43143_CORE_SOCRAM_BASE;
495 ci->c_inf[2].wrapbase = ci->c_inf[2].base + 0x00100000;
496 ci->c_inf[2].cib = 0x14000000;
497 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
498 ci->c_inf[3].base = BCM43143_CORE_ARM_BASE;
499 ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000;
500 ci->c_inf[3].cib = 0x07000000;
501 ci->ramsize = BCM43143_RAMSIZE;
503 case BCM43241_CHIP_ID:
504 ci->c_inf[0].wrapbase = 0x18100000;
505 ci->c_inf[0].cib = 0x2a084411;
506 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
507 ci->c_inf[1].base = 0x18002000;
508 ci->c_inf[1].wrapbase = 0x18102000;
509 ci->c_inf[1].cib = 0x0e004211;
510 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
511 ci->c_inf[2].base = 0x18004000;
512 ci->c_inf[2].wrapbase = 0x18104000;
513 ci->c_inf[2].cib = 0x14080401;
514 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
515 ci->c_inf[3].base = 0x18003000;
516 ci->c_inf[3].wrapbase = 0x18103000;
517 ci->c_inf[3].cib = 0x07004211;
518 ci->ramsize = 0x90000;
520 case BCM4329_CHIP_ID:
521 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
522 ci->c_inf[1].base = BCM4329_CORE_BUS_BASE;
523 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
524 ci->c_inf[2].base = BCM4329_CORE_SOCRAM_BASE;
525 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
526 ci->c_inf[3].base = BCM4329_CORE_ARM_BASE;
527 ci->ramsize = BCM4329_RAMSIZE;
529 case BCM4330_CHIP_ID:
530 ci->c_inf[0].wrapbase = 0x18100000;
531 ci->c_inf[0].cib = 0x27004211;
532 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
533 ci->c_inf[1].base = 0x18002000;
534 ci->c_inf[1].wrapbase = 0x18102000;
535 ci->c_inf[1].cib = 0x07004211;
536 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
537 ci->c_inf[2].base = 0x18004000;
538 ci->c_inf[2].wrapbase = 0x18104000;
539 ci->c_inf[2].cib = 0x0d080401;
540 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
541 ci->c_inf[3].base = 0x18003000;
542 ci->c_inf[3].wrapbase = 0x18103000;
543 ci->c_inf[3].cib = 0x03004211;
544 ci->ramsize = 0x48000;
546 case BCM4334_CHIP_ID:
547 ci->c_inf[0].wrapbase = 0x18100000;
548 ci->c_inf[0].cib = 0x29004211;
549 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
550 ci->c_inf[1].base = 0x18002000;
551 ci->c_inf[1].wrapbase = 0x18102000;
552 ci->c_inf[1].cib = 0x0d004211;
553 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
554 ci->c_inf[2].base = 0x18004000;
555 ci->c_inf[2].wrapbase = 0x18104000;
556 ci->c_inf[2].cib = 0x13080401;
557 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
558 ci->c_inf[3].base = 0x18003000;
559 ci->c_inf[3].wrapbase = 0x18103000;
560 ci->c_inf[3].cib = 0x07004211;
561 ci->ramsize = 0x80000;
563 case BCM4335_CHIP_ID:
564 ci->c_inf[0].wrapbase = 0x18100000;
565 ci->c_inf[0].cib = 0x2b084411;
566 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
567 ci->c_inf[1].base = 0x18005000;
568 ci->c_inf[1].wrapbase = 0x18105000;
569 ci->c_inf[1].cib = 0x0f004211;
570 ci->c_inf[2].id = BCMA_CORE_ARM_CR4;
571 ci->c_inf[2].base = 0x18002000;
572 ci->c_inf[2].wrapbase = 0x18102000;
573 ci->c_inf[2].cib = 0x01084411;
574 ci->ramsize = 0xc0000;
575 ci->rambase = 0x180000;
577 case BCM4339_CHIP_ID:
578 ci->c_inf[0].wrapbase = 0x18100000;
579 ci->c_inf[0].cib = 0x2e084411;
580 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
581 ci->c_inf[1].base = 0x18005000;
582 ci->c_inf[1].wrapbase = 0x18105000;
583 ci->c_inf[1].cib = 0x15004211;
584 ci->c_inf[2].id = BCMA_CORE_ARM_CR4;
585 ci->c_inf[2].base = 0x18002000;
586 ci->c_inf[2].wrapbase = 0x18102000;
587 ci->c_inf[2].cib = 0x04084411;
588 ci->ramsize = 0xc0000;
589 ci->rambase = 0x180000;
591 case BCM43362_CHIP_ID:
592 ci->c_inf[0].wrapbase = 0x18100000;
593 ci->c_inf[0].cib = 0x27004211;
594 ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
595 ci->c_inf[1].base = 0x18002000;
596 ci->c_inf[1].wrapbase = 0x18102000;
597 ci->c_inf[1].cib = 0x0a004211;
598 ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
599 ci->c_inf[2].base = 0x18004000;
600 ci->c_inf[2].wrapbase = 0x18104000;
601 ci->c_inf[2].cib = 0x08080401;
602 ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
603 ci->c_inf[3].base = 0x18003000;
604 ci->c_inf[3].wrapbase = 0x18103000;
605 ci->c_inf[3].cib = 0x03004211;
606 ci->ramsize = 0x3C000;
609 brcmf_err("chipid 0x%x is not supported\n", ci->chip);
613 ret = brcmf_sdio_chip_cichk(ci);
617 switch (ci->socitype) {
619 ci->iscoreup = brcmf_sdio_sb_iscoreup;
620 ci->corerev = brcmf_sdio_sb_corerev;
621 ci->coredisable = brcmf_sdio_sb_coredisable;
622 ci->resetcore = brcmf_sdio_sb_resetcore;
625 ci->iscoreup = brcmf_sdio_ai_iscoreup;
626 ci->corerev = brcmf_sdio_ai_corerev;
627 ci->coredisable = brcmf_sdio_ai_coredisable;
628 ci->resetcore = brcmf_sdio_ai_resetcore;
631 brcmf_err("socitype %u not supported\n", ci->socitype);
639 brcmf_sdio_chip_buscoreprep(struct brcmf_sdio_dev *sdiodev)
644 /* Try forcing SDIO core to do ALPAvail request only */
645 clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_ALP_AVAIL_REQ;
646 brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
648 brcmf_err("error writing for HT off\n");
652 /* If register supported, wait for ALPAvail and then force ALP */
653 /* This may take up to 15 milliseconds */
654 clkval = brcmf_sdiod_regrb(sdiodev,
655 SBSDIO_FUNC1_CHIPCLKCSR, NULL);
657 if ((clkval & ~SBSDIO_AVBITS) != clkset) {
658 brcmf_err("ChipClkCSR access: wrote 0x%02x read 0x%02x\n",
663 SPINWAIT(((clkval = brcmf_sdiod_regrb(sdiodev,
664 SBSDIO_FUNC1_CHIPCLKCSR, NULL)),
665 !SBSDIO_ALPAV(clkval)),
666 PMU_MAX_TRANSITION_DLY);
667 if (!SBSDIO_ALPAV(clkval)) {
668 brcmf_err("timeout on ALPAV wait, clkval 0x%02x\n",
673 clkset = SBSDIO_FORCE_HW_CLKREQ_OFF | SBSDIO_FORCE_ALP;
674 brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR, clkset, &err);
677 /* Also, disable the extra SDIO pull-ups */
678 brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_SDIOPULLUP, 0, NULL);
684 brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev,
685 struct chip_info *ci)
687 u32 base = ci->c_inf[0].base;
689 /* get chipcommon rev */
690 ci->c_inf[0].rev = ci->corerev(sdiodev, ci, ci->c_inf[0].id);
692 /* get chipcommon capabilites */
693 ci->c_inf[0].caps = brcmf_sdiod_regrl(sdiodev,
694 CORE_CC_REG(base, capabilities),
697 /* get pmu caps & rev */
698 if (ci->c_inf[0].caps & CC_CAP_PMU) {
700 brcmf_sdiod_regrl(sdiodev,
701 CORE_CC_REG(base, pmucapabilities),
703 ci->pmurev = ci->pmucaps & PCAP_REV_MASK;
706 ci->c_inf[1].rev = ci->corerev(sdiodev, ci, ci->c_inf[1].id);
708 brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n",
709 ci->c_inf[0].rev, ci->pmurev,
710 ci->c_inf[1].rev, ci->c_inf[1].id);
713 * Make sure any on-chip ARM is off (in case strapping is wrong),
714 * or downloaded code was already running.
716 ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0);
719 int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
720 struct chip_info **ci_ptr)
723 struct chip_info *ci;
725 brcmf_dbg(TRACE, "Enter\n");
727 /* alloc chip_info_t */
728 ci = kzalloc(sizeof(struct chip_info), GFP_ATOMIC);
732 ret = brcmf_sdio_chip_buscoreprep(sdiodev);
736 ret = brcmf_sdio_chip_recognition(sdiodev, ci);
740 brcmf_sdio_chip_buscoresetup(sdiodev, ci);
742 brcmf_sdiod_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopullup),
744 brcmf_sdiod_regwl(sdiodev, CORE_CC_REG(ci->c_inf[0].base, gpiopulldown),
756 brcmf_sdio_chip_detach(struct chip_info **ci_ptr)
758 brcmf_dbg(TRACE, "Enter\n");
764 static char *brcmf_sdio_chip_name(uint chipid, char *buf, uint len)
768 fmt = ((chipid > 0xa000) || (chipid < 0x4000)) ? "%d" : "%x";
769 snprintf(buf, len, fmt, chipid);
774 brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
775 struct chip_info *ci, u32 drivestrength)
777 const struct sdiod_drive_str *str_tab = NULL;
781 u32 base = ci->c_inf[0].base;
783 u32 drivestrength_sel = 0;
787 if (!(ci->c_inf[0].caps & CC_CAP_PMU))
790 switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) {
791 case SDIOD_DRVSTR_KEY(BCM4330_CHIP_ID, 12):
792 str_tab = sdiod_drvstr_tab1_1v8;
793 str_mask = 0x00003800;
796 case SDIOD_DRVSTR_KEY(BCM4334_CHIP_ID, 17):
797 str_tab = sdiod_drvstr_tab6_1v8;
798 str_mask = 0x00001800;
801 case SDIOD_DRVSTR_KEY(BCM43143_CHIP_ID, 17):
802 /* note: 43143 does not support tristate */
803 i = ARRAY_SIZE(sdiod_drvstr_tab2_3v3) - 1;
804 if (drivestrength >= sdiod_drvstr_tab2_3v3[i].strength) {
805 str_tab = sdiod_drvstr_tab2_3v3;
806 str_mask = 0x00000007;
809 brcmf_err("Invalid SDIO Drive strength for chip %s, strength=%d\n",
810 brcmf_sdio_chip_name(ci->chip, chn, 8),
813 case SDIOD_DRVSTR_KEY(BCM43362_CHIP_ID, 13):
814 str_tab = sdiod_drive_strength_tab5_1v8;
815 str_mask = 0x00003800;
819 brcmf_err("No SDIO Drive strength init done for chip %s rev %d pmurev %d\n",
820 brcmf_sdio_chip_name(ci->chip, chn, 8),
821 ci->chiprev, ci->pmurev);
825 if (str_tab != NULL) {
826 for (i = 0; str_tab[i].strength != 0; i++) {
827 if (drivestrength >= str_tab[i].strength) {
828 drivestrength_sel = str_tab[i].sel;
832 addr = CORE_CC_REG(base, chipcontrol_addr);
833 brcmf_sdiod_regwl(sdiodev, addr, 1, NULL);
834 cc_data_temp = brcmf_sdiod_regrl(sdiodev, addr, NULL);
835 cc_data_temp &= ~str_mask;
836 drivestrength_sel <<= str_shift;
837 cc_data_temp |= drivestrength_sel;
838 brcmf_sdiod_regwl(sdiodev, addr, cc_data_temp, NULL);
840 brcmf_dbg(INFO, "SDIO: %d mA (req=%d mA) drive strength selected, set to 0x%08x\n",
841 str_tab[i].strength, drivestrength, cc_data_temp);
846 brcmf_sdio_chip_cm3_enterdl(struct brcmf_sdio_dev *sdiodev,
847 struct chip_info *ci)
849 ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0);
850 ci->resetcore(sdiodev, ci, BCMA_CORE_INTERNAL_MEM, 0);
854 brcmf_sdio_chip_cm3_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci)
859 if (!ci->iscoreup(sdiodev, ci, BCMA_CORE_INTERNAL_MEM)) {
860 brcmf_err("SOCRAM core is down after reset?\n");
864 /* clear all interrupts */
865 core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV);
866 reg_addr = ci->c_inf[core_idx].base;
867 reg_addr += offsetof(struct sdpcmd_regs, intstatus);
868 brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
870 ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CM3, 0);
876 brcmf_sdio_chip_cr4_enterdl(struct brcmf_sdio_dev *sdiodev,
877 struct chip_info *ci)
879 ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4,
880 ARMCR4_BCMA_IOCTL_CPUHALT);
884 brcmf_sdio_chip_cr4_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci)
889 /* clear all interrupts */
890 core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV);
891 reg_addr = ci->c_inf[core_idx].base;
892 reg_addr += offsetof(struct sdpcmd_regs, intstatus);
893 brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL);
895 /* Write reset vector to address 0 */
896 brcmf_sdiod_ramrw(sdiodev, true, 0, (void *)&ci->rst_vec,
897 sizeof(ci->rst_vec));
900 ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, 0);
905 void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev,
906 struct chip_info *ci)
910 arm_core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3);
911 if (BRCMF_MAX_CORENUM != arm_core_idx) {
912 brcmf_sdio_chip_cm3_enterdl(sdiodev, ci);
916 brcmf_sdio_chip_cr4_enterdl(sdiodev, ci);
919 bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev,
920 struct chip_info *ci)
924 arm_core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3);
925 if (BRCMF_MAX_CORENUM != arm_core_idx)
926 return brcmf_sdio_chip_cm3_exitdl(sdiodev, ci);
928 return brcmf_sdio_chip_cr4_exitdl(sdiodev, ci);