diff options
Diffstat (limited to 'arch/mips/alchemy/common/clock.c')
| -rw-r--r-- | arch/mips/alchemy/common/clock.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/arch/mips/alchemy/common/clock.c b/arch/mips/alchemy/common/clock.c index 604b7d009d8d..6a98d2cb402c 100644 --- a/arch/mips/alchemy/common/clock.c +++ b/arch/mips/alchemy/common/clock.c | |||
| @@ -127,12 +127,20 @@ static unsigned long alchemy_clk_cpu_recalc(struct clk_hw *hw, | |||
| 127 | t = 396000000; | 127 | t = 396000000; |
| 128 | else { | 128 | else { |
| 129 | t = alchemy_rdsys(AU1000_SYS_CPUPLL) & 0x7f; | 129 | t = alchemy_rdsys(AU1000_SYS_CPUPLL) & 0x7f; |
| 130 | if (alchemy_get_cputype() < ALCHEMY_CPU_AU1300) | ||
| 131 | t &= 0x3f; | ||
| 130 | t *= parent_rate; | 132 | t *= parent_rate; |
| 131 | } | 133 | } |
| 132 | 134 | ||
| 133 | return t; | 135 | return t; |
| 134 | } | 136 | } |
| 135 | 137 | ||
| 138 | void __init alchemy_set_lpj(void) | ||
| 139 | { | ||
| 140 | preset_lpj = alchemy_clk_cpu_recalc(NULL, ALCHEMY_ROOTCLK_RATE); | ||
| 141 | preset_lpj /= 2 * HZ; | ||
| 142 | } | ||
| 143 | |||
| 136 | static struct clk_ops alchemy_clkops_cpu = { | 144 | static struct clk_ops alchemy_clkops_cpu = { |
| 137 | .recalc_rate = alchemy_clk_cpu_recalc, | 145 | .recalc_rate = alchemy_clk_cpu_recalc, |
| 138 | }; | 146 | }; |
| @@ -315,17 +323,26 @@ static struct clk __init *alchemy_clk_setup_mem(const char *pn, int ct) | |||
| 315 | 323 | ||
| 316 | /* lrclk: external synchronous static bus clock ***********************/ | 324 | /* lrclk: external synchronous static bus clock ***********************/ |
| 317 | 325 | ||
| 318 | static struct clk __init *alchemy_clk_setup_lrclk(const char *pn) | 326 | static struct clk __init *alchemy_clk_setup_lrclk(const char *pn, int t) |
| 319 | { | 327 | { |
| 320 | /* MEM_STCFG0[15:13] = divisor. | 328 | /* Au1000, Au1500: MEM_STCFG0[11]: If bit is set, lrclk=pclk/5, |
| 329 | * otherwise lrclk=pclk/4. | ||
| 330 | * All other variants: MEM_STCFG0[15:13] = divisor. | ||
| 321 | * L/RCLK = periph_clk / (divisor + 1) | 331 | * L/RCLK = periph_clk / (divisor + 1) |
| 322 | * On Au1000, Au1500, Au1100 it's called LCLK, | 332 | * On Au1000, Au1500, Au1100 it's called LCLK, |
| 323 | * on later models it's called RCLK, but it's the same thing. | 333 | * on later models it's called RCLK, but it's the same thing. |
| 324 | */ | 334 | */ |
| 325 | struct clk *c; | 335 | struct clk *c; |
| 326 | unsigned long v = alchemy_rdsmem(AU1000_MEM_STCFG0) >> 13; | 336 | unsigned long v = alchemy_rdsmem(AU1000_MEM_STCFG0); |
| 327 | 337 | ||
| 328 | v = (v & 7) + 1; | 338 | switch (t) { |
| 339 | case ALCHEMY_CPU_AU1000: | ||
| 340 | case ALCHEMY_CPU_AU1500: | ||
| 341 | v = 4 + ((v >> 11) & 1); | ||
| 342 | break; | ||
| 343 | default: /* all other models */ | ||
| 344 | v = ((v >> 13) & 7) + 1; | ||
| 345 | } | ||
| 329 | c = clk_register_fixed_factor(NULL, ALCHEMY_LR_CLK, | 346 | c = clk_register_fixed_factor(NULL, ALCHEMY_LR_CLK, |
| 330 | pn, 0, 1, v); | 347 | pn, 0, 1, v); |
| 331 | if (!IS_ERR(c)) | 348 | if (!IS_ERR(c)) |
| @@ -1066,7 +1083,7 @@ static int __init alchemy_clk_init(void) | |||
| 1066 | ERRCK(c) | 1083 | ERRCK(c) |
| 1067 | 1084 | ||
| 1068 | /* L/RCLK: external static bus clock for synchronous mode */ | 1085 | /* L/RCLK: external static bus clock for synchronous mode */ |
| 1069 | c = alchemy_clk_setup_lrclk(ALCHEMY_PERIPH_CLK); | 1086 | c = alchemy_clk_setup_lrclk(ALCHEMY_PERIPH_CLK, ctype); |
| 1070 | ERRCK(c) | 1087 | ERRCK(c) |
| 1071 | 1088 | ||
| 1072 | /* Frequency dividers 0-5 */ | 1089 | /* Frequency dividers 0-5 */ |
