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 /arch/mips/netlogic | |
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>
Diffstat (limited to 'arch/mips/netlogic')
-rw-r--r-- | arch/mips/netlogic/common/time.c | 3 | ||||
-rw-r--r-- | arch/mips/netlogic/xlp/nlm_hal.c | 123 |
2 files changed, 117 insertions, 9 deletions
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); |