aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/bcma/driver_chipcommon_pmu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/bcma/driver_chipcommon_pmu.c')
-rw-r--r--drivers/bcma/driver_chipcommon_pmu.c47
1 files changed, 27 insertions, 20 deletions
diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c
index 201faf106b3f..c62c788b3289 100644
--- a/drivers/bcma/driver_chipcommon_pmu.c
+++ b/drivers/bcma/driver_chipcommon_pmu.c
@@ -13,12 +13,13 @@
13#include <linux/export.h> 13#include <linux/export.h>
14#include <linux/bcma/bcma.h> 14#include <linux/bcma/bcma.h>
15 15
16static u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset) 16u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset)
17{ 17{
18 bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset); 18 bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset);
19 bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR); 19 bcma_cc_read32(cc, BCMA_CC_PLLCTL_ADDR);
20 return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA); 20 return bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA);
21} 21}
22EXPORT_SYMBOL_GPL(bcma_chipco_pll_read);
22 23
23void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value) 24void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value)
24{ 25{
@@ -144,7 +145,7 @@ static void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
144 } 145 }
145} 146}
146 147
147void bcma_pmu_init(struct bcma_drv_cc *cc) 148void bcma_pmu_early_init(struct bcma_drv_cc *cc)
148{ 149{
149 u32 pmucap; 150 u32 pmucap;
150 151
@@ -153,7 +154,10 @@ void bcma_pmu_init(struct bcma_drv_cc *cc)
153 154
154 bcma_debug(cc->core->bus, "Found rev %u PMU (capabilities 0x%08X)\n", 155 bcma_debug(cc->core->bus, "Found rev %u PMU (capabilities 0x%08X)\n",
155 cc->pmu.rev, pmucap); 156 cc->pmu.rev, pmucap);
157}
156 158
159void bcma_pmu_init(struct bcma_drv_cc *cc)
160{
157 if (cc->pmu.rev == 1) 161 if (cc->pmu.rev == 1)
158 bcma_cc_mask32(cc, BCMA_CC_PMU_CTL, 162 bcma_cc_mask32(cc, BCMA_CC_PMU_CTL,
159 ~BCMA_CC_PMU_CTL_NOILPONW); 163 ~BCMA_CC_PMU_CTL_NOILPONW);
@@ -165,7 +169,7 @@ void bcma_pmu_init(struct bcma_drv_cc *cc)
165 bcma_pmu_workarounds(cc); 169 bcma_pmu_workarounds(cc);
166} 170}
167 171
168u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc) 172u32 bcma_pmu_get_alp_clock(struct bcma_drv_cc *cc)
169{ 173{
170 struct bcma_bus *bus = cc->core->bus; 174 struct bcma_bus *bus = cc->core->bus;
171 175
@@ -193,7 +197,7 @@ u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc)
193/* Find the output of the "m" pll divider given pll controls that start with 197/* Find the output of the "m" pll divider given pll controls that start with
194 * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc. 198 * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc.
195 */ 199 */
196static u32 bcma_pmu_clock(struct bcma_drv_cc *cc, u32 pll0, u32 m) 200static u32 bcma_pmu_pll_clock(struct bcma_drv_cc *cc, u32 pll0, u32 m)
197{ 201{
198 u32 tmp, div, ndiv, p1, p2, fc; 202 u32 tmp, div, ndiv, p1, p2, fc;
199 struct bcma_bus *bus = cc->core->bus; 203 struct bcma_bus *bus = cc->core->bus;
@@ -222,14 +226,14 @@ static u32 bcma_pmu_clock(struct bcma_drv_cc *cc, u32 pll0, u32 m)
222 ndiv = (tmp & BCMA_CC_PPL_NDIV_MASK) >> BCMA_CC_PPL_NDIV_SHIFT; 226 ndiv = (tmp & BCMA_CC_PPL_NDIV_MASK) >> BCMA_CC_PPL_NDIV_SHIFT;
223 227
224 /* Do calculation in Mhz */ 228 /* Do calculation in Mhz */
225 fc = bcma_pmu_alp_clock(cc) / 1000000; 229 fc = bcma_pmu_get_alp_clock(cc) / 1000000;
226 fc = (p1 * ndiv * fc) / p2; 230 fc = (p1 * ndiv * fc) / p2;
227 231
228 /* Return clock in Hertz */ 232 /* Return clock in Hertz */
229 return (fc / div) * 1000000; 233 return (fc / div) * 1000000;
230} 234}
231 235
232static u32 bcma_pmu_clock_bcm4706(struct bcma_drv_cc *cc, u32 pll0, u32 m) 236static u32 bcma_pmu_pll_clock_bcm4706(struct bcma_drv_cc *cc, u32 pll0, u32 m)
233{ 237{
234 u32 tmp, ndiv, p1div, p2div; 238 u32 tmp, ndiv, p1div, p2div;
235 u32 clock; 239 u32 clock;
@@ -260,7 +264,7 @@ static u32 bcma_pmu_clock_bcm4706(struct bcma_drv_cc *cc, u32 pll0, u32 m)
260} 264}
261 265
262/* query bus clock frequency for PMU-enabled chipcommon */ 266/* query bus clock frequency for PMU-enabled chipcommon */
263static u32 bcma_pmu_get_clockcontrol(struct bcma_drv_cc *cc) 267static u32 bcma_pmu_get_bus_clock(struct bcma_drv_cc *cc)
264{ 268{
265 struct bcma_bus *bus = cc->core->bus; 269 struct bcma_bus *bus = cc->core->bus;
266 270
@@ -268,40 +272,42 @@ static u32 bcma_pmu_get_clockcontrol(struct bcma_drv_cc *cc)
268 case BCMA_CHIP_ID_BCM4716: 272 case BCMA_CHIP_ID_BCM4716:
269 case BCMA_CHIP_ID_BCM4748: 273 case BCMA_CHIP_ID_BCM4748:
270 case BCMA_CHIP_ID_BCM47162: 274 case BCMA_CHIP_ID_BCM47162:
271 return bcma_pmu_clock(cc, BCMA_CC_PMU4716_MAINPLL_PLL0, 275 return bcma_pmu_pll_clock(cc, BCMA_CC_PMU4716_MAINPLL_PLL0,
272 BCMA_CC_PMU5_MAINPLL_SSB); 276 BCMA_CC_PMU5_MAINPLL_SSB);
273 case BCMA_CHIP_ID_BCM5356: 277 case BCMA_CHIP_ID_BCM5356:
274 return bcma_pmu_clock(cc, BCMA_CC_PMU5356_MAINPLL_PLL0, 278 return bcma_pmu_pll_clock(cc, BCMA_CC_PMU5356_MAINPLL_PLL0,
275 BCMA_CC_PMU5_MAINPLL_SSB); 279 BCMA_CC_PMU5_MAINPLL_SSB);
276 case BCMA_CHIP_ID_BCM5357: 280 case BCMA_CHIP_ID_BCM5357:
277 case BCMA_CHIP_ID_BCM4749: 281 case BCMA_CHIP_ID_BCM4749:
278 return bcma_pmu_clock(cc, BCMA_CC_PMU5357_MAINPLL_PLL0, 282 return bcma_pmu_pll_clock(cc, BCMA_CC_PMU5357_MAINPLL_PLL0,
279 BCMA_CC_PMU5_MAINPLL_SSB); 283 BCMA_CC_PMU5_MAINPLL_SSB);
280 case BCMA_CHIP_ID_BCM4706: 284 case BCMA_CHIP_ID_BCM4706:
281 return bcma_pmu_clock_bcm4706(cc, BCMA_CC_PMU4706_MAINPLL_PLL0, 285 return bcma_pmu_pll_clock_bcm4706(cc,
282 BCMA_CC_PMU5_MAINPLL_SSB); 286 BCMA_CC_PMU4706_MAINPLL_PLL0,
287 BCMA_CC_PMU5_MAINPLL_SSB);
283 case BCMA_CHIP_ID_BCM53572: 288 case BCMA_CHIP_ID_BCM53572:
284 return 75000000; 289 return 75000000;
285 default: 290 default:
286 bcma_warn(bus, "No backplane clock specified for %04X device, pmu rev. %d, using default %d Hz\n", 291 bcma_warn(bus, "No bus clock specified for %04X device, pmu rev. %d, using default %d Hz\n",
287 bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_HT_CLOCK); 292 bus->chipinfo.id, cc->pmu.rev, BCMA_CC_PMU_HT_CLOCK);
288 } 293 }
289 return BCMA_CC_PMU_HT_CLOCK; 294 return BCMA_CC_PMU_HT_CLOCK;
290} 295}
291 296
292/* query cpu clock frequency for PMU-enabled chipcommon */ 297/* query cpu clock frequency for PMU-enabled chipcommon */
293u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc) 298u32 bcma_pmu_get_cpu_clock(struct bcma_drv_cc *cc)
294{ 299{
295 struct bcma_bus *bus = cc->core->bus; 300 struct bcma_bus *bus = cc->core->bus;
296 301
297 if (bus->chipinfo.id == BCMA_CHIP_ID_BCM53572) 302 if (bus->chipinfo.id == BCMA_CHIP_ID_BCM53572)
298 return 300000000; 303 return 300000000;
299 304
305 /* New PMUs can have different clock for bus and CPU */
300 if (cc->pmu.rev >= 5) { 306 if (cc->pmu.rev >= 5) {
301 u32 pll; 307 u32 pll;
302 switch (bus->chipinfo.id) { 308 switch (bus->chipinfo.id) {
303 case BCMA_CHIP_ID_BCM4706: 309 case BCMA_CHIP_ID_BCM4706:
304 return bcma_pmu_clock_bcm4706(cc, 310 return bcma_pmu_pll_clock_bcm4706(cc,
305 BCMA_CC_PMU4706_MAINPLL_PLL0, 311 BCMA_CC_PMU4706_MAINPLL_PLL0,
306 BCMA_CC_PMU5_MAINPLL_CPU); 312 BCMA_CC_PMU5_MAINPLL_CPU);
307 case BCMA_CHIP_ID_BCM5356: 313 case BCMA_CHIP_ID_BCM5356:
@@ -316,10 +322,11 @@ u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc)
316 break; 322 break;
317 } 323 }
318 324
319 return bcma_pmu_clock(cc, pll, BCMA_CC_PMU5_MAINPLL_CPU); 325 return bcma_pmu_pll_clock(cc, pll, BCMA_CC_PMU5_MAINPLL_CPU);
320 } 326 }
321 327
322 return bcma_pmu_get_clockcontrol(cc); 328 /* On old PMUs CPU has the same clock as the bus */
329 return bcma_pmu_get_bus_clock(cc);
323} 330}
324 331
325static void bcma_pmu_spuravoid_pll_write(struct bcma_drv_cc *cc, u32 offset, 332static void bcma_pmu_spuravoid_pll_write(struct bcma_drv_cc *cc, u32 offset,