aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ssb/driver_chipcommon.c
diff options
context:
space:
mode:
authorRafał Miłecki <zajec5@gmail.com>2011-04-27 11:40:11 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-05-02 14:49:14 -0400
commit0ca699552c441e2c4201a6f60eac98b8865c1743 (patch)
tree7e9e68d7ce291b6ab32c0ff89c69e983d70f24c6 /drivers/ssb/driver_chipcommon.c
parentd6d023a1948d13652d719238f8039c09acceda8c (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.c62
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);