diff options
Diffstat (limited to 'drivers/bcma/driver_chipcommon_pmu.c')
| -rw-r--r-- | drivers/bcma/driver_chipcommon_pmu.c | 47 |
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 | ||
| 16 | static u32 bcma_chipco_pll_read(struct bcma_drv_cc *cc, u32 offset) | 16 | u32 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 | } |
| 22 | EXPORT_SYMBOL_GPL(bcma_chipco_pll_read); | ||
| 22 | 23 | ||
| 23 | void bcma_chipco_pll_write(struct bcma_drv_cc *cc, u32 offset, u32 value) | 24 | void 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 | ||
| 147 | void bcma_pmu_init(struct bcma_drv_cc *cc) | 148 | void 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 | ||
| 159 | void 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 | ||
| 168 | u32 bcma_pmu_alp_clock(struct bcma_drv_cc *cc) | 172 | u32 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 | */ |
| 196 | static u32 bcma_pmu_clock(struct bcma_drv_cc *cc, u32 pll0, u32 m) | 200 | static 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 | ||
| 232 | static u32 bcma_pmu_clock_bcm4706(struct bcma_drv_cc *cc, u32 pll0, u32 m) | 236 | static 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 */ |
| 263 | static u32 bcma_pmu_get_clockcontrol(struct bcma_drv_cc *cc) | 267 | static 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 */ |
| 293 | u32 bcma_pmu_get_clockcpu(struct bcma_drv_cc *cc) | 298 | u32 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 | ||
| 325 | static void bcma_pmu_spuravoid_pll_write(struct bcma_drv_cc *cc, u32 offset, | 332 | static void bcma_pmu_spuravoid_pll_write(struct bcma_drv_cc *cc, u32 offset, |
