Commit edf3ed5e authored by Jayachandran C's avatar Jayachandran C Committed by Ralf Baechle

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: default avatarJayachandran C <jchandra@broadcom.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/6870/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent c065909e
...@@ -118,6 +118,10 @@ ...@@ -118,6 +118,10 @@
#define SYS_SCRTCH3 0x4c #define SYS_SCRTCH3 0x4c
/* PLL registers XLP2XX */ /* 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_CTRL0 0x240
#define SYS_PLL_CTRL1 0x241 #define SYS_PLL_CTRL1 0x241
#define SYS_PLL_CTRL2 0x242 #define SYS_PLL_CTRL2 0x242
...@@ -148,6 +152,10 @@ ...@@ -148,6 +152,10 @@
#define SYS_PLL_MEM_STAT 0x2a4 #define SYS_PLL_MEM_STAT 0x2a4
/* PLL registers XLP9XX */ /* 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_CTRL0 0x140
#define SYS_9XX_DMC_PLL_CTRL1 0x141 #define SYS_9XX_DMC_PLL_CTRL1 0x141
#define SYS_9XX_DMC_PLL_CTRL2 0x142 #define SYS_9XX_DMC_PLL_CTRL2 0x142
......
...@@ -206,34 +206,81 @@ int nlm_irq_to_irt(int irq) ...@@ -206,34 +206,81 @@ int nlm_irq_to_irt(int irq)
return xlp_irq_to_irt(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 pll_divf, pll_divr, dfs_div, ext_div;
unsigned int rstval, dfsval, denom; unsigned int rstval, dfsval, denom;
uint64_t num, sysbase; uint64_t num, sysbase;
sysbase = nlm_get_node(node)->sysbase; sysbase = nlm_get_node(node)->sysbase;
if (cpu_is_xlp9xx()) rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG);
rstval = nlm_read_sys_reg(sysbase, SYS_9XX_POWER_ON_RESET_CFG); dfsval = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIV_VALUE);
else pll_divf = ((rstval >> 10) & 0x7f) + 1;
rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG); pll_divr = ((rstval >> 8) & 0x3) + 1;
if (cpu_is_xlpii()) { ext_div = ((rstval >> 30) & 0x3) + 1;
num = 1000000ULL * (400 * 3 + 100 * (rstval >> 26)); dfs_div = ((dfsval >> (core * 4)) & 0xf) + 1;
denom = 3;
} else { num = 800000000ULL * pll_divf;
dfsval = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIV_VALUE); denom = 3 * pll_divr * ext_div * dfs_div;
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); do_div(num, denom);
return (unsigned int)num; 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. * Calculate PIC frequency from PLL registers.
* freq_out = (ref_freq/2 * (6 + ctrl2[7:0]) + ctrl2[20:8]/2^13) / * freq_out = (ref_freq/2 * (6 + ctrl2[7:0]) + ctrl2[20:8]/2^13) /
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment