diff options
Diffstat (limited to 'drivers/ssb/driver_chipcommon_pmu.c')
-rw-r--r-- | drivers/ssb/driver_chipcommon_pmu.c | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/drivers/ssb/driver_chipcommon_pmu.c b/drivers/ssb/driver_chipcommon_pmu.c index e5a2e0e9bc19..b58fef780ea0 100644 --- a/drivers/ssb/driver_chipcommon_pmu.c +++ b/drivers/ssb/driver_chipcommon_pmu.c | |||
@@ -13,6 +13,9 @@ | |||
13 | #include <linux/ssb/ssb_driver_chipcommon.h> | 13 | #include <linux/ssb/ssb_driver_chipcommon.h> |
14 | #include <linux/delay.h> | 14 | #include <linux/delay.h> |
15 | #include <linux/export.h> | 15 | #include <linux/export.h> |
16 | #ifdef CONFIG_BCM47XX | ||
17 | #include <asm/mach-bcm47xx/nvram.h> | ||
18 | #endif | ||
16 | 19 | ||
17 | #include "ssb_private.h" | 20 | #include "ssb_private.h" |
18 | 21 | ||
@@ -92,10 +95,6 @@ static void ssb_pmu0_pllinit_r0(struct ssb_chipcommon *cc, | |||
92 | u32 pmuctl, tmp, pllctl; | 95 | u32 pmuctl, tmp, pllctl; |
93 | unsigned int i; | 96 | unsigned int i; |
94 | 97 | ||
95 | if ((bus->chip_id == 0x5354) && !crystalfreq) { | ||
96 | /* The 5354 crystal freq is 25MHz */ | ||
97 | crystalfreq = 25000; | ||
98 | } | ||
99 | if (crystalfreq) | 98 | if (crystalfreq) |
100 | e = pmu0_plltab_find_entry(crystalfreq); | 99 | e = pmu0_plltab_find_entry(crystalfreq); |
101 | if (!e) | 100 | if (!e) |
@@ -321,7 +320,11 @@ static void ssb_pmu_pll_init(struct ssb_chipcommon *cc) | |||
321 | u32 crystalfreq = 0; /* in kHz. 0 = keep default freq. */ | 320 | u32 crystalfreq = 0; /* in kHz. 0 = keep default freq. */ |
322 | 321 | ||
323 | if (bus->bustype == SSB_BUSTYPE_SSB) { | 322 | if (bus->bustype == SSB_BUSTYPE_SSB) { |
324 | /* TODO: The user may override the crystal frequency. */ | 323 | #ifdef CONFIG_BCM47XX |
324 | char buf[20]; | ||
325 | if (nvram_getenv("xtalfreq", buf, sizeof(buf)) >= 0) | ||
326 | crystalfreq = simple_strtoul(buf, NULL, 0); | ||
327 | #endif | ||
325 | } | 328 | } |
326 | 329 | ||
327 | switch (bus->chip_id) { | 330 | switch (bus->chip_id) { |
@@ -330,7 +333,11 @@ static void ssb_pmu_pll_init(struct ssb_chipcommon *cc) | |||
330 | ssb_pmu1_pllinit_r0(cc, crystalfreq); | 333 | ssb_pmu1_pllinit_r0(cc, crystalfreq); |
331 | break; | 334 | break; |
332 | case 0x4328: | 335 | case 0x4328: |
336 | ssb_pmu0_pllinit_r0(cc, crystalfreq); | ||
337 | break; | ||
333 | case 0x5354: | 338 | case 0x5354: |
339 | if (crystalfreq == 0) | ||
340 | crystalfreq = 25000; | ||
334 | ssb_pmu0_pllinit_r0(cc, crystalfreq); | 341 | ssb_pmu0_pllinit_r0(cc, crystalfreq); |
335 | break; | 342 | break; |
336 | case 0x4322: | 343 | case 0x4322: |
@@ -607,3 +614,34 @@ void ssb_pmu_set_ldo_paref(struct ssb_chipcommon *cc, bool on) | |||
607 | 614 | ||
608 | EXPORT_SYMBOL(ssb_pmu_set_ldo_voltage); | 615 | EXPORT_SYMBOL(ssb_pmu_set_ldo_voltage); |
609 | EXPORT_SYMBOL(ssb_pmu_set_ldo_paref); | 616 | EXPORT_SYMBOL(ssb_pmu_set_ldo_paref); |
617 | |||
618 | u32 ssb_pmu_get_cpu_clock(struct ssb_chipcommon *cc) | ||
619 | { | ||
620 | struct ssb_bus *bus = cc->dev->bus; | ||
621 | |||
622 | switch (bus->chip_id) { | ||
623 | case 0x5354: | ||
624 | /* 5354 chip uses a non programmable PLL of frequency 240MHz */ | ||
625 | return 240000000; | ||
626 | default: | ||
627 | ssb_printk(KERN_ERR PFX | ||
628 | "ERROR: PMU cpu clock unknown for device %04X\n", | ||
629 | bus->chip_id); | ||
630 | return 0; | ||
631 | } | ||
632 | } | ||
633 | |||
634 | u32 ssb_pmu_get_controlclock(struct ssb_chipcommon *cc) | ||
635 | { | ||
636 | struct ssb_bus *bus = cc->dev->bus; | ||
637 | |||
638 | switch (bus->chip_id) { | ||
639 | case 0x5354: | ||
640 | return 120000000; | ||
641 | default: | ||
642 | ssb_printk(KERN_ERR PFX | ||
643 | "ERROR: PMU controlclock unknown for device %04X\n", | ||
644 | bus->chip_id); | ||
645 | return 0; | ||
646 | } | ||
647 | } | ||