1/* 2 * Copyright 2003-2011 NetLogic Microsystems, Inc. (NetLogic). All rights 3 * reserved. 4 * 5 * This software is available to you under a choice of one of two 6 * licenses. You may choose to be licensed under the terms of the GNU 7 * General Public License (GPL) Version 2, available from the file 8 * COPYING in the main directory of this source tree, or the NetLogic 9 * license below: 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in 19 * the documentation and/or other materials provided with the 20 * distribution. 21 * 22 * THIS SOFTWARE IS PROVIDED BY NETLOGIC ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 24 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL NETLOGIC OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 29 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 30 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 31 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 32 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35#include <linux/types.h> 36#include <linux/kernel.h> 37#include <linux/mm.h> 38#include <linux/delay.h> 39 40#include <asm/mipsregs.h> 41#include <asm/time.h> 42 43#include <asm/netlogic/common.h> 44#include <asm/netlogic/haldefs.h> 45#include <asm/netlogic/xlp-hal/iomap.h> 46#include <asm/netlogic/xlp-hal/xlp.h> 47#include <asm/netlogic/xlp-hal/bridge.h> 48#include <asm/netlogic/xlp-hal/pic.h> 49#include <asm/netlogic/xlp-hal/sys.h> 50 51/* Main initialization */ 52void nlm_node_init(int node) 53{ 54 struct nlm_soc_info *nodep; 55 56 nodep = nlm_get_node(node); 57 if (node == 0) 58 nodep->coremask = 1; /* node 0, boot cpu */ 59 nodep->sysbase = nlm_get_sys_regbase(node); 60 nodep->picbase = nlm_get_pic_regbase(node); 61 nodep->ebase = read_c0_ebase() & (~((1 << 12) - 1)); 62 if (cpu_is_xlp9xx()) 63 nodep->socbus = xlp9xx_get_socbus(node); 64 else 65 nodep->socbus = 0; 66 spin_lock_init(&nodep->piclock); 67} 68 69static int xlp9xx_irq_to_irt(int irq) 70{ 71 switch (irq) { 72 case PIC_GPIO_IRQ: 73 return 12; 74 case PIC_I2C_0_IRQ: 75 return 125; 76 case PIC_I2C_1_IRQ: 77 return 126; 78 case PIC_I2C_2_IRQ: 79 return 127; 80 case PIC_I2C_3_IRQ: 81 return 128; 82 case PIC_9XX_XHCI_0_IRQ: 83 return 114; 84 case PIC_9XX_XHCI_1_IRQ: 85 return 115; 86 case PIC_9XX_XHCI_2_IRQ: 87 return 116; 88 case PIC_UART_0_IRQ: 89 return 133; 90 case PIC_UART_1_IRQ: 91 return 134; 92 case PIC_SATA_IRQ: 93 return 143; 94 case PIC_SPI_IRQ: 95 return 152; 96 case PIC_MMC_IRQ: 97 return 153; 98 case PIC_PCIE_LINK_LEGACY_IRQ(0): 99 case PIC_PCIE_LINK_LEGACY_IRQ(1): 100 case PIC_PCIE_LINK_LEGACY_IRQ(2): 101 case PIC_PCIE_LINK_LEGACY_IRQ(3): 102 return 191 + irq - PIC_PCIE_LINK_LEGACY_IRQ_BASE; 103 } 104 return -1; 105} 106 107static int xlp_irq_to_irt(int irq) 108{ 109 uint64_t pcibase; 110 int devoff, irt; 111 112 devoff = 0; 113 switch (irq) { 114 case PIC_UART_0_IRQ: 115 devoff = XLP_IO_UART0_OFFSET(0); 116 break; 117 case PIC_UART_1_IRQ: 118 devoff = XLP_IO_UART1_OFFSET(0); 119 break; 120 case PIC_MMC_IRQ: 121 devoff = XLP_IO_MMC_OFFSET(0); 122 break; 123 case PIC_I2C_0_IRQ: /* I2C will be fixed up */ 124 case PIC_I2C_1_IRQ: 125 case PIC_I2C_2_IRQ: 126 case PIC_I2C_3_IRQ: 127 if (cpu_is_xlpii()) 128 devoff = XLP2XX_IO_I2C_OFFSET(0); 129 else 130 devoff = XLP_IO_I2C0_OFFSET(0); 131 break; 132 case PIC_SATA_IRQ: 133 devoff = XLP_IO_SATA_OFFSET(0); 134 break; 135 case PIC_GPIO_IRQ: 136 devoff = XLP_IO_GPIO_OFFSET(0); 137 break; 138 case PIC_NAND_IRQ: 139 devoff = XLP_IO_NAND_OFFSET(0); 140 break; 141 case PIC_SPI_IRQ: 142 devoff = XLP_IO_SPI_OFFSET(0); 143 break; 144 default: 145 if (cpu_is_xlpii()) { 146 switch (irq) { 147 /* XLP2XX has three XHCI USB controller */ 148 case PIC_2XX_XHCI_0_IRQ: 149 devoff = XLP2XX_IO_USB_XHCI0_OFFSET(0); 150 break; 151 case PIC_2XX_XHCI_1_IRQ: 152 devoff = XLP2XX_IO_USB_XHCI1_OFFSET(0); 153 break; 154 case PIC_2XX_XHCI_2_IRQ: 155 devoff = XLP2XX_IO_USB_XHCI2_OFFSET(0); 156 break; 157 } 158 } else { 159 switch (irq) { 160 case PIC_EHCI_0_IRQ: 161 devoff = XLP_IO_USB_EHCI0_OFFSET(0); 162 break; 163 case PIC_EHCI_1_IRQ: 164 devoff = XLP_IO_USB_EHCI1_OFFSET(0); 165 break; 166 case PIC_OHCI_0_IRQ: 167 devoff = XLP_IO_USB_OHCI0_OFFSET(0); 168 break; 169 case PIC_OHCI_1_IRQ: 170 devoff = XLP_IO_USB_OHCI1_OFFSET(0); 171 break; 172 case PIC_OHCI_2_IRQ: 173 devoff = XLP_IO_USB_OHCI2_OFFSET(0); 174 break; 175 case PIC_OHCI_3_IRQ: 176 devoff = XLP_IO_USB_OHCI3_OFFSET(0); 177 break; 178 } 179 } 180 } 181 182 if (devoff != 0) { 183 uint32_t val; 184 185 pcibase = nlm_pcicfg_base(devoff); 186 val = nlm_read_reg(pcibase, XLP_PCI_IRTINFO_REG); 187 if (val == 0xffffffff) { 188 irt = -1; 189 } else { 190 irt = val & 0xffff; 191 /* HW weirdness, I2C IRT entry has to be fixed up */ 192 switch (irq) { 193 case PIC_I2C_1_IRQ: 194 irt = irt + 1; break; 195 case PIC_I2C_2_IRQ: 196 irt = irt + 2; break; 197 case PIC_I2C_3_IRQ: 198 irt = irt + 3; break; 199 } 200 } 201 } else if (irq >= PIC_PCIE_LINK_LEGACY_IRQ(0) && 202 irq <= PIC_PCIE_LINK_LEGACY_IRQ(3)) { 203 /* HW bug, PCI IRT entries are bad on early silicon, fix */ 204 irt = PIC_IRT_PCIE_LINK_INDEX(irq - 205 PIC_PCIE_LINK_LEGACY_IRQ_BASE); 206 } else { 207 irt = -1; 208 } 209 return irt; 210} 211 212int nlm_irq_to_irt(int irq) 213{ 214 /* return -2 for irqs without 1-1 mapping */ 215 if (irq >= PIC_PCIE_LINK_MSI_IRQ(0) && irq <= PIC_PCIE_LINK_MSI_IRQ(3)) 216 return -2; 217 if (irq >= PIC_PCIE_MSIX_IRQ(0) && irq <= PIC_PCIE_MSIX_IRQ(3)) 218 return -2; 219 220 if (cpu_is_xlp9xx()) 221 return xlp9xx_irq_to_irt(irq); 222 else 223 return xlp_irq_to_irt(irq); 224} 225 226static unsigned int nlm_xlp2_get_core_frequency(int node, int core) 227{ 228 unsigned int pll_post_div, ctrl_val0, ctrl_val1, denom; 229 uint64_t num, sysbase, clockbase; 230 231 if (cpu_is_xlp9xx()) { 232 clockbase = nlm_get_clock_regbase(node); 233 ctrl_val0 = nlm_read_sys_reg(clockbase, 234 SYS_9XX_CPU_PLL_CTRL0(core)); 235 ctrl_val1 = nlm_read_sys_reg(clockbase, 236 SYS_9XX_CPU_PLL_CTRL1(core)); 237 } else { 238 sysbase = nlm_get_node(node)->sysbase; 239 ctrl_val0 = nlm_read_sys_reg(sysbase, 240 SYS_CPU_PLL_CTRL0(core)); 241 ctrl_val1 = nlm_read_sys_reg(sysbase, 242 SYS_CPU_PLL_CTRL1(core)); 243 } 244 245 /* Find PLL post divider value */ 246 switch ((ctrl_val0 >> 24) & 0x7) { 247 case 1: 248 pll_post_div = 2; 249 break; 250 case 3: 251 pll_post_div = 4; 252 break; 253 case 7: 254 pll_post_div = 8; 255 break; 256 case 6: 257 pll_post_div = 16; 258 break; 259 case 0: 260 default: 261 pll_post_div = 1; 262 break; 263 } 264 265 num = 1000000ULL * (400 * 3 + 100 * (ctrl_val1 & 0x3f)); 266 denom = 3 * pll_post_div; 267 do_div(num, denom); 268 269 return (unsigned int)num; 270} 271 272static unsigned int nlm_xlp_get_core_frequency(int node, int core) 273{ 274 unsigned int pll_divf, pll_divr, dfs_div, ext_div; 275 unsigned int rstval, dfsval, denom; 276 uint64_t num, sysbase; 277 278 sysbase = nlm_get_node(node)->sysbase; 279 rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG); 280 dfsval = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIV_VALUE); 281 pll_divf = ((rstval >> 10) & 0x7f) + 1; 282 pll_divr = ((rstval >> 8) & 0x3) + 1; 283 ext_div = ((rstval >> 30) & 0x3) + 1; 284 dfs_div = ((dfsval >> (core * 4)) & 0xf) + 1; 285 286 num = 800000000ULL * pll_divf; 287 denom = 3 * pll_divr * ext_div * dfs_div; 288 do_div(num, denom); 289 290 return (unsigned int)num; 291} 292 293unsigned int nlm_get_core_frequency(int node, int core) 294{ 295 if (cpu_is_xlpii()) 296 return nlm_xlp2_get_core_frequency(node, core); 297 else 298 return nlm_xlp_get_core_frequency(node, core); 299} 300 301/* 302 * Calculate PIC frequency from PLL registers. 303 * freq_out = (ref_freq/2 * (6 + ctrl2[7:0]) + ctrl2[20:8]/2^13) / 304 * ((2^ctrl0[7:5]) * Table(ctrl0[26:24])) 305 */ 306static unsigned int nlm_xlp2_get_pic_frequency(int node) 307{ 308 u32 ctrl_val0, ctrl_val2, vco_post_div, pll_post_div, cpu_xlp9xx; 309 u32 mdiv, fdiv, pll_out_freq_den, reg_select, ref_div, pic_div; 310 u64 sysbase, pll_out_freq_num, ref_clk_select, clockbase, ref_clk; 311 312 sysbase = nlm_get_node(node)->sysbase; 313 clockbase = nlm_get_clock_regbase(node); 314 cpu_xlp9xx = cpu_is_xlp9xx(); 315 316 /* Find ref_clk_base */ 317 if (cpu_xlp9xx) 318 ref_clk_select = (nlm_read_sys_reg(sysbase, 319 SYS_9XX_POWER_ON_RESET_CFG) >> 18) & 0x3; 320 else 321 ref_clk_select = (nlm_read_sys_reg(sysbase, 322 SYS_POWER_ON_RESET_CFG) >> 18) & 0x3; 323 switch (ref_clk_select) { 324 case 0: 325 ref_clk = 200000000ULL; 326 ref_div = 3; 327 break; 328 case 1: 329 ref_clk = 100000000ULL; 330 ref_div = 1; 331 break; 332 case 2: 333 ref_clk = 125000000ULL; 334 ref_div = 1; 335 break; 336 case 3: 337 ref_clk = 400000000ULL; 338 ref_div = 3; 339 break; 340 } 341 342 /* Find the clock source PLL device for PIC */ 343 if (cpu_xlp9xx) { 344 reg_select = nlm_read_sys_reg(clockbase, 345 SYS_9XX_CLK_DEV_SEL_REG) & 0x3; 346 switch (reg_select) { 347 case 0: 348 ctrl_val0 = nlm_read_sys_reg(clockbase, 349 SYS_9XX_PLL_CTRL0); 350 ctrl_val2 = nlm_read_sys_reg(clockbase, 351 SYS_9XX_PLL_CTRL2); 352 break; 353 case 1: 354 ctrl_val0 = nlm_read_sys_reg(clockbase, 355 SYS_9XX_PLL_CTRL0_DEVX(0)); 356 ctrl_val2 = nlm_read_sys_reg(clockbase, 357 SYS_9XX_PLL_CTRL2_DEVX(0)); 358 break; 359 case 2: 360 ctrl_val0 = nlm_read_sys_reg(clockbase, 361 SYS_9XX_PLL_CTRL0_DEVX(1)); 362 ctrl_val2 = nlm_read_sys_reg(clockbase, 363 SYS_9XX_PLL_CTRL2_DEVX(1)); 364 break; 365 case 3: 366 ctrl_val0 = nlm_read_sys_reg(clockbase, 367 SYS_9XX_PLL_CTRL0_DEVX(2)); 368 ctrl_val2 = nlm_read_sys_reg(clockbase, 369 SYS_9XX_PLL_CTRL2_DEVX(2)); 370 break; 371 } 372 } else { 373 reg_select = (nlm_read_sys_reg(sysbase, 374 SYS_CLK_DEV_SEL_REG) >> 22) & 0x3; 375 switch (reg_select) { 376 case 0: 377 ctrl_val0 = nlm_read_sys_reg(sysbase, 378 SYS_PLL_CTRL0); 379 ctrl_val2 = nlm_read_sys_reg(sysbase, 380 SYS_PLL_CTRL2); 381 break; 382 case 1: 383 ctrl_val0 = nlm_read_sys_reg(sysbase, 384 SYS_PLL_CTRL0_DEVX(0)); 385 ctrl_val2 = nlm_read_sys_reg(sysbase, 386 SYS_PLL_CTRL2_DEVX(0)); 387 break; 388 case 2: 389 ctrl_val0 = nlm_read_sys_reg(sysbase, 390 SYS_PLL_CTRL0_DEVX(1)); 391 ctrl_val2 = nlm_read_sys_reg(sysbase, 392 SYS_PLL_CTRL2_DEVX(1)); 393 break; 394 case 3: 395 ctrl_val0 = nlm_read_sys_reg(sysbase, 396 SYS_PLL_CTRL0_DEVX(2)); 397 ctrl_val2 = nlm_read_sys_reg(sysbase, 398 SYS_PLL_CTRL2_DEVX(2)); 399 break; 400 } 401 } 402 403 vco_post_div = (ctrl_val0 >> 5) & 0x7; 404 pll_post_div = (ctrl_val0 >> 24) & 0x7; 405 mdiv = ctrl_val2 & 0xff; 406 fdiv = (ctrl_val2 >> 8) & 0x1fff; 407 408 /* Find PLL post divider value */ 409 switch (pll_post_div) { 410 case 1: 411 pll_post_div = 2; 412 break; 413 case 3: 414 pll_post_div = 4; 415 break; 416 case 7: 417 pll_post_div = 8; 418 break; 419 case 6: 420 pll_post_div = 16; 421 break; 422 case 0: 423 default: 424 pll_post_div = 1; 425 break; 426 } 427 428 fdiv = fdiv/(1 << 13); 429 pll_out_freq_num = ((ref_clk >> 1) * (6 + mdiv)) + fdiv; 430 pll_out_freq_den = (1 << vco_post_div) * pll_post_div * ref_div; 431 432 if (pll_out_freq_den > 0) 433 do_div(pll_out_freq_num, pll_out_freq_den); 434 435 /* PIC post divider, which happens after PLL */ 436 if (cpu_xlp9xx) 437 pic_div = nlm_read_sys_reg(clockbase, 438 SYS_9XX_CLK_DEV_DIV_REG) & 0x3; 439 else 440 pic_div = (nlm_read_sys_reg(sysbase, 441 SYS_CLK_DEV_DIV_REG) >> 22) & 0x3; 442 do_div(pll_out_freq_num, 1 << pic_div); 443 444 return pll_out_freq_num; 445} 446 447unsigned int nlm_get_pic_frequency(int node) 448{ 449 if (cpu_is_xlpii()) 450 return nlm_xlp2_get_pic_frequency(node); 451 else 452 return 133333333; 453} 454 455unsigned int nlm_get_cpu_frequency(void) 456{ 457 return nlm_get_core_frequency(0, 0); 458} 459 460/* 461 * Fills upto 8 pairs of entries containing the DRAM map of a node 462 * if node < 0, get dram map for all nodes 463 */ 464int nlm_get_dram_map(int node, uint64_t *dram_map, int nentries) 465{ 466 uint64_t bridgebase, base, lim; 467 uint32_t val; 468 unsigned int barreg, limreg, xlatreg; 469 int i, n, rv; 470 471 /* Look only at mapping on Node 0, we don't handle crazy configs */ 472 bridgebase = nlm_get_bridge_regbase(0); 473 rv = 0; 474 for (i = 0; i < 8; i++) { 475 if (rv + 1 >= nentries) 476 break; 477 if (cpu_is_xlp9xx()) { 478 barreg = BRIDGE_9XX_DRAM_BAR(i); 479 limreg = BRIDGE_9XX_DRAM_LIMIT(i); 480 xlatreg = BRIDGE_9XX_DRAM_NODE_TRANSLN(i); 481 } else { 482 barreg = BRIDGE_DRAM_BAR(i); 483 limreg = BRIDGE_DRAM_LIMIT(i); 484 xlatreg = BRIDGE_DRAM_NODE_TRANSLN(i); 485 } 486 if (node >= 0) { 487 /* node specified, get node mapping of BAR */ 488 val = nlm_read_bridge_reg(bridgebase, xlatreg); 489 n = (val >> 1) & 0x3; 490 if (n != node) 491 continue; 492 } 493 val = nlm_read_bridge_reg(bridgebase, barreg); 494 val = (val >> 12) & 0xfffff; 495 base = (uint64_t) val << 20; 496 val = nlm_read_bridge_reg(bridgebase, limreg); 497 val = (val >> 12) & 0xfffff; 498 if (val == 0) /* BAR not used */ 499 continue; 500 lim = ((uint64_t)val + 1) << 20; 501 dram_map[rv] = base; 502 dram_map[rv + 1] = lim; 503 rv += 2; 504 } 505 return rv; 506} 507