Commit 99ba15cd authored by Franky Lin's avatar Franky Lin Committed by John W. Linville

brcm80211: fmac: optimize chip core info management

Prepare for adding backplane interconnect type support
Reviewed-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarFranky Lin <frankyl@broadcom.com>
Signed-off-by: default avatarArend van Spriel <arend@broadcom.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 61213be4
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <linux/semaphore.h> #include <linux/semaphore.h>
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/bcma/bcma.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <defs.h> #include <defs.h>
#include <brcmu_wifi.h> #include <brcmu_wifi.h>
...@@ -614,10 +615,12 @@ static bool data_ok(struct brcmf_bus *bus) ...@@ -614,10 +615,12 @@ static bool data_ok(struct brcmf_bus *bus)
static void static void
r_sdreg32(struct brcmf_bus *bus, u32 *regvar, u32 reg_offset, u32 *retryvar) r_sdreg32(struct brcmf_bus *bus, u32 *regvar, u32 reg_offset, u32 *retryvar)
{ {
u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
*retryvar = 0; *retryvar = 0;
do { do {
*regvar = brcmf_sdcard_reg_read(bus->sdiodev, *regvar = brcmf_sdcard_reg_read(bus->sdiodev,
bus->ci->buscorebase + reg_offset, sizeof(u32)); bus->ci->c_inf[idx].base + reg_offset,
sizeof(u32));
} while (brcmf_sdcard_regfail(bus->sdiodev) && } while (brcmf_sdcard_regfail(bus->sdiodev) &&
(++(*retryvar) <= retry_limit)); (++(*retryvar) <= retry_limit));
if (*retryvar) { if (*retryvar) {
...@@ -632,10 +635,11 @@ r_sdreg32(struct brcmf_bus *bus, u32 *regvar, u32 reg_offset, u32 *retryvar) ...@@ -632,10 +635,11 @@ r_sdreg32(struct brcmf_bus *bus, u32 *regvar, u32 reg_offset, u32 *retryvar)
static void static void
w_sdreg32(struct brcmf_bus *bus, u32 regval, u32 reg_offset, u32 *retryvar) w_sdreg32(struct brcmf_bus *bus, u32 regval, u32 reg_offset, u32 *retryvar)
{ {
u8 idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
*retryvar = 0; *retryvar = 0;
do { do {
brcmf_sdcard_reg_write(bus->sdiodev, brcmf_sdcard_reg_write(bus->sdiodev,
bus->ci->buscorebase + reg_offset, bus->ci->c_inf[idx].base + reg_offset,
sizeof(u32), regval); sizeof(u32), regval);
} while (brcmf_sdcard_regfail(bus->sdiodev) && } while (brcmf_sdcard_regfail(bus->sdiodev) &&
(++(*retryvar) <= retry_limit)); (++(*retryvar) <= retry_limit));
...@@ -683,8 +687,8 @@ static int brcmf_sdbrcm_htclk(struct brcmf_bus *bus, bool on, bool pendok) ...@@ -683,8 +687,8 @@ static int brcmf_sdbrcm_htclk(struct brcmf_bus *bus, bool on, bool pendok)
return -EBADE; return -EBADE;
} }
if (pendok && ((bus->ci->buscoretype == PCMCIA_CORE_ID) if (pendok && ((bus->ci->c_inf[1].id == PCMCIA_CORE_ID)
&& (bus->ci->buscorerev == 9))) { && (bus->ci->c_inf[1].rev == 9))) {
u32 dummy, retries; u32 dummy, retries;
r_sdreg32(bus, &dummy, r_sdreg32(bus, &dummy,
offsetof(struct sdpcmd_regs, clockctlstatus), offsetof(struct sdpcmd_regs, clockctlstatus),
...@@ -909,8 +913,8 @@ static int brcmf_sdbrcm_bussleep(struct brcmf_bus *bus, bool sleep) ...@@ -909,8 +913,8 @@ static int brcmf_sdbrcm_bussleep(struct brcmf_bus *bus, bool sleep)
/* Force pad isolation off if possible /* Force pad isolation off if possible
(in case power never toggled) */ (in case power never toggled) */
if ((bus->ci->buscoretype == PCMCIA_CORE_ID) if ((bus->ci->c_inf[1].id == PCMCIA_CORE_ID)
&& (bus->ci->buscorerev >= 10)) && (bus->ci->c_inf[1].rev >= 10))
brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1, brcmf_sdcard_cfg_write(bus->sdiodev, SDIO_FUNC_1,
SBSDIO_DEVICE_CTL, 0, NULL); SBSDIO_DEVICE_CTL, 0, NULL);
...@@ -3094,6 +3098,8 @@ static int brcmf_sdbrcm_download_state(struct brcmf_bus *bus, bool enter) ...@@ -3094,6 +3098,8 @@ static int brcmf_sdbrcm_download_state(struct brcmf_bus *bus, bool enter)
{ {
uint retries; uint retries;
int bcmerror = 0; int bcmerror = 0;
u8 idx;
struct chip_info *ci = bus->ci;
/* To enter download state, disable ARM and reset SOCRAM. /* To enter download state, disable ARM and reset SOCRAM.
* To exit download state, simply reset ARM (default is RAM boot). * To exit download state, simply reset ARM (default is RAM boot).
...@@ -3101,10 +3107,11 @@ static int brcmf_sdbrcm_download_state(struct brcmf_bus *bus, bool enter) ...@@ -3101,10 +3107,11 @@ static int brcmf_sdbrcm_download_state(struct brcmf_bus *bus, bool enter)
if (enter) { if (enter) {
bus->alp_only = true; bus->alp_only = true;
brcmf_sdio_chip_coredisable(bus->sdiodev, idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3);
bus->ci->armcorebase); brcmf_sdio_chip_coredisable(bus->sdiodev, ci->c_inf[idx].base);
brcmf_sdio_chip_resetcore(bus->sdiodev, bus->ci->ramcorebase); idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_INTERNAL_MEM);
brcmf_sdio_chip_resetcore(bus->sdiodev, ci->c_inf[idx].base);
/* Clear the top bit of memory */ /* Clear the top bit of memory */
if (bus->ramsize) { if (bus->ramsize) {
...@@ -3113,8 +3120,9 @@ static int brcmf_sdbrcm_download_state(struct brcmf_bus *bus, bool enter) ...@@ -3113,8 +3120,9 @@ static int brcmf_sdbrcm_download_state(struct brcmf_bus *bus, bool enter)
(u8 *)&zeros, 4); (u8 *)&zeros, 4);
} }
} else { } else {
idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_INTERNAL_MEM);
if (!brcmf_sdio_chip_iscoreup(bus->sdiodev, if (!brcmf_sdio_chip_iscoreup(bus->sdiodev,
bus->ci->ramcorebase)) { ci->c_inf[idx].base)) {
brcmf_dbg(ERROR, "SOCRAM core is down after reset?\n"); brcmf_dbg(ERROR, "SOCRAM core is down after reset?\n");
bcmerror = -EBADE; bcmerror = -EBADE;
goto fail; goto fail;
...@@ -3129,7 +3137,8 @@ static int brcmf_sdbrcm_download_state(struct brcmf_bus *bus, bool enter) ...@@ -3129,7 +3137,8 @@ static int brcmf_sdbrcm_download_state(struct brcmf_bus *bus, bool enter)
w_sdreg32(bus, 0xFFFFFFFF, w_sdreg32(bus, 0xFFFFFFFF,
offsetof(struct sdpcmd_regs, intstatus), &retries); offsetof(struct sdpcmd_regs, intstatus), &retries);
brcmf_sdio_chip_resetcore(bus->sdiodev, bus->ci->armcorebase); idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3);
brcmf_sdio_chip_resetcore(bus->sdiodev, ci->c_inf[idx].base);
/* Allow HT Clock now that the ARM is running. */ /* Allow HT Clock now that the ARM is running. */
bus->alp_only = false; bus->alp_only = false;
...@@ -3711,6 +3720,7 @@ brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, u32 regsva) ...@@ -3711,6 +3720,7 @@ brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, u32 regsva)
int err = 0; int err = 0;
int reg_addr; int reg_addr;
u32 reg_val; u32 reg_val;
u8 idx;
bus->alp_only = true; bus->alp_only = true;
...@@ -3764,7 +3774,8 @@ brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, u32 regsva) ...@@ -3764,7 +3774,8 @@ brcmf_sdbrcm_probe_attach(struct brcmf_bus *bus, u32 regsva)
} }
/* Set core control so an SDIO reset does a backplane reset */ /* Set core control so an SDIO reset does a backplane reset */
reg_addr = bus->ci->buscorebase + idx = brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_SDIO_DEV);
reg_addr = bus->ci->c_inf[idx].base +
offsetof(struct sdpcmd_regs, corecontrol); offsetof(struct sdpcmd_regs, corecontrol);
reg_val = brcmf_sdcard_reg_read(bus->sdiodev, reg_addr, sizeof(u32)); reg_val = brcmf_sdcard_reg_read(bus->sdiodev, reg_addr, sizeof(u32));
brcmf_sdcard_reg_write(bus->sdiodev, reg_addr, sizeof(u32), brcmf_sdcard_reg_write(bus->sdiodev, reg_addr, sizeof(u32),
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/mmc/card.h> #include <linux/mmc/card.h>
#include <linux/ssb/ssb_regs.h> #include <linux/ssb/ssb_regs.h>
#include <linux/bcma/bcma.h>
#include <chipcommon.h> #include <chipcommon.h>
#include <brcm_hw_ids.h> #include <brcm_hw_ids.h>
...@@ -82,6 +83,18 @@ static const struct sdiod_drive_str sdiod_drive_strength_tab3[] = { ...@@ -82,6 +83,18 @@ static const struct sdiod_drive_str sdiod_drive_strength_tab3[] = {
0, 0x0} 0, 0x0}
}; };
u8
brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid)
{
u8 idx;
for (idx = 0; idx < BRCMF_MAX_CORENUM; idx++)
if (coreid == ci->c_inf[idx].id)
return idx;
return BRCMF_MAX_CORENUM;
}
static u32 static u32
brcmf_sdio_chip_corerev(struct brcmf_sdio_dev *sdiodev, brcmf_sdio_chip_corerev(struct brcmf_sdio_dev *sdiodev,
u32 corebase) u32 corebase)
...@@ -239,9 +252,10 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, ...@@ -239,9 +252,10 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
* For different chiptypes or old sdio hosts w/o chipcommon, * For different chiptypes or old sdio hosts w/o chipcommon,
* other ways of recognition should be added here. * other ways of recognition should be added here.
*/ */
ci->cccorebase = regs; ci->c_inf[0].id = BCMA_CORE_CHIPCOMMON;
ci->c_inf[0].base = regs;
regdata = brcmf_sdcard_reg_read(sdiodev, regdata = brcmf_sdcard_reg_read(sdiodev,
CORE_CC_REG(ci->cccorebase, chipid), 4); CORE_CC_REG(ci->c_inf[0].base, chipid), 4);
ci->chip = regdata & CID_ID_MASK; ci->chip = regdata & CID_ID_MASK;
ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT; ci->chiprev = (regdata & CID_REV_MASK) >> CID_REV_SHIFT;
...@@ -250,9 +264,12 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev, ...@@ -250,9 +264,12 @@ static int brcmf_sdio_chip_recognition(struct brcmf_sdio_dev *sdiodev,
/* Address of cores for new chips should be added here */ /* Address of cores for new chips should be added here */
switch (ci->chip) { switch (ci->chip) {
case BCM4329_CHIP_ID: case BCM4329_CHIP_ID:
ci->buscorebase = BCM4329_CORE_BUS_BASE; ci->c_inf[1].id = BCMA_CORE_SDIO_DEV;
ci->ramcorebase = BCM4329_CORE_SOCRAM_BASE; ci->c_inf[1].base = BCM4329_CORE_BUS_BASE;
ci->armcorebase = BCM4329_CORE_ARM_BASE; ci->c_inf[2].id = BCMA_CORE_INTERNAL_MEM;
ci->c_inf[2].base = BCM4329_CORE_SOCRAM_BASE;
ci->c_inf[3].id = BCMA_CORE_ARM_CM3;
ci->c_inf[3].base = BCM4329_CORE_ARM_BASE;
ci->ramsize = BCM4329_RAMSIZE; ci->ramsize = BCM4329_RAMSIZE;
break; break;
default: default:
...@@ -316,35 +333,39 @@ brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev, ...@@ -316,35 +333,39 @@ brcmf_sdio_chip_buscoresetup(struct brcmf_sdio_dev *sdiodev,
struct chip_info *ci) struct chip_info *ci)
{ {
u32 regdata; u32 regdata;
u8 idx;
/* get chipcommon rev */ /* get chipcommon rev */
ci->ccrev = brcmf_sdio_chip_corerev(sdiodev, ci->cccorebase); ci->c_inf[0].rev =
brcmf_sdio_chip_corerev(sdiodev, ci->c_inf[0].base);
/* get chipcommon capabilites */ /* get chipcommon capabilites */
ci->cccaps = brcmf_sdcard_reg_read(sdiodev, ci->c_inf[0].caps =
CORE_CC_REG(ci->cccorebase, capabilities), 4); brcmf_sdcard_reg_read(sdiodev,
CORE_CC_REG(ci->c_inf[0].base, capabilities), 4);
/* get pmu caps & rev */ /* get pmu caps & rev */
if (ci->cccaps & CC_CAP_PMU) { if (ci->c_inf[0].caps & CC_CAP_PMU) {
ci->pmucaps = brcmf_sdcard_reg_read(sdiodev, ci->pmucaps = brcmf_sdcard_reg_read(sdiodev,
CORE_CC_REG(ci->cccorebase, pmucapabilities), 4); CORE_CC_REG(ci->c_inf[0].base, pmucapabilities), 4);
ci->pmurev = ci->pmucaps & PCAP_REV_MASK; ci->pmurev = ci->pmucaps & PCAP_REV_MASK;
} }
ci->c_inf[1].rev = brcmf_sdio_chip_corerev(sdiodev, ci->c_inf[1].base);
ci->buscorerev = brcmf_sdio_chip_corerev(sdiodev, ci->buscorebase);
regdata = brcmf_sdcard_reg_read(sdiodev, regdata = brcmf_sdcard_reg_read(sdiodev,
CORE_SB(ci->buscorebase, sbidhigh), 4); CORE_SB(ci->c_inf[1].base, sbidhigh), 4);
ci->buscoretype = (regdata & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT; ci->c_inf[1].id = (regdata & SSB_IDHIGH_CC) >> SSB_IDHIGH_CC_SHIFT;
brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n", brcmf_dbg(INFO, "ccrev=%d, pmurev=%d, buscore rev/type=%d/0x%x\n",
ci->ccrev, ci->pmurev, ci->buscorerev, ci->buscoretype); ci->c_inf[0].rev, ci->pmurev,
ci->c_inf[1].rev, ci->c_inf[1].id);
/* /*
* Make sure any on-chip ARM is off (in case strapping is wrong), * Make sure any on-chip ARM is off (in case strapping is wrong),
* or downloaded code was already running. * or downloaded code was already running.
*/ */
brcmf_sdio_chip_coredisable(sdiodev, ci->armcorebase); idx = brcmf_sdio_chip_getinfidx(ci, BCMA_CORE_ARM_CM3);
brcmf_sdio_chip_coredisable(sdiodev, ci->c_inf[idx].base);
} }
int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
...@@ -371,9 +392,9 @@ int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev, ...@@ -371,9 +392,9 @@ int brcmf_sdio_chip_attach(struct brcmf_sdio_dev *sdiodev,
brcmf_sdio_chip_buscoresetup(sdiodev, ci); brcmf_sdio_chip_buscoresetup(sdiodev, ci);
brcmf_sdcard_reg_write(sdiodev, brcmf_sdcard_reg_write(sdiodev,
CORE_CC_REG(ci->cccorebase, gpiopullup), 4, 0); CORE_CC_REG(ci->c_inf[0].base, gpiopullup), 4, 0);
brcmf_sdcard_reg_write(sdiodev, brcmf_sdcard_reg_write(sdiodev,
CORE_CC_REG(ci->cccorebase, gpiopulldown), 4, 0); CORE_CC_REG(ci->c_inf[0].base, gpiopulldown), 4, 0);
*ci_ptr = ci; *ci_ptr = ci;
return 0; return 0;
...@@ -410,7 +431,7 @@ brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, ...@@ -410,7 +431,7 @@ brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
u32 str_shift = 0; u32 str_shift = 0;
char chn[8]; char chn[8];
if (!(ci->cccaps & CC_CAP_PMU)) if (!(ci->c_inf[0].caps & CC_CAP_PMU))
return; return;
switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) { switch (SDIOD_DRVSTR_KEY(ci->chip, ci->pmurev)) {
...@@ -450,15 +471,15 @@ brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, ...@@ -450,15 +471,15 @@ brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
} }
brcmf_sdcard_reg_write(sdiodev, brcmf_sdcard_reg_write(sdiodev,
CORE_CC_REG(ci->cccorebase, chipcontrol_addr), CORE_CC_REG(ci->c_inf[0].base, chipcontrol_addr),
4, 1); 4, 1);
cc_data_temp = brcmf_sdcard_reg_read(sdiodev, cc_data_temp = brcmf_sdcard_reg_read(sdiodev,
CORE_CC_REG(ci->cccorebase, chipcontrol_addr), 4); CORE_CC_REG(ci->c_inf[0].base, chipcontrol_addr), 4);
cc_data_temp &= ~str_mask; cc_data_temp &= ~str_mask;
drivestrength_sel <<= str_shift; drivestrength_sel <<= str_shift;
cc_data_temp |= drivestrength_sel; cc_data_temp |= drivestrength_sel;
brcmf_sdcard_reg_write(sdiodev, brcmf_sdcard_reg_write(sdiodev,
CORE_CC_REG(ci->cccorebase, chipcontrol_addr), CORE_CC_REG(ci->c_inf[0].base, chipcontrol_addr),
4, cc_data_temp); 4, cc_data_temp);
brcmf_dbg(INFO, "SDIO: %dmA drive strength selected, set to 0x%08x\n", brcmf_dbg(INFO, "SDIO: %dmA drive strength selected, set to 0x%08x\n",
......
...@@ -52,17 +52,22 @@ ...@@ -52,17 +52,22 @@
#define SBSDIO_CLKAV(regval, alponly) \ #define SBSDIO_CLKAV(regval, alponly) \
(SBSDIO_ALPAV(regval) && (alponly ? 1 : SBSDIO_HTAV(regval))) (SBSDIO_ALPAV(regval) && (alponly ? 1 : SBSDIO_HTAV(regval)))
#define BRCMF_MAX_CORENUM 6
struct chip_core_info {
u16 id;
u16 rev;
u32 base;
u32 wrapbase;
u32 caps;
};
struct chip_info { struct chip_info {
u32 chip; u32 chip;
u32 chiprev; u32 chiprev;
u32 cccorebase; /* core info */
u32 ccrev; /* always put chipcommon core at 0, bus core at 1 */
u32 cccaps; struct chip_core_info c_inf[BRCMF_MAX_CORENUM];
u32 buscorebase; /* 32 bits backplane bus address */
u32 buscorerev;
u32 buscoretype;
u32 ramcorebase;
u32 armcorebase;
u32 pmurev; u32 pmurev;
u32 pmucaps; u32 pmucaps;
u32 ramsize; u32 ramsize;
...@@ -120,5 +125,7 @@ extern void brcmf_sdio_chip_detach(struct chip_info **ci_ptr); ...@@ -120,5 +125,7 @@ extern void brcmf_sdio_chip_detach(struct chip_info **ci_ptr);
extern void brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev, extern void brcmf_sdio_chip_drivestrengthinit(struct brcmf_sdio_dev *sdiodev,
struct chip_info *ci, struct chip_info *ci,
u32 drivestrength); u32 drivestrength);
extern u8 brcmf_sdio_chip_getinfidx(struct chip_info *ci, u16 coreid);
#endif /* _BRCMFMAC_SDIO_CHIP_H_ */ #endif /* _BRCMFMAC_SDIO_CHIP_H_ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment