Loading drivers/bcma/bcma_private.h +2 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ struct bcma_bus; /* main.c */ bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value, int timeout); int bcma_bus_register(struct bcma_bus *bus); void bcma_bus_unregister(struct bcma_bus *bus); int __init bcma_bus_early_register(struct bcma_bus *bus, Loading drivers/bcma/driver_chipcommon.c +9 −2 Original line number Diff line number Diff line Loading @@ -140,8 +140,15 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc) bcma_core_chipcommon_early_init(cc); if (cc->core->id.rev >= 20) { bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0); bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, 0); u32 pullup = 0, pulldown = 0; if (cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM43142) { pullup = 0x402e0; pulldown = 0x20500; } bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, pullup); bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, pulldown); } if (cc->capabilities & BCMA_CC_CAP_PMU) Loading drivers/bcma/driver_chipcommon_pmu.c +123 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,109 @@ void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask, } EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset); static u32 bcma_pmu_xtalfreq(struct bcma_drv_cc *cc) { u32 ilp_ctl, alp_hz; if (!(bcma_cc_read32(cc, BCMA_CC_PMU_STAT) & BCMA_CC_PMU_STAT_EXT_LPO_AVAIL)) return 0; bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ, BIT(BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT)); usleep_range(1000, 2000); ilp_ctl = bcma_cc_read32(cc, BCMA_CC_PMU_XTAL_FREQ); ilp_ctl &= BCMA_CC_PMU_XTAL_FREQ_ILPCTL_MASK; bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ, 0); alp_hz = ilp_ctl * 32768 / 4; return (alp_hz + 50000) / 100000 * 100; } static void bcma_pmu2_pll_init0(struct bcma_drv_cc *cc, u32 xtalfreq) { struct bcma_bus *bus = cc->core->bus; u32 freq_tgt_target = 0, freq_tgt_current; u32 pll0, mask; switch (bus->chipinfo.id) { case BCMA_CHIP_ID_BCM43142: /* pmu2_xtaltab0_adfll_485 */ switch (xtalfreq) { case 12000: freq_tgt_target = 0x50D52; break; case 20000: freq_tgt_target = 0x307FE; break; case 26000: freq_tgt_target = 0x254EA; break; case 37400: freq_tgt_target = 0x19EF8; break; case 52000: freq_tgt_target = 0x12A75; break; } break; } if (!freq_tgt_target) { bcma_err(bus, "Unknown TGT frequency for xtalfreq %d\n", xtalfreq); return; } pll0 = bcma_chipco_pll_read(cc, BCMA_CC_PMU15_PLL_PLLCTL0); freq_tgt_current = (pll0 & BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK) >> BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT; if (freq_tgt_current == freq_tgt_target) { bcma_debug(bus, "Target TGT frequency already set\n"); return; } /* Turn off PLL */ switch (bus->chipinfo.id) { case BCMA_CHIP_ID_BCM43142: mask = (u32)~(BCMA_RES_4314_HT_AVAIL | BCMA_RES_4314_MACPHY_CLK_AVAIL); bcma_cc_mask32(cc, BCMA_CC_PMU_MINRES_MSK, mask); bcma_cc_mask32(cc, BCMA_CC_PMU_MAXRES_MSK, mask); bcma_wait_value(cc->core, BCMA_CLKCTLST, BCMA_CLKCTLST_HAVEHT, 0, 20000); break; } pll0 &= ~BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK; pll0 |= freq_tgt_target << BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT; bcma_chipco_pll_write(cc, BCMA_CC_PMU15_PLL_PLLCTL0, pll0); /* Flush */ if (cc->pmu.rev >= 2) bcma_cc_set32(cc, BCMA_CC_PMU_CTL, BCMA_CC_PMU_CTL_PLL_UPD); /* TODO: Do we need to update OTP? */ } static void bcma_pmu_pll_init(struct bcma_drv_cc *cc) { struct bcma_bus *bus = cc->core->bus; u32 xtalfreq = bcma_pmu_xtalfreq(cc); switch (bus->chipinfo.id) { case BCMA_CHIP_ID_BCM43142: if (xtalfreq == 0) xtalfreq = 20000; bcma_pmu2_pll_init0(cc, xtalfreq); break; } } static void bcma_pmu_resources_init(struct bcma_drv_cc *cc) { struct bcma_bus *bus = cc->core->bus; Loading @@ -66,6 +169,25 @@ static void bcma_pmu_resources_init(struct bcma_drv_cc *cc) min_msk = 0x200D; max_msk = 0xFFFF; break; case BCMA_CHIP_ID_BCM43142: min_msk = BCMA_RES_4314_LPLDO_PU | BCMA_RES_4314_PMU_SLEEP_DIS | BCMA_RES_4314_PMU_BG_PU | BCMA_RES_4314_CBUCK_LPOM_PU | BCMA_RES_4314_CBUCK_PFM_PU | BCMA_RES_4314_CLDO_PU | BCMA_RES_4314_LPLDO2_LVM | BCMA_RES_4314_WL_PMU_PU | BCMA_RES_4314_LDO3P3_PU | BCMA_RES_4314_OTP_PU | BCMA_RES_4314_WL_PWRSW_PU | BCMA_RES_4314_LQ_AVAIL | BCMA_RES_4314_LOGIC_RET | BCMA_RES_4314_MEM_SLEEP | BCMA_RES_4314_MACPHY_RET | BCMA_RES_4314_WL_CORE_READY; max_msk = 0x3FFFFFFF; break; default: bcma_debug(bus, "PMU resource config unknown or not needed for device 0x%04X\n", bus->chipinfo.id); Loading Loading @@ -165,6 +287,7 @@ void bcma_pmu_init(struct bcma_drv_cc *cc) bcma_cc_set32(cc, BCMA_CC_PMU_CTL, BCMA_CC_PMU_CTL_NOILPONW); bcma_pmu_pll_init(cc); bcma_pmu_resources_init(cc); bcma_pmu_workarounds(cc); } Loading drivers/bcma/host_pci.c +1 −0 Original line number Diff line number Diff line Loading @@ -275,6 +275,7 @@ static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4358) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4365) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, { 0, }, }; Loading drivers/bcma/main.c +19 −0 Original line number Diff line number Diff line Loading @@ -93,6 +93,25 @@ struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid, return NULL; } bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value, int timeout) { unsigned long deadline = jiffies + timeout; u32 val; do { val = bcma_read32(core, reg); if ((val & mask) == value) return true; cpu_relax(); udelay(10); } while (!time_after_eq(jiffies, deadline)); bcma_warn(core->bus, "Timeout waiting for register 0x%04X!\n", reg); return false; } static void bcma_release_core_dev(struct device *dev) { struct bcma_device *core = container_of(dev, struct bcma_device, dev); Loading Loading
drivers/bcma/bcma_private.h +2 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,8 @@ struct bcma_bus; /* main.c */ bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value, int timeout); int bcma_bus_register(struct bcma_bus *bus); void bcma_bus_unregister(struct bcma_bus *bus); int __init bcma_bus_early_register(struct bcma_bus *bus, Loading
drivers/bcma/driver_chipcommon.c +9 −2 Original line number Diff line number Diff line Loading @@ -140,8 +140,15 @@ void bcma_core_chipcommon_init(struct bcma_drv_cc *cc) bcma_core_chipcommon_early_init(cc); if (cc->core->id.rev >= 20) { bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, 0); bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, 0); u32 pullup = 0, pulldown = 0; if (cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM43142) { pullup = 0x402e0; pulldown = 0x20500; } bcma_cc_write32(cc, BCMA_CC_GPIOPULLUP, pullup); bcma_cc_write32(cc, BCMA_CC_GPIOPULLDOWN, pulldown); } if (cc->capabilities & BCMA_CC_CAP_PMU) Loading
drivers/bcma/driver_chipcommon_pmu.c +123 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,109 @@ void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, u32 offset, u32 mask, } EXPORT_SYMBOL_GPL(bcma_chipco_regctl_maskset); static u32 bcma_pmu_xtalfreq(struct bcma_drv_cc *cc) { u32 ilp_ctl, alp_hz; if (!(bcma_cc_read32(cc, BCMA_CC_PMU_STAT) & BCMA_CC_PMU_STAT_EXT_LPO_AVAIL)) return 0; bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ, BIT(BCMA_CC_PMU_XTAL_FREQ_MEASURE_SHIFT)); usleep_range(1000, 2000); ilp_ctl = bcma_cc_read32(cc, BCMA_CC_PMU_XTAL_FREQ); ilp_ctl &= BCMA_CC_PMU_XTAL_FREQ_ILPCTL_MASK; bcma_cc_write32(cc, BCMA_CC_PMU_XTAL_FREQ, 0); alp_hz = ilp_ctl * 32768 / 4; return (alp_hz + 50000) / 100000 * 100; } static void bcma_pmu2_pll_init0(struct bcma_drv_cc *cc, u32 xtalfreq) { struct bcma_bus *bus = cc->core->bus; u32 freq_tgt_target = 0, freq_tgt_current; u32 pll0, mask; switch (bus->chipinfo.id) { case BCMA_CHIP_ID_BCM43142: /* pmu2_xtaltab0_adfll_485 */ switch (xtalfreq) { case 12000: freq_tgt_target = 0x50D52; break; case 20000: freq_tgt_target = 0x307FE; break; case 26000: freq_tgt_target = 0x254EA; break; case 37400: freq_tgt_target = 0x19EF8; break; case 52000: freq_tgt_target = 0x12A75; break; } break; } if (!freq_tgt_target) { bcma_err(bus, "Unknown TGT frequency for xtalfreq %d\n", xtalfreq); return; } pll0 = bcma_chipco_pll_read(cc, BCMA_CC_PMU15_PLL_PLLCTL0); freq_tgt_current = (pll0 & BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK) >> BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT; if (freq_tgt_current == freq_tgt_target) { bcma_debug(bus, "Target TGT frequency already set\n"); return; } /* Turn off PLL */ switch (bus->chipinfo.id) { case BCMA_CHIP_ID_BCM43142: mask = (u32)~(BCMA_RES_4314_HT_AVAIL | BCMA_RES_4314_MACPHY_CLK_AVAIL); bcma_cc_mask32(cc, BCMA_CC_PMU_MINRES_MSK, mask); bcma_cc_mask32(cc, BCMA_CC_PMU_MAXRES_MSK, mask); bcma_wait_value(cc->core, BCMA_CLKCTLST, BCMA_CLKCTLST_HAVEHT, 0, 20000); break; } pll0 &= ~BCMA_CC_PMU15_PLL_PC0_FREQTGT_MASK; pll0 |= freq_tgt_target << BCMA_CC_PMU15_PLL_PC0_FREQTGT_SHIFT; bcma_chipco_pll_write(cc, BCMA_CC_PMU15_PLL_PLLCTL0, pll0); /* Flush */ if (cc->pmu.rev >= 2) bcma_cc_set32(cc, BCMA_CC_PMU_CTL, BCMA_CC_PMU_CTL_PLL_UPD); /* TODO: Do we need to update OTP? */ } static void bcma_pmu_pll_init(struct bcma_drv_cc *cc) { struct bcma_bus *bus = cc->core->bus; u32 xtalfreq = bcma_pmu_xtalfreq(cc); switch (bus->chipinfo.id) { case BCMA_CHIP_ID_BCM43142: if (xtalfreq == 0) xtalfreq = 20000; bcma_pmu2_pll_init0(cc, xtalfreq); break; } } static void bcma_pmu_resources_init(struct bcma_drv_cc *cc) { struct bcma_bus *bus = cc->core->bus; Loading @@ -66,6 +169,25 @@ static void bcma_pmu_resources_init(struct bcma_drv_cc *cc) min_msk = 0x200D; max_msk = 0xFFFF; break; case BCMA_CHIP_ID_BCM43142: min_msk = BCMA_RES_4314_LPLDO_PU | BCMA_RES_4314_PMU_SLEEP_DIS | BCMA_RES_4314_PMU_BG_PU | BCMA_RES_4314_CBUCK_LPOM_PU | BCMA_RES_4314_CBUCK_PFM_PU | BCMA_RES_4314_CLDO_PU | BCMA_RES_4314_LPLDO2_LVM | BCMA_RES_4314_WL_PMU_PU | BCMA_RES_4314_LDO3P3_PU | BCMA_RES_4314_OTP_PU | BCMA_RES_4314_WL_PWRSW_PU | BCMA_RES_4314_LQ_AVAIL | BCMA_RES_4314_LOGIC_RET | BCMA_RES_4314_MEM_SLEEP | BCMA_RES_4314_MACPHY_RET | BCMA_RES_4314_WL_CORE_READY; max_msk = 0x3FFFFFFF; break; default: bcma_debug(bus, "PMU resource config unknown or not needed for device 0x%04X\n", bus->chipinfo.id); Loading Loading @@ -165,6 +287,7 @@ void bcma_pmu_init(struct bcma_drv_cc *cc) bcma_cc_set32(cc, BCMA_CC_PMU_CTL, BCMA_CC_PMU_CTL_NOILPONW); bcma_pmu_pll_init(cc); bcma_pmu_resources_init(cc); bcma_pmu_workarounds(cc); } Loading
drivers/bcma/host_pci.c +1 −0 Original line number Diff line number Diff line Loading @@ -275,6 +275,7 @@ static DEFINE_PCI_DEVICE_TABLE(bcma_pci_bridge_tbl) = { { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4358) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4365) }, { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) }, { 0, }, }; Loading
drivers/bcma/main.c +19 −0 Original line number Diff line number Diff line Loading @@ -93,6 +93,25 @@ struct bcma_device *bcma_find_core_unit(struct bcma_bus *bus, u16 coreid, return NULL; } bool bcma_wait_value(struct bcma_device *core, u16 reg, u32 mask, u32 value, int timeout) { unsigned long deadline = jiffies + timeout; u32 val; do { val = bcma_read32(core, reg); if ((val & mask) == value) return true; cpu_relax(); udelay(10); } while (!time_after_eq(jiffies, deadline)); bcma_warn(core->bus, "Timeout waiting for register 0x%04X!\n", reg); return false; } static void bcma_release_core_dev(struct device *dev) { struct bcma_device *core = container_of(dev, struct bcma_device, dev); Loading