diff options
author | Rafał Miłecki <zajec5@gmail.com> | 2011-04-27 11:40:11 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-05-02 14:49:14 -0400 |
commit | 0ca699552c441e2c4201a6f60eac98b8865c1743 (patch) | |
tree | 7e9e68d7ce291b6ab32c0ff89c69e983d70f24c6 /drivers/ssb/driver_chipcommon.c | |
parent | d6d023a1948d13652d719238f8039c09acceda8c (diff) |
ssb: cc: prepare clockmode support for cores rev 10+
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/ssb/driver_chipcommon.c')
-rw-r--r-- | drivers/ssb/driver_chipcommon.c | 62 |
1 files changed, 44 insertions, 18 deletions
diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c index b4b3733aefcf..06d15b6f2215 100644 --- a/drivers/ssb/driver_chipcommon.c +++ b/drivers/ssb/driver_chipcommon.c | |||
@@ -46,40 +46,66 @@ void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc, | |||
46 | if (!ccdev) | 46 | if (!ccdev) |
47 | return; | 47 | return; |
48 | bus = ccdev->bus; | 48 | bus = ccdev->bus; |
49 | |||
50 | /* We support SLOW only on 6..9 */ | ||
51 | if (ccdev->id.revision >= 10 && mode == SSB_CLKMODE_SLOW) | ||
52 | mode = SSB_CLKMODE_DYNAMIC; | ||
53 | |||
54 | if (cc->capabilities & SSB_CHIPCO_CAP_PMU) | ||
55 | return; /* PMU controls clockmode, separated function needed */ | ||
56 | SSB_WARN_ON(ccdev->id.revision >= 20); | ||
57 | |||
49 | /* chipcommon cores prior to rev6 don't support dynamic clock control */ | 58 | /* chipcommon cores prior to rev6 don't support dynamic clock control */ |
50 | if (ccdev->id.revision < 6) | 59 | if (ccdev->id.revision < 6) |
51 | return; | 60 | return; |
52 | /* chipcommon cores rev10 are a whole new ball game */ | 61 | |
62 | /* ChipCommon cores rev10+ need testing */ | ||
53 | if (ccdev->id.revision >= 10) | 63 | if (ccdev->id.revision >= 10) |
54 | return; | 64 | return; |
65 | |||
55 | if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL)) | 66 | if (!(cc->capabilities & SSB_CHIPCO_CAP_PCTL)) |
56 | return; | 67 | return; |
57 | 68 | ||
58 | switch (mode) { | 69 | switch (mode) { |
59 | case SSB_CLKMODE_SLOW: | 70 | case SSB_CLKMODE_SLOW: /* For revs 6..9 only */ |
60 | tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL); | 71 | tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL); |
61 | tmp |= SSB_CHIPCO_SLOWCLKCTL_FSLOW; | 72 | tmp |= SSB_CHIPCO_SLOWCLKCTL_FSLOW; |
62 | chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp); | 73 | chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp); |
63 | break; | 74 | break; |
64 | case SSB_CLKMODE_FAST: | 75 | case SSB_CLKMODE_FAST: |
65 | ssb_pci_xtal(bus, SSB_GPIO_XTAL, 1); /* Force crystal on */ | 76 | if (ccdev->id.revision < 10) { |
66 | tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL); | 77 | ssb_pci_xtal(bus, SSB_GPIO_XTAL, 1); /* Force crystal on */ |
67 | tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW; | 78 | tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL); |
68 | tmp |= SSB_CHIPCO_SLOWCLKCTL_IPLL; | 79 | tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW; |
69 | chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp); | 80 | tmp |= SSB_CHIPCO_SLOWCLKCTL_IPLL; |
81 | chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp); | ||
82 | } else { | ||
83 | chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL, | ||
84 | (chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) | | ||
85 | SSB_CHIPCO_SYSCLKCTL_FORCEHT)); | ||
86 | /* udelay(150); TODO: not available in early init */ | ||
87 | } | ||
70 | break; | 88 | break; |
71 | case SSB_CLKMODE_DYNAMIC: | 89 | case SSB_CLKMODE_DYNAMIC: |
72 | tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL); | 90 | if (ccdev->id.revision < 10) { |
73 | tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW; | 91 | tmp = chipco_read32(cc, SSB_CHIPCO_SLOWCLKCTL); |
74 | tmp &= ~SSB_CHIPCO_SLOWCLKCTL_IPLL; | 92 | tmp &= ~SSB_CHIPCO_SLOWCLKCTL_FSLOW; |
75 | tmp &= ~SSB_CHIPCO_SLOWCLKCTL_ENXTAL; | 93 | tmp &= ~SSB_CHIPCO_SLOWCLKCTL_IPLL; |
76 | if ((tmp & SSB_CHIPCO_SLOWCLKCTL_SRC) != SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL) | 94 | tmp &= ~SSB_CHIPCO_SLOWCLKCTL_ENXTAL; |
77 | tmp |= SSB_CHIPCO_SLOWCLKCTL_ENXTAL; | 95 | if ((tmp & SSB_CHIPCO_SLOWCLKCTL_SRC) != |
78 | chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp); | 96 | SSB_CHIPCO_SLOWCLKCTL_SRC_XTAL) |
79 | 97 | tmp |= SSB_CHIPCO_SLOWCLKCTL_ENXTAL; | |
80 | /* for dynamic control, we have to release our xtal_pu "force on" */ | 98 | chipco_write32(cc, SSB_CHIPCO_SLOWCLKCTL, tmp); |
81 | if (tmp & SSB_CHIPCO_SLOWCLKCTL_ENXTAL) | 99 | |
82 | ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0); | 100 | /* For dynamic control, we have to release our xtal_pu |
101 | * "force on" */ | ||
102 | if (tmp & SSB_CHIPCO_SLOWCLKCTL_ENXTAL) | ||
103 | ssb_pci_xtal(bus, SSB_GPIO_XTAL, 0); | ||
104 | } else { | ||
105 | chipco_write32(cc, SSB_CHIPCO_SYSCLKCTL, | ||
106 | (chipco_read32(cc, SSB_CHIPCO_SYSCLKCTL) & | ||
107 | ~SSB_CHIPCO_SYSCLKCTL_FORCEHT)); | ||
108 | } | ||
83 | break; | 109 | break; |
84 | default: | 110 | default: |
85 | SSB_WARN_ON(1); | 111 | SSB_WARN_ON(1); |