bcma: add support for BCM43142

Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Rafał Miłecki
2013-06-26 10:02:11 +02:00
committed by John W. Linville
parent 8960400eee
commit 88f9b65d44
8 changed files with 211 additions and 2 deletions

View File

@@ -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;
@@ -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);
@@ -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);
}