diff options
author | Ganesan Ramalingam <ganesanr@broadcom.com> | 2014-04-29 10:37:51 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2014-05-30 10:49:41 -0400 |
commit | c065909e47aea3575e51304e7411b46df22b20ca (patch) | |
tree | 37329d173c186f0b14d27f3f311692c92af6a929 /arch/mips/netlogic/xlp/nlm_hal.c | |
parent | 77bef0e4b532341d2d21e4ef28111de7c239432e (diff) |
MIPS: Netlogic: PIC freq calculation for XLP 9XX/2XX
Update PIC frequency calculation for XLP9XX and 2XX processors using
the correct PLL registers. This should work for all possible board
configurations.
Signed-off-by: Ganesan Ramalingam <ganesanr@broadcom.com>
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/6876/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/netlogic/xlp/nlm_hal.c')
-rw-r--r-- | arch/mips/netlogic/xlp/nlm_hal.c | 114 |
1 files changed, 81 insertions, 33 deletions
diff --git a/arch/mips/netlogic/xlp/nlm_hal.c b/arch/mips/netlogic/xlp/nlm_hal.c index 9f9814d646a9..59f1303b69d7 100644 --- a/arch/mips/netlogic/xlp/nlm_hal.c +++ b/arch/mips/netlogic/xlp/nlm_hal.c | |||
@@ -234,21 +234,28 @@ unsigned int nlm_get_core_frequency(int node, int core) | |||
234 | return (unsigned int)num; | 234 | return (unsigned int)num; |
235 | } | 235 | } |
236 | 236 | ||
237 | /* Calculate Frequency to the PIC from PLL. | 237 | /* |
238 | * freq_out = ( ref_freq/2 * (6 + ctrl2[7:0]) + ctrl2[20:8]/2^13 ) / | 238 | * Calculate PIC frequency from PLL registers. |
239 | * ((2^ctrl0[7:5]) * Table(ctrl0[26:24])) | 239 | * freq_out = (ref_freq/2 * (6 + ctrl2[7:0]) + ctrl2[20:8]/2^13) / |
240 | * ((2^ctrl0[7:5]) * Table(ctrl0[26:24])) | ||
240 | */ | 241 | */ |
241 | static unsigned int nlm_2xx_get_pic_frequency(int node) | 242 | static unsigned int nlm_xlp2_get_pic_frequency(int node) |
242 | { | 243 | { |
243 | u32 ctrl_val0, ctrl_val2, vco_post_div, pll_post_div; | 244 | u32 ctrl_val0, ctrl_val2, vco_post_div, pll_post_div, cpu_xlp9xx; |
244 | u32 mdiv, fdiv, pll_out_freq_den, reg_select, ref_div, pic_div; | 245 | u32 mdiv, fdiv, pll_out_freq_den, reg_select, ref_div, pic_div; |
245 | u64 ref_clk, sysbase, pll_out_freq_num, ref_clk_select; | 246 | u64 sysbase, pll_out_freq_num, ref_clk_select, clockbase, ref_clk; |
246 | 247 | ||
247 | sysbase = nlm_get_node(node)->sysbase; | 248 | sysbase = nlm_get_node(node)->sysbase; |
249 | clockbase = nlm_get_clock_regbase(node); | ||
250 | cpu_xlp9xx = cpu_is_xlp9xx(); | ||
248 | 251 | ||
249 | /* Find ref_clk_base */ | 252 | /* Find ref_clk_base */ |
250 | ref_clk_select = | 253 | if (cpu_xlp9xx) |
251 | (nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG) >> 18) & 0x3; | 254 | ref_clk_select = (nlm_read_sys_reg(sysbase, |
255 | SYS_9XX_POWER_ON_RESET_CFG) >> 18) & 0x3; | ||
256 | else | ||
257 | ref_clk_select = (nlm_read_sys_reg(sysbase, | ||
258 | SYS_POWER_ON_RESET_CFG) >> 18) & 0x3; | ||
252 | switch (ref_clk_select) { | 259 | switch (ref_clk_select) { |
253 | case 0: | 260 | case 0: |
254 | ref_clk = 200000000ULL; | 261 | ref_clk = 200000000ULL; |
@@ -269,30 +276,70 @@ static unsigned int nlm_2xx_get_pic_frequency(int node) | |||
269 | } | 276 | } |
270 | 277 | ||
271 | /* Find the clock source PLL device for PIC */ | 278 | /* Find the clock source PLL device for PIC */ |
272 | reg_select = (nlm_read_sys_reg(sysbase, SYS_CLK_DEV_SEL) >> 22) & 0x3; | 279 | if (cpu_xlp9xx) { |
273 | switch (reg_select) { | 280 | reg_select = nlm_read_sys_reg(clockbase, |
274 | case 0: | 281 | SYS_9XX_CLK_DEV_SEL) & 0x3; |
275 | ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0); | 282 | switch (reg_select) { |
276 | ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2); | 283 | case 0: |
277 | break; | 284 | ctrl_val0 = nlm_read_sys_reg(clockbase, |
278 | case 1: | 285 | SYS_9XX_PLL_CTRL0); |
279 | ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0_DEVX(0)); | 286 | ctrl_val2 = nlm_read_sys_reg(clockbase, |
280 | ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2_DEVX(0)); | 287 | SYS_9XX_PLL_CTRL2); |
281 | break; | 288 | break; |
282 | case 2: | 289 | case 1: |
283 | ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0_DEVX(1)); | 290 | ctrl_val0 = nlm_read_sys_reg(clockbase, |
284 | ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2_DEVX(1)); | 291 | SYS_9XX_PLL_CTRL0_DEVX(0)); |
285 | break; | 292 | ctrl_val2 = nlm_read_sys_reg(clockbase, |
286 | case 3: | 293 | SYS_9XX_PLL_CTRL2_DEVX(0)); |
287 | ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0_DEVX(2)); | 294 | break; |
288 | ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2_DEVX(2)); | 295 | case 2: |
289 | break; | 296 | ctrl_val0 = nlm_read_sys_reg(clockbase, |
297 | SYS_9XX_PLL_CTRL0_DEVX(1)); | ||
298 | ctrl_val2 = nlm_read_sys_reg(clockbase, | ||
299 | SYS_9XX_PLL_CTRL2_DEVX(1)); | ||
300 | break; | ||
301 | case 3: | ||
302 | ctrl_val0 = nlm_read_sys_reg(clockbase, | ||
303 | SYS_9XX_PLL_CTRL0_DEVX(2)); | ||
304 | ctrl_val2 = nlm_read_sys_reg(clockbase, | ||
305 | SYS_9XX_PLL_CTRL2_DEVX(2)); | ||
306 | break; | ||
307 | } | ||
308 | } else { | ||
309 | reg_select = (nlm_read_sys_reg(sysbase, | ||
310 | SYS_CLK_DEV_SEL) >> 22) & 0x3; | ||
311 | switch (reg_select) { | ||
312 | case 0: | ||
313 | ctrl_val0 = nlm_read_sys_reg(sysbase, | ||
314 | SYS_PLL_CTRL0); | ||
315 | ctrl_val2 = nlm_read_sys_reg(sysbase, | ||
316 | SYS_PLL_CTRL2); | ||
317 | break; | ||
318 | case 1: | ||
319 | ctrl_val0 = nlm_read_sys_reg(sysbase, | ||
320 | SYS_PLL_CTRL0_DEVX(0)); | ||
321 | ctrl_val2 = nlm_read_sys_reg(sysbase, | ||
322 | SYS_PLL_CTRL2_DEVX(0)); | ||
323 | break; | ||
324 | case 2: | ||
325 | ctrl_val0 = nlm_read_sys_reg(sysbase, | ||
326 | SYS_PLL_CTRL0_DEVX(1)); | ||
327 | ctrl_val2 = nlm_read_sys_reg(sysbase, | ||
328 | SYS_PLL_CTRL2_DEVX(1)); | ||
329 | break; | ||
330 | case 3: | ||
331 | ctrl_val0 = nlm_read_sys_reg(sysbase, | ||
332 | SYS_PLL_CTRL0_DEVX(2)); | ||
333 | ctrl_val2 = nlm_read_sys_reg(sysbase, | ||
334 | SYS_PLL_CTRL2_DEVX(2)); | ||
335 | break; | ||
336 | } | ||
290 | } | 337 | } |
291 | 338 | ||
292 | vco_post_div = (ctrl_val0 >> 5) & 0x7; | 339 | vco_post_div = (ctrl_val0 >> 5) & 0x7; |
293 | pll_post_div = (ctrl_val0 >> 24) & 0x7; | 340 | pll_post_div = (ctrl_val0 >> 24) & 0x7; |
294 | mdiv = ctrl_val2 & 0xff; | 341 | mdiv = ctrl_val2 & 0xff; |
295 | fdiv = (ctrl_val2 >> 8) & 0xfff; | 342 | fdiv = (ctrl_val2 >> 8) & 0x1fff; |
296 | 343 | ||
297 | /* Find PLL post divider value */ | 344 | /* Find PLL post divider value */ |
298 | switch (pll_post_div) { | 345 | switch (pll_post_div) { |
@@ -322,7 +369,12 @@ static unsigned int nlm_2xx_get_pic_frequency(int node) | |||
322 | do_div(pll_out_freq_num, pll_out_freq_den); | 369 | do_div(pll_out_freq_num, pll_out_freq_den); |
323 | 370 | ||
324 | /* PIC post divider, which happens after PLL */ | 371 | /* PIC post divider, which happens after PLL */ |
325 | pic_div = (nlm_read_sys_reg(sysbase, SYS_CLK_DEV_DIV) >> 22) & 0x3; | 372 | if (cpu_xlp9xx) |
373 | pic_div = nlm_read_sys_reg(clockbase, | ||
374 | SYS_9XX_CLK_DEV_DIV) & 0x3; | ||
375 | else | ||
376 | pic_div = (nlm_read_sys_reg(sysbase, | ||
377 | SYS_CLK_DEV_DIV) >> 22) & 0x3; | ||
326 | do_div(pll_out_freq_num, 1 << pic_div); | 378 | do_div(pll_out_freq_num, 1 << pic_div); |
327 | 379 | ||
328 | return pll_out_freq_num; | 380 | return pll_out_freq_num; |
@@ -330,12 +382,8 @@ static unsigned int nlm_2xx_get_pic_frequency(int node) | |||
330 | 382 | ||
331 | unsigned int nlm_get_pic_frequency(int node) | 383 | unsigned int nlm_get_pic_frequency(int node) |
332 | { | 384 | { |
333 | /* TODO Has to calculate freq as like 2xx */ | ||
334 | if (cpu_is_xlp9xx()) | ||
335 | return 250000000; | ||
336 | |||
337 | if (cpu_is_xlpii()) | 385 | if (cpu_is_xlpii()) |
338 | return nlm_2xx_get_pic_frequency(node); | 386 | return nlm_xlp2_get_pic_frequency(node); |
339 | else | 387 | else |
340 | return 133333333; | 388 | return 133333333; |
341 | } | 389 | } |