aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGanesan Ramalingam <ganesanr@broadcom.com>2013-08-11 05:13:56 -0400
committerRalf Baechle <ralf@linux-mips.org>2013-09-03 17:22:19 -0400
commit57ceb4b02045bd677b70f9e2b3d41e8c1bb86598 (patch)
treed8745a3424a87b5fa8ca56208943a21e16282550
parent5b6ff35d33cb0310c36f9081b9e39cd016715e9c (diff)
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>
-rw-r--r--arch/mips/include/asm/netlogic/xlp-hal/pic.h5
-rw-r--r--arch/mips/include/asm/netlogic/xlp-hal/sys.h31
-rw-r--r--arch/mips/include/asm/netlogic/xlr/pic.h2
-rw-r--r--arch/mips/netlogic/common/time.c3
-rw-r--r--arch/mips/netlogic/xlp/nlm_hal.c123
5 files changed, 153 insertions, 11 deletions
diff --git a/arch/mips/include/asm/netlogic/xlp-hal/pic.h b/arch/mips/include/asm/netlogic/xlp-hal/pic.h
index 4b5108dfaa16..105389b79f09 100644
--- a/arch/mips/include/asm/netlogic/xlp-hal/pic.h
+++ b/arch/mips/include/asm/netlogic/xlp-hal/pic.h
@@ -208,13 +208,14 @@
208#define PIC_LOCAL_SCHEDULING 1 208#define PIC_LOCAL_SCHEDULING 1
209#define PIC_GLOBAL_SCHEDULING 0 209#define PIC_GLOBAL_SCHEDULING 0
210 210
211#define PIC_CLK_HZ 133333333
212
213#define nlm_read_pic_reg(b, r) nlm_read_reg64(b, r) 211#define nlm_read_pic_reg(b, r) nlm_read_reg64(b, r)
214#define nlm_write_pic_reg(b, r, v) nlm_write_reg64(b, r, v) 212#define nlm_write_pic_reg(b, r, v) nlm_write_reg64(b, r, v)
215#define nlm_get_pic_pcibase(node) nlm_pcicfg_base(XLP_IO_PIC_OFFSET(node)) 213#define nlm_get_pic_pcibase(node) nlm_pcicfg_base(XLP_IO_PIC_OFFSET(node))
216#define nlm_get_pic_regbase(node) (nlm_get_pic_pcibase(node) + XLP_IO_PCI_HDRSZ) 214#define nlm_get_pic_regbase(node) (nlm_get_pic_pcibase(node) + XLP_IO_PCI_HDRSZ)
217 215
216/* We use PIC on node 0 as a timer */
217#define pic_timer_freq() nlm_get_pic_frequency(0)
218
218/* IRT and h/w interrupt routines */ 219/* IRT and h/w interrupt routines */
219static inline int 220static inline int
220nlm_pic_read_irt(uint64_t base, int irt_index) 221nlm_pic_read_irt(uint64_t base, int irt_index)
diff --git a/arch/mips/include/asm/netlogic/xlp-hal/sys.h b/arch/mips/include/asm/netlogic/xlp-hal/sys.h
index 470e52bfc061..fcf2833c16ca 100644
--- a/arch/mips/include/asm/netlogic/xlp-hal/sys.h
+++ b/arch/mips/include/asm/netlogic/xlp-hal/sys.h
@@ -117,6 +117,36 @@
117#define SYS_SCRTCH2 0x4b 117#define SYS_SCRTCH2 0x4b
118#define SYS_SCRTCH3 0x4c 118#define SYS_SCRTCH3 0x4c
119 119
120/* PLL registers XLP2XX */
121#define SYS_PLL_CTRL0 0x240
122#define SYS_PLL_CTRL1 0x241
123#define SYS_PLL_CTRL2 0x242
124#define SYS_PLL_CTRL3 0x243
125#define SYS_DMC_PLL_CTRL0 0x244
126#define SYS_DMC_PLL_CTRL1 0x245
127#define SYS_DMC_PLL_CTRL2 0x246
128#define SYS_DMC_PLL_CTRL3 0x247
129
130#define SYS_PLL_CTRL0_DEVX(x) (0x248 + (x) * 4)
131#define SYS_PLL_CTRL1_DEVX(x) (0x249 + (x) * 4)
132#define SYS_PLL_CTRL2_DEVX(x) (0x24a + (x) * 4)
133#define SYS_PLL_CTRL3_DEVX(x) (0x24b + (x) * 4)
134
135#define SYS_CPU_PLL_CHG_CTRL 0x288
136#define SYS_PLL_CHG_CTRL 0x289
137#define SYS_CLK_DEV_DIS 0x28a
138#define SYS_CLK_DEV_SEL 0x28b
139#define SYS_CLK_DEV_DIV 0x28c
140#define SYS_CLK_DEV_CHG 0x28d
141#define SYS_CLK_DEV_SEL_REG 0x28e
142#define SYS_CLK_DEV_DIV_REG 0x28f
143#define SYS_CPU_PLL_LOCK 0x29f
144#define SYS_SYS_PLL_LOCK 0x2a0
145#define SYS_PLL_MEM_CMD 0x2a1
146#define SYS_CPU_PLL_MEM_REQ 0x2a2
147#define SYS_SYS_PLL_MEM_REQ 0x2a3
148#define SYS_PLL_MEM_STAT 0x2a4
149
120#ifndef __ASSEMBLY__ 150#ifndef __ASSEMBLY__
121 151
122#define nlm_read_sys_reg(b, r) nlm_read_reg(b, r) 152#define nlm_read_sys_reg(b, r) nlm_read_reg(b, r)
@@ -124,5 +154,6 @@
124#define nlm_get_sys_pcibase(node) nlm_pcicfg_base(XLP_IO_SYS_OFFSET(node)) 154#define nlm_get_sys_pcibase(node) nlm_pcicfg_base(XLP_IO_SYS_OFFSET(node))
125#define nlm_get_sys_regbase(node) (nlm_get_sys_pcibase(node) + XLP_IO_PCI_HDRSZ) 155#define nlm_get_sys_regbase(node) (nlm_get_sys_pcibase(node) + XLP_IO_PCI_HDRSZ)
126 156
157unsigned int nlm_get_pic_frequency(int node);
127#endif 158#endif
128#endif 159#endif
diff --git a/arch/mips/include/asm/netlogic/xlr/pic.h b/arch/mips/include/asm/netlogic/xlr/pic.h
index 63c99176dffe..3c80a75233bd 100644
--- a/arch/mips/include/asm/netlogic/xlr/pic.h
+++ b/arch/mips/include/asm/netlogic/xlr/pic.h
@@ -36,6 +36,8 @@
36#define _ASM_NLM_XLR_PIC_H 36#define _ASM_NLM_XLR_PIC_H
37 37
38#define PIC_CLK_HZ 66666666 38#define PIC_CLK_HZ 66666666
39#define pic_timer_freq() PIC_CLK_HZ
40
39/* PIC hardware interrupt numbers */ 41/* PIC hardware interrupt numbers */
40#define PIC_IRT_WD_INDEX 0 42#define PIC_IRT_WD_INDEX 0
41#define PIC_IRT_TIMER_0_INDEX 1 43#define PIC_IRT_TIMER_0_INDEX 1
diff --git a/arch/mips/netlogic/common/time.c b/arch/mips/netlogic/common/time.c
index 045a396c57ce..13391b8a6031 100644
--- a/arch/mips/netlogic/common/time.c
+++ b/arch/mips/netlogic/common/time.c
@@ -45,6 +45,7 @@
45#if defined(CONFIG_CPU_XLP) 45#if defined(CONFIG_CPU_XLP)
46#include <asm/netlogic/xlp-hal/iomap.h> 46#include <asm/netlogic/xlp-hal/iomap.h>
47#include <asm/netlogic/xlp-hal/xlp.h> 47#include <asm/netlogic/xlp-hal/xlp.h>
48#include <asm/netlogic/xlp-hal/sys.h>
48#include <asm/netlogic/xlp-hal/pic.h> 49#include <asm/netlogic/xlp-hal/pic.h>
49#elif defined(CONFIG_CPU_XLR) 50#elif defined(CONFIG_CPU_XLR)
50#include <asm/netlogic/xlr/iomap.h> 51#include <asm/netlogic/xlr/iomap.h>
@@ -91,7 +92,7 @@ static void nlm_init_pic_timer(void)
91 csrc_pic.read = nlm_get_pic_timer; 92 csrc_pic.read = nlm_get_pic_timer;
92 } 93 }
93 csrc_pic.rating = 1000; 94 csrc_pic.rating = 1000;
94 clocksource_register_hz(&csrc_pic, PIC_CLK_HZ); 95 clocksource_register_hz(&csrc_pic, pic_timer_freq());
95} 96}
96 97
97void __init plat_time_init(void) 98void __init plat_time_init(void)
diff --git a/arch/mips/netlogic/xlp/nlm_hal.c b/arch/mips/netlogic/xlp/nlm_hal.c
index 6f2c21008ddb..22e2e028fbe4 100644
--- a/arch/mips/netlogic/xlp/nlm_hal.c
+++ b/arch/mips/netlogic/xlp/nlm_hal.c
@@ -127,18 +127,125 @@ unsigned int nlm_get_core_frequency(int node, int core)
127 127
128 sysbase = nlm_get_node(node)->sysbase; 128 sysbase = nlm_get_node(node)->sysbase;
129 rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG); 129 rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG);
130 dfsval = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIV_VALUE); 130 if (cpu_is_xlpii()) {
131 pll_divf = ((rstval >> 10) & 0x7f) + 1; 131 num = 1000000ULL * (400 * 3 + 100 * (rstval >> 26));
132 pll_divr = ((rstval >> 8) & 0x3) + 1; 132 denom = 3;
133 ext_div = ((rstval >> 30) & 0x3) + 1; 133 } else {
134 dfs_div = ((dfsval >> (core * 4)) & 0xf) + 1; 134 dfsval = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIV_VALUE);
135 135 pll_divf = ((rstval >> 10) & 0x7f) + 1;
136 num = 800000000ULL * pll_divf; 136 pll_divr = ((rstval >> 8) & 0x3) + 1;
137 denom = 3 * pll_divr * ext_div * dfs_div; 137 ext_div = ((rstval >> 30) & 0x3) + 1;
138 dfs_div = ((dfsval >> (core * 4)) & 0xf) + 1;
139
140 num = 800000000ULL * pll_divf;
141 denom = 3 * pll_divr * ext_div * dfs_div;
142 }
138 do_div(num, denom); 143 do_div(num, denom);
139 return (unsigned int)num; 144 return (unsigned int)num;
140} 145}
141 146
147/* Calculate Frequency to the PIC from PLL.
148 * freq_out = ( ref_freq/2 * (6 + ctrl2[7:0]) + ctrl2[20:8]/2^13 ) /
149 * ((2^ctrl0[7:5]) * Table(ctrl0[26:24]))
150 */
151static unsigned int nlm_2xx_get_pic_frequency(int node)
152{
153 u32 ctrl_val0, ctrl_val2, vco_post_div, pll_post_div;
154 u32 mdiv, fdiv, pll_out_freq_den, reg_select, ref_div, pic_div;
155 u64 ref_clk, sysbase, pll_out_freq_num, ref_clk_select;
156
157 sysbase = nlm_get_node(node)->sysbase;
158
159 /* Find ref_clk_base */
160 ref_clk_select =
161 (nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG) >> 18) & 0x3;
162 switch (ref_clk_select) {
163 case 0:
164 ref_clk = 200000000ULL;
165 ref_div = 3;
166 break;
167 case 1:
168 ref_clk = 100000000ULL;
169 ref_div = 1;
170 break;
171 case 2:
172 ref_clk = 125000000ULL;
173 ref_div = 1;
174 break;
175 case 3:
176 ref_clk = 400000000ULL;
177 ref_div = 3;
178 break;
179 }
180
181 /* Find the clock source PLL device for PIC */
182 reg_select = (nlm_read_sys_reg(sysbase, SYS_CLK_DEV_SEL) >> 22) & 0x3;
183 switch (reg_select) {
184 case 0:
185 ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0);
186 ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2);
187 break;
188 case 1:
189 ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0_DEVX(0));
190 ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2_DEVX(0));
191 break;
192 case 2:
193 ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0_DEVX(1));
194 ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2_DEVX(1));
195 break;
196 case 3:
197 ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0_DEVX(2));
198 ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2_DEVX(2));
199 break;
200 }
201
202 vco_post_div = (ctrl_val0 >> 5) & 0x7;
203 pll_post_div = (ctrl_val0 >> 24) & 0x7;
204 mdiv = ctrl_val2 & 0xff;
205 fdiv = (ctrl_val2 >> 8) & 0xfff;
206
207 /* Find PLL post divider value */
208 switch (pll_post_div) {
209 case 1:
210 pll_post_div = 2;
211 break;
212 case 3:
213 pll_post_div = 4;
214 break;
215 case 7:
216 pll_post_div = 8;
217 break;
218 case 6:
219 pll_post_div = 16;
220 break;
221 case 0:
222 default:
223 pll_post_div = 1;
224 break;
225 }
226
227 fdiv = fdiv/(1 << 13);
228 pll_out_freq_num = ((ref_clk >> 1) * (6 + mdiv)) + fdiv;
229 pll_out_freq_den = (1 << vco_post_div) * pll_post_div * 3;
230
231 if (pll_out_freq_den > 0)
232 do_div(pll_out_freq_num, pll_out_freq_den);
233
234 /* PIC post divider, which happens after PLL */
235 pic_div = (nlm_read_sys_reg(sysbase, SYS_CLK_DEV_DIV) >> 22) & 0x3;
236 do_div(pll_out_freq_num, 1 << pic_div);
237
238 return pll_out_freq_num;
239}
240
241unsigned int nlm_get_pic_frequency(int node)
242{
243 if (cpu_is_xlpii())
244 return nlm_2xx_get_pic_frequency(node);
245 else
246 return 133333333;
247}
248
142unsigned int nlm_get_cpu_frequency(void) 249unsigned int nlm_get_cpu_frequency(void)
143{ 250{
144 return nlm_get_core_frequency(0, 0); 251 return nlm_get_core_frequency(0, 0);