Commit c065909e authored by Ganesan Ramalingam's avatar Ganesan Ramalingam Committed by Ralf Baechle

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: default avatarGanesan Ramalingam <ganesanr@broadcom.com>
Signed-off-by: default avatarJayachandran C <jchandra@broadcom.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/6876/Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 77bef0e4
...@@ -120,6 +120,8 @@ ...@@ -120,6 +120,8 @@
#define XLP9XX_IO_UART_OFFSET(node) XLP9XX_HDR_OFFSET(node, 2, 2) #define XLP9XX_IO_UART_OFFSET(node) XLP9XX_HDR_OFFSET(node, 2, 2)
#define XLP9XX_IO_SYS_OFFSET(node) XLP9XX_HDR_OFFSET(node, 6, 0) #define XLP9XX_IO_SYS_OFFSET(node) XLP9XX_HDR_OFFSET(node, 6, 0)
#define XLP9XX_IO_FUSE_OFFSET(node) XLP9XX_HDR_OFFSET(node, 6, 1) #define XLP9XX_IO_FUSE_OFFSET(node) XLP9XX_HDR_OFFSET(node, 6, 1)
#define XLP9XX_IO_CLOCK_OFFSET(node) XLP9XX_HDR_OFFSET(node, 6, 2)
#define XLP9XX_IO_POWER_OFFSET(node) XLP9XX_HDR_OFFSET(node, 6, 3)
#define XLP9XX_IO_JTAG_OFFSET(node) XLP9XX_HDR_OFFSET(node, 6, 4) #define XLP9XX_IO_JTAG_OFFSET(node) XLP9XX_HDR_OFFSET(node, 6, 4)
#define XLP9XX_IO_PCIE_OFFSET(node, i) XLP9XX_HDR_OFFSET(node, 1, i) #define XLP9XX_IO_PCIE_OFFSET(node, i) XLP9XX_HDR_OFFSET(node, 1, i)
......
...@@ -147,6 +147,28 @@ ...@@ -147,6 +147,28 @@
#define SYS_SYS_PLL_MEM_REQ 0x2a3 #define SYS_SYS_PLL_MEM_REQ 0x2a3
#define SYS_PLL_MEM_STAT 0x2a4 #define SYS_PLL_MEM_STAT 0x2a4
/* PLL registers XLP9XX */
#define SYS_9XX_DMC_PLL_CTRL0 0x140
#define SYS_9XX_DMC_PLL_CTRL1 0x141
#define SYS_9XX_DMC_PLL_CTRL2 0x142
#define SYS_9XX_DMC_PLL_CTRL3 0x143
#define SYS_9XX_PLL_CTRL0 0x144
#define SYS_9XX_PLL_CTRL1 0x145
#define SYS_9XX_PLL_CTRL2 0x146
#define SYS_9XX_PLL_CTRL3 0x147
#define SYS_9XX_PLL_CTRL0_DEVX(x) (0x148 + (x) * 4)
#define SYS_9XX_PLL_CTRL1_DEVX(x) (0x149 + (x) * 4)
#define SYS_9XX_PLL_CTRL2_DEVX(x) (0x14a + (x) * 4)
#define SYS_9XX_PLL_CTRL3_DEVX(x) (0x14b + (x) * 4)
#define SYS_9XX_CPU_PLL_CHG_CTRL 0x188
#define SYS_9XX_PLL_CHG_CTRL 0x189
#define SYS_9XX_CLK_DEV_DIS 0x18a
#define SYS_9XX_CLK_DEV_SEL 0x18b
#define SYS_9XX_CLK_DEV_DIV 0x18d
#define SYS_9XX_CLK_DEV_CHG 0x18f
/* Registers changed on 9XX */ /* Registers changed on 9XX */
#define SYS_9XX_POWER_ON_RESET_CFG 0x00 #define SYS_9XX_POWER_ON_RESET_CFG 0x00
#define SYS_9XX_CHIP_RESET 0x01 #define SYS_9XX_CHIP_RESET 0x01
...@@ -170,6 +192,11 @@ ...@@ -170,6 +192,11 @@
#define nlm_get_fuse_regbase(node) \ #define nlm_get_fuse_regbase(node) \
(nlm_get_fuse_pcibase(node) + XLP_IO_PCI_HDRSZ) (nlm_get_fuse_pcibase(node) + XLP_IO_PCI_HDRSZ)
#define nlm_get_clock_pcibase(node) \
nlm_pcicfg_base(XLP9XX_IO_CLOCK_OFFSET(node))
#define nlm_get_clock_regbase(node) \
(nlm_get_clock_pcibase(node) + XLP_IO_PCI_HDRSZ)
unsigned int nlm_get_pic_frequency(int node); unsigned int nlm_get_pic_frequency(int node);
#endif #endif
#endif #endif
...@@ -82,6 +82,7 @@ static struct clocksource csrc_pic = { ...@@ -82,6 +82,7 @@ static struct clocksource csrc_pic = {
static void nlm_init_pic_timer(void) static void nlm_init_pic_timer(void)
{ {
uint64_t picbase = nlm_get_node(0)->picbase; uint64_t picbase = nlm_get_node(0)->picbase;
u32 picfreq;
nlm_pic_set_timer(picbase, PIC_CLOCK_TIMER, ~0ULL, 0, 0); nlm_pic_set_timer(picbase, PIC_CLOCK_TIMER, ~0ULL, 0, 0);
if (current_cpu_data.cputype == CPU_XLR) { if (current_cpu_data.cputype == CPU_XLR) {
...@@ -92,7 +93,9 @@ static void nlm_init_pic_timer(void) ...@@ -92,7 +93,9 @@ static void nlm_init_pic_timer(void)
csrc_pic.read = nlm_get_pic_timer; csrc_pic.read = nlm_get_pic_timer;
} }
csrc_pic.rating = 1000; csrc_pic.rating = 1000;
clocksource_register_hz(&csrc_pic, pic_timer_freq()); picfreq = pic_timer_freq();
clocksource_register_hz(&csrc_pic, picfreq);
pr_info("PIC clock source added, frequency %d\n", picfreq);
} }
void __init plat_time_init(void) void __init plat_time_init(void)
......
...@@ -234,21 +234,28 @@ unsigned int nlm_get_core_frequency(int node, int core) ...@@ -234,21 +234,28 @@ unsigned int nlm_get_core_frequency(int node, int core)
return (unsigned int)num; 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 ) / * Calculate PIC frequency from PLL registers.
* ((2^ctrl0[7:5]) * Table(ctrl0[26:24])) * 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) static unsigned int nlm_xlp2_get_pic_frequency(int node)
{ {
u32 ctrl_val0, ctrl_val2, vco_post_div, pll_post_div; u32 ctrl_val0, ctrl_val2, vco_post_div, pll_post_div, cpu_xlp9xx;
u32 mdiv, fdiv, pll_out_freq_den, reg_select, ref_div, pic_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; u64 sysbase, pll_out_freq_num, ref_clk_select, clockbase, ref_clk;
sysbase = nlm_get_node(node)->sysbase; sysbase = nlm_get_node(node)->sysbase;
clockbase = nlm_get_clock_regbase(node);
cpu_xlp9xx = cpu_is_xlp9xx();
/* Find ref_clk_base */ /* Find ref_clk_base */
ref_clk_select = if (cpu_xlp9xx)
(nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG) >> 18) & 0x3; ref_clk_select = (nlm_read_sys_reg(sysbase,
SYS_9XX_POWER_ON_RESET_CFG) >> 18) & 0x3;
else
ref_clk_select = (nlm_read_sys_reg(sysbase,
SYS_POWER_ON_RESET_CFG) >> 18) & 0x3;
switch (ref_clk_select) { switch (ref_clk_select) {
case 0: case 0:
ref_clk = 200000000ULL; ref_clk = 200000000ULL;
...@@ -269,30 +276,70 @@ static unsigned int nlm_2xx_get_pic_frequency(int node) ...@@ -269,30 +276,70 @@ static unsigned int nlm_2xx_get_pic_frequency(int node)
} }
/* Find the clock source PLL device for PIC */ /* Find the clock source PLL device for PIC */
reg_select = (nlm_read_sys_reg(sysbase, SYS_CLK_DEV_SEL) >> 22) & 0x3; if (cpu_xlp9xx) {
switch (reg_select) { reg_select = nlm_read_sys_reg(clockbase,
case 0: SYS_9XX_CLK_DEV_SEL) & 0x3;
ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0); switch (reg_select) {
ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2); case 0:
break; ctrl_val0 = nlm_read_sys_reg(clockbase,
case 1: SYS_9XX_PLL_CTRL0);
ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0_DEVX(0)); ctrl_val2 = nlm_read_sys_reg(clockbase,
ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2_DEVX(0)); SYS_9XX_PLL_CTRL2);
break; break;
case 2: case 1:
ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0_DEVX(1)); ctrl_val0 = nlm_read_sys_reg(clockbase,
ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2_DEVX(1)); SYS_9XX_PLL_CTRL0_DEVX(0));
break; ctrl_val2 = nlm_read_sys_reg(clockbase,
case 3: SYS_9XX_PLL_CTRL2_DEVX(0));
ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0_DEVX(2)); break;
ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2_DEVX(2)); case 2:
break; ctrl_val0 = nlm_read_sys_reg(clockbase,
SYS_9XX_PLL_CTRL0_DEVX(1));
ctrl_val2 = nlm_read_sys_reg(clockbase,
SYS_9XX_PLL_CTRL2_DEVX(1));
break;
case 3:
ctrl_val0 = nlm_read_sys_reg(clockbase,
SYS_9XX_PLL_CTRL0_DEVX(2));
ctrl_val2 = nlm_read_sys_reg(clockbase,
SYS_9XX_PLL_CTRL2_DEVX(2));
break;
}
} else {
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; vco_post_div = (ctrl_val0 >> 5) & 0x7;
pll_post_div = (ctrl_val0 >> 24) & 0x7; pll_post_div = (ctrl_val0 >> 24) & 0x7;
mdiv = ctrl_val2 & 0xff; mdiv = ctrl_val2 & 0xff;
fdiv = (ctrl_val2 >> 8) & 0xfff; fdiv = (ctrl_val2 >> 8) & 0x1fff;
/* Find PLL post divider value */ /* Find PLL post divider value */
switch (pll_post_div) { switch (pll_post_div) {
...@@ -322,7 +369,12 @@ static unsigned int nlm_2xx_get_pic_frequency(int node) ...@@ -322,7 +369,12 @@ static unsigned int nlm_2xx_get_pic_frequency(int node)
do_div(pll_out_freq_num, pll_out_freq_den); do_div(pll_out_freq_num, pll_out_freq_den);
/* PIC post divider, which happens after PLL */ /* PIC post divider, which happens after PLL */
pic_div = (nlm_read_sys_reg(sysbase, SYS_CLK_DEV_DIV) >> 22) & 0x3; if (cpu_xlp9xx)
pic_div = nlm_read_sys_reg(clockbase,
SYS_9XX_CLK_DEV_DIV) & 0x3;
else
pic_div = (nlm_read_sys_reg(sysbase,
SYS_CLK_DEV_DIV) >> 22) & 0x3;
do_div(pll_out_freq_num, 1 << pic_div); do_div(pll_out_freq_num, 1 << pic_div);
return pll_out_freq_num; return pll_out_freq_num;
...@@ -330,12 +382,8 @@ static unsigned int nlm_2xx_get_pic_frequency(int node) ...@@ -330,12 +382,8 @@ static unsigned int nlm_2xx_get_pic_frequency(int node)
unsigned int nlm_get_pic_frequency(int node) unsigned int nlm_get_pic_frequency(int node)
{ {
/* TODO Has to calculate freq as like 2xx */
if (cpu_is_xlp9xx())
return 250000000;
if (cpu_is_xlpii()) if (cpu_is_xlpii())
return nlm_2xx_get_pic_frequency(node); return nlm_xlp2_get_pic_frequency(node);
else else
return 133333333; return 133333333;
} }
......
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