diff options
author | Ganesan Ramalingam <ganesanr@broadcom.com> | 2013-08-11 05:13:56 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2013-09-03 17:22:19 -0400 |
commit | 57ceb4b02045bd677b70f9e2b3d41e8c1bb86598 (patch) | |
tree | d8745a3424a87b5fa8ca56208943a21e16282550 | |
parent | 5b6ff35d33cb0310c36f9081b9e39cd016715e9c (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.h | 5 | ||||
-rw-r--r-- | arch/mips/include/asm/netlogic/xlp-hal/sys.h | 31 | ||||
-rw-r--r-- | arch/mips/include/asm/netlogic/xlr/pic.h | 2 | ||||
-rw-r--r-- | arch/mips/netlogic/common/time.c | 3 | ||||
-rw-r--r-- | arch/mips/netlogic/xlp/nlm_hal.c | 123 |
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 */ |
219 | static inline int | 220 | static inline int |
220 | nlm_pic_read_irt(uint64_t base, int irt_index) | 221 | nlm_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 | ||
157 | unsigned 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 | ||
97 | void __init plat_time_init(void) | 98 | void __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 | */ | ||
151 | static 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 | |||
241 | unsigned 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 | |||
142 | unsigned int nlm_get_cpu_frequency(void) | 249 | unsigned int nlm_get_cpu_frequency(void) |
143 | { | 250 | { |
144 | return nlm_get_core_frequency(0, 0); | 251 | return nlm_get_core_frequency(0, 0); |