Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bcma: implement BCM4331 workaround for external PA lines

We need to disable ext. PA lines for reading SPROM. It's disabled by
default, but this patch allows using bcma after loading wl, which leaves
workaround enabled.

Cc: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

authored by

Rafał Miłecki and committed by
John W. Linville
984e5bef 17030f48

+43 -1
+19 -1
drivers/bcma/driver_chipcommon_pmu.c
··· 90 90 } 91 91 } 92 92 93 + /* Disable to allow reading SPROM. Don't know the adventages of enabling it. */ 94 + void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable) 95 + { 96 + struct bcma_bus *bus = cc->core->bus; 97 + u32 val; 98 + 99 + val = bcma_cc_read32(cc, BCMA_CC_CHIPCTL); 100 + if (enable) { 101 + val |= BCMA_CHIPCTL_4331_EXTPA_EN; 102 + if (bus->chipinfo.pkg == 9 || bus->chipinfo.pkg == 11) 103 + val |= BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5; 104 + } else { 105 + val &= ~BCMA_CHIPCTL_4331_EXTPA_EN; 106 + val &= ~BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5; 107 + } 108 + bcma_cc_write32(cc, BCMA_CC_CHIPCTL, val); 109 + } 110 + 93 111 void bcma_pmu_workarounds(struct bcma_drv_cc *cc) 94 112 { 95 113 struct bcma_bus *bus = cc->core->bus; ··· 117 99 bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7); 118 100 break; 119 101 case 0x4331: 120 - pr_err("Enabling Ext PA lines not implemented\n"); 102 + /* BCM4331 workaround is SPROM-related, we put it in sprom.c */ 121 103 break; 122 104 case 43224: 123 105 if (bus->chipinfo.rev == 0) {
+6
drivers/bcma/sprom.c
··· 152 152 if (!sprom) 153 153 return -ENOMEM; 154 154 155 + if (bus->chipinfo.id == 0x4331) 156 + bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false); 157 + 155 158 /* Most cards have SPROM moved by additional offset 0x30 (48 dwords). 156 159 * According to brcm80211 this applies to cards with PCIe rev >= 6 157 160 * TODO: understand this condition and use it */ 158 161 offset = (bus->chipinfo.id == 0x4331) ? BCMA_CC_SPROM : 159 162 BCMA_CC_SPROM_PCIE6; 160 163 bcma_sprom_read(bus, offset, sprom); 164 + 165 + if (bus->chipinfo.id == 0x4331) 166 + bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true); 161 167 162 168 err = bcma_sprom_valid(sprom); 163 169 if (err)
+18
include/linux/bcma/bcma_driver_chipcommon.h
··· 283 283 #define BCMA_CC_PPL_PCHI_OFF 5 284 284 #define BCMA_CC_PPL_PCHI_MASK 0x0000003f 285 285 286 + /* BCM4331 ChipControl numbers. */ 287 + #define BCMA_CHIPCTL_4331_BT_COEXIST BIT(0) /* 0 disable */ 288 + #define BCMA_CHIPCTL_4331_SECI BIT(1) /* 0 SECI is disabled (JATG functional) */ 289 + #define BCMA_CHIPCTL_4331_EXT_LNA BIT(2) /* 0 disable */ 290 + #define BCMA_CHIPCTL_4331_SPROM_GPIO13_15 BIT(3) /* sprom/gpio13-15 mux */ 291 + #define BCMA_CHIPCTL_4331_EXTPA_EN BIT(4) /* 0 ext pa disable, 1 ext pa enabled */ 292 + #define BCMA_CHIPCTL_4331_GPIOCLK_ON_SPROMCS BIT(5) /* set drive out GPIO_CLK on sprom_cs pin */ 293 + #define BCMA_CHIPCTL_4331_PCIE_MDIO_ON_SPROMCS BIT(6) /* use sprom_cs pin as PCIE mdio interface */ 294 + #define BCMA_CHIPCTL_4331_EXTPA_ON_GPIO2_5 BIT(7) /* aband extpa will be at gpio2/5 and sprom_dout */ 295 + #define BCMA_CHIPCTL_4331_OVR_PIPEAUXCLKEN BIT(8) /* override core control on pipe_AuxClkEnable */ 296 + #define BCMA_CHIPCTL_4331_OVR_PIPEAUXPWRDOWN BIT(9) /* override core control on pipe_AuxPowerDown */ 297 + #define BCMA_CHIPCTL_4331_PCIE_AUXCLKEN BIT(10) /* pcie_auxclkenable */ 298 + #define BCMA_CHIPCTL_4331_PCIE_PIPE_PLLDOWN BIT(11) /* pcie_pipe_pllpowerdown */ 299 + #define BCMA_CHIPCTL_4331_BT_SHD0_ON_GPIO4 BIT(16) /* enable bt_shd0 at gpio4 */ 300 + #define BCMA_CHIPCTL_4331_BT_SHD1_ON_GPIO5 BIT(17) /* enable bt_shd1 at gpio5 */ 301 + 286 302 /* Data for the PMU, if available. 287 303 * Check availability with ((struct bcma_chipcommon)->capabilities & BCMA_CC_CAP_PMU) 288 304 */ ··· 357 341 358 342 extern void bcma_chipco_suspend(struct bcma_drv_cc *cc); 359 343 extern void bcma_chipco_resume(struct bcma_drv_cc *cc); 344 + 345 + void bcma_chipco_bcm4331_ext_pa_lines_ctl(struct bcma_drv_cc *cc, bool enable); 360 346 361 347 extern void bcma_chipco_watchdog_timer_set(struct bcma_drv_cc *cc, 362 348 u32 ticks);