rpcd: iwinfo plugin fixes
[openwrt.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;