diff options
author | Hauke Mehrtens <hauke@hauke-m.de> | 2012-12-05 12:46:03 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-12-06 14:58:57 -0500 |
commit | f924e1e989b0bdaf6472668400d67a2142cb6b60 (patch) | |
tree | 7da7eb703e6c302c50bcc383f32bb576f474c595 /drivers/ssb | |
parent | a4855f39d4eb3f550ca5f4aac79bd999da42dc54 (diff) |
ssb: get alp clock from devices with PMU
If there is a PMU in the device, get the alp clock from that part and
do not assume 20000000.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/ssb')
-rw-r--r-- | drivers/ssb/driver_chipcommon.c | 15 | ||||
-rw-r--r-- | drivers/ssb/driver_chipcommon_pmu.c | 27 | ||||
-rw-r--r-- | drivers/ssb/ssb_private.h | 1 |
3 files changed, 37 insertions, 6 deletions
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c index e9d2ca11283b..603b63032e93 100644 --- a/drivers/ssb/driver_chipcommon.c +++ b/drivers/ssb/driver_chipcommon.c | |||
@@ -280,6 +280,14 @@ static void calc_fast_powerup_delay(struct ssb_chipcommon *cc) | |||
280 | cc->fast_pwrup_delay = tmp; | 280 | cc->fast_pwrup_delay = tmp; |
281 | } | 281 | } |
282 | 282 | ||
283 | static u32 ssb_chipco_alp_clock(struct ssb_chipcommon *cc) | ||
284 | { | ||
285 | if (cc->capabilities & SSB_CHIPCO_CAP_PMU) | ||
286 | return ssb_pmu_get_alp_clock(cc); | ||
287 | |||
288 | return 20000000; | ||
289 | } | ||
290 | |||
283 | void ssb_chipcommon_init(struct ssb_chipcommon *cc) | 291 | void ssb_chipcommon_init(struct ssb_chipcommon *cc) |
284 | { | 292 | { |
285 | if (!cc->dev) | 293 | if (!cc->dev) |
@@ -473,12 +481,7 @@ int ssb_chipco_serial_init(struct ssb_chipcommon *cc, | |||
473 | chipco_read32(cc, SSB_CHIPCO_CORECTL) | 481 | chipco_read32(cc, SSB_CHIPCO_CORECTL) |
474 | | SSB_CHIPCO_CORECTL_UARTCLK0); | 482 | | SSB_CHIPCO_CORECTL_UARTCLK0); |
475 | } else if ((ccrev >= 11) && (ccrev != 15)) { | 483 | } else if ((ccrev >= 11) && (ccrev != 15)) { |
476 | /* Fixed ALP clock */ | 484 | baud_base = ssb_chipco_alp_clock(cc); |
477 | baud_base = 20000000; | ||
478 | if (cc->capabilities & SSB_CHIPCO_CAP_PMU) { | ||
479 | /* FIXME: baud_base is different for devices with a PMU */ | ||
480 | SSB_WARN_ON(1); | ||
481 | } | ||
482 | div = 1; | 485 | div = 1; |
483 | if (ccrev >= 21) { | 486 | if (ccrev >= 21) { |
484 | /* Turn off UART clock before switching clocksource. */ | 487 | /* Turn off UART clock before switching clocksource. */ |
diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c index d7d58044b4bc..a43415a7fbed 100644 --- 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_chipcommon *cc, bool on) | |||
618 | EXPORT_SYMBOL(ssb_pmu_set_ldo_voltage); | 618 | EXPORT_SYMBOL(ssb_pmu_set_ldo_voltage); |
619 | EXPORT_SYMBOL(ssb_pmu_set_ldo_paref); | 619 | EXPORT_SYMBOL(ssb_pmu_set_ldo_paref); |
620 | 620 | ||
621 | static u32 ssb_pmu_get_alp_clock_clk0(struct ssb_chipcommon *cc) | ||
622 | { | ||
623 | u32 crystalfreq; | ||
624 | const struct pmu0_plltab_entry *e = NULL; | ||
625 | |||
626 | crystalfreq = chipco_read32(cc, SSB_CHIPCO_PMU_CTL) & | ||
627 | SSB_CHIPCO_PMU_CTL_XTALFREQ >> SSB_CHIPCO_PMU_CTL_XTALFREQ_SHIFT; | ||
628 | e = pmu0_plltab_find_entry(crystalfreq); | ||
629 | BUG_ON(!e); | ||
630 | return e->freq * 1000; | ||
631 | } | ||
632 | |||
633 | u32 ssb_pmu_get_alp_clock(struct ssb_chipcommon *cc) | ||
634 | { | ||
635 | struct ssb_bus *bus = cc->dev->bus; | ||
636 | |||
637 | switch (bus->chip_id) { | ||
638 | case 0x5354: | ||
639 | ssb_pmu_get_alp_clock_clk0(cc); | ||
640 | default: | ||
641 | ssb_printk(KERN_ERR PFX | ||
642 | "ERROR: PMU alp clock unknown for device %04X\n", | ||
643 | bus->chip_id); | ||
644 | return 0; | ||
645 | } | ||
646 | } | ||
647 | |||
621 | u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc) | 648 | u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc) |
622 | { | 649 | { |
623 | struct ssb_bus *bus = cc->dev->bus; | 650 | struct ssb_bus *bus = cc->dev->bus; |
diff --git a/drivers/ssb/ssb_private.h b/drivers/ssb/ssb_private.h index a305550b4b65..98b2915cd30b 100644 --- a/drivers/ssb/ssb_private.h +++ b/drivers/ssb/ssb_private.h | |||
@@ -210,5 +210,6 @@ static inline void b43_pci_ssb_bridge_exit(void) | |||
210 | /* driver_chipcommon_pmu.c */ | 210 | /* driver_chipcommon_pmu.c */ |
211 | extern u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc); | 211 | extern u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc); |
212 | extern u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc); | 212 | extern u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc); |
213 | extern u32 ssb_pmu_get_alp_clock(struct ssb_chipcommon *cc); | ||
213 | 214 | ||
214 | #endif /* LINUX_SSB_PRIVATE_H_ */ | 215 | #endif /* LINUX_SSB_PRIVATE_H_ */ |