MIPS: Netlogic: Update XLP9XX/2XX core freq calculation
authorJayachandran C <jchandra@broadcom.com>
Tue, 29 Apr 2014 14:37:52 +0000 (20:07 +0530)
committerRalf Baechle <ralf@linux-mips.org>
Fri, 30 May 2014 14:50:13 +0000 (16:50 +0200)
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 <jchandra@broadcom.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/6870/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
arch/mips/include/asm/netlogic/xlp-hal/sys.h
arch/mips/netlogic/xlp/nlm_hal.c

index bcb136d224e65801ffa36ffa259751aac9ff9783..bc7bddf25be92963695fdd29b8707631d923e8e1 100644 (file)
 #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
 #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
index 59f1303b69d758c9d3de72f2633ac831167a6404..bc24beb3a42655440b94f25e7859104fc38c9a73 100644 (file)
@@ -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;
-
-               num = 800000000ULL * pll_divf;
-               denom = 3 * pll_divr * ext_div * dfs_div;
-       }
+       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;
        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) /