diff options
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c | 149 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h | 6 |
3 files changed, 106 insertions, 57 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 4f936c6b682d..19057896d92e 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | |||
@@ -2263,8 +2263,6 @@ static void brcmf_sdio_bus_stop(struct device *dev) | |||
2263 | w_sdreg32(bus, local_hostintmask, | 2263 | w_sdreg32(bus, local_hostintmask, |
2264 | offsetof(struct sdpcmd_regs, intstatus)); | 2264 | offsetof(struct sdpcmd_regs, intstatus)); |
2265 | 2265 | ||
2266 | /* Turn off the backplane clock (only) */ | ||
2267 | brcmf_sdio_clkctl(bus, CLK_SDONLY, false); | ||
2268 | sdio_release_host(bus->sdiodev->func[1]); | 2266 | sdio_release_host(bus->sdiodev->func[1]); |
2269 | 2267 | ||
2270 | /* Clear the data packet queues */ | 2268 | /* Clear the data packet queues */ |
@@ -4085,6 +4083,12 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus) | |||
4085 | if (bus->ci) { | 4083 | if (bus->ci) { |
4086 | sdio_claim_host(bus->sdiodev->func[1]); | 4084 | sdio_claim_host(bus->sdiodev->func[1]); |
4087 | brcmf_sdio_clkctl(bus, CLK_AVAIL, false); | 4085 | brcmf_sdio_clkctl(bus, CLK_AVAIL, false); |
4086 | /* Leave the device in state where it is 'quiet'. This | ||
4087 | * is done by putting it in download_state which | ||
4088 | * essentially resets all necessary cores | ||
4089 | */ | ||
4090 | msleep(20); | ||
4091 | brcmf_sdio_download_state(bus, true); | ||
4088 | brcmf_sdio_clkctl(bus, CLK_NONE, false); | 4092 | brcmf_sdio_clkctl(bus, CLK_NONE, false); |
4089 | sdio_release_host(bus->sdiodev->func[1]); | 4093 | sdio_release_host(bus->sdiodev->func[1]); |
4090 | brcmf_sdio_chip_detach(&bus->ci); | 4094 | brcmf_sdio_chip_detach(&bus->ci); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c index a74a3d1c3e00..434297648e34 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c | |||
@@ -51,6 +51,9 @@ | |||
51 | #define BCM43143_CORE_ARM_BASE 0x18003000 | 51 | #define BCM43143_CORE_ARM_BASE 0x18003000 |
52 | #define BCM43143_RAMSIZE 0x70000 | 52 | #define BCM43143_RAMSIZE 0x70000 |
53 | 53 | ||
54 | /* All D11 cores, ID 0x812 */ | ||
55 | #define BCM43xx_CORE_D11_BASE 0x18001000 | ||
56 | |||
54 | #define SBCOREREV(sbidh) \ | 57 | #define SBCOREREV(sbidh) \ |
55 | ((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \ | 58 | ((((sbidh) & SSB_IDHIGH_RCHI) >> SSB_IDHIGH_RCHI_SHIFT) | \ |
56 | ((sbidh) & SSB_IDHIGH_RCLO)) | 59 | ((sbidh) & SSB_IDHIGH_RCLO)) |
@@ -66,6 +69,10 @@ | |||
66 | /* ARM CR4 core specific control flag bits */ | 69 | /* ARM CR4 core specific control flag bits */ |
67 | #define ARMCR4_BCMA_IOCTL_CPUHALT 0x0020 | 70 | #define ARMCR4_BCMA_IOCTL_CPUHALT 0x0020 |
68 | 71 | ||
72 | /* D11 core specific control flag bits */ | ||
73 | #define D11_BCMA_IOCTL_PHYCLOCKEN 0x0004 | ||
74 | #define D11_BCMA_IOCTL_PHYRESET 0x0008 | ||
75 | |||
69 | #define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) | 76 | #define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) |
70 | /* SDIO Pad drive strength to select value mappings */ | 77 | /* SDIO Pad drive strength to select value mappings */ |
71 | struct sdiod_drive_str { | 78 | struct sdiod_drive_str { |
@@ -193,7 +200,8 @@ brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev, | |||
193 | 200 | ||
194 | static void | 201 | static void |
195 | brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev, | 202 | brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev, |
196 | struct chip_info *ci, u16 coreid, u32 core_bits) | 203 | struct chip_info *ci, u16 coreid, u32 pre_resetbits, |
204 | u32 in_resetbits) | ||
197 | { | 205 | { |
198 | u32 regdata, base; | 206 | u32 regdata, base; |
199 | u8 idx; | 207 | u8 idx; |
@@ -279,52 +287,48 @@ brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev, | |||
279 | 287 | ||
280 | static void | 288 | static void |
281 | brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev, | 289 | brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev, |
282 | struct chip_info *ci, u16 coreid, u32 core_bits) | 290 | struct chip_info *ci, u16 coreid, u32 pre_resetbits, |
291 | u32 in_resetbits) | ||
283 | { | 292 | { |
284 | u8 idx; | 293 | u8 idx; |
285 | u32 regdata; | 294 | u32 regdata; |
295 | u32 wrapbase; | ||
286 | 296 | ||
287 | idx = brcmf_sdio_chip_getinfidx(ci, coreid); | 297 | idx = brcmf_sdio_chip_getinfidx(ci, coreid); |
288 | if (idx == BRCMF_MAX_CORENUM) | 298 | if (idx == BRCMF_MAX_CORENUM) |
289 | return; | 299 | return; |
290 | 300 | ||
301 | wrapbase = ci->c_inf[idx].wrapbase; | ||
302 | |||
291 | /* if core is already in reset, just return */ | 303 | /* if core is already in reset, just return */ |
292 | regdata = brcmf_sdiod_regrl(sdiodev, | 304 | regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_RESET_CTL, NULL); |
293 | ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, | ||
294 | NULL); | ||
295 | if ((regdata & BCMA_RESET_CTL_RESET) != 0) | 305 | if ((regdata & BCMA_RESET_CTL_RESET) != 0) |
296 | return; | 306 | return; |
297 | 307 | ||
298 | /* ensure no pending backplane operation | 308 | /* configure reset */ |
299 | * 300uc should be sufficient for backplane ops to be finish | 309 | brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_IOCTL, pre_resetbits | |
300 | * extra 10ms is taken into account for firmware load stage | 310 | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL); |
301 | * after 10300us carry on disabling the core anyway | 311 | regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL); |
302 | */ | ||
303 | SPINWAIT(brcmf_sdiod_regrl(sdiodev, | ||
304 | ci->c_inf[idx].wrapbase+BCMA_RESET_ST, | ||
305 | NULL), 10300); | ||
306 | regdata = brcmf_sdiod_regrl(sdiodev, | ||
307 | ci->c_inf[idx].wrapbase+BCMA_RESET_ST, | ||
308 | NULL); | ||
309 | if (regdata) | ||
310 | brcmf_err("disabling core 0x%x with reset status %x\n", | ||
311 | coreid, regdata); | ||
312 | 312 | ||
313 | brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, | 313 | /* put in reset */ |
314 | brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_RESET_CTL, | ||
314 | BCMA_RESET_CTL_RESET, NULL); | 315 | BCMA_RESET_CTL_RESET, NULL); |
315 | udelay(1); | ||
316 | |||
317 | brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, | ||
318 | core_bits, NULL); | ||
319 | regdata = brcmf_sdiod_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, | ||
320 | NULL); | ||
321 | usleep_range(10, 20); | 316 | usleep_range(10, 20); |
322 | 317 | ||
318 | /* wait till reset is 1 */ | ||
319 | SPINWAIT(brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_RESET_CTL, NULL) != | ||
320 | BCMA_RESET_CTL_RESET, 300); | ||
321 | |||
322 | /* post reset configure */ | ||
323 | brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_IOCTL, pre_resetbits | | ||
324 | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL); | ||
325 | regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL); | ||
323 | } | 326 | } |
324 | 327 | ||
325 | static void | 328 | static void |
326 | brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, | 329 | brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, |
327 | struct chip_info *ci, u16 coreid, u32 core_bits) | 330 | struct chip_info *ci, u16 coreid, u32 pre_resetbits, |
331 | u32 in_resetbits, u32 post_resetbits) | ||
328 | { | 332 | { |
329 | u32 regdata; | 333 | u32 regdata; |
330 | u8 idx; | 334 | u8 idx; |
@@ -337,7 +341,8 @@ brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, | |||
337 | * Must do the disable sequence first to work for | 341 | * Must do the disable sequence first to work for |
338 | * arbitrary current core state. | 342 | * arbitrary current core state. |
339 | */ | 343 | */ |
340 | brcmf_sdio_sb_coredisable(sdiodev, ci, coreid, 0); | 344 | brcmf_sdio_sb_coredisable(sdiodev, ci, coreid, pre_resetbits, |
345 | in_resetbits); | ||
341 | 346 | ||
342 | /* | 347 | /* |
343 | * Now do the initialization sequence. | 348 | * Now do the initialization sequence. |
@@ -390,35 +395,32 @@ brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, | |||
390 | 395 | ||
391 | static void | 396 | static void |
392 | brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev, | 397 | brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev, |
393 | struct chip_info *ci, u16 coreid, u32 core_bits) | 398 | struct chip_info *ci, u16 coreid, u32 pre_resetbits, |
399 | u32 in_resetbits, u32 post_resetbits) | ||
394 | { | 400 | { |
395 | u8 idx; | 401 | u8 idx; |
396 | u32 regdata; | 402 | u32 regdata; |
403 | u32 wrapbase; | ||
397 | 404 | ||
398 | idx = brcmf_sdio_chip_getinfidx(ci, coreid); | 405 | idx = brcmf_sdio_chip_getinfidx(ci, coreid); |
399 | if (idx == BRCMF_MAX_CORENUM) | 406 | if (idx == BRCMF_MAX_CORENUM) |
400 | return; | 407 | return; |
401 | 408 | ||
409 | wrapbase = ci->c_inf[idx].wrapbase; | ||
410 | |||
402 | /* must disable first to work for arbitrary current core state */ | 411 | /* must disable first to work for arbitrary current core state */ |
403 | brcmf_sdio_ai_coredisable(sdiodev, ci, coreid, core_bits); | 412 | brcmf_sdio_ai_coredisable(sdiodev, ci, coreid, pre_resetbits, |
413 | in_resetbits); | ||
404 | 414 | ||
405 | /* now do initialization sequence */ | 415 | while (brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_RESET_CTL, NULL) & |
406 | brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, | 416 | BCMA_RESET_CTL_RESET) { |
407 | core_bits | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL); | 417 | brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_RESET_CTL, 0, NULL); |
408 | regdata = brcmf_sdiod_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, | 418 | usleep_range(40, 60); |
409 | NULL); | 419 | } |
410 | brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, | ||
411 | 0, NULL); | ||
412 | regdata = brcmf_sdiod_regrl(sdiodev, | ||
413 | ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, | ||
414 | NULL); | ||
415 | udelay(1); | ||
416 | 420 | ||
417 | brcmf_sdiod_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, | 421 | brcmf_sdiod_regwl(sdiodev, wrapbase + BCMA_IOCTL, post_resetbits | |
418 | core_bits | BCMA_IOCTL_CLK, NULL); | 422 | BCMA_IOCTL_CLK, NULL); |
419 | regdata = brcmf_sdiod_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, | 423 | regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL); |
420 | NULL); | ||
421 | udelay(1); | ||
422 | } | 424 | } |
423 | 425 | ||
424 | #ifdef DEBUG | 426 | #ifdef DEBUG |
@@ -498,6 +500,9 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, | |||
498 | ci->c_inf[3].base = BCM43143_CORE_ARM_BASE; | 500 | ci->c_inf[3].base = BCM43143_CORE_ARM_BASE; |
499 | ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000; | 501 | ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000; |
500 | ci->c_inf[3].cib = 0x07000000; | 502 | ci->c_inf[3].cib = 0x07000000; |
503 | ci->c_inf[4].id = BCMA_CORE_80211; | ||
504 | ci->c_inf[4].base = BCM43xx_CORE_D11_BASE; | ||
505 | ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000; | ||
501 | ci->ramsize = BCM43143_RAMSIZE; | 506 | ci->ramsize = BCM43143_RAMSIZE; |
502 | break; | 507 | break; |
503 | case BCM43241_CHIP_ID: | 508 | case BCM43241_CHIP_ID: |
@@ -515,6 +520,9 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, | |||
515 | ci->c_inf[3].base = 0x18003000; | 520 | ci->c_inf[3].base = 0x18003000; |
516 | ci->c_inf[3].wrapbase = 0x18103000; | 521 | ci->c_inf[3].wrapbase = 0x18103000; |
517 | ci->c_inf[3].cib = 0x07004211; | 522 | ci->c_inf[3].cib = 0x07004211; |
523 | ci->c_inf[4].id = BCMA_CORE_80211; | ||
524 | ci->c_inf[4].base = BCM43xx_CORE_D11_BASE; | ||
525 | ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000; | ||
518 | ci->ramsize = 0x90000; | 526 | ci->ramsize = 0x90000; |
519 | break; | 527 | break; |
520 | case BCM4329_CHIP_ID: | 528 | case BCM4329_CHIP_ID: |
@@ -524,6 +532,8 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, | |||
524 | ci->c_inf[2].base = BCM4329_CORE_SOCRAM_BASE; | 532 | ci->c_inf[2].base = BCM4329_CORE_SOCRAM_BASE; |
525 | ci->c_inf[3].id = BCMA_CORE_ARM_CM3; | 533 | ci->c_inf[3].id = BCMA_CORE_ARM_CM3; |
526 | ci->c_inf[3].base = BCM4329_CORE_ARM_BASE; | 534 | ci->c_inf[3].base = BCM4329_CORE_ARM_BASE; |
535 | ci->c_inf[4].id = BCMA_CORE_80211; | ||
536 | ci->c_inf[4].base = BCM43xx_CORE_D11_BASE; | ||
527 | ci->ramsize = BCM4329_RAMSIZE; | 537 | ci->ramsize = BCM4329_RAMSIZE; |
528 | break; | 538 | break; |
529 | case BCM4330_CHIP_ID: | 539 | case BCM4330_CHIP_ID: |
@@ -541,6 +551,9 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, | |||
541 | ci->c_inf[3].base = 0x18003000; | 551 | ci->c_inf[3].base = 0x18003000; |
542 | ci->c_inf[3].wrapbase = 0x18103000; | 552 | ci->c_inf[3].wrapbase = 0x18103000; |
543 | ci->c_inf[3].cib = 0x03004211; | 553 | ci->c_inf[3].cib = 0x03004211; |
554 | ci->c_inf[4].id = BCMA_CORE_80211; | ||
555 | ci->c_inf[4].base = BCM43xx_CORE_D11_BASE; | ||
556 | ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000; | ||
544 | ci->ramsize = 0x48000; | 557 | ci->ramsize = 0x48000; |
545 | break; | 558 | break; |
546 | case BCM4334_CHIP_ID: | 559 | case BCM4334_CHIP_ID: |
@@ -558,6 +571,9 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, | |||
558 | ci->c_inf[3].base = 0x18003000; | 571 | ci->c_inf[3].base = 0x18003000; |
559 | ci->c_inf[3].wrapbase = 0x18103000; | 572 | ci->c_inf[3].wrapbase = 0x18103000; |
560 | ci->c_inf[3].cib = 0x07004211; | 573 | ci->c_inf[3].cib = 0x07004211; |
574 | ci->c_inf[4].id = BCMA_CORE_80211; | ||
575 | ci->c_inf[4].base = BCM43xx_CORE_D11_BASE; | ||
576 | ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000; | ||
561 | ci->ramsize = 0x80000; | 577 | ci->ramsize = 0x80000; |
562 | break; | 578 | break; |
563 | case BCM4335_CHIP_ID: | 579 | case BCM4335_CHIP_ID: |
@@ -571,6 +587,9 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, | |||
571 | ci->c_inf[2].base = 0x18002000; | 587 | ci->c_inf[2].base = 0x18002000; |
572 | ci->c_inf[2].wrapbase = 0x18102000; | 588 | ci->c_inf[2].wrapbase = 0x18102000; |
573 | ci->c_inf[2].cib = 0x01084411; | 589 | ci->c_inf[2].cib = 0x01084411; |
590 | ci->c_inf[3].id = BCMA_CORE_80211; | ||
591 | ci->c_inf[3].base = BCM43xx_CORE_D11_BASE; | ||
592 | ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000; | ||
574 | ci->ramsize = 0xc0000; | 593 | ci->ramsize = 0xc0000; |
575 | ci->rambase = 0x180000; | 594 | ci->rambase = 0x180000; |
576 | break; | 595 | break; |
@@ -585,6 +604,9 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, | |||
585 | ci->c_inf[2].base = 0x18002000; | 604 | ci->c_inf[2].base = 0x18002000; |
586 | ci->c_inf[2].wrapbase = 0x18102000; | 605 | ci->c_inf[2].wrapbase = 0x18102000; |
587 | ci->c_inf[2].cib = 0x04084411; | 606 | ci->c_inf[2].cib = 0x04084411; |
607 | ci->c_inf[3].id = BCMA_CORE_80211; | ||
608 | ci->c_inf[3].base = BCM43xx_CORE_D11_BASE; | ||
609 | ci->c_inf[3].wrapbase = ci->c_inf[3].base + 0x00100000; | ||
588 | ci->ramsize = 0xc0000; | 610 | ci->ramsize = 0xc0000; |
589 | ci->rambase = 0x180000; | 611 | ci->rambase = 0x180000; |
590 | break; | 612 | break; |
@@ -603,6 +625,9 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, | |||
603 | ci->c_inf[3].base = 0x18003000; | 625 | ci->c_inf[3].base = 0x18003000; |
604 | ci->c_inf[3].wrapbase = 0x18103000; | 626 | ci->c_inf[3].wrapbase = 0x18103000; |
605 | ci->c_inf[3].cib = 0x03004211; | 627 | ci->c_inf[3].cib = 0x03004211; |
628 | ci->c_inf[4].id = BCMA_CORE_80211; | ||
629 | ci->c_inf[4].base = BCM43xx_CORE_D11_BASE; | ||
630 | ci->c_inf[4].wrapbase = ci->c_inf[4].base + 0x00100000; | ||
606 | ci->ramsize = 0x3C000; | 631 | ci->ramsize = 0x3C000; |
607 | break; | 632 | break; |
608 | default: | 633 | default: |
@@ -713,7 +738,7 @@ brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev, | |||
713 | * Make sure any on-chip ARM is off (in case strapping is wrong), | 738 | * Make sure any on-chip ARM is off (in case strapping is wrong), |
714 | * or downloaded code was already running. | 739 | * or downloaded code was already running. |
715 | */ | 740 | */ |
716 | ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0); | 741 | ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0, 0); |
717 | } | 742 | } |
718 | 743 | ||
719 | int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, | 744 | int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, |
@@ -846,8 +871,11 @@ static void | |||
846 | brcmf_sdio_chip_cm3_enterdl(struct brcmf_sdio_dev *sdiodev, | 871 | brcmf_sdio_chip_cm3_enterdl(struct brcmf_sdio_dev *sdiodev, |
847 | struct chip_info *ci) | 872 | struct chip_info *ci) |
848 | { | 873 | { |
849 | ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0); | 874 | ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0, 0); |
850 | ci->resetcore(sdiodev, ci, BCMA_CORE_INTERNAL_MEM, 0); | 875 | ci->resetcore(sdiodev, ci, BCMA_CORE_80211, |
876 | D11_BCMA_IOCTL_PHYRESET | D11_BCMA_IOCTL_PHYCLOCKEN, | ||
877 | D11_BCMA_IOCTL_PHYCLOCKEN, D11_BCMA_IOCTL_PHYCLOCKEN); | ||
878 | ci->resetcore(sdiodev, ci, BCMA_CORE_INTERNAL_MEM, 0, 0, 0); | ||
851 | } | 879 | } |
852 | 880 | ||
853 | static bool | 881 | static bool |
@@ -867,7 +895,7 @@ brcmf_sdio_chip_cm3_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci) | |||
867 | reg_addr += offsetof(struct sdpcmd_regs, intstatus); | 895 | reg_addr += offsetof(struct sdpcmd_regs, intstatus); |
868 | brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL); | 896 | brcmf_sdiod_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL); |
869 | 897 | ||
870 | ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CM3, 0); | 898 | ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CM3, 0, 0, 0); |
871 | 899 | ||
872 | return true; | 900 | return true; |
873 | } | 901 | } |
@@ -876,8 +904,22 @@ static inline void | |||
876 | brcmf_sdio_chip_cr4_enterdl(struct brcmf_sdio_dev *sdiodev, | 904 | brcmf_sdio_chip_cr4_enterdl(struct brcmf_sdio_dev *sdiodev, |
877 | struct chip_info *ci) | 905 | struct chip_info *ci) |
878 | { | 906 | { |
879 | ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, | 907 | u8 idx; |
880 | ARMCR4_BCMA_IOCTL_CPUHALT); | 908 | u32 regdata; |
909 | u32 wrapbase; | ||
910 | idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CR4); | ||
911 | |||
912 | if (idx == BRCMF_MAX_CORENUM) | ||
913 | return; | ||
914 | |||
915 | wrapbase = ci->c_inf[idx].wrapbase; | ||
916 | regdata = brcmf_sdiod_regrl(sdiodev, wrapbase + BCMA_IOCTL, NULL); | ||
917 | regdata &= ARMCR4_BCMA_IOCTL_CPUHALT; | ||
918 | ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, regdata, | ||
919 | ARMCR4_BCMA_IOCTL_CPUHALT, ARMCR4_BCMA_IOCTL_CPUHALT); | ||
920 | ci->resetcore(sdiodev, ci, BCMA_CORE_80211, | ||
921 | D11_BCMA_IOCTL_PHYRESET | D11_BCMA_IOCTL_PHYCLOCKEN, | ||
922 | D11_BCMA_IOCTL_PHYCLOCKEN, D11_BCMA_IOCTL_PHYCLOCKEN); | ||
881 | } | 923 | } |
882 | 924 | ||
883 | static bool | 925 | static bool |
@@ -897,7 +939,8 @@ brcmf_sdio_chip_cr4_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci) | |||
897 | sizeof(ci->rst_vec)); | 939 | sizeof(ci->rst_vec)); |
898 | 940 | ||
899 | /* restore ARM */ | 941 | /* restore ARM */ |
900 | ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, 0); | 942 | ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, ARMCR4_BCMA_IOCTL_CPUHALT, |
943 | 0, 0); | ||
901 | 944 | ||
902 | return true; | 945 | return true; |
903 | } | 946 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h index c7d0dbc1ab59..91c61cb9de87 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h | |||
@@ -81,9 +81,11 @@ struct chip_info { | |||
81 | u32 (*corerev)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, | 81 | u32 (*corerev)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, |
82 | u16 coreid); | 82 | u16 coreid); |
83 | void (*coredisable)(struct brcmf_sdio_dev *sdiodev, | 83 | void (*coredisable)(struct brcmf_sdio_dev *sdiodev, |
84 | struct chip_info *ci, u16 coreid, u32 core_bits); | 84 | struct chip_info *ci, u16 coreid, u32 pre_resetbits, |
85 | u32 in_resetbits); | ||
85 | void (*resetcore)(struct brcmf_sdio_dev *sdiodev, | 86 | void (*resetcore)(struct brcmf_sdio_dev *sdiodev, |
86 | struct chip_info *ci, u16 coreid, u32 core_bits); | 87 | struct chip_info *ci, u16 coreid, u32 pre_resetbits, |
88 | u32 in_resetbits, u32 post_resetbits); | ||
87 | }; | 89 | }; |
88 | 90 | ||
89 | struct sbconfig { | 91 | struct sbconfig { |