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() & MIPS_EBASE_BASE; 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_NAND_IRQ: 95 return 151; 96 case PIC_SPI_IRQ: 97 return 152; 98 case PIC_MMC_IRQ: 99 return 153; 100 case PIC_PCIE_LINK_LEGACY_IRQ(0): 101 case PIC_PCIE_LINK_LEGACY_IRQ(1): 102 case PIC_PCIE_LINK_LEGACY_IRQ(2): 103 case PIC_PCIE_LINK_LEGACY_IRQ(3): 104 return 191 + irq - PIC_PCIE_LINK_LEGACY_IRQ_BASE; 105 } 106 return -1; 107} 108 109static int xlp_irq_to_irt(int irq) 110{ 111 uint64_t pcibase; 112 int devoff, irt; 113 114 devoff = 0; 115 switch (irq) { 116 case PIC_UART_0_IRQ: 117 devoff = XLP_IO_UART0_OFFSET(0); 118 break; 119 case PIC_UART_1_IRQ: 120 devoff = XLP_IO_UART1_OFFSET(0); 121 break; 122 case PIC_MMC_IRQ: 123 devoff = XLP_IO_MMC_OFFSET(0); 124 break; 125 case PIC_I2C_0_IRQ: /* I2C will be fixed up */ 126 case PIC_I2C_1_IRQ: 127 case PIC_I2C_2_IRQ: 128 case PIC_I2C_3_IRQ: 129 if (cpu_is_xlpii()) 130 devoff = XLP2XX_IO_I2C_OFFSET(0); 131 else 132 devoff = XLP_IO_I2C0_OFFSET(0); 133 break; 134 case PIC_SATA_IRQ: 135 devoff = XLP_IO_SATA_OFFSET(0); 136 break; 137 case PIC_GPIO_IRQ: 138 devoff = XLP_IO_GPIO_OFFSET(0); 139 break; 140 case PIC_NAND_IRQ: 141 devoff = XLP_IO_NAND_OFFSET(0); 142 break; 143 case PIC_SPI_IRQ: 144 devoff = XLP_IO_SPI_OFFSET(0); 145 break; 146 default: 147 if (cpu_is_xlpii()) { 148 switch (irq) { 149 /* XLP2XX has three XHCI USB controller */ 150 case PIC_2XX_XHCI_0_IRQ: 151 devoff = XLP2XX_IO_USB_XHCI0_OFFSET(0); 152 break; 153 case PIC_2XX_XHCI_1_IRQ: 154 devoff = XLP2XX_IO_USB_XHCI1_OFFSET(0); 155 break; 156 case PIC_2XX_XHCI_2_IRQ: 157 devoff = XLP2XX_IO_USB_XHCI2_OFFSET(0); 158 break; 159 } 160 } else { 161 switch (irq) { 162 case PIC_EHCI_0_IRQ: 163 devoff = XLP_IO_USB_EHCI0_OFFSET(0); 164 break; 165 case PIC_EHCI_1_IRQ: 166 devoff = XLP_IO_USB_EHCI1_OFFSET(0); 167 break; 168 case PIC_OHCI_0_IRQ: 169 devoff = XLP_IO_USB_OHCI0_OFFSET(0); 170 break; 171 case PIC_OHCI_1_IRQ: 172 devoff = XLP_IO_USB_OHCI1_OFFSET(0); 173 break; 174 case PIC_OHCI_2_IRQ: 175 devoff = XLP_IO_USB_OHCI2_OFFSET(0); 176 break; 177 case PIC_OHCI_3_IRQ: 178 devoff = XLP_IO_USB_OHCI3_OFFSET(0); 179 break; 180 } 181 } 182 } 183 184 if (devoff != 0) { 185 uint32_t val; 186 187 pcibase = nlm_pcicfg_base(devoff); 188 val = nlm_read_reg(pcibase, XLP_PCI_IRTINFO_REG); 189 if (val == 0xffffffff) { 190 irt = -1; 191 } else { 192 irt = val & 0xffff; 193 /* HW weirdness, I2C IRT entry has to be fixed up */ 194 switch (irq) { 195 case PIC_I2C_1_IRQ: 196 irt = irt + 1; break; 197 case PIC_I2C_2_IRQ: 198 irt = irt + 2; break; 199 case PIC_I2C_3_IRQ: 200 irt = irt + 3; break; 201 } 202 } 203 } else if (irq >= PIC_PCIE_LINK_LEGACY_IRQ(0) && 204 irq <= PIC_PCIE_LINK_LEGACY_IRQ(3)) { 205 /* HW bug, PCI IRT entries are bad on early silicon, fix */ 206 irt = PIC_IRT_PCIE_LINK_INDEX(irq - 207 PIC_PCIE_LINK_LEGACY_IRQ_BASE); 208 } else { 209 irt = -1; 210 } 211 return irt; 212} 213 214int nlm_irq_to_irt(int irq) 215{ 216 /* return -2 for irqs without 1-1 mapping */ 217 if (irq >= PIC_PCIE_LINK_MSI_IRQ(0) && irq <= PIC_PCIE_LINK_MSI_IRQ(3)) 218 return -2; 219 if (irq >= PIC_PCIE_MSIX_IRQ(0) && irq <= PIC_PCIE_MSIX_IRQ(3)) 220 return -2; 221 222 if (cpu_is_xlp9xx()) 223 return xlp9xx_irq_to_irt(irq); 224 else 225 return xlp_irq_to_irt(irq); 226} 227 228static unsigned int nlm_xlp2_get_core_frequency(int node, int core) 229{ 230 unsigned int pll_post_div, ctrl_val0, ctrl_val1, denom; 231 uint64_t num, sysbase, clockbase; 232 233 if (cpu_is_xlp9xx()) { 234 clockbase = nlm_get_clock_regbase(node); 235 ctrl_val0 = nlm_read_sys_reg(clockbase, 236 SYS_9XX_CPU_PLL_CTRL0(core)); 237 ctrl_val1 = nlm_read_sys_reg(clockbase, 238 SYS_9XX_CPU_PLL_CTRL1(core)); 239 } else { 240 sysbase = nlm_get_node(node)->sysbase; 241 ctrl_val0 = nlm_read_sys_reg(sysbase, 242 SYS_CPU_PLL_CTRL0(core)); 243 ctrl_val1 = nlm_read_sys_reg(sysbase, 244 SYS_CPU_PLL_CTRL1(core)); 245 } 246 247 /* Find PLL post divider value */ 248 switch ((ctrl_val0 >> 24) & 0x7) { 249 case 1: 250 pll_post_div = 2; 251 break; 252 case 3: 253 pll_post_div = 4; 254 break; 255 case 7: 256 pll_post_div = 8; 257 break; 258 case 6: 259 pll_post_div = 16; 260 break; 261 case 0: 262 default: 263 pll_post_div = 1; 264 break; 265 } 266 267 num = 1000000ULL * (400 * 3 + 100 * (ctrl_val1 & 0x3f)); 268 denom = 3 * pll_post_div; 269 do_div(num, denom); 270 271 return (unsigned int)num; 272} 273 274static unsigned int nlm_xlp_get_core_frequency(int node, int core) 275{ 276 unsigned int pll_divf, pll_divr, dfs_div, ext_div; 277 unsigned int rstval, dfsval, denom; 278 uint64_t num, sysbase; 279 280 sysbase = nlm_get_node(node)->sysbase; 281 rstval = nlm_read_sys_reg(sysbase, SYS_POWER_ON_RESET_CFG); 282 dfsval = nlm_read_sys_reg(sysbase, SYS_CORE_DFS_DIV_VALUE); 283 pll_divf = ((rstval >> 10) & 0x7f) + 1; 284 pll_divr = ((rstval >> 8) & 0x3) + 1; 285 ext_div = ((rstval >> 30) & 0x3) + 1; 286 dfs_div = ((dfsval >> (core * 4)) & 0xf) + 1; 287 288 num = 800000000ULL * pll_divf; 289 denom = 3 * pll_divr * ext_div * dfs_div; 290 do_div(num, denom); 291 292 return (unsigned int)num; 293} 294 295unsigned int nlm_get_core_frequency(int node, int core) 296{ 297 if (cpu_is_xlpii()) 298 return nlm_xlp2_get_core_frequency(node, core); 299 else 300 return nlm_xlp_get_core_frequency(node, core); 301} 302 303/* 304 * Calculate PIC frequency from PLL registers. 305 * freq_out = (ref_freq/2 * (6 + ctrl2[7:0]) + ctrl2[20:8]/2^13) / 306 * ((2^ctrl0[7:5]) * Table(ctrl0[26:24])) 307 */ 308static unsigned int nlm_xlp2_get_pic_frequency(int node) 309{ 310 u32 ctrl_val0, ctrl_val2, vco_post_div, pll_post_div, cpu_xlp9xx; 311 u32 mdiv, fdiv, pll_out_freq_den, reg_select, ref_div, pic_div; 312 u64 sysbase, pll_out_freq_num, ref_clk_select, clockbase, ref_clk; 313 314 sysbase = nlm_get_node(node)->sysbase; 315 clockbase = nlm_get_clock_regbase(node); 316 cpu_xlp9xx = cpu_is_xlp9xx(); 317 318 /* Find ref_clk_base */ 319 if (cpu_xlp9xx) 320 ref_clk_select = (nlm_read_sys_reg(sysbase, 321 SYS_9XX_POWER_ON_RESET_CFG) >> 18) & 0x3; 322 else 323 ref_clk_select = (nlm_read_sys_reg(sysbase, 324 SYS_POWER_ON_RESET_CFG) >> 18) & 0x3; 325 switch (ref_clk_select) { 326 case 0: 327 ref_clk = 200000000ULL; 328 ref_div = 3; 329 break; 330 case 1: 331 ref_clk = 100000000ULL; 332 ref_div = 1; 333 break; 334 case 2: 335 ref_clk = 125000000ULL; 336 ref_div = 1; 337 break; 338 case 3: 339 ref_clk = 400000000ULL; 340 ref_div = 3; 341 break; 342 } 343 344 /* Find the clock source PLL device for PIC */ 345 if (cpu_xlp9xx) { 346 reg_select = nlm_read_sys_reg(clockbase, 347 SYS_9XX_CLK_DEV_SEL_REG) & 0x3; 348 switch (reg_select) { 349 case 0: 350 ctrl_val0 = nlm_read_sys_reg(clockbase, 351 SYS_9XX_PLL_CTRL0); 352 ctrl_val2 = nlm_read_sys_reg(clockbase, 353 SYS_9XX_PLL_CTRL2); 354 break; 355 case 1: 356 ctrl_val0 = nlm_read_sys_reg(clockbase, 357 SYS_9XX_PLL_CTRL0_DEVX(0)); 358 ctrl_val2 = nlm_read_sys_reg(clockbase, 359 SYS_9XX_PLL_CTRL2_DEVX(0)); 360 break; 361 case 2: 362 ctrl_val0 = nlm_read_sys_reg(clockbase, 363 SYS_9XX_PLL_CTRL0_DEVX(1)); 364 ctrl_val2 = nlm_read_sys_reg(clockbase, 365 SYS_9XX_PLL_CTRL2_DEVX(1)); 366 break; 367 case 3: 368 ctrl_val0 = nlm_read_sys_reg(clockbase, 369 SYS_9XX_PLL_CTRL0_DEVX(2)); 370 ctrl_val2 = nlm_read_sys_reg(clockbase, 371 SYS_9XX_PLL_CTRL2_DEVX(2)); 372 break; 373 } 374 } else { 375 reg_select = (nlm_read_sys_reg(sysbase, 376 SYS_CLK_DEV_SEL_REG) >> 22) & 0x3; 377 switch (reg_select) { 378 case 0: 379 ctrl_val0 = nlm_read_sys_reg(sysbase, 380 SYS_PLL_CTRL0); 381 ctrl_val2 = nlm_read_sys_reg(sysbase, 382 SYS_PLL_CTRL2); 383 break; 384 case 1: 385 ctrl_val0 = nlm_read_sys_reg(sysbase, 386 SYS_PLL_CTRL0_DEVX(0)); 387 ctrl_val2 = nlm_read_sys_reg(sysbase, 388 SYS_PLL_CTRL2_DEVX(0)); 389 break; 390 case 2: 391 ctrl_val0 = nlm_read_sys_reg(sysbase, 392 SYS_PLL_CTRL0_DEVX(1)); 393 ctrl_val2 = nlm_read_sys_reg(sysbase, 394 SYS_PLL_CTRL2_DEVX(1)); 395 break; 396 case 3: 397 ctrl_val0 = nlm_read_sys_reg(sysbase, 398 SYS_PLL_CTRL0_DEVX(2)); 399 ctrl_val2 = nlm_read_sys_reg(sysbase, 400 SYS_PLL_CTRL2_DEVX(2)); 401 break; 402 } 403 } 404 405 vco_post_div = (ctrl_val0 >> 5) & 0x7; 406 pll_post_div = (ctrl_val0 >> 24) & 0x7; 407 mdiv = ctrl_val2 & 0xff; 408 fdiv = (ctrl_val2 >> 8) & 0x1fff; 409 410 /* Find PLL post divider value */ 411 switch (pll_post_div) { 412 case 1: 413 pll_post_div = 2; 414 break; 415 case 3: 416 pll_post_div = 4; 417 break; 418 case 7: 419 pll_post_div = 8; 420 break; 421 case 6: 422 pll_post_div = 16; 423 break; 424 case 0: 425 default: 426 pll_post_div = 1; 427 break; 428 } 429 430 fdiv = fdiv/(1 << 13); 431 pll_out_freq_num = ((ref_clk >> 1) * (6 + mdiv)) + fdiv; 432 pll_out_freq_den = (1 << vco_post_div) * pll_post_div * ref_div; 433 434 if (pll_out_freq_den > 0) 435 do_div(pll_out_freq_num, pll_out_freq_den); 436 437 /* PIC post divider, which happens after PLL */ 438 if (cpu_xlp9xx) 439 pic_div = nlm_read_sys_reg(clockbase, 440 SYS_9XX_CLK_DEV_DIV_REG) & 0x3; 441 else 442 pic_div = (nlm_read_sys_reg(sysbase, 443 SYS_CLK_DEV_DIV_REG) >> 22) & 0x3; 444 do_div(pll_out_freq_num, 1 << pic_div); 445 446 return pll_out_freq_num; 447} 448 449unsigned int nlm_get_pic_frequency(int node) 450{ 451 if (cpu_is_xlpii()) 452 return nlm_xlp2_get_pic_frequency(node); 453 else 454 return 133333333; 455} 456 457unsigned int nlm_get_cpu_frequency(void) 458{ 459 return nlm_get_core_frequency(0, 0); 460} 461 462/* 463 * Fills upto 8 pairs of entries containing the DRAM map of a node 464 * if node < 0, get dram map for all nodes 465 */ 466int nlm_get_dram_map(int node, uint64_t *dram_map, int nentries) 467{ 468 uint64_t bridgebase, base, lim; 469 uint32_t val; 470 unsigned int barreg, limreg, xlatreg; 471 int i, n, rv; 472 473 /* Look only at mapping on Node 0, we don't handle crazy configs */ 474 bridgebase = nlm_get_bridge_regbase(0); 475 rv = 0; 476 for (i = 0; i < 8; i++) { 477 if (rv + 1 >= nentries) 478 break; 479 if (cpu_is_xlp9xx()) { 480 barreg = BRIDGE_9XX_DRAM_BAR(i); 481 limreg = BRIDGE_9XX_DRAM_LIMIT(i); 482 xlatreg = BRIDGE_9XX_DRAM_NODE_TRANSLN(i); 483 } else { 484 barreg = BRIDGE_DRAM_BAR(i); 485 limreg = BRIDGE_DRAM_LIMIT(i); 486 xlatreg = BRIDGE_DRAM_NODE_TRANSLN(i); 487 } 488 if (node >= 0) { 489 /* node specified, get node mapping of BAR */ 490 val = nlm_read_bridge_reg(bridgebase, xlatreg); 491 n = (val >> 1) & 0x3; 492 if (n != node) 493 continue; 494 } 495 val = nlm_read_bridge_reg(bridgebase, barreg); 496 val = (val >> 12) & 0xfffff; 497 base = (uint64_t) val << 20; 498 val = nlm_read_bridge_reg(bridgebase, limreg); 499 val = (val >> 12) & 0xfffff; 500 if (val == 0) /* BAR not used */ 501 continue; 502 lim = ((uint64_t)val + 1) << 20; 503 dram_map[rv] = base; 504 dram_map[rv + 1] = lim; 505 rv += 2; 506 } 507 return rv; 508} 509