| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <[email protected]>
- Date: Tue, 26 Jan 2016 17:57:04 +0100
- Subject: [PATCH] brcmfmac: access PMU registers using standalone PMU core if
- available
- MIME-Version: 1.0
- Content-Type: text/plain; charset=UTF-8
- Content-Transfer-Encoding: 8bit
- On recent Broadcom chipsets PMU is present as separated core and it
- can't be accessed using ChipCommon anymore as it fails with e.g.:
- [ 18.198412] Unhandled fault: imprecise external abort (0x1406) at 0xb6da200f
- Add a new helper function that will return a proper core that should be
- used for accessing PMU registers.
- Signed-off-by: Rafał Miłecki <[email protected]>
- Signed-off-by: Kalle Valo <[email protected]>
- ---
- --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
- +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
- @@ -1014,6 +1014,7 @@ static int brcmf_chip_setup(struct brcmf
- {
- struct brcmf_chip *pub;
- struct brcmf_core_priv *cc;
- + struct brcmf_core *pmu;
- u32 base;
- u32 val;
- int ret = 0;
- @@ -1030,9 +1031,10 @@ static int brcmf_chip_setup(struct brcmf
- capabilities_ext));
-
- /* get pmu caps & rev */
- + pmu = brcmf_chip_get_pmu(pub); /* after reading cc_caps_ext */
- if (pub->cc_caps & CC_CAP_PMU) {
- val = chip->ops->read32(chip->ctx,
- - CORE_CC_REG(base, pmucapabilities));
- + CORE_CC_REG(pmu->base, pmucapabilities));
- pub->pmurev = val & PCAP_REV_MASK;
- pub->pmucaps = val;
- }
- @@ -1131,6 +1133,23 @@ struct brcmf_core *brcmf_chip_get_chipco
- return &cc->pub;
- }
-
- +struct brcmf_core *brcmf_chip_get_pmu(struct brcmf_chip *pub)
- +{
- + struct brcmf_core *cc = brcmf_chip_get_chipcommon(pub);
- + struct brcmf_core *pmu;
- +
- + /* See if there is separated PMU core available */
- + if (cc->rev >= 35 &&
- + pub->cc_caps_ext & BCMA_CC_CAP_EXT_AOB_PRESENT) {
- + pmu = brcmf_chip_get_core(pub, BCMA_CORE_PMU);
- + if (pmu)
- + return pmu;
- + }
- +
- + /* Fallback to ChipCommon core for older hardware */
- + return cc;
- +}
- +
- bool brcmf_chip_iscoreup(struct brcmf_core *pub)
- {
- struct brcmf_core_priv *core;
- @@ -1301,6 +1320,7 @@ bool brcmf_chip_sr_capable(struct brcmf_
- {
- u32 base, addr, reg, pmu_cc3_mask = ~0;
- struct brcmf_chip_priv *chip;
- + struct brcmf_core *pmu = brcmf_chip_get_pmu(pub);
-
- brcmf_dbg(TRACE, "Enter\n");
-
- @@ -1320,9 +1340,9 @@ bool brcmf_chip_sr_capable(struct brcmf_
- case BRCM_CC_4335_CHIP_ID:
- case BRCM_CC_4339_CHIP_ID:
- /* read PMU chipcontrol register 3 */
- - addr = CORE_CC_REG(base, chipcontrol_addr);
- + addr = CORE_CC_REG(pmu->base, chipcontrol_addr);
- chip->ops->write32(chip->ctx, addr, 3);
- - addr = CORE_CC_REG(base, chipcontrol_data);
- + addr = CORE_CC_REG(pmu->base, chipcontrol_data);
- reg = chip->ops->read32(chip->ctx, addr);
- return (reg & pmu_cc3_mask) != 0;
- case BRCM_CC_43430_CHIP_ID:
- @@ -1330,12 +1350,12 @@ bool brcmf_chip_sr_capable(struct brcmf_
- reg = chip->ops->read32(chip->ctx, addr);
- return reg != 0;
- default:
- - addr = CORE_CC_REG(base, pmucapabilities_ext);
- + addr = CORE_CC_REG(pmu->base, pmucapabilities_ext);
- reg = chip->ops->read32(chip->ctx, addr);
- if ((reg & PCAPEXT_SR_SUPPORTED_MASK) == 0)
- return false;
-
- - addr = CORE_CC_REG(base, retention_ctl);
- + addr = CORE_CC_REG(pmu->base, retention_ctl);
- reg = chip->ops->read32(chip->ctx, addr);
- return (reg & (PMU_RCTL_MACPHY_DISABLE_MASK |
- PMU_RCTL_LOGIC_DISABLE_MASK)) == 0;
- --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h
- +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h
- @@ -85,6 +85,7 @@ struct brcmf_chip *brcmf_chip_attach(voi
- void brcmf_chip_detach(struct brcmf_chip *chip);
- struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *chip, u16 coreid);
- struct brcmf_core *brcmf_chip_get_chipcommon(struct brcmf_chip *chip);
- +struct brcmf_core *brcmf_chip_get_pmu(struct brcmf_chip *pub);
- bool brcmf_chip_iscoreup(struct brcmf_core *core);
- void brcmf_chip_coredisable(struct brcmf_core *core, u32 prereset, u32 reset);
- void brcmf_chip_resetcore(struct brcmf_core *core, u32 prereset, u32 reset,
- --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
- +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
- @@ -3615,7 +3615,6 @@ brcmf_sdio_drivestrengthinit(struct brcm
- const struct sdiod_drive_str *str_tab = NULL;
- u32 str_mask;
- u32 str_shift;
- - u32 base;
- u32 i;
- u32 drivestrength_sel = 0;
- u32 cc_data_temp;
- @@ -3658,14 +3657,15 @@ brcmf_sdio_drivestrengthinit(struct brcm
- }
-
- if (str_tab != NULL) {
- + struct brcmf_core *pmu = brcmf_chip_get_pmu(ci);
- +
- for (i = 0; str_tab[i].strength != 0; i++) {
- if (drivestrength >= str_tab[i].strength) {
- drivestrength_sel = str_tab[i].sel;
- break;
- }
- }
- - base = brcmf_chip_get_chipcommon(ci)->base;
- - addr = CORE_CC_REG(base, chipcontrol_addr);
- + addr = CORE_CC_REG(pmu->base, chipcontrol_addr);
- brcmf_sdiod_regwl(sdiodev, addr, 1, NULL);
- cc_data_temp = brcmf_sdiod_regrl(sdiodev, addr, NULL);
- cc_data_temp &= ~str_mask;
- @@ -3835,8 +3835,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdi
- goto fail;
-
- /* set PMUControl so a backplane reset does PMU state reload */
- - reg_addr = CORE_CC_REG(brcmf_chip_get_chipcommon(bus->ci)->base,
- - pmucontrol);
- + reg_addr = CORE_CC_REG(brcmf_chip_get_pmu(bus->ci)->base, pmucontrol);
- reg_val = brcmf_sdiod_regrl(bus->sdiodev, reg_addr, &err);
- if (err)
- goto fail;
|