diff options
author | Franky Lin <frankyl@broadcom.com> | 2013-04-11 07:28:51 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-04-12 14:27:54 -0400 |
commit | 1640f28f6b839637d9b82a3c4a19120601e59c66 (patch) | |
tree | aa993155ba1352b8c26b7aa3a9fe3651925dbf37 /drivers/net | |
parent | 83cf17aa80820248178deb7ca263123cced179dc (diff) |
brcmfmac: add support for dongle ARM CR4 core
Newer WiFi chip use ARM CR4 core to achieve higher performance. Add necessary
code for host driver in order to support CR4 core.
Reviewed-by: Arend van Spriel <arend@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Signed-off-by: Franky Lin <frankyl@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | 15 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c | 150 | ||||
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h | 6 |
3 files changed, 146 insertions, 25 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c index 3147960ad975..d24eb66d324d 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c | |||
@@ -2652,7 +2652,7 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus, | |||
2652 | struct sdpcm_shared_le sh_le; | 2652 | struct sdpcm_shared_le sh_le; |
2653 | __le32 addr_le; | 2653 | __le32 addr_le; |
2654 | 2654 | ||
2655 | shaddr = bus->ramsize - 4; | 2655 | shaddr = bus->ci->rambase + bus->ramsize - 4; |
2656 | 2656 | ||
2657 | /* | 2657 | /* |
2658 | * Read last word in socram to determine | 2658 | * Read last word in socram to determine |
@@ -3030,10 +3030,11 @@ static int brcmf_sdbrcm_get_image(char *buf, int len, struct brcmf_sdio *bus) | |||
3030 | 3030 | ||
3031 | static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus) | 3031 | static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus) |
3032 | { | 3032 | { |
3033 | int offset = 0; | 3033 | int offset; |
3034 | uint len; | 3034 | uint len; |
3035 | u8 *memblock = NULL, *memptr; | 3035 | u8 *memblock = NULL, *memptr; |
3036 | int ret; | 3036 | int ret; |
3037 | u8 idx; | ||
3037 | 3038 | ||
3038 | brcmf_dbg(INFO, "Enter\n"); | 3039 | brcmf_dbg(INFO, "Enter\n"); |
3039 | 3040 | ||
@@ -3054,9 +3055,14 @@ static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus) | |||
3054 | memptr += (BRCMF_SDALIGN - | 3055 | memptr += (BRCMF_SDALIGN - |
3055 | ((u32)(unsigned long)memblock % BRCMF_SDALIGN)); | 3056 | ((u32)(unsigned long)memblock % BRCMF_SDALIGN)); |
3056 | 3057 | ||
3058 | offset = bus->ci->rambase; | ||
3059 | |||
3057 | /* Download image */ | 3060 | /* Download image */ |
3058 | while ((len = | 3061 | len = brcmf_sdbrcm_get_image((char *)memptr, MEMBLOCK, bus); |
3059 | brcmf_sdbrcm_get_image((char *)memptr, MEMBLOCK, bus))) { | 3062 | idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_ARM_CR4); |
3063 | if (BRCMF_MAX_CORENUM != idx) | ||
3064 | memcpy(&bus->ci->rst_vec, memptr, sizeof(bus->ci->rst_vec)); | ||
3065 | while (len) { | ||
3060 | ret = brcmf_sdio_ramrw(bus->sdiodev, true, offset, memptr, len); | 3066 | ret = brcmf_sdio_ramrw(bus->sdiodev, true, offset, memptr, len); |
3061 | if (ret) { | 3067 | if (ret) { |
3062 | brcmf_err("error %d on writing %d membytes at 0x%08x\n", | 3068 | brcmf_err("error %d on writing %d membytes at 0x%08x\n", |
@@ -3065,6 +3071,7 @@ static int brcmf_sdbrcm_download_code_file(struct brcmf_sdio *bus) | |||
3065 | } | 3071 | } |
3066 | 3072 | ||
3067 | offset += MEMBLOCK; | 3073 | offset += MEMBLOCK; |
3074 | len = brcmf_sdbrcm_get_image((char *)memptr, MEMBLOCK, bus); | ||
3068 | } | 3075 | } |
3069 | 3076 | ||
3070 | err: | 3077 | err: |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c index 9818598f30ea..5db985cb0e0a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.c | |||
@@ -52,6 +52,9 @@ | |||
52 | #define CIB_REV_MASK 0xff000000 | 52 | #define CIB_REV_MASK 0xff000000 |
53 | #define CIB_REV_SHIFT 24 | 53 | #define CIB_REV_SHIFT 24 |
54 | 54 | ||
55 | /* ARM CR4 core specific control flag bits */ | ||
56 | #define ARMCR4_BCMA_IOCTL_CPUHALT 0x0020 | ||
57 | |||
55 | #define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) | 58 | #define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) |
56 | /* SDIO Pad drive strength to select value mappings */ | 59 | /* SDIO Pad drive strength to select value mappings */ |
57 | struct sdiod_drive_str { | 60 | struct sdiod_drive_str { |
@@ -149,7 +152,7 @@ brcmf_sdio_ai_iscoreup(struct brcmf_sdio_dev *sdiodev, | |||
149 | 152 | ||
150 | static void | 153 | static void |
151 | brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev, | 154 | brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev, |
152 | struct chip_info *ci, u16 coreid) | 155 | struct chip_info *ci, u16 coreid, u32 core_bits) |
153 | { | 156 | { |
154 | u32 regdata, base; | 157 | u32 regdata, base; |
155 | u8 idx; | 158 | u8 idx; |
@@ -235,7 +238,7 @@ brcmf_sdio_sb_coredisable(struct brcmf_sdio_dev *sdiodev, | |||
235 | 238 | ||
236 | static void | 239 | static void |
237 | brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev, | 240 | brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev, |
238 | struct chip_info *ci, u16 coreid) | 241 | struct chip_info *ci, u16 coreid, u32 core_bits) |
239 | { | 242 | { |
240 | u8 idx; | 243 | u8 idx; |
241 | u32 regdata; | 244 | u32 regdata; |
@@ -249,19 +252,36 @@ brcmf_sdio_ai_coredisable(struct brcmf_sdio_dev *sdiodev, | |||
249 | if ((regdata & BCMA_RESET_CTL_RESET) != 0) | 252 | if ((regdata & BCMA_RESET_CTL_RESET) != 0) |
250 | return; | 253 | return; |
251 | 254 | ||
252 | brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, 0, NULL); | 255 | /* ensure no pending backplane operation |
253 | regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, | 256 | * 300uc should be sufficient for backplane ops to be finish |
257 | * extra 10ms is taken into account for firmware load stage | ||
258 | * after 10300us carry on disabling the core anyway | ||
259 | */ | ||
260 | SPINWAIT(brcmf_sdio_regrl(sdiodev, | ||
261 | ci->c_inf[idx].wrapbase+BCMA_RESET_ST, | ||
262 | NULL), 10300); | ||
263 | regdata = brcmf_sdio_regrl(sdiodev, | ||
264 | ci->c_inf[idx].wrapbase+BCMA_RESET_ST, | ||
254 | NULL); | 265 | NULL); |
255 | udelay(10); | 266 | if (regdata) |
267 | brcmf_err("disabling core 0x%x with reset status %x\n", | ||
268 | coreid, regdata); | ||
256 | 269 | ||
257 | brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, | 270 | brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, |
258 | BCMA_RESET_CTL_RESET, NULL); | 271 | BCMA_RESET_CTL_RESET, NULL); |
259 | udelay(1); | 272 | udelay(1); |
273 | |||
274 | brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, | ||
275 | core_bits, NULL); | ||
276 | regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, | ||
277 | NULL); | ||
278 | usleep_range(10, 20); | ||
279 | |||
260 | } | 280 | } |
261 | 281 | ||
262 | static void | 282 | static void |
263 | brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, | 283 | brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, |
264 | struct chip_info *ci, u16 coreid) | 284 | struct chip_info *ci, u16 coreid, u32 core_bits) |
265 | { | 285 | { |
266 | u32 regdata; | 286 | u32 regdata; |
267 | u8 idx; | 287 | u8 idx; |
@@ -272,7 +292,7 @@ brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, | |||
272 | * Must do the disable sequence first to work for | 292 | * Must do the disable sequence first to work for |
273 | * arbitrary current core state. | 293 | * arbitrary current core state. |
274 | */ | 294 | */ |
275 | brcmf_sdio_sb_coredisable(sdiodev, ci, coreid); | 295 | brcmf_sdio_sb_coredisable(sdiodev, ci, coreid, 0); |
276 | 296 | ||
277 | /* | 297 | /* |
278 | * Now do the initialization sequence. | 298 | * Now do the initialization sequence. |
@@ -325,7 +345,7 @@ brcmf_sdio_sb_resetcore(struct brcmf_sdio_dev *sdiodev, | |||
325 | 345 | ||
326 | static void | 346 | static void |
327 | brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev, | 347 | brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev, |
328 | struct chip_info *ci, u16 coreid) | 348 | struct chip_info *ci, u16 coreid, u32 core_bits) |
329 | { | 349 | { |
330 | u8 idx; | 350 | u8 idx; |
331 | u32 regdata; | 351 | u32 regdata; |
@@ -333,28 +353,67 @@ brcmf_sdio_ai_resetcore(struct brcmf_sdio_dev *sdiodev, | |||
333 | idx = brcmf_sdio_chip_getinfidx(ci, coreid); | 353 | idx = brcmf_sdio_chip_getinfidx(ci, coreid); |
334 | 354 | ||
335 | /* must disable first to work for arbitrary current core state */ | 355 | /* must disable first to work for arbitrary current core state */ |
336 | brcmf_sdio_ai_coredisable(sdiodev, ci, coreid); | 356 | brcmf_sdio_ai_coredisable(sdiodev, ci, coreid, core_bits); |
337 | 357 | ||
338 | /* now do initialization sequence */ | 358 | /* now do initialization sequence */ |
339 | brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, | 359 | brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, |
340 | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL); | 360 | core_bits | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK, NULL); |
341 | regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, | 361 | regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, |
342 | NULL); | 362 | NULL); |
343 | brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, | 363 | brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, |
344 | 0, NULL); | 364 | 0, NULL); |
365 | regdata = brcmf_sdio_regrl(sdiodev, | ||
366 | ci->c_inf[idx].wrapbase+BCMA_RESET_CTL, | ||
367 | NULL); | ||
345 | udelay(1); | 368 | udelay(1); |
346 | 369 | ||
347 | brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, | 370 | brcmf_sdio_regwl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, |
348 | BCMA_IOCTL_CLK, NULL); | 371 | core_bits | BCMA_IOCTL_CLK, NULL); |
349 | regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, | 372 | regdata = brcmf_sdio_regrl(sdiodev, ci->c_inf[idx].wrapbase+BCMA_IOCTL, |
350 | NULL); | 373 | NULL); |
351 | udelay(1); | 374 | udelay(1); |
352 | } | 375 | } |
353 | 376 | ||
377 | #ifdef DEBUG | ||
378 | /* safety check for chipinfo */ | ||
379 | static int brcmf_sdio_chip_cichk(struct chip_info *ci) | ||
380 | { | ||
381 | u8 core_idx; | ||
382 | |||
383 | /* check RAM core presence for ARM CM3 core */ | ||
384 | core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3); | ||
385 | if (BRCMF_MAX_CORENUM != core_idx) { | ||
386 | core_idx = brcmf_sdio_chip_getinfidx(ci, | ||
387 | BCMA_CORE_INTERNAL_MEM); | ||
388 | if (BRCMF_MAX_CORENUM == core_idx) { | ||
389 | brcmf_err("RAM core not provided with ARM CM3 core\n"); | ||
390 | return -ENODEV; | ||
391 | } | ||
392 | } | ||
393 | |||
394 | /* check RAM base for ARM CR4 core */ | ||
395 | core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CR4); | ||
396 | if (BRCMF_MAX_CORENUM != core_idx) { | ||
397 | if (ci->rambase == 0) { | ||
398 | brcmf_err("RAM base not provided with ARM CR4 core\n"); | ||
399 | return -ENOMEM; | ||
400 | } | ||
401 | } | ||
402 | |||
403 | return 0; | ||
404 | } | ||
405 | #else /* DEBUG */ | ||
406 | static inline int brcmf_sdio_chip_cichk(struct chip_info *ci) | ||
407 | { | ||
408 | return 0; | ||
409 | } | ||
410 | #endif | ||
411 | |||
354 | static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, | 412 | static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, |
355 | struct chip_info *ci, u32 regs) | 413 | struct chip_info *ci, u32 regs) |
356 | { | 414 | { |
357 | u32 regdata; | 415 | u32 regdata; |
416 | int ret; | ||
358 | 417 | ||
359 | /* Get CC core rev | 418 | /* Get CC core rev |
360 | * Chipid is assume to be at offset 0 from regs arg | 419 | * Chipid is assume to be at offset 0 from regs arg |
@@ -439,6 +498,10 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, | |||
439 | return -ENODEV; | 498 | return -ENODEV; |
440 | } | 499 | } |
441 | 500 | ||
501 | ret = brcmf_sdio_chip_cichk(ci); | ||
502 | if (ret) | ||
503 | return ret; | ||
504 | |||
442 | switch (ci->socitype) { | 505 | switch (ci->socitype) { |
443 | case SOCI_SB: | 506 | case SOCI_SB: |
444 | ci->iscoreup = brcmf_sdio_sb_iscoreup; | 507 | ci->iscoreup = brcmf_sdio_sb_iscoreup; |
@@ -538,7 +601,7 @@ brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev, | |||
538 | * Make sure any on-chip ARM is off (in case strapping is wrong), | 601 | * Make sure any on-chip ARM is off (in case strapping is wrong), |
539 | * or downloaded code was already running. | 602 | * or downloaded code was already running. |
540 | */ | 603 | */ |
541 | ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3); | 604 | ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0); |
542 | } | 605 | } |
543 | 606 | ||
544 | int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, | 607 | int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, |
@@ -701,7 +764,7 @@ static bool brcmf_sdio_chip_writenvram(struct brcmf_sdio_dev *sdiodev, | |||
701 | u32 token; | 764 | u32 token; |
702 | __le32 token_le; | 765 | __le32 token_le; |
703 | 766 | ||
704 | nvram_addr = (ci->ramsize - 4) - nvram_sz; | 767 | nvram_addr = (ci->ramsize - 4) - nvram_sz + ci->rambase; |
705 | 768 | ||
706 | /* Write the vars list */ | 769 | /* Write the vars list */ |
707 | err = brcmf_sdio_ramrw(sdiodev, true, nvram_addr, nvram_dat, nvram_sz); | 770 | err = brcmf_sdio_ramrw(sdiodev, true, nvram_addr, nvram_dat, nvram_sz); |
@@ -728,7 +791,7 @@ static bool brcmf_sdio_chip_writenvram(struct brcmf_sdio_dev *sdiodev, | |||
728 | nvram_addr, nvram_sz, token); | 791 | nvram_addr, nvram_sz, token); |
729 | 792 | ||
730 | /* Write the length token to the last word */ | 793 | /* Write the length token to the last word */ |
731 | if (brcmf_sdio_ramrw(sdiodev, true, (ci->ramsize - 4), | 794 | if (brcmf_sdio_ramrw(sdiodev, true, (ci->ramsize - 4 + ci->rambase), |
732 | (u8 *)&token_le, 4)) | 795 | (u8 *)&token_le, 4)) |
733 | return false; | 796 | return false; |
734 | 797 | ||
@@ -741,8 +804,8 @@ brcmf_sdio_chip_cm3_enterdl(struct brcmf_sdio_dev *sdiodev, | |||
741 | { | 804 | { |
742 | u32 zeros = 0; | 805 | u32 zeros = 0; |
743 | 806 | ||
744 | ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3); | 807 | ci->coredisable(sdiodev, ci, BCMA_CORE_ARM_CM3, 0); |
745 | ci->resetcore(sdiodev, ci, BCMA_CORE_INTERNAL_MEM); | 808 | ci->resetcore(sdiodev, ci, BCMA_CORE_INTERNAL_MEM, 0); |
746 | 809 | ||
747 | /* clear length token */ | 810 | /* clear length token */ |
748 | brcmf_sdio_ramrw(sdiodev, true, ci->ramsize - 4, (u8 *)&zeros, 4); | 811 | brcmf_sdio_ramrw(sdiodev, true, ci->ramsize - 4, (u8 *)&zeros, 4); |
@@ -769,7 +832,41 @@ brcmf_sdio_chip_cm3_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, | |||
769 | reg_addr += offsetof(struct sdpcmd_regs, intstatus); | 832 | reg_addr += offsetof(struct sdpcmd_regs, intstatus); |
770 | brcmf_sdio_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL); | 833 | brcmf_sdio_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL); |
771 | 834 | ||
772 | ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CM3); | 835 | ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CM3, 0); |
836 | |||
837 | return true; | ||
838 | } | ||
839 | |||
840 | static inline void | ||
841 | brcmf_sdio_chip_cr4_enterdl(struct brcmf_sdio_dev *sdiodev, | ||
842 | struct chip_info *ci) | ||
843 | { | ||
844 | ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, | ||
845 | ARMCR4_BCMA_IOCTL_CPUHALT); | ||
846 | } | ||
847 | |||
848 | static bool | ||
849 | brcmf_sdio_chip_cr4_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, | ||
850 | char *nvram_dat, uint nvram_sz) | ||
851 | { | ||
852 | u8 core_idx; | ||
853 | u32 reg_addr; | ||
854 | |||
855 | if (!brcmf_sdio_chip_writenvram(sdiodev, ci, nvram_dat, nvram_sz)) | ||
856 | return false; | ||
857 | |||
858 | /* clear all interrupts */ | ||
859 | core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_SDIO_DEV); | ||
860 | reg_addr = ci->c_inf[core_idx].base; | ||
861 | reg_addr += offsetof(struct sdpcmd_regs, intstatus); | ||
862 | brcmf_sdio_regwl(sdiodev, reg_addr, 0xFFFFFFFF, NULL); | ||
863 | |||
864 | /* Write reset vector to address 0 */ | ||
865 | brcmf_sdio_ramrw(sdiodev, true, 0, (void *)&ci->rst_vec, | ||
866 | sizeof(ci->rst_vec)); | ||
867 | |||
868 | /* restore ARM */ | ||
869 | ci->resetcore(sdiodev, ci, BCMA_CORE_ARM_CR4, 0); | ||
773 | 870 | ||
774 | return true; | 871 | return true; |
775 | } | 872 | } |
@@ -777,12 +874,27 @@ brcmf_sdio_chip_cm3_exitdl(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, | |||
777 | void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev, | 874 | void brcmf_sdio_chip_enter_download(struct brcmf_sdio_dev *sdiodev, |
778 | struct chip_info *ci) | 875 | struct chip_info *ci) |
779 | { | 876 | { |
780 | brcmf_sdio_chip_cm3_enterdl(sdiodev, ci); | 877 | u8 arm_core_idx; |
878 | |||
879 | arm_core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3); | ||
880 | if (BRCMF_MAX_CORENUM != arm_core_idx) { | ||
881 | brcmf_sdio_chip_cm3_enterdl(sdiodev, ci); | ||
882 | return; | ||
883 | } | ||
884 | |||
885 | brcmf_sdio_chip_cr4_enterdl(sdiodev, ci); | ||
781 | } | 886 | } |
782 | 887 | ||
783 | bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev, | 888 | bool brcmf_sdio_chip_exit_download(struct brcmf_sdio_dev *sdiodev, |
784 | struct chip_info *ci, char *nvram_dat, | 889 | struct chip_info *ci, char *nvram_dat, |
785 | uint nvram_sz) | 890 | uint nvram_sz) |
786 | { | 891 | { |
787 | return brcmf_sdio_chip_cm3_exitdl(sdiodev, ci, nvram_dat, nvram_sz); | 892 | u8 arm_core_idx; |
893 | |||
894 | arm_core_idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3); | ||
895 | if (BRCMF_MAX_CORENUM != arm_core_idx) | ||
896 | return brcmf_sdio_chip_cm3_exitdl(sdiodev, ci, nvram_dat, | ||
897 | nvram_sz); | ||
898 | |||
899 | return brcmf_sdio_chip_cr4_exitdl(sdiodev, ci, nvram_dat, nvram_sz); | ||
788 | } | 900 | } |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h index 2123ea71d127..83c041f1bf4a 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h +++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_chip.h | |||
@@ -73,15 +73,17 @@ struct chip_info { | |||
73 | u32 pmurev; | 73 | u32 pmurev; |
74 | u32 pmucaps; | 74 | u32 pmucaps; |
75 | u32 ramsize; | 75 | u32 ramsize; |
76 | u32 rambase; | ||
77 | u32 rst_vec; /* reset vertor for ARM CR4 core */ | ||
76 | 78 | ||
77 | bool (*iscoreup)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, | 79 | bool (*iscoreup)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, |
78 | u16 coreid); | 80 | u16 coreid); |
79 | u32 (*corerev)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, | 81 | u32 (*corerev)(struct brcmf_sdio_dev *sdiodev, struct chip_info *ci, |
80 | u16 coreid); | 82 | u16 coreid); |
81 | void (*coredisable)(struct brcmf_sdio_dev *sdiodev, | 83 | void (*coredisable)(struct brcmf_sdio_dev *sdiodev, |
82 | struct chip_info *ci, u16 coreid); | 84 | struct chip_info *ci, u16 coreid, u32 core_bits); |
83 | void (*resetcore)(struct brcmf_sdio_dev *sdiodev, | 85 | void (*resetcore)(struct brcmf_sdio_dev *sdiodev, |
84 | struct chip_info *ci, u16 coreid); | 86 | struct chip_info *ci, u16 coreid, u32 core_bits); |
85 | }; | 87 | }; |
86 | 88 | ||
87 | struct sbconfig { | 89 | struct sbconfig { |