bcma: add support for BCM43142
Signed-off-by: Rafał Miłecki <zajec5@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
此提交包含在:
@@ -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,
|
||||
|
@@ -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)
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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, },
|
||||
};
|
||||
|
@@ -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);
|
||||
|
@@ -503,6 +503,7 @@ static bool bcma_sprom_onchip_available(struct bcma_bus *bus)
|
||||
case BCMA_CHIP_ID_BCM4331:
|
||||
present = chip_status & BCMA_CC_CHIPST_4331_OTP_PRESENT;
|
||||
break;
|
||||
case BCMA_CHIP_ID_BCM43142:
|
||||
case BCMA_CHIP_ID_BCM43224:
|
||||
case BCMA_CHIP_ID_BCM43225:
|
||||
/* for these chips OTP is always available */
|
||||
|
新增問題並參考
封鎖使用者