From edf3ed5e69bcf3f60087099eccab34be0ebcf60a Mon Sep 17 00:00:00 2001 From: Jayachandran C Date: Tue, 29 Apr 2014 20:07:52 +0530 Subject: [PATCH] MIPS: Netlogic: Update XLP9XX/2XX core freq calculation Calculate XLP 9XX and 2XX core frequency from the per-core PLL. This should give the correct value for all board configurations. Signed-off-by: Jayachandran C Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/6870/ Signed-off-by: Ralf Baechle --- arch/mips/include/asm/netlogic/xlp-hal/sys.h | 8 ++ arch/mips/netlogic/xlp/nlm_hal.c | 81 ++++++++++++++++---- 2 files changed, 72 insertions(+), 17 deletions(-) diff --git a/arch/mips/include/asm/netlogic/xlp-hal/sys.h b/arch/mips/include/asm/netlogic/xlp-hal/sys.h index bcb136d224e6..bc7bddf25be9 100644 --- a/arch/mips/include/asm/netlogic/xlp-hal/sys.h +++ b/arch/mips/include/asm/netlogic/xlp-hal/sys.h @@ -118,6 +118,10 @@ #define SYS_SCRTCH3 0x4c /* PLL registers XLP2XX */ +#define SYS_CPU_PLL_CTRL0(core) (0x1c0 + (core * 4)) +#define SYS_CPU_PLL_CTRL1(core) (0x1c1 + (core * 4)) +#define SYS_CPU_PLL_CTRL2(core) (0x1c2 + (core * 4)) +#define SYS_CPU_PLL_CTRL3(core) (0x1c3 + (core * 4)) #define SYS_PLL_CTRL0 0x240 #define SYS_PLL_CTRL1 0x241 #define SYS_PLL_CTRL2 0x242 @@ -148,6 +152,10 @@ #define SYS_PLL_MEM_STAT 0x2a4 /* PLL registers XLP9XX */ +#define SYS_9XX_CPU_PLL_CTRL0(core) (0xc0 + (core * 4)) +#define SYS_9XX_CPU_PLL_CTRL1(core) (0xc1 + (core * 4)) +#define SYS_9XX_CPU_PLL_CTRL2(core) (0xc2 + (core * 4)) +#define SYS_9XX_CPU_PLL_CTRL3(core) (0xc3 + (core * 4)) #define SYS_9XX_DMC_PLL_CTRL0 0x140 #define SYS_9XX_DMC_PLL_CTRL1 0x141 #define SYS_9XX_DMC_PLL_CTRL2 0x142 diff --git a/arch/mips/netlogic/xlp/nlm_hal.c b/arch/mips/netlogic/xlp/nlm_hal.c index 59f1303b69d7..bc24beb3a426 100644 --- a/arch/mips/netlogic/xlp/nlm_hal.c +++ b/arch/mips/netlogic/xlp/nlm_hal.c @@ -206,34 +206,81 @@ int nlm_irq_to_irt(int irq) return xlp_irq_to_irt(irq); } -unsigned int nlm_get_core_frequency(int node, int core) +static unsigned int nlm_xlp2_get_core_frequency(int node, int core) +{ + unsigned int pll_post_div, ctrl_val0, ctrl_val1, denom; + uint64_t num, sysbase, clockbase; + + if (cpu_is_xlp9xx()) { + clockbase = nlm_get_clock_regbase(node); + ctrl_val0 = nlm_read_sys_reg(clockbase, + SYS_9XX_CPU_PLL_CTRL0(core)); + ctrl_val1 = nlm_read_sys_reg(clockbase, + SYS_9XX_CPU_PLL_CTRL1(core)); + } else { + sysbase = nlm_get_node(node)->sysbase; + ctrl_val0 = nlm_read_sys_reg(sysbase, + SYS_CPU_PLL_CTRL0(core)); + ctrl_val1 = nlm_read_sys_reg(sysbase, + SYS_CPU_PLL_CTRL1(core)); + } + + /* Find PLL post divider value */ + switch ((ctrl_val0 >> 24) & 0x7) { + case 1: + pll_post_div = 2; + break; + case 3: + pll_post_div = 4; + break; + case 7: + pll_post_div = 8; + break; + case 6: + pll_post_div = 16; + break; + case 0: + default: + pll_post_div = 1; + break; + } + + num = 1000000ULL * (400 * 3 + 100 * (ctrl_val1 & 0x3f)); + denom = 3 * pll_post_div; + do_div(num, denom); + + return (unsigned int)num; +} + +static unsigned int nlm_xlp_get_core_frequency(int node, int core) { unsigned int pll_divf, pll_divr, dfs_div, ext_div; unsigned int rstval, dfsval, denom; uint64_t num, sysbase; sysbase = nlm_get_node(node)->sysbase; - if (cpu_is_xlp9xx()) - rstval = nlm_read_sys_reg(sysbase, SYS_9XX_POWER_ON_RESET_CFG); - else - rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG); - if (cpu_is_xlpii()) { - num = 1000000ULL * (400 * 3 + 100 * (rstval >> 26)); - denom = 3; - } else { - dfsval = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIV_VALUE); - pll_divf = ((rstval >> 10) & 0x7f) + 1; - pll_divr = ((rstval >> 8) & 0x3) + 1; - ext_div = ((rstval >> 30) & 0x3) + 1; - dfs_div = ((dfsval >> (core * 4)) & 0xf) + 1; + rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG); + dfsval = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIV_VALUE); + pll_divf = ((rstval >> 10) & 0x7f) + 1; + pll_divr = ((rstval >> 8) & 0x3) + 1; + ext_div = ((rstval >> 30) & 0x3) + 1; + dfs_div = ((dfsval >> (core * 4)) & 0xf) + 1; - num = 800000000ULL * pll_divf; - denom = 3 * pll_divr * ext_div * dfs_div; - } + num = 800000000ULL * pll_divf; + denom = 3 * pll_divr * ext_div * dfs_div; do_div(num, denom); + return (unsigned int)num; } +unsigned int nlm_get_core_frequency(int node, int core) +{ + if (cpu_is_xlpii()) + return nlm_xlp2_get_core_frequency(node, core); + else + return nlm_xlp_get_core_frequency(node, core); +} + /* * Calculate PIC frequency from PLL registers. * freq_out = (ref_freq/2 * (6 + ctrl2[7:0]) + ctrl2[20:8]/2^13) /