diff options
Diffstat (limited to 'target/linux/brcm47xx/patches-3.6/549-ssb-get-alp-clock-from-devices-with-PMU.patch')
-rw-r--r-- | target/linux/brcm47xx/patches-3.6/549-ssb-get-alp-clock-from-devices-with-PMU.patch | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/target/linux/brcm47xx/patches-3.6/549-ssb-get-alp-clock-from-devices-with-PMU.patch b/target/linux/brcm47xx/patches-3.6/549-ssb-get-alp-clock-from-devices-with-PMU.patch new file mode 100644 index 0000000000..f5912984d7 --- /dev/null +++ b/target/linux/brcm47xx/patches-3.6/549-ssb-get-alp-clock-from-devices-with-PMU.patch @@ -0,0 +1,76 @@ +--- a/drivers/ssb/driver_chipcommon.c ++++ b/drivers/ssb/driver_chipcommon.c +@@ -280,6 +280,14 @@ static void calc_fast_powerup_delay(stru + cc->fast_pwrup_delay = tmp; + } + ++static u32 ssb_chipco_alp_clock(struct ssb_chipcommon *cc) ++{ ++ if (cc->capabilities & SSB_CHIPCO_CAP_PMU) ++ return ssb_pmu_get_alp_clock(cc); ++ ++ return 20000000; ++} ++ + void ssb_chipcommon_init(struct ssb_chipcommon *cc) + { + if (!cc->dev) +@@ -474,11 +482,7 @@ int ssb_chipco_serial_init(struct ssb_ch + | SSB_CHIPCO_CORECTL_UARTCLK0); + } else if ((ccrev >= 11) && (ccrev != 15)) { + /* Fixed ALP clock */ +- baud_base = 20000000; +- if (cc->capabilities & SSB_CHIPCO_CAP_PMU) { +- /* FIXME: baud_base is different for devices with a PMU */ +- SSB_WARN_ON(1); +- } ++ baud_base = ssb_chipco_alp_clock(cc); + div = 1; + if (ccrev >= 21) { + /* Turn off UART clock before switching clocksource. */ +--- a/drivers/ssb/driver_chipcommon_pmu.c ++++ b/drivers/ssb/driver_chipcommon_pmu.c +@@ -618,6 +618,33 @@ void ssb_pmu_set_ldo_paref(struct ssb_ch + EXPORT_SYMBOL(ssb_pmu_set_ldo_voltage); + EXPORT_SYMBOL(ssb_pmu_set_ldo_paref); + ++static u32 ssb_pmu_get_alp_clock_clk0(struct ssb_chipcommon *cc) ++{ ++ u32 crystalfreq; ++ const struct pmu0_plltab_entry *e = NULL; ++ ++ crystalfreq = chipco_read32(cc, SSB_CHIPCO_PMU_CTL) & ++ SSB_CHIPCO_PMU_CTL_XTALFREQ >> SSB_CHIPCO_PMU_CTL_XTALFREQ_SHIFT; ++ e = pmu0_plltab_find_entry(crystalfreq); ++ BUG_ON(!e); ++ return e->freq * 1000; ++} ++ ++u32 ssb_pmu_get_alp_clock(struct ssb_chipcommon *cc) ++{ ++ struct ssb_bus *bus = cc->dev->bus; ++ ++ switch (bus->chip_id) { ++ case 0x5354: ++ ssb_pmu_get_alp_clock_clk0(cc); ++ default: ++ ssb_printk(KERN_ERR PFX ++ "ERROR: PMU alp clock unknown for device %04X\n", ++ bus->chip_id); ++ return 0; ++ } ++} ++ + u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc) + { + struct ssb_bus *bus = cc->dev->bus; +--- a/drivers/ssb/ssb_private.h ++++ b/drivers/ssb/ssb_private.h +@@ -210,6 +210,7 @@ static inline void b43_pci_ssb_bridge_ex + /* driver_chipcommon_pmu.c */ + extern u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc); + extern u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc); ++extern u32 ssb_pmu_get_alp_clock(struct ssb_chipcommon *cc); + + #ifdef CONFIG_SSB_SFLASH + /* driver_chipcommon_sflash.c */ |