2af6fd93bc06142b459144caf49489d51f7f6304
[openwrt/staging/yousong.git] / package / kernel / mac80211 / patches / 323-0004-brcmfmac-access-PMU-registers-using-standalone-PMU-c.patch
1 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
2 Date: Tue, 26 Jan 2016 17:57:04 +0100
3 Subject: [PATCH] brcmfmac: access PMU registers using standalone PMU core if
4 available
5 MIME-Version: 1.0
6 Content-Type: text/plain; charset=UTF-8
7 Content-Transfer-Encoding: 8bit
8
9 On recent Broadcom chipsets PMU is present as separated core and it
10 can't be accessed using ChipCommon anymore as it fails with e.g.:
11 [ 18.198412] Unhandled fault: imprecise external abort (0x1406) at 0xb6da200f
12
13 Add a new helper function that will return a proper core that should be
14 used for accessing PMU registers.
15
16 Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
17 Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
18 ---
19
20 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
21 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
22 @@ -1014,6 +1014,7 @@ static int brcmf_chip_setup(struct brcmf
23 {
24 struct brcmf_chip *pub;
25 struct brcmf_core_priv *cc;
26 + struct brcmf_core *pmu;
27 u32 base;
28 u32 val;
29 int ret = 0;
30 @@ -1030,9 +1031,10 @@ static int brcmf_chip_setup(struct brcmf
31 capabilities_ext));
32
33 /* get pmu caps & rev */
34 + pmu = brcmf_chip_get_pmu(pub); /* after reading cc_caps_ext */
35 if (pub->cc_caps & CC_CAP_PMU) {
36 val = chip->ops->read32(chip->ctx,
37 - CORE_CC_REG(base, pmucapabilities));
38 + CORE_CC_REG(pmu->base, pmucapabilities));
39 pub->pmurev = val & PCAP_REV_MASK;
40 pub->pmucaps = val;
41 }
42 @@ -1131,6 +1133,23 @@ struct brcmf_core *brcmf_chip_get_chipco
43 return &cc->pub;
44 }
45
46 +struct brcmf_core *brcmf_chip_get_pmu(struct brcmf_chip *pub)
47 +{
48 + struct brcmf_core *cc = brcmf_chip_get_chipcommon(pub);
49 + struct brcmf_core *pmu;
50 +
51 + /* See if there is separated PMU core available */
52 + if (cc->rev >= 35 &&
53 + pub->cc_caps_ext & BCMA_CC_CAP_EXT_AOB_PRESENT) {
54 + pmu = brcmf_chip_get_core(pub, BCMA_CORE_PMU);
55 + if (pmu)
56 + return pmu;
57 + }
58 +
59 + /* Fallback to ChipCommon core for older hardware */
60 + return cc;
61 +}
62 +
63 bool brcmf_chip_iscoreup(struct brcmf_core *pub)
64 {
65 struct brcmf_core_priv *core;
66 @@ -1301,6 +1320,7 @@ bool brcmf_chip_sr_capable(struct brcmf_
67 {
68 u32 base, addr, reg, pmu_cc3_mask = ~0;
69 struct brcmf_chip_priv *chip;
70 + struct brcmf_core *pmu = brcmf_chip_get_pmu(pub);
71
72 brcmf_dbg(TRACE, "Enter\n");
73
74 @@ -1320,9 +1340,9 @@ bool brcmf_chip_sr_capable(struct brcmf_
75 case BRCM_CC_4335_CHIP_ID:
76 case BRCM_CC_4339_CHIP_ID:
77 /* read PMU chipcontrol register 3 */
78 - addr = CORE_CC_REG(base, chipcontrol_addr);
79 + addr = CORE_CC_REG(pmu->base, chipcontrol_addr);
80 chip->ops->write32(chip->ctx, addr, 3);
81 - addr = CORE_CC_REG(base, chipcontrol_data);
82 + addr = CORE_CC_REG(pmu->base, chipcontrol_data);
83 reg = chip->ops->read32(chip->ctx, addr);
84 return (reg & pmu_cc3_mask) != 0;
85 case BRCM_CC_43430_CHIP_ID:
86 @@ -1330,12 +1350,12 @@ bool brcmf_chip_sr_capable(struct brcmf_
87 reg = chip->ops->read32(chip->ctx, addr);
88 return reg != 0;
89 default:
90 - addr = CORE_CC_REG(base, pmucapabilities_ext);
91 + addr = CORE_CC_REG(pmu->base, pmucapabilities_ext);
92 reg = chip->ops->read32(chip->ctx, addr);
93 if ((reg & PCAPEXT_SR_SUPPORTED_MASK) == 0)
94 return false;
95
96 - addr = CORE_CC_REG(base, retention_ctl);
97 + addr = CORE_CC_REG(pmu->base, retention_ctl);
98 reg = chip->ops->read32(chip->ctx, addr);
99 return (reg & (PMU_RCTL_MACPHY_DISABLE_MASK |
100 PMU_RCTL_LOGIC_DISABLE_MASK)) == 0;
101 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h
102 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h
103 @@ -85,6 +85,7 @@ struct brcmf_chip *brcmf_chip_attach(voi
104 void brcmf_chip_detach(struct brcmf_chip *chip);
105 struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *chip, u16 coreid);
106 struct brcmf_core *brcmf_chip_get_chipcommon(struct brcmf_chip *chip);
107 +struct brcmf_core *brcmf_chip_get_pmu(struct brcmf_chip *pub);
108 bool brcmf_chip_iscoreup(struct brcmf_core *core);
109 void brcmf_chip_coredisable(struct brcmf_core *core, u32 prereset, u32 reset);
110 void brcmf_chip_resetcore(struct brcmf_core *core, u32 prereset, u32 reset,
111 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
112 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
113 @@ -3615,7 +3615,6 @@ brcmf_sdio_drivestrengthinit(struct brcm
114 const struct sdiod_drive_str *str_tab = NULL;
115 u32 str_mask;
116 u32 str_shift;
117 - u32 base;
118 u32 i;
119 u32 drivestrength_sel = 0;
120 u32 cc_data_temp;
121 @@ -3658,14 +3657,15 @@ brcmf_sdio_drivestrengthinit(struct brcm
122 }
123
124 if (str_tab != NULL) {
125 + struct brcmf_core *pmu = brcmf_chip_get_pmu(ci);
126 +
127 for (i = 0; str_tab[i].strength != 0; i++) {
128 if (drivestrength >= str_tab[i].strength) {
129 drivestrength_sel = str_tab[i].sel;
130 break;
131 }
132 }
133 - base = brcmf_chip_get_chipcommon(ci)->base;
134 - addr = CORE_CC_REG(base, chipcontrol_addr);
135 + addr = CORE_CC_REG(pmu->base, chipcontrol_addr);
136 brcmf_sdiod_regwl(sdiodev, addr, 1, NULL);
137 cc_data_temp = brcmf_sdiod_regrl(sdiodev, addr, NULL);
138 cc_data_temp &= ~str_mask;
139 @@ -3835,8 +3835,7 @@ brcmf_sdio_probe_attach(struct brcmf_sdi
140 goto fail;
141
142 /* set PMUControl so a backplane reset does PMU state reload */
143 - reg_addr = CORE_CC_REG(brcmf_chip_get_chipcommon(bus->ci)->base,
144 - pmucontrol);
145 + reg_addr = CORE_CC_REG(brcmf_chip_get_pmu(bus->ci)->base, pmucontrol);
146 reg_val = brcmf_sdiod_regrl(bus->sdiodev, reg_addr, &err);
147 if (err)
148 goto fail;