diff options
author | Hauke Mehrtens <hauke@hauke-m.de> | 2012-06-29 19:44:44 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-07-09 16:36:06 -0400 |
commit | c586e10992b2e5e2dfe7cca9be615818cfb98605 (patch) | |
tree | ef26566c0647ce12c915d016c61c40fc35c66eac | |
parent | 6270d1c39c96088c3cbbab35a2658d07cee364ae (diff) |
bcma: add bcma_pmu_spuravoid_pllupdate()
This function is needed by brcmsmac. This code is based on code from
the Broadcom SDK.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | drivers/bcma/driver_chipcommon_pmu.c | 183 | ||||
-rw-r--r-- | include/linux/bcma/bcma_driver_chipcommon.h | 14 |
2 files changed, 196 insertions, 1 deletions
diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c index 1a7a72fb77d6..35c9130746fb 100644 --- a/drivers/bcma/driver_chipcommon_pmu.c +++ b/drivers/bcma/driver_chipcommon_pmu.c | |||
@@ -3,7 +3,8 @@ | |||
3 | * ChipCommon Power Management Unit driver | 3 | * ChipCommon Power Management Unit driver |
4 | * | 4 | * |
5 | * Copyright 2009, Michael Buesch <m@bues.ch> | 5 | * Copyright 2009, Michael Buesch <m@bues.ch> |
6 | * Copyright 2007, Broadcom Corporation | 6 | * Copyright 2007, 2011, Broadcom Corporation |
7 | * Copyright 2011, 2012, Hauke Mehrtens <hauke@hauke-m.de> | ||
7 | * | 8 | * |
8 | * Licensed under the GNU/GPL. See COPYING for details. | 9 | * Licensed under the GNU/GPL. See COPYING for details. |
9 | */ | 10 | */ |
@@ -284,3 +285,183 @@ u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc) | |||
284 | 285 | ||
285 | return bcma_pmu_get_clockcontrol(cc); | 286 | return bcma_pmu_get_clockcontrol(cc); |
286 | } | 287 | } |
288 | |||
289 | static void bcma_pmu_spuravoid_pll_write(struct bcma_drv_cc *cc, u32 offset, | ||
290 | u32 value) | ||
291 | { | ||
292 | bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, offset); | ||
293 | bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, value); | ||
294 | } | ||
295 | |||
296 | void bcma_pmu_spuravoid_pllupdate(struct bcma_drv_cc *cc, int spuravoid) | ||
297 | { | ||
298 | u32 tmp = 0; | ||
299 | u8 phypll_offset = 0; | ||
300 | u8 bcm5357_bcm43236_p1div[] = {0x1, 0x5, 0x5}; | ||
301 | u8 bcm5357_bcm43236_ndiv[] = {0x30, 0xf6, 0xfc}; | ||
302 | struct bcma_bus *bus = cc->core->bus; | ||
303 | |||
304 | switch (bus->chipinfo.id) { | ||
305 | case BCMA_CHIP_ID_BCM5357: | ||
306 | case BCMA_CHIP_ID_BCM4749: | ||
307 | case BCMA_CHIP_ID_BCM53572: | ||
308 | /* 5357[ab]0, 43236[ab]0, and 6362b0 */ | ||
309 | |||
310 | /* BCM5357 needs to touch PLL1_PLLCTL[02], | ||
311 | so offset PLL0_PLLCTL[02] by 6 */ | ||
312 | phypll_offset = (bus->chipinfo.id == BCMA_CHIP_ID_BCM5357 || | ||
313 | bus->chipinfo.id == BCMA_CHIP_ID_BCM4749 || | ||
314 | bus->chipinfo.id == BCMA_CHIP_ID_BCM53572) ? 6 : 0; | ||
315 | |||
316 | /* RMW only the P1 divider */ | ||
317 | bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, | ||
318 | BCMA_CC_PMU_PLL_CTL0 + phypll_offset); | ||
319 | tmp = bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA); | ||
320 | tmp &= (~(BCMA_CC_PMU1_PLL0_PC0_P1DIV_MASK)); | ||
321 | tmp |= (bcm5357_bcm43236_p1div[spuravoid] << BCMA_CC_PMU1_PLL0_PC0_P1DIV_SHIFT); | ||
322 | bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, tmp); | ||
323 | |||
324 | /* RMW only the int feedback divider */ | ||
325 | bcma_cc_write32(cc, BCMA_CC_PLLCTL_ADDR, | ||
326 | BCMA_CC_PMU_PLL_CTL2 + phypll_offset); | ||
327 | tmp = bcma_cc_read32(cc, BCMA_CC_PLLCTL_DATA); | ||
328 | tmp &= ~(BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_MASK); | ||
329 | tmp |= (bcm5357_bcm43236_ndiv[spuravoid]) << BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_SHIFT; | ||
330 | bcma_cc_write32(cc, BCMA_CC_PLLCTL_DATA, tmp); | ||
331 | |||
332 | tmp = 1 << 10; | ||
333 | break; | ||
334 | |||
335 | case BCMA_CHIP_ID_BCM4331: | ||
336 | case BCMA_CHIP_ID_BCM43431: | ||
337 | if (spuravoid == 2) { | ||
338 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0, | ||
339 | 0x11500014); | ||
340 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2, | ||
341 | 0x0FC00a08); | ||
342 | } else if (spuravoid == 1) { | ||
343 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0, | ||
344 | 0x11500014); | ||
345 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2, | ||
346 | 0x0F600a08); | ||
347 | } else { | ||
348 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0, | ||
349 | 0x11100014); | ||
350 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2, | ||
351 | 0x03000a08); | ||
352 | } | ||
353 | tmp = 1 << 10; | ||
354 | break; | ||
355 | |||
356 | case BCMA_CHIP_ID_BCM43224: | ||
357 | case BCMA_CHIP_ID_BCM43225: | ||
358 | case BCMA_CHIP_ID_BCM43421: | ||
359 | if (spuravoid == 1) { | ||
360 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0, | ||
361 | 0x11500010); | ||
362 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL1, | ||
363 | 0x000C0C06); | ||
364 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2, | ||
365 | 0x0F600a08); | ||
366 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL3, | ||
367 | 0x00000000); | ||
368 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL4, | ||
369 | 0x2001E920); | ||
370 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5, | ||
371 | 0x88888815); | ||
372 | } else { | ||
373 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0, | ||
374 | 0x11100010); | ||
375 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL1, | ||
376 | 0x000c0c06); | ||
377 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2, | ||
378 | 0x03000a08); | ||
379 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL3, | ||
380 | 0x00000000); | ||
381 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL4, | ||
382 | 0x200005c0); | ||
383 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5, | ||
384 | 0x88888815); | ||
385 | } | ||
386 | tmp = 1 << 10; | ||
387 | break; | ||
388 | |||
389 | case BCMA_CHIP_ID_BCM4716: | ||
390 | case BCMA_CHIP_ID_BCM4748: | ||
391 | case BCMA_CHIP_ID_BCM47162: | ||
392 | if (spuravoid == 1) { | ||
393 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0, | ||
394 | 0x11500060); | ||
395 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL1, | ||
396 | 0x080C0C06); | ||
397 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2, | ||
398 | 0x0F600000); | ||
399 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL3, | ||
400 | 0x00000000); | ||
401 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL4, | ||
402 | 0x2001E924); | ||
403 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5, | ||
404 | 0x88888815); | ||
405 | } else { | ||
406 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0, | ||
407 | 0x11100060); | ||
408 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL1, | ||
409 | 0x080c0c06); | ||
410 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2, | ||
411 | 0x03000000); | ||
412 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL3, | ||
413 | 0x00000000); | ||
414 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL4, | ||
415 | 0x200005c0); | ||
416 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5, | ||
417 | 0x88888815); | ||
418 | } | ||
419 | |||
420 | tmp = 3 << 9; | ||
421 | break; | ||
422 | |||
423 | case BCMA_CHIP_ID_BCM43227: | ||
424 | case BCMA_CHIP_ID_BCM43228: | ||
425 | case BCMA_CHIP_ID_BCM43428: | ||
426 | /* LCNXN */ | ||
427 | /* PLL Settings for spur avoidance on/off mode, | ||
428 | no on2 support for 43228A0 */ | ||
429 | if (spuravoid == 1) { | ||
430 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0, | ||
431 | 0x01100014); | ||
432 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL1, | ||
433 | 0x040C0C06); | ||
434 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2, | ||
435 | 0x03140A08); | ||
436 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL3, | ||
437 | 0x00333333); | ||
438 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL4, | ||
439 | 0x202C2820); | ||
440 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5, | ||
441 | 0x88888815); | ||
442 | } else { | ||
443 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL0, | ||
444 | 0x11100014); | ||
445 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL1, | ||
446 | 0x040c0c06); | ||
447 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL2, | ||
448 | 0x03000a08); | ||
449 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL3, | ||
450 | 0x00000000); | ||
451 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL4, | ||
452 | 0x200005c0); | ||
453 | bcma_pmu_spuravoid_pll_write(cc, BCMA_CC_PMU_PLL_CTL5, | ||
454 | 0x88888815); | ||
455 | } | ||
456 | tmp = 1 << 10; | ||
457 | break; | ||
458 | default: | ||
459 | pr_err("unknown spuravoidance settings for chip 0x%04X, not changing PLL\n", | ||
460 | bus->chipinfo.id); | ||
461 | break; | ||
462 | } | ||
463 | |||
464 | tmp |= bcma_cc_read32(cc, BCMA_CC_PMU_CTL); | ||
465 | bcma_cc_write32(cc, BCMA_CC_PMU_CTL, tmp); | ||
466 | } | ||
467 | EXPORT_SYMBOL_GPL(bcma_pmu_spuravoid_pllupdate); | ||
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h index 09f31ade1410..12975eac403f 100644 --- a/include/linux/bcma/bcma_driver_chipcommon.h +++ b/include/linux/bcma/bcma_driver_chipcommon.h | |||
@@ -308,6 +308,19 @@ | |||
308 | #define BCMA_CC_PPL_PCHI_OFF 5 | 308 | #define BCMA_CC_PPL_PCHI_OFF 5 |
309 | #define BCMA_CC_PPL_PCHI_MASK 0x0000003f | 309 | #define BCMA_CC_PPL_PCHI_MASK 0x0000003f |
310 | 310 | ||
311 | #define BCMA_CC_PMU_PLL_CTL0 0 | ||
312 | #define BCMA_CC_PMU_PLL_CTL1 1 | ||
313 | #define BCMA_CC_PMU_PLL_CTL2 2 | ||
314 | #define BCMA_CC_PMU_PLL_CTL3 3 | ||
315 | #define BCMA_CC_PMU_PLL_CTL4 4 | ||
316 | #define BCMA_CC_PMU_PLL_CTL5 5 | ||
317 | |||
318 | #define BCMA_CC_PMU1_PLL0_PC0_P1DIV_MASK 0x00f00000 | ||
319 | #define BCMA_CC_PMU1_PLL0_PC0_P1DIV_SHIFT 20 | ||
320 | |||
321 | #define BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_MASK 0x1ff00000 | ||
322 | #define BCMA_CC_PMU1_PLL0_PC2_NDIV_INT_SHIFT 20 | ||
323 | |||
311 | /* BCM4331 ChipControl numbers. */ | 324 | /* BCM4331 ChipControl numbers. */ |
312 | #define BCMA_CHIPCTL_4331_BT_COEXIST BIT(0) /* 0 disable */ | 325 | #define BCMA_CHIPCTL_4331_BT_COEXIST BIT(0) /* 0 disable */ |
313 | #define BCMA_CHIPCTL_4331_SECI BIT(1) /* 0 SECI is disabled (JATG functional) */ | 326 | #define BCMA_CHIPCTL_4331_SECI BIT(1) /* 0 SECI is disabled (JATG functional) */ |
@@ -420,5 +433,6 @@ extern void bcma_chipco_chipctl_maskset(struct bcma_drv_cc *cc, | |||
420 | u32 offset, u32 mask, u32 set); | 433 | u32 offset, u32 mask, u32 set); |
421 | extern void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, | 434 | extern void bcma_chipco_regctl_maskset(struct bcma_drv_cc *cc, |
422 | u32 offset, u32 mask, u32 set); | 435 | u32 offset, u32 mask, u32 set); |
436 | extern void bcma_pmu_spuravoid_pllupdate(struct bcma_drv_cc *cc, int spuravoid); | ||
423 | 437 | ||
424 | #endif /* LINUX_BCMA_DRIVER_CC_H_ */ | 438 | #endif /* LINUX_BCMA_DRIVER_CC_H_ */ |