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 | |
| 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')
| -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 b4b3733aefc..06d15b6f221 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); |
