summaryrefslogtreecommitdiffstats
path: root/target/linux/brcm47xx/patches-3.6/549-ssb-get-alp-clock-from-devices-with-PMU.patch
diff options
context:
space:
mode:
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.patch76
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 000000000..f5912984d
--- /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 */