aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/netlogic/xlp/nlm_hal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/netlogic/xlp/nlm_hal.c')
-rw-r--r--arch/mips/netlogic/xlp/nlm_hal.c283
1 files changed, 204 insertions, 79 deletions
diff --git a/arch/mips/netlogic/xlp/nlm_hal.c b/arch/mips/netlogic/xlp/nlm_hal.c
index 997cd9ee10de..bc24beb3a426 100644
--- a/arch/mips/netlogic/xlp/nlm_hal.c
+++ b/arch/mips/netlogic/xlp/nlm_hal.c
@@ -54,6 +54,8 @@ void nlm_node_init(int node)
54 struct nlm_soc_info *nodep; 54 struct nlm_soc_info *nodep;
55 55
56 nodep = nlm_get_node(node); 56 nodep = nlm_get_node(node);
57 if (node == 0)
58 nodep->coremask = 1; /* node 0, boot cpu */
57 nodep->sysbase = nlm_get_sys_regbase(node); 59 nodep->sysbase = nlm_get_sys_regbase(node);
58 nodep->picbase = nlm_get_pic_regbase(node); 60 nodep->picbase = nlm_get_pic_regbase(node);
59 nodep->ebase = read_c0_ebase() & (~((1 << 12) - 1)); 61 nodep->ebase = read_c0_ebase() & (~((1 << 12) - 1));
@@ -64,31 +66,39 @@ void nlm_node_init(int node)
64 spin_lock_init(&nodep->piclock); 66 spin_lock_init(&nodep->piclock);
65} 67}
66 68
67int nlm_irq_to_irt(int irq) 69static int xlp9xx_irq_to_irt(int irq)
70{
71 switch (irq) {
72 case PIC_GPIO_IRQ:
73 return 12;
74 case PIC_9XX_XHCI_0_IRQ:
75 return 114;
76 case PIC_9XX_XHCI_1_IRQ:
77 return 115;
78 case PIC_UART_0_IRQ:
79 return 133;
80 case PIC_UART_1_IRQ:
81 return 134;
82 case PIC_SATA_IRQ:
83 return 143;
84 case PIC_SPI_IRQ:
85 return 152;
86 case PIC_MMC_IRQ:
87 return 153;
88 case PIC_PCIE_LINK_LEGACY_IRQ(0):
89 case PIC_PCIE_LINK_LEGACY_IRQ(1):
90 case PIC_PCIE_LINK_LEGACY_IRQ(2):
91 case PIC_PCIE_LINK_LEGACY_IRQ(3):
92 return 191 + irq - PIC_PCIE_LINK_LEGACY_IRQ_BASE;
93 }
94 return -1;
95}
96
97static int xlp_irq_to_irt(int irq)
68{ 98{
69 uint64_t pcibase; 99 uint64_t pcibase;
70 int devoff, irt; 100 int devoff, irt;
71 101
72 /* bypass for 9xx */
73 if (cpu_is_xlp9xx()) {
74 switch (irq) {
75 case PIC_9XX_XHCI_0_IRQ:
76 return 114;
77 case PIC_9XX_XHCI_1_IRQ:
78 return 115;
79 case PIC_UART_0_IRQ:
80 return 133;
81 case PIC_UART_1_IRQ:
82 return 134;
83 case PIC_PCIE_LINK_LEGACY_IRQ(0):
84 case PIC_PCIE_LINK_LEGACY_IRQ(1):
85 case PIC_PCIE_LINK_LEGACY_IRQ(2):
86 case PIC_PCIE_LINK_LEGACY_IRQ(3):
87 return 191 + irq - PIC_PCIE_LINK_LEGACY_IRQ_BASE;
88 }
89 return -1;
90 }
91
92 devoff = 0; 102 devoff = 0;
93 switch (irq) { 103 switch (irq) {
94 case PIC_UART_0_IRQ: 104 case PIC_UART_0_IRQ:
@@ -98,7 +108,7 @@ int nlm_irq_to_irt(int irq)
98 devoff = XLP_IO_UART1_OFFSET(0); 108 devoff = XLP_IO_UART1_OFFSET(0);
99 break; 109 break;
100 case PIC_MMC_IRQ: 110 case PIC_MMC_IRQ:
101 devoff = XLP_IO_SD_OFFSET(0); 111 devoff = XLP_IO_MMC_OFFSET(0);
102 break; 112 break;
103 case PIC_I2C_0_IRQ: /* I2C will be fixed up */ 113 case PIC_I2C_0_IRQ: /* I2C will be fixed up */
104 case PIC_I2C_1_IRQ: 114 case PIC_I2C_1_IRQ:
@@ -109,6 +119,18 @@ int nlm_irq_to_irt(int irq)
109 else 119 else
110 devoff = XLP_IO_I2C0_OFFSET(0); 120 devoff = XLP_IO_I2C0_OFFSET(0);
111 break; 121 break;
122 case PIC_SATA_IRQ:
123 devoff = XLP_IO_SATA_OFFSET(0);
124 break;
125 case PIC_GPIO_IRQ:
126 devoff = XLP_IO_GPIO_OFFSET(0);
127 break;
128 case PIC_NAND_IRQ:
129 devoff = XLP_IO_NAND_OFFSET(0);
130 break;
131 case PIC_SPI_IRQ:
132 devoff = XLP_IO_SPI_OFFSET(0);
133 break;
112 default: 134 default:
113 if (cpu_is_xlpii()) { 135 if (cpu_is_xlpii()) {
114 switch (irq) { 136 switch (irq) {
@@ -164,61 +186,123 @@ int nlm_irq_to_irt(int irq)
164 /* HW bug, PCI IRT entries are bad on early silicon, fix */ 186 /* HW bug, PCI IRT entries are bad on early silicon, fix */
165 irt = PIC_IRT_PCIE_LINK_INDEX(irq - 187 irt = PIC_IRT_PCIE_LINK_INDEX(irq -
166 PIC_PCIE_LINK_LEGACY_IRQ_BASE); 188 PIC_PCIE_LINK_LEGACY_IRQ_BASE);
167 } else if (irq >= PIC_PCIE_LINK_MSI_IRQ(0) &&
168 irq <= PIC_PCIE_LINK_MSI_IRQ(3)) {
169 irt = -2;
170 } else if (irq >= PIC_PCIE_MSIX_IRQ(0) &&
171 irq <= PIC_PCIE_MSIX_IRQ(3)) {
172 irt = -2;
173 } else { 189 } else {
174 irt = -1; 190 irt = -1;
175 } 191 }
176 return irt; 192 return irt;
177} 193}
178 194
179unsigned int nlm_get_core_frequency(int node, int core) 195int nlm_irq_to_irt(int irq)
180{ 196{
181 unsigned int pll_divf, pll_divr, dfs_div, ext_div; 197 /* return -2 for irqs without 1-1 mapping */
182 unsigned int rstval, dfsval, denom; 198 if (irq >= PIC_PCIE_LINK_MSI_IRQ(0) && irq <= PIC_PCIE_LINK_MSI_IRQ(3))
183 uint64_t num, sysbase; 199 return -2;
200 if (irq >= PIC_PCIE_MSIX_IRQ(0) && irq <= PIC_PCIE_MSIX_IRQ(3))
201 return -2;
184 202
185 sysbase = nlm_get_node(node)->sysbase;
186 if (cpu_is_xlp9xx()) 203 if (cpu_is_xlp9xx())
187 rstval = nlm_read_sys_reg(sysbase, SYS_9XX_POWER_ON_RESET_CFG); 204 return xlp9xx_irq_to_irt(irq);
188 else 205 else
189 rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG); 206 return xlp_irq_to_irt(irq);
190 if (cpu_is_xlpii()) { 207}
191 num = 1000000ULL * (400 * 3 + 100 * (rstval >> 26)); 208
192 denom = 3; 209static unsigned int nlm_xlp2_get_core_frequency(int node, int core)
210{
211 unsigned int pll_post_div, ctrl_val0, ctrl_val1, denom;
212 uint64_t num, sysbase, clockbase;
213
214 if (cpu_is_xlp9xx()) {
215 clockbase = nlm_get_clock_regbase(node);
216 ctrl_val0 = nlm_read_sys_reg(clockbase,
217 SYS_9XX_CPU_PLL_CTRL0(core));
218 ctrl_val1 = nlm_read_sys_reg(clockbase,
219 SYS_9XX_CPU_PLL_CTRL1(core));
193 } else { 220 } else {
194 dfsval = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIV_VALUE); 221 sysbase = nlm_get_node(node)->sysbase;
195 pll_divf = ((rstval >> 10) & 0x7f) + 1; 222 ctrl_val0 = nlm_read_sys_reg(sysbase,
196 pll_divr = ((rstval >> 8) & 0x3) + 1; 223 SYS_CPU_PLL_CTRL0(core));
197 ext_div = ((rstval >> 30) & 0x3) + 1; 224 ctrl_val1 = nlm_read_sys_reg(sysbase,
198 dfs_div = ((dfsval >> (core * 4)) & 0xf) + 1; 225 SYS_CPU_PLL_CTRL1(core));
199 226 }
200 num = 800000000ULL * pll_divf; 227
201 denom = 3 * pll_divr * ext_div * dfs_div; 228 /* Find PLL post divider value */
229 switch ((ctrl_val0 >> 24) & 0x7) {
230 case 1:
231 pll_post_div = 2;
232 break;
233 case 3:
234 pll_post_div = 4;
235 break;
236 case 7:
237 pll_post_div = 8;
238 break;
239 case 6:
240 pll_post_div = 16;
241 break;
242 case 0:
243 default:
244 pll_post_div = 1;
245 break;
202 } 246 }
247
248 num = 1000000ULL * (400 * 3 + 100 * (ctrl_val1 & 0x3f));
249 denom = 3 * pll_post_div;
203 do_div(num, denom); 250 do_div(num, denom);
251
204 return (unsigned int)num; 252 return (unsigned int)num;
205} 253}
206 254
207/* Calculate Frequency to the PIC from PLL. 255static unsigned int nlm_xlp_get_core_frequency(int node, int core)
208 * freq_out = ( ref_freq/2 * (6 + ctrl2[7:0]) + ctrl2[20:8]/2^13 ) / 256{
209 * ((2^ctrl0[7:5]) * Table(ctrl0[26:24])) 257 unsigned int pll_divf, pll_divr, dfs_div, ext_div;
258 unsigned int rstval, dfsval, denom;
259 uint64_t num, sysbase;
260
261 sysbase = nlm_get_node(node)->sysbase;
262 rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG);
263 dfsval = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIV_VALUE);
264 pll_divf = ((rstval >> 10) & 0x7f) + 1;
265 pll_divr = ((rstval >> 8) & 0x3) + 1;
266 ext_div = ((rstval >> 30) & 0x3) + 1;
267 dfs_div = ((dfsval >> (core * 4)) & 0xf) + 1;
268
269 num = 800000000ULL * pll_divf;
270 denom = 3 * pll_divr * ext_div * dfs_div;
271 do_div(num, denom);
272
273 return (unsigned int)num;
274}
275
276unsigned int nlm_get_core_frequency(int node, int core)
277{
278 if (cpu_is_xlpii())
279 return nlm_xlp2_get_core_frequency(node, core);
280 else
281 return nlm_xlp_get_core_frequency(node, core);
282}
283
284/*
285 * Calculate PIC frequency from PLL registers.
286 * freq_out = (ref_freq/2 * (6 + ctrl2[7:0]) + ctrl2[20:8]/2^13) /
287 * ((2^ctrl0[7:5]) * Table(ctrl0[26:24]))
210 */ 288 */
211static unsigned int nlm_2xx_get_pic_frequency(int node) 289static unsigned int nlm_xlp2_get_pic_frequency(int node)
212{ 290{
213 u32 ctrl_val0, ctrl_val2, vco_post_div, pll_post_div; 291 u32 ctrl_val0, ctrl_val2, vco_post_div, pll_post_div, cpu_xlp9xx;
214 u32 mdiv, fdiv, pll_out_freq_den, reg_select, ref_div, pic_div; 292 u32 mdiv, fdiv, pll_out_freq_den, reg_select, ref_div, pic_div;
215 u64 ref_clk, sysbase, pll_out_freq_num, ref_clk_select; 293 u64 sysbase, pll_out_freq_num, ref_clk_select, clockbase, ref_clk;
216 294
217 sysbase = nlm_get_node(node)->sysbase; 295 sysbase = nlm_get_node(node)->sysbase;
296 clockbase = nlm_get_clock_regbase(node);
297 cpu_xlp9xx = cpu_is_xlp9xx();
218 298
219 /* Find ref_clk_base */ 299 /* Find ref_clk_base */
220 ref_clk_select = 300 if (cpu_xlp9xx)
221 (nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG) >> 18) & 0x3; 301 ref_clk_select = (nlm_read_sys_reg(sysbase,
302 SYS_9XX_POWER_ON_RESET_CFG) >> 18) & 0x3;
303 else
304 ref_clk_select = (nlm_read_sys_reg(sysbase,
305 SYS_POWER_ON_RESET_CFG) >> 18) & 0x3;
222 switch (ref_clk_select) { 306 switch (ref_clk_select) {
223 case 0: 307 case 0:
224 ref_clk = 200000000ULL; 308 ref_clk = 200000000ULL;
@@ -239,30 +323,70 @@ static unsigned int nlm_2xx_get_pic_frequency(int node)
239 } 323 }
240 324
241 /* Find the clock source PLL device for PIC */ 325 /* Find the clock source PLL device for PIC */
242 reg_select = (nlm_read_sys_reg(sysbase, SYS_CLK_DEV_SEL) >> 22) & 0x3; 326 if (cpu_xlp9xx) {
243 switch (reg_select) { 327 reg_select = nlm_read_sys_reg(clockbase,
244 case 0: 328 SYS_9XX_CLK_DEV_SEL) & 0x3;
245 ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0); 329 switch (reg_select) {
246 ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2); 330 case 0:
247 break; 331 ctrl_val0 = nlm_read_sys_reg(clockbase,
248 case 1: 332 SYS_9XX_PLL_CTRL0);
249 ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0_DEVX(0)); 333 ctrl_val2 = nlm_read_sys_reg(clockbase,
250 ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2_DEVX(0)); 334 SYS_9XX_PLL_CTRL2);
251 break; 335 break;
252 case 2: 336 case 1:
253 ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0_DEVX(1)); 337 ctrl_val0 = nlm_read_sys_reg(clockbase,
254 ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2_DEVX(1)); 338 SYS_9XX_PLL_CTRL0_DEVX(0));
255 break; 339 ctrl_val2 = nlm_read_sys_reg(clockbase,
256 case 3: 340 SYS_9XX_PLL_CTRL2_DEVX(0));
257 ctrl_val0 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL0_DEVX(2)); 341 break;
258 ctrl_val2 = nlm_read_sys_reg(sysbase, SYS_PLL_CTRL2_DEVX(2)); 342 case 2:
259 break; 343 ctrl_val0 = nlm_read_sys_reg(clockbase,
344 SYS_9XX_PLL_CTRL0_DEVX(1));
345 ctrl_val2 = nlm_read_sys_reg(clockbase,
346 SYS_9XX_PLL_CTRL2_DEVX(1));
347 break;
348 case 3:
349 ctrl_val0 = nlm_read_sys_reg(clockbase,
350 SYS_9XX_PLL_CTRL0_DEVX(2));
351 ctrl_val2 = nlm_read_sys_reg(clockbase,
352 SYS_9XX_PLL_CTRL2_DEVX(2));
353 break;
354 }
355 } else {
356 reg_select = (nlm_read_sys_reg(sysbase,
357 SYS_CLK_DEV_SEL) >> 22) & 0x3;
358 switch (reg_select) {
359 case 0:
360 ctrl_val0 = nlm_read_sys_reg(sysbase,
361 SYS_PLL_CTRL0);
362 ctrl_val2 = nlm_read_sys_reg(sysbase,
363 SYS_PLL_CTRL2);
364 break;
365 case 1:
366 ctrl_val0 = nlm_read_sys_reg(sysbase,
367 SYS_PLL_CTRL0_DEVX(0));
368 ctrl_val2 = nlm_read_sys_reg(sysbase,
369 SYS_PLL_CTRL2_DEVX(0));
370 break;
371 case 2:
372 ctrl_val0 = nlm_read_sys_reg(sysbase,
373 SYS_PLL_CTRL0_DEVX(1));
374 ctrl_val2 = nlm_read_sys_reg(sysbase,
375 SYS_PLL_CTRL2_DEVX(1));
376 break;
377 case 3:
378 ctrl_val0 = nlm_read_sys_reg(sysbase,
379 SYS_PLL_CTRL0_DEVX(2));
380 ctrl_val2 = nlm_read_sys_reg(sysbase,
381 SYS_PLL_CTRL2_DEVX(2));
382 break;
383 }
260 } 384 }
261 385
262 vco_post_div = (ctrl_val0 >> 5) & 0x7; 386 vco_post_div = (ctrl_val0 >> 5) & 0x7;
263 pll_post_div = (ctrl_val0 >> 24) & 0x7; 387 pll_post_div = (ctrl_val0 >> 24) & 0x7;
264 mdiv = ctrl_val2 & 0xff; 388 mdiv = ctrl_val2 & 0xff;
265 fdiv = (ctrl_val2 >> 8) & 0xfff; 389 fdiv = (ctrl_val2 >> 8) & 0x1fff;
266 390
267 /* Find PLL post divider value */ 391 /* Find PLL post divider value */
268 switch (pll_post_div) { 392 switch (pll_post_div) {
@@ -292,7 +416,12 @@ static unsigned int nlm_2xx_get_pic_frequency(int node)
292 do_div(pll_out_freq_num, pll_out_freq_den); 416 do_div(pll_out_freq_num, pll_out_freq_den);
293 417
294 /* PIC post divider, which happens after PLL */ 418 /* PIC post divider, which happens after PLL */
295 pic_div = (nlm_read_sys_reg(sysbase, SYS_CLK_DEV_DIV) >> 22) & 0x3; 419 if (cpu_xlp9xx)
420 pic_div = nlm_read_sys_reg(clockbase,
421 SYS_9XX_CLK_DEV_DIV) & 0x3;
422 else
423 pic_div = (nlm_read_sys_reg(sysbase,
424 SYS_CLK_DEV_DIV) >> 22) & 0x3;
296 do_div(pll_out_freq_num, 1 << pic_div); 425 do_div(pll_out_freq_num, 1 << pic_div);
297 426
298 return pll_out_freq_num; 427 return pll_out_freq_num;
@@ -300,12 +429,8 @@ static unsigned int nlm_2xx_get_pic_frequency(int node)
300 429
301unsigned int nlm_get_pic_frequency(int node) 430unsigned int nlm_get_pic_frequency(int node)
302{ 431{
303 /* TODO Has to calculate freq as like 2xx */
304 if (cpu_is_xlp9xx())
305 return 250000000;
306
307 if (cpu_is_xlpii()) 432 if (cpu_is_xlpii())
308 return nlm_2xx_get_pic_frequency(node); 433 return nlm_xlp2_get_pic_frequency(node);
309 else 434 else
310 return 133333333; 435 return 133333333;
311} 436}