MIPS: Netlogic: XLP2XX CPU and PIC frequency
Add code to calculate the CPU and PIC frequency for XLP2XX SoCs. Since the PIC frequency on XLP2XX can be configured, add a new macro pic_timer_freq() to be used in netlogic/common/time.c. Signed-off-by: Jayachandran C <jchandra@broadcom.com> Cc: linux-mips@linux-mips.org Cc: Ganesan Ramalingam <ganesanr@broadcom.com> Patchwork: http://patchwork.linux-mips.org/patch/5701/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
parent
5b6ff35d33
commit
57ceb4b020
5 changed files with 152 additions and 10 deletions
|
@ -208,13 +208,14 @@
|
|||
#define PIC_LOCAL_SCHEDULING 1
|
||||
#define PIC_GLOBAL_SCHEDULING 0
|
||||
|
||||
#define PIC_CLK_HZ 133333333
|
||||
|
||||
#define nlm_read_pic_reg(b, r) nlm_read_reg64(b, r)
|
||||
#define nlm_write_pic_reg(b, r, v) nlm_write_reg64(b, r, v)
|
||||
#define nlm_get_pic_pcibase(node) nlm_pcicfg_base(XLP_IO_PIC_OFFSET(node))
|
||||
#define nlm_get_pic_regbase(node) (nlm_get_pic_pcibase(node) + XLP_IO_PCI_HDRSZ)
|
||||
|
||||
/* We use PIC on node 0 as a timer */
|
||||
#define pic_timer_freq() nlm_get_pic_frequency(0)
|
||||
|
||||
/* IRT and h/w interrupt routines */
|
||||
static inline int
|
||||
nlm_pic_read_irt(uint64_t base, int irt_index)
|
||||
|
|
|
@ -117,6 +117,36 @@
|
|||
#define SYS_SCRTCH2 0x4b
|
||||
#define SYS_SCRTCH3 0x4c
|
||||
|
||||
/* PLL registers XLP2XX */
|
||||
#define SYS_PLL_CTRL0 0x240
|
||||
#define SYS_PLL_CTRL1 0x241
|
||||
#define SYS_PLL_CTRL2 0x242
|
||||
#define SYS_PLL_CTRL3 0x243
|
||||
#define SYS_DMC_PLL_CTRL0 0x244
|
||||
#define SYS_DMC_PLL_CTRL1 0x245
|
||||
#define SYS_DMC_PLL_CTRL2 0x246
|
||||
#define SYS_DMC_PLL_CTRL3 0x247
|
||||
|
||||
#define SYS_PLL_CTRL0_DEVX(x) (0x248 + (x) * 4)
|
||||
#define SYS_PLL_CTRL1_DEVX(x) (0x249 + (x) * 4)
|
||||
#define SYS_PLL_CTRL2_DEVX(x) (0x24a + (x) * 4)
|
||||
#define SYS_PLL_CTRL3_DEVX(x) (0x24b + (x) * 4)
|
||||
|
||||
#define SYS_CPU_PLL_CHG_CTRL 0x288
|
||||
#define SYS_PLL_CHG_CTRL 0x289
|
||||
#define SYS_CLK_DEV_DIS 0x28a
|
||||
#define SYS_CLK_DEV_SEL 0x28b
|
||||
#define SYS_CLK_DEV_DIV 0x28c
|
||||
#define SYS_CLK_DEV_CHG 0x28d
|
||||
#define SYS_CLK_DEV_SEL_REG 0x28e
|
||||
#define SYS_CLK_DEV_DIV_REG 0x28f
|
||||
#define SYS_CPU_PLL_LOCK 0x29f
|
||||
#define SYS_SYS_PLL_LOCK 0x2a0
|
||||
#define SYS_PLL_MEM_CMD 0x2a1
|
||||
#define SYS_CPU_PLL_MEM_REQ 0x2a2
|
||||
#define SYS_SYS_PLL_MEM_REQ 0x2a3
|
||||
#define SYS_PLL_MEM_STAT 0x2a4
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
#define nlm_read_sys_reg(b, r) nlm_read_reg(b, r)
|
||||
|
@ -124,5 +154,6 @@
|
|||
#define nlm_get_sys_pcibase(node) nlm_pcicfg_base(XLP_IO_SYS_OFFSET(node))
|
||||
#define nlm_get_sys_regbase(node) (nlm_get_sys_pcibase(node) + XLP_IO_PCI_HDRSZ)
|
||||
|
||||
unsigned int nlm_get_pic_frequency(int node);
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
#define _ASM_NLM_XLR_PIC_H
|
||||
|
||||
#define PIC_CLK_HZ 66666666
|
||||
#define pic_timer_freq() PIC_CLK_HZ
|
||||
|
||||
/* PIC hardware interrupt numbers */
|
||||
#define PIC_IRT_WD_INDEX 0
|
||||
#define PIC_IRT_TIMER_0_INDEX 1
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#if defined(CONFIG_CPU_XLP)
|
||||
#include <asm/netlogic/xlp-hal/iomap.h>
|
||||
#include <asm/netlogic/xlp-hal/xlp.h>
|
||||
#include <asm/netlogic/xlp-hal/sys.h>
|
||||
#include <asm/netlogic/xlp-hal/pic.h>
|
||||
#elif defined(CONFIG_CPU_XLR)
|
||||
#include <asm/netlogic/xlr/iomap.h>
|
||||
|
@ -91,7 +92,7 @@ static void nlm_init_pic_timer(void)
|
|||
csrc_pic.read = nlm_get_pic_timer;
|
||||
}
|
||||
csrc_pic.rating = 1000;
|
||||
clocksource_register_hz(&csrc_pic, PIC_CLK_HZ);
|
||||
clocksource_register_hz(&csrc_pic, pic_timer_freq());
|
||||
}
|
||||
|
||||
void __init plat_time_init(void)
|
||||
|
|
|
@ -127,18 +127,125 @@ unsigned int nlm_get_core_frequency(int node, int core)
|
|||
|
||||
sysbase = nlm_get_node(node)->sysbase;
|
||||
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;
|
||||
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;
|
||||
num = 800000000ULL * pll_divf;
|
||||
denom = 3 * pll_divr * ext_div * dfs_div;
|
||||
}
|
||||
do_div(num, denom);
|
||||
return (unsigned int)num;
|
||||
}
|
||||
|
||||
/* Calculate Frequency to the PIC from PLL.
|
||||
* freq_out = ( ref_freq/2 * (6 + ctrl2[7:0]) + ctrl2[20:8]/2^13 ) /
|
||||
* ((2^ctrl0[7:5]) * Table(ctrl0[26:24]))
|
||||
*/
|
||||
static unsigned int nlm_2xx_get_pic_frequency(int node)
|
||||
{
|
||||
u32 ctrl_val0, ctrl_val2, vco_post_div, pll_post_div;
|
||||
u32 mdiv, fdiv, pll_out_freq_den, reg_select, ref_div, pic_div;
|
||||
u64 ref_clk, sysbase, pll_out_freq_num, ref_clk_select;
|
||||
|
||||
sysbase = nlm_get_node(node)->sysbase;
|
||||
|
||||
/* Find ref_clk_base */
|
||||
ref_clk_select =
|
||||
(nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG) >> 18) & 0x3;
|
||||
switch (ref_clk_select) {
|
||||
case 0:
|
||||
ref_clk = 200000000ULL;
|
||||
ref_div = 3;
|
||||
break;
|
||||
case 1:
|
||||
ref_clk = 100000000ULL;
|
||||
ref_div = 1;
|
||||
break;
|
||||
case 2:
|
||||
ref_clk = 125000000ULL;
|
||||
ref_div = 1;
|
||||
break;
|
||||
case 3:
|
||||
ref_clk = 400000000ULL;
|
||||
ref_div = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Find the clock source PLL device for PIC */
|
||||
reg_select = (nlm_read_sys_reg(sysbase, SYS_CLK_DEV_SEL) >> 22) & 0x3;
|
||||
switch (reg_select) {
|
||||
case 0:
|
||||
ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0);
|
||||
ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2);
|
||||
break;
|
||||
case 1:
|
||||
ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0_DEVX(0));
|
||||
ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2_DEVX(0));
|
||||
break;
|
||||
case 2:
|
||||
ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0_DEVX(1));
|
||||
ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2_DEVX(1));
|
||||
break;
|
||||
case 3:
|
||||
ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0_DEVX(2));
|
||||
ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2_DEVX(2));
|
||||
break;
|
||||
}
|
||||
|
||||
vco_post_div = (ctrl_val0 >> 5) & 0x7;
|
||||
pll_post_div = (ctrl_val0 >> 24) & 0x7;
|
||||
mdiv = ctrl_val2 & 0xff;
|
||||
fdiv = (ctrl_val2 >> 8) & 0xfff;
|
||||
|
||||
/* Find PLL post divider value */
|
||||
switch (pll_post_div) {
|
||||
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;
|
||||
}
|
||||
|
||||
fdiv = fdiv/(1 << 13);
|
||||
pll_out_freq_num = ((ref_clk >> 1) * (6 + mdiv)) + fdiv;
|
||||
pll_out_freq_den = (1 << vco_post_div) * pll_post_div * 3;
|
||||
|
||||
if (pll_out_freq_den > 0)
|
||||
do_div(pll_out_freq_num, pll_out_freq_den);
|
||||
|
||||
/* PIC post divider, which happens after PLL */
|
||||
pic_div = (nlm_read_sys_reg(sysbase, SYS_CLK_DEV_DIV) >> 22) & 0x3;
|
||||
do_div(pll_out_freq_num, 1 << pic_div);
|
||||
|
||||
return pll_out_freq_num;
|
||||
}
|
||||
|
||||
unsigned int nlm_get_pic_frequency(int node)
|
||||
{
|
||||
if (cpu_is_xlpii())
|
||||
return nlm_2xx_get_pic_frequency(node);
|
||||
else
|
||||
return 133333333;
|
||||
}
|
||||
|
||||
unsigned int nlm_get_cpu_frequency(void)
|
||||
{
|
||||
return nlm_get_core_frequency(0, 0);
|
||||
|
|
Loading…
Reference in a new issue