1/*- 2 * Copyright (C) 2008 MARVELL INTERNATIONAL LTD. 3 * All rights reserved. 4 * 5 * Developed by Semihalf. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of MARVELL nor the names of contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32#include <sys/cdefs.h> 33__FBSDID("$FreeBSD$"); 34 35#include <sys/param.h> 36#include <sys/systm.h> 37#include <sys/bus.h> 38#include <sys/kernel.h> 39 40#include <dev/fdt/fdt_common.h> 41#include <dev/ofw/openfirm.h> 42 43#include <machine/bus.h> 44#include <machine/fdt.h> 45 46#include <arm/mv/mvreg.h> 47#include <arm/mv/mvvar.h> 48#include <arm/mv/mvwin.h> 49 50#define MAX_CPU_WIN 5 51 52#define DEBUG 53#undef DEBUG 54 55#ifdef DEBUG 56#define debugf(fmt, args...) do { printf("%s(): ", __func__); \ 57 printf(fmt,##args); } while (0) 58#else 59#define debugf(fmt, args...) 60#endif 61 62#ifdef DEBUG 63#define MV_DUMP_WIN 1 64#else 65#define MV_DUMP_WIN 0 66#endif 67 68static int win_eth_can_remap(int i); 69 70static int decode_win_cpu_valid(void); 71static int decode_win_usb_valid(void); 72static int decode_win_eth_valid(void); 73static int decode_win_pcie_valid(void); 74static int decode_win_sata_valid(void); 75static int decode_win_cesa_valid(void); 76static int decode_win_idma_valid(void); 77static int decode_win_xor_valid(void); 78 79static void decode_win_cpu_setup(void); 80static void decode_win_usb_setup(u_long); 81static void decode_win_eth_setup(u_long); 82static void decode_win_pcie_setup(u_long); 83static void decode_win_sata_setup(u_long); 84static void decode_win_cesa_setup(u_long); 85static void decode_win_idma_setup(u_long); 86static void decode_win_xor_setup(u_long); 87 88static void decode_win_cesa_dump(u_long); 89static void decode_win_usb_dump(u_long); 90static void decode_win_eth_dump(u_long base); 91static void decode_win_idma_dump(u_long base); 92static void decode_win_xor_dump(u_long base); 93 94static int fdt_get_ranges(const char *, void *, int, int *, int *); 95 96static int win_cpu_from_dt(void); 97static int fdt_win_setup(void); 98 99static uint32_t used_cpu_wins; 100static uint32_t dev_mask = 0; 101static int cpu_wins_no = 0; 102static int eth_port = 0; 103static int usb_port = 0; 104 105static struct decode_win cpu_win_tbl[MAX_CPU_WIN]; 106 107static const struct decode_win *cpu_wins = cpu_win_tbl; 108 109typedef void (*decode_win_setup_t)(u_long); 110typedef void (*dump_win_t)(u_long); 111 112struct soc_node_spec { 113 const char *compat; 114 decode_win_setup_t decode_handler; 115 dump_win_t dump_handler; 116}; 117 118static struct soc_node_spec soc_nodes[] = { 119 { "mrvl,cesa", &decode_win_cesa_setup, &decode_win_cesa_dump }, 120 { "mrvl,ge", &decode_win_eth_setup, &decode_win_eth_dump }, 121 { "mrvl,usb-ehci", &decode_win_usb_setup, &decode_win_usb_dump }, 122 { "mrvl,sata", &decode_win_sata_setup, NULL }, 123 { "mrvl,xor", &decode_win_xor_setup, &decode_win_xor_dump }, 124 { "mrvl,idma", &decode_win_idma_setup, &decode_win_idma_dump }, 125 { "mrvl,pcie", &decode_win_pcie_setup, NULL }, 126 { NULL, NULL, NULL }, 127}; 128 129struct fdt_pm_mask_entry fdt_pm_mask_table[] = { 130 { "mrvl,ge", CPU_PM_CTRL_GE(0) }, 131 { "mrvl,ge", CPU_PM_CTRL_GE(1) }, 132 { "mrvl,usb-ehci", CPU_PM_CTRL_USB(0) }, 133 { "mrvl,usb-ehci", CPU_PM_CTRL_USB(1) }, 134 { "mrvl,usb-ehci", CPU_PM_CTRL_USB(2) }, 135 { "mrvl,cesa", CPU_PM_CTRL_CRYPTO }, 136 { "mrvl,xor", CPU_PM_CTRL_XOR }, 137 { "mrvl,sata", CPU_PM_CTRL_SATA }, 138 139 { NULL, 0 } 140}; 141 142static __inline int 143pm_is_disabled(uint32_t mask) 144{ 145 146 return (soc_power_ctrl_get(mask) == mask ? 0 : 1); 147} 148 149/* 150 * Disable device using power management register. 151 * 1 - Device Power On 152 * 0 - Device Power Off 153 * Mask can be set in loader. 154 * EXAMPLE: 155 * loader> set hw.pm-disable-mask=0x2 156 * 157 * Common mask: 158 * |-------------------------------| 159 * | Device | Kirkwood | Discovery | 160 * |-------------------------------| 161 * | USB0 | 0x00008 | 0x020000 | 162 * |-------------------------------| 163 * | USB1 | - | 0x040000 | 164 * |-------------------------------| 165 * | USB2 | - | 0x080000 | 166 * |-------------------------------| 167 * | GE0 | 0x00001 | 0x000002 | 168 * |-------------------------------| 169 * | GE1 | - | 0x000004 | 170 * |-------------------------------| 171 * | IDMA | - | 0x100000 | 172 * |-------------------------------| 173 * | XOR | 0x10000 | 0x200000 | 174 * |-------------------------------| 175 * | CESA | 0x20000 | 0x400000 | 176 * |-------------------------------| 177 * | SATA | 0x04000 | 0x004000 | 178 * --------------------------------| 179 * This feature can be used only on Kirkwood and Discovery 180 * machines. 181 */ 182static __inline void 183pm_disable_device(int mask) 184{ 185#ifdef DIAGNOSTIC 186 uint32_t reg; 187 188 reg = soc_power_ctrl_get(CPU_PM_CTRL_ALL); 189 printf("Power Management Register: 0%x\n", reg); 190 191 reg &= ~mask; 192 soc_power_ctrl_set(reg); 193 printf("Device %x is disabled\n", mask); 194 195 reg = soc_power_ctrl_get(CPU_PM_CTRL_ALL); 196 printf("Power Management Register: 0%x\n", reg); 197#endif 198} 199 200int 201fdt_pm(phandle_t node) 202{ 203 uint32_t cpu_pm_ctrl; 204 int i, ena, compat; 205 206 ena = 1; 207 cpu_pm_ctrl = read_cpu_ctrl(CPU_PM_CTRL); 208 for (i = 0; fdt_pm_mask_table[i].compat != NULL; i++) { 209 if (dev_mask & (1 << i)) 210 continue; 211 212 compat = fdt_is_compatible(node, fdt_pm_mask_table[i].compat); 213 214 if (compat && (~cpu_pm_ctrl & fdt_pm_mask_table[i].mask)) { 215 dev_mask |= (1 << i); 216 ena = 0; 217 break; 218 } else if (compat) { 219 dev_mask |= (1 << i); 220 break; 221 } 222 } 223 224 return (ena); 225} 226 227uint32_t 228read_cpu_ctrl(uint32_t reg) 229{ 230 231 return (bus_space_read_4(fdtbus_bs_tag, MV_CPU_CONTROL_BASE, reg)); 232} 233 234void 235write_cpu_ctrl(uint32_t reg, uint32_t val) 236{ 237 238 bus_space_write_4(fdtbus_bs_tag, MV_CPU_CONTROL_BASE, reg, val); 239} 240 241void 242cpu_reset(void) 243{ 244 245 write_cpu_ctrl(RSTOUTn_MASK, SOFT_RST_OUT_EN); 246 write_cpu_ctrl(SYSTEM_SOFT_RESET, SYS_SOFT_RST); 247 while (1); 248} 249 250uint32_t 251cpu_extra_feat(void) 252{ 253 uint32_t dev, rev; 254 uint32_t ef = 0; 255 256 soc_id(&dev, &rev); 257 if (dev == MV_DEV_88F6281 || dev == MV_DEV_MV78100_Z0 || 258 dev == MV_DEV_MV78100) 259 __asm __volatile("mrc p15, 1, %0, c15, c1, 0" : "=r" (ef)); 260 else if (dev == MV_DEV_88F5182 || dev == MV_DEV_88F5281) 261 __asm __volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (ef)); 262 else if (bootverbose) 263 printf("This ARM Core does not support any extra features\n"); 264 265 return (ef); 266} 267 268/* 269 * Get the power status of device. This feature is only supported on 270 * Kirkwood and Discovery SoCs. 271 */ 272uint32_t 273soc_power_ctrl_get(uint32_t mask) 274{ 275 276#ifndef SOC_MV_ORION 277 if (mask != CPU_PM_CTRL_NONE) 278 mask &= read_cpu_ctrl(CPU_PM_CTRL); 279 280 return (mask); 281#else 282 return (mask); 283#endif 284} 285 286/* 287 * Set the power status of device. This feature is only supported on 288 * Kirkwood and Discovery SoCs. 289 */ 290void 291soc_power_ctrl_set(uint32_t mask) 292{ 293 294#ifndef SOC_MV_ORION 295 if (mask != CPU_PM_CTRL_NONE) 296 write_cpu_ctrl(CPU_PM_CTRL, mask); 297#endif 298} 299 300void 301soc_id(uint32_t *dev, uint32_t *rev) 302{ 303 304 /* 305 * Notice: system identifiers are available in the registers range of 306 * PCIE controller, so using this function is only allowed (and 307 * possible) after the internal registers range has been mapped in via 308 * pmap_devmap_bootstrap(). 309 */ 310 *dev = bus_space_read_4(fdtbus_bs_tag, MV_PCIE_BASE, 0) >> 16; 311 *rev = bus_space_read_4(fdtbus_bs_tag, MV_PCIE_BASE, 8) & 0xff; 312} 313 314static void 315soc_identify(void) 316{ 317 uint32_t d, r; 318 const char *dev; 319 const char *rev; 320 321 soc_id(&d, &r); 322 323 printf("SOC: "); 324 if (bootverbose) 325 printf("(0x%4x:0x%02x) ", d, r); 326 327 rev = ""; 328 switch (d) { 329 case MV_DEV_88F5181: 330 dev = "Marvell 88F5181"; 331 if (r == 3) 332 rev = "B1"; 333 break; 334 case MV_DEV_88F5182: 335 dev = "Marvell 88F5182"; 336 if (r == 2) 337 rev = "A2"; 338 break; 339 case MV_DEV_88F5281: 340 dev = "Marvell 88F5281"; 341 if (r == 4) 342 rev = "D0"; 343 else if (r == 5) 344 rev = "D1"; 345 else if (r == 6) 346 rev = "D2"; 347 break; 348 case MV_DEV_88F6281: 349 dev = "Marvell 88F6281"; 350 if (r == 0) 351 rev = "Z0"; 352 else if (r == 2) 353 rev = "A0"; 354 else if (r == 3) 355 rev = "A1"; 356 break; 357 case MV_DEV_MV78100_Z0: 358 dev = "Marvell MV78100 Z0"; 359 break; 360 case MV_DEV_MV78100: 361 dev = "Marvell MV78100"; 362 break; 363 default: 364 dev = "UNKNOWN"; 365 break; 366 } 367 368 printf("%s", dev); 369 if (*rev != '\0') 370 printf(" rev %s", rev); 371 printf(", TClock %dMHz\n", get_tclk() / 1000 / 1000); 372 373 /* TODO add info on currently set endianess */ 374} 375 376static void 377platform_identify(void *dummy) 378{ 379 380 soc_identify(); 381 382 /* 383 * XXX Board identification e.g. read out from FPGA or similar should 384 * go here 385 */ 386} 387SYSINIT(platform_identify, SI_SUB_CPU, SI_ORDER_SECOND, platform_identify, 388 NULL); 389 390int 391soc_decode_win(void) 392{ 393 uint32_t dev, rev; 394 int mask, err; 395 396 mask = 0; 397 TUNABLE_INT_FETCH("hw.pm-disable-mask", &mask); 398 399 if (mask != 0) 400 pm_disable_device(mask); 401 402 /* Retrieve data about physical addresses from device tree. */ 403 if ((err = win_cpu_from_dt()) != 0) 404 return (err); 405 406 /* Retrieve our ID: some windows facilities vary between SoC models */ 407 soc_id(&dev, &rev); 408 409 if (!decode_win_cpu_valid() || !decode_win_usb_valid() || 410 !decode_win_eth_valid() || !decode_win_idma_valid() || 411 !decode_win_pcie_valid() || !decode_win_sata_valid() || 412 !decode_win_cesa_valid() || !decode_win_xor_valid()) 413 return (EINVAL); 414 415 decode_win_cpu_setup(); 416 if (MV_DUMP_WIN) 417 soc_dump_decode_win(); 418 419 eth_port = 0; 420 usb_port = 0; 421 if ((err = fdt_win_setup()) != 0) 422 return (err); 423 424 return (0); 425} 426 427/************************************************************************** 428 * Decode windows registers accessors 429 **************************************************************************/ 430WIN_REG_IDX_RD(win_cpu, cr, MV_WIN_CPU_CTRL, MV_MBUS_BRIDGE_BASE) 431WIN_REG_IDX_RD(win_cpu, br, MV_WIN_CPU_BASE, MV_MBUS_BRIDGE_BASE) 432WIN_REG_IDX_RD(win_cpu, remap_l, MV_WIN_CPU_REMAP_LO, MV_MBUS_BRIDGE_BASE) 433WIN_REG_IDX_RD(win_cpu, remap_h, MV_WIN_CPU_REMAP_HI, MV_MBUS_BRIDGE_BASE) 434WIN_REG_IDX_WR(win_cpu, cr, MV_WIN_CPU_CTRL, MV_MBUS_BRIDGE_BASE) 435WIN_REG_IDX_WR(win_cpu, br, MV_WIN_CPU_BASE, MV_MBUS_BRIDGE_BASE) 436WIN_REG_IDX_WR(win_cpu, remap_l, MV_WIN_CPU_REMAP_LO, MV_MBUS_BRIDGE_BASE) 437WIN_REG_IDX_WR(win_cpu, remap_h, MV_WIN_CPU_REMAP_HI, MV_MBUS_BRIDGE_BASE) 438 439WIN_REG_IDX_RD(ddr, br, MV_WIN_DDR_BASE, MV_DDR_CADR_BASE) 440WIN_REG_IDX_RD(ddr, sz, MV_WIN_DDR_SIZE, MV_DDR_CADR_BASE) 441 442WIN_REG_BASE_IDX_RD(win_usb, cr, MV_WIN_USB_CTRL) 443WIN_REG_BASE_IDX_RD(win_usb, br, MV_WIN_USB_BASE) 444WIN_REG_BASE_IDX_WR(win_usb, cr, MV_WIN_USB_CTRL) 445WIN_REG_BASE_IDX_WR(win_usb, br, MV_WIN_USB_BASE) 446 447WIN_REG_BASE_IDX_RD(win_cesa, cr, MV_WIN_CESA_CTRL) 448WIN_REG_BASE_IDX_RD(win_cesa, br, MV_WIN_CESA_BASE) 449WIN_REG_BASE_IDX_WR(win_cesa, cr, MV_WIN_CESA_CTRL) 450WIN_REG_BASE_IDX_WR(win_cesa, br, MV_WIN_CESA_BASE) 451 452WIN_REG_BASE_IDX_RD(win_eth, br, MV_WIN_ETH_BASE) 453WIN_REG_BASE_IDX_RD(win_eth, sz, MV_WIN_ETH_SIZE) 454WIN_REG_BASE_IDX_RD(win_eth, har, MV_WIN_ETH_REMAP) 455WIN_REG_BASE_IDX_WR(win_eth, br, MV_WIN_ETH_BASE) 456WIN_REG_BASE_IDX_WR(win_eth, sz, MV_WIN_ETH_SIZE) 457WIN_REG_BASE_IDX_WR(win_eth, har, MV_WIN_ETH_REMAP) 458 459WIN_REG_BASE_IDX_RD2(win_xor, br, MV_WIN_XOR_BASE) 460WIN_REG_BASE_IDX_RD2(win_xor, sz, MV_WIN_XOR_SIZE) 461WIN_REG_BASE_IDX_RD2(win_xor, har, MV_WIN_XOR_REMAP) 462WIN_REG_BASE_IDX_RD2(win_xor, ctrl, MV_WIN_XOR_CTRL) 463WIN_REG_BASE_IDX_WR2(win_xor, br, MV_WIN_XOR_BASE) 464WIN_REG_BASE_IDX_WR2(win_xor, sz, MV_WIN_XOR_SIZE) 465WIN_REG_BASE_IDX_WR2(win_xor, har, MV_WIN_XOR_REMAP) 466WIN_REG_BASE_IDX_WR2(win_xor, ctrl, MV_WIN_XOR_CTRL) 467 468WIN_REG_BASE_RD(win_eth, bare, 0x290) 469WIN_REG_BASE_RD(win_eth, epap, 0x294) 470WIN_REG_BASE_WR(win_eth, bare, 0x290) 471WIN_REG_BASE_WR(win_eth, epap, 0x294) 472 473WIN_REG_BASE_IDX_RD(win_pcie, cr, MV_WIN_PCIE_CTRL); 474WIN_REG_BASE_IDX_RD(win_pcie, br, MV_WIN_PCIE_BASE); 475WIN_REG_BASE_IDX_RD(win_pcie, remap, MV_WIN_PCIE_REMAP); 476WIN_REG_BASE_IDX_WR(win_pcie, cr, MV_WIN_PCIE_CTRL); 477WIN_REG_BASE_IDX_WR(win_pcie, br, MV_WIN_PCIE_BASE); 478WIN_REG_BASE_IDX_WR(win_pcie, remap, MV_WIN_PCIE_REMAP); 479WIN_REG_BASE_IDX_WR(pcie, bar, MV_PCIE_BAR); 480 481WIN_REG_BASE_IDX_RD(win_idma, br, MV_WIN_IDMA_BASE) 482WIN_REG_BASE_IDX_RD(win_idma, sz, MV_WIN_IDMA_SIZE) 483WIN_REG_BASE_IDX_RD(win_idma, har, MV_WIN_IDMA_REMAP) 484WIN_REG_BASE_IDX_RD(win_idma, cap, MV_WIN_IDMA_CAP) 485WIN_REG_BASE_IDX_WR(win_idma, br, MV_WIN_IDMA_BASE) 486WIN_REG_BASE_IDX_WR(win_idma, sz, MV_WIN_IDMA_SIZE) 487WIN_REG_BASE_IDX_WR(win_idma, har, MV_WIN_IDMA_REMAP) 488WIN_REG_BASE_IDX_WR(win_idma, cap, MV_WIN_IDMA_CAP) 489WIN_REG_BASE_RD(win_idma, bare, 0xa80) 490WIN_REG_BASE_WR(win_idma, bare, 0xa80) 491 492WIN_REG_BASE_IDX_RD(win_sata, cr, MV_WIN_SATA_CTRL); 493WIN_REG_BASE_IDX_RD(win_sata, br, MV_WIN_SATA_BASE); 494WIN_REG_BASE_IDX_WR(win_sata, cr, MV_WIN_SATA_CTRL); 495WIN_REG_BASE_IDX_WR(win_sata, br, MV_WIN_SATA_BASE); 496 497/************************************************************************** 498 * Decode windows helper routines 499 **************************************************************************/ 500void 501soc_dump_decode_win(void) 502{ 503 uint32_t dev, rev; 504 int i; 505 506 soc_id(&dev, &rev); 507 508 for (i = 0; i < MV_WIN_CPU_MAX; i++) { 509 printf("CPU window#%d: c 0x%08x, b 0x%08x", i, 510 win_cpu_cr_read(i), 511 win_cpu_br_read(i)); 512 513 if (win_cpu_can_remap(i)) 514 printf(", rl 0x%08x, rh 0x%08x", 515 win_cpu_remap_l_read(i), 516 win_cpu_remap_h_read(i)); 517 518 printf("\n"); 519 } 520 printf("Internal regs base: 0x%08x\n", 521 bus_space_read_4(fdtbus_bs_tag, MV_INTREGS_BASE, 0)); 522 523 for (i = 0; i < MV_WIN_DDR_MAX; i++) 524 printf("DDR CS#%d: b 0x%08x, s 0x%08x\n", i, 525 ddr_br_read(i), ddr_sz_read(i)); 526} 527 528/************************************************************************** 529 * CPU windows routines 530 **************************************************************************/ 531int 532win_cpu_can_remap(int i) 533{ 534 uint32_t dev, rev; 535 536 soc_id(&dev, &rev); 537 538 /* Depending on the SoC certain windows have remap capability */ 539 if ((dev == MV_DEV_88F5182 && i < 2) || 540 (dev == MV_DEV_88F5281 && i < 4) || 541 (dev == MV_DEV_88F6281 && i < 4) || 542 (dev == MV_DEV_MV78100 && i < 8) || 543 (dev == MV_DEV_MV78100_Z0 && i < 8)) 544 return (1); 545 546 return (0); 547} 548 549/* XXX This should check for overlapping remap fields too.. */ 550int 551decode_win_overlap(int win, int win_no, const struct decode_win *wintab) 552{ 553 const struct decode_win *tab; 554 int i; 555 556 tab = wintab; 557 558 for (i = 0; i < win_no; i++, tab++) { 559 if (i == win) 560 /* Skip self */ 561 continue; 562 563 if ((tab->base + tab->size - 1) < (wintab + win)->base) 564 continue; 565 566 else if (((wintab + win)->base + (wintab + win)->size - 1) < 567 tab->base) 568 continue; 569 else 570 return (i); 571 } 572 573 return (-1); 574} 575 576static int 577decode_win_cpu_valid(void) 578{ 579 int i, j, rv; 580 uint32_t b, e, s; 581 582 if (cpu_wins_no > MV_WIN_CPU_MAX) { 583 printf("CPU windows: too many entries: %d\n", cpu_wins_no); 584 return (0); 585 } 586 587 rv = 1; 588 for (i = 0; i < cpu_wins_no; i++) { 589 590 if (cpu_wins[i].target == 0) { 591 printf("CPU window#%d: DDR target window is not " 592 "supposed to be reprogrammed!\n", i); 593 rv = 0; 594 } 595 596 if (cpu_wins[i].remap >= 0 && win_cpu_can_remap(i) != 1) { 597 printf("CPU window#%d: not capable of remapping, but " 598 "val 0x%08x defined\n", i, cpu_wins[i].remap); 599 rv = 0; 600 } 601 602 s = cpu_wins[i].size; 603 b = cpu_wins[i].base; 604 e = b + s - 1; 605 if (s > (0xFFFFFFFF - b + 1)) { 606 /* 607 * XXX this boundary check should account for 64bit 608 * and remapping.. 609 */ 610 printf("CPU window#%d: no space for size 0x%08x at " 611 "0x%08x\n", i, s, b); 612 rv = 0; 613 continue; 614 } 615 616 j = decode_win_overlap(i, cpu_wins_no, &cpu_wins[0]); 617 if (j >= 0) { 618 printf("CPU window#%d: (0x%08x - 0x%08x) overlaps " 619 "with #%d (0x%08x - 0x%08x)\n", i, b, e, j, 620 cpu_wins[j].base, 621 cpu_wins[j].base + cpu_wins[j].size - 1); 622 rv = 0; 623 } 624 } 625 626 return (rv); 627} 628 629int 630decode_win_cpu_set(int target, int attr, vm_paddr_t base, uint32_t size, 631 int remap) 632{ 633 uint32_t br, cr; 634 int win; 635 636 if (used_cpu_wins >= MV_WIN_CPU_MAX) 637 return (0); 638 639 win = used_cpu_wins++; 640 641 br = base & 0xffff0000; 642 win_cpu_br_write(win, br); 643 644 if (win_cpu_can_remap(win)) { 645 if (remap >= 0) { 646 win_cpu_remap_l_write(win, remap & 0xffff0000); 647 win_cpu_remap_h_write(win, 0); 648 } else { 649 /* 650 * Remap function is not used for a given window 651 * (capable of remapping) - set remap field with the 652 * same value as base. 653 */ 654 win_cpu_remap_l_write(win, base & 0xffff0000); 655 win_cpu_remap_h_write(win, 0); 656 } 657 } 658 659 cr = ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1; 660 win_cpu_cr_write(win, cr); 661 662 return (0); 663} 664 665static void 666decode_win_cpu_setup(void) 667{ 668 int i; 669 670 used_cpu_wins = 0; 671 672 /* Disable all CPU windows */ 673 for (i = 0; i < MV_WIN_CPU_MAX; i++) { 674 win_cpu_cr_write(i, 0); 675 win_cpu_br_write(i, 0); 676 if (win_cpu_can_remap(i)) { 677 win_cpu_remap_l_write(i, 0); 678 win_cpu_remap_h_write(i, 0); 679 } 680 } 681 682 for (i = 0; i < cpu_wins_no; i++) 683 if (cpu_wins[i].target > 0) 684 decode_win_cpu_set(cpu_wins[i].target, 685 cpu_wins[i].attr, cpu_wins[i].base, 686 cpu_wins[i].size, cpu_wins[i].remap); 687 688} 689 690/* 691 * Check if we're able to cover all active DDR banks. 692 */ 693static int 694decode_win_can_cover_ddr(int max) 695{ 696 int i, c; 697 698 c = 0; 699 for (i = 0; i < MV_WIN_DDR_MAX; i++) 700 if (ddr_is_active(i)) 701 c++; 702 703 if (c > max) { 704 printf("Unable to cover all active DDR banks: " 705 "%d, available windows: %d\n", c, max); 706 return (0); 707 } 708 709 return (1); 710} 711 712/************************************************************************** 713 * DDR windows routines 714 **************************************************************************/ 715int 716ddr_is_active(int i) 717{ 718 719 if (ddr_sz_read(i) & 0x1) 720 return (1); 721 722 return (0); 723} 724 725uint32_t 726ddr_base(int i) 727{ 728 729 return (ddr_br_read(i) & 0xff000000); 730} 731 732uint32_t 733ddr_size(int i) 734{ 735 736 return ((ddr_sz_read(i) | 0x00ffffff) + 1); 737} 738 739uint32_t 740ddr_attr(int i) 741{ 742 743 return (i == 0 ? 0xe : 744 (i == 1 ? 0xd : 745 (i == 2 ? 0xb : 746 (i == 3 ? 0x7 : 0xff)))); 747} 748 749uint32_t 750ddr_target(int i) 751{ 752 753 /* Mbus unit ID is 0x0 for DDR SDRAM controller */ 754 return (0); 755} 756 757/************************************************************************** 758 * USB windows routines 759 **************************************************************************/ 760static int 761decode_win_usb_valid(void) 762{ 763 764 return (decode_win_can_cover_ddr(MV_WIN_USB_MAX)); 765} 766 767static void 768decode_win_usb_dump(u_long base) 769{ 770 int i; 771 772 if (pm_is_disabled(CPU_PM_CTRL_USB(usb_port - 1))) 773 return; 774 775 for (i = 0; i < MV_WIN_USB_MAX; i++) 776 printf("USB window#%d: c 0x%08x, b 0x%08x\n", i, 777 win_usb_cr_read(base, i), win_usb_br_read(base, i)); 778} 779 780/* 781 * Set USB decode windows. 782 */ 783static void 784decode_win_usb_setup(u_long base) 785{ 786 uint32_t br, cr; 787 int i, j; 788 789 790 if (pm_is_disabled(CPU_PM_CTRL_USB(usb_port))) 791 return; 792 793 usb_port++; 794 795 for (i = 0; i < MV_WIN_USB_MAX; i++) { 796 win_usb_cr_write(base, i, 0); 797 win_usb_br_write(base, i, 0); 798 } 799 800 /* Only access to active DRAM banks is required */ 801 for (i = 0; i < MV_WIN_DDR_MAX; i++) { 802 if (ddr_is_active(i)) { 803 br = ddr_base(i); 804 /* 805 * XXX for 6281 we should handle Mbus write 806 * burst limit field in the ctrl reg 807 */ 808 cr = (((ddr_size(i) - 1) & 0xffff0000) | 809 (ddr_attr(i) << 8) | 810 (ddr_target(i) << 4) | 1); 811 812 /* Set the first free USB window */ 813 for (j = 0; j < MV_WIN_USB_MAX; j++) { 814 if (win_usb_cr_read(base, j) & 0x1) 815 continue; 816 817 win_usb_br_write(base, j, br); 818 win_usb_cr_write(base, j, cr); 819 break; 820 } 821 } 822 } 823} 824 825/************************************************************************** 826 * ETH windows routines 827 **************************************************************************/ 828 829static int 830win_eth_can_remap(int i) 831{ 832 833 /* ETH encode windows 0-3 have remap capability */ 834 if (i < 4) 835 return (1); 836 837 return (0); 838} 839 840static int 841eth_bare_read(uint32_t base, int i) 842{ 843 uint32_t v; 844 845 v = win_eth_bare_read(base); 846 v &= (1 << i); 847 848 return (v >> i); 849} 850 851static void 852eth_bare_write(uint32_t base, int i, int val) 853{ 854 uint32_t v; 855 856 v = win_eth_bare_read(base); 857 v &= ~(1 << i); 858 v |= (val << i); 859 win_eth_bare_write(base, v); 860} 861 862static void 863eth_epap_write(uint32_t base, int i, int val) 864{ 865 uint32_t v; 866 867 v = win_eth_epap_read(base); 868 v &= ~(0x3 << (i * 2)); 869 v |= (val << (i * 2)); 870 win_eth_epap_write(base, v); 871} 872 873static void 874decode_win_eth_dump(u_long base) 875{ 876 int i; 877 878 if (pm_is_disabled(CPU_PM_CTRL_GE(eth_port - 1))) 879 return; 880 881 for (i = 0; i < MV_WIN_ETH_MAX; i++) { 882 printf("ETH window#%d: b 0x%08x, s 0x%08x", i, 883 win_eth_br_read(base, i), 884 win_eth_sz_read(base, i)); 885 886 if (win_eth_can_remap(i)) 887 printf(", ha 0x%08x", 888 win_eth_har_read(base, i)); 889 890 printf("\n"); 891 } 892 printf("ETH windows: bare 0x%08x, epap 0x%08x\n", 893 win_eth_bare_read(base), 894 win_eth_epap_read(base)); 895} 896 897static void 898decode_win_eth_setup(u_long base) 899{ 900 uint32_t br, sz; 901 int i, j; 902 903 if (pm_is_disabled(CPU_PM_CTRL_GE(eth_port))) 904 return; 905 906 eth_port++; 907 908 /* Disable, clear and revoke protection for all ETH windows */ 909 for (i = 0; i < MV_WIN_ETH_MAX; i++) { 910 911 eth_bare_write(base, i, 1); 912 eth_epap_write(base, i, 0); 913 win_eth_br_write(base, i, 0); 914 win_eth_sz_write(base, i, 0); 915 if (win_eth_can_remap(i)) 916 win_eth_har_write(base, i, 0); 917 } 918 919 /* Only access to active DRAM banks is required */ 920 for (i = 0; i < MV_WIN_DDR_MAX; i++) 921 if (ddr_is_active(i)) { 922 923 br = ddr_base(i) | (ddr_attr(i) << 8) | ddr_target(i); 924 sz = ((ddr_size(i) - 1) & 0xffff0000); 925 926 /* Set the first free ETH window */ 927 for (j = 0; j < MV_WIN_ETH_MAX; j++) { 928 if (eth_bare_read(base, j) == 0) 929 continue; 930 931 win_eth_br_write(base, j, br); 932 win_eth_sz_write(base, j, sz); 933 934 /* XXX remapping ETH windows not supported */ 935 936 /* Set protection RW */ 937 eth_epap_write(base, j, 0x3); 938 939 /* Enable window */ 940 eth_bare_write(base, j, 0); 941 break; 942 } 943 } 944} 945 946static int 947decode_win_eth_valid(void) 948{ 949 950 return (decode_win_can_cover_ddr(MV_WIN_ETH_MAX)); 951} 952 953/************************************************************************** 954 * PCIE windows routines 955 **************************************************************************/ 956 957static void 958decode_win_pcie_setup(u_long base) 959{ 960 uint32_t size = 0; 961 uint32_t cr, br; 962 int i, j; 963 964 for (i = 0; i < MV_PCIE_BAR_MAX; i++) 965 pcie_bar_write(base, i, 0); 966 967 for (i = 0; i < MV_WIN_PCIE_MAX; i++) { 968 win_pcie_cr_write(base, i, 0); 969 win_pcie_br_write(base, i, 0); 970 win_pcie_remap_write(base, i, 0); 971 } 972 973 for (i = 0; i < MV_WIN_DDR_MAX; i++) { 974 if (ddr_is_active(i)) { 975 /* Map DDR to BAR 1 */ 976 cr = (ddr_size(i) - 1) & 0xffff0000; 977 size += ddr_size(i) & 0xffff0000; 978 cr |= (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1; 979 br = ddr_base(i); 980 981 /* Use the first available PCIE window */ 982 for (j = 0; j < MV_WIN_PCIE_MAX; j++) { 983 if (win_pcie_cr_read(base, j) != 0) 984 continue; 985 986 win_pcie_br_write(base, j, br); 987 win_pcie_cr_write(base, j, cr); 988 break; 989 } 990 } 991 } 992 993 /* 994 * Upper 16 bits in BAR register is interpreted as BAR size 995 * (in 64 kB units) plus 64kB, so substract 0x10000 996 * form value passed to register to get correct value. 997 */ 998 size -= 0x10000; 999 pcie_bar_write(base, 0, size | 1); 1000} 1001 1002static int 1003decode_win_pcie_valid(void) 1004{ 1005 1006 return (decode_win_can_cover_ddr(MV_WIN_PCIE_MAX)); 1007} 1008 1009/************************************************************************** 1010 * IDMA windows routines 1011 **************************************************************************/ 1012#if defined(SOC_MV_ORION) || defined(SOC_MV_DISCOVERY) 1013static int 1014idma_bare_read(u_long base, int i) 1015{ 1016 uint32_t v; 1017 1018 v = win_idma_bare_read(base); 1019 v &= (1 << i); 1020 1021 return (v >> i); 1022} 1023 1024static void 1025idma_bare_write(u_long base, int i, int val) 1026{ 1027 uint32_t v; 1028 1029 v = win_idma_bare_read(base); 1030 v &= ~(1 << i); 1031 v |= (val << i); 1032 win_idma_bare_write(base, v); 1033} 1034 1035/* 1036 * Sets channel protection 'val' for window 'w' on channel 'c' 1037 */ 1038static void 1039idma_cap_write(u_long base, int c, int w, int val) 1040{ 1041 uint32_t v; 1042 1043 v = win_idma_cap_read(base, c); 1044 v &= ~(0x3 << (w * 2)); 1045 v |= (val << (w * 2)); 1046 win_idma_cap_write(base, c, v); 1047} 1048 1049/* 1050 * Set protection 'val' on all channels for window 'w' 1051 */ 1052static void 1053idma_set_prot(u_long base, int w, int val) 1054{ 1055 int c; 1056 1057 for (c = 0; c < MV_IDMA_CHAN_MAX; c++) 1058 idma_cap_write(base, c, w, val); 1059} 1060 1061static int 1062win_idma_can_remap(int i) 1063{ 1064 1065 /* IDMA decode windows 0-3 have remap capability */ 1066 if (i < 4) 1067 return (1); 1068 1069 return (0); 1070} 1071 1072void 1073decode_win_idma_setup(u_long base) 1074{ 1075 uint32_t br, sz; 1076 int i, j; 1077 1078 if (pm_is_disabled(CPU_PM_CTRL_IDMA)) 1079 return; 1080 /* 1081 * Disable and clear all IDMA windows, revoke protection for all channels 1082 */ 1083 for (i = 0; i < MV_WIN_IDMA_MAX; i++) { 1084 1085 idma_bare_write(base, i, 1); 1086 win_idma_br_write(base, i, 0); 1087 win_idma_sz_write(base, i, 0); 1088 if (win_idma_can_remap(i) == 1) 1089 win_idma_har_write(base, i, 0); 1090 } 1091 for (i = 0; i < MV_IDMA_CHAN_MAX; i++) 1092 win_idma_cap_write(base, i, 0); 1093 1094 /* 1095 * Set up access to all active DRAM banks 1096 */ 1097 for (i = 0; i < MV_WIN_DDR_MAX; i++) 1098 if (ddr_is_active(i)) { 1099 br = ddr_base(i) | (ddr_attr(i) << 8) | ddr_target(i); 1100 sz = ((ddr_size(i) - 1) & 0xffff0000); 1101 1102 /* Place DDR entries in non-remapped windows */ 1103 for (j = 0; j < MV_WIN_IDMA_MAX; j++) 1104 if (win_idma_can_remap(j) != 1 && 1105 idma_bare_read(base, j) == 1) { 1106 1107 /* Configure window */ 1108 win_idma_br_write(base, j, br); 1109 win_idma_sz_write(base, j, sz); 1110 1111 /* Set protection RW on all channels */ 1112 idma_set_prot(base, j, 0x3); 1113 1114 /* Enable window */ 1115 idma_bare_write(base, j, 0); 1116 break; 1117 } 1118 } 1119 1120 /* 1121 * Remaining targets -- from statically defined table 1122 */ 1123 for (i = 0; i < idma_wins_no; i++) 1124 if (idma_wins[i].target > 0) { 1125 br = (idma_wins[i].base & 0xffff0000) | 1126 (idma_wins[i].attr << 8) | idma_wins[i].target; 1127 sz = ((idma_wins[i].size - 1) & 0xffff0000); 1128 1129 /* Set the first free IDMA window */ 1130 for (j = 0; j < MV_WIN_IDMA_MAX; j++) { 1131 if (idma_bare_read(base, j) == 0) 1132 continue; 1133 1134 /* Configure window */ 1135 win_idma_br_write(base, j, br); 1136 win_idma_sz_write(base, j, sz); 1137 if (win_idma_can_remap(j) && 1138 idma_wins[j].remap >= 0) 1139 win_idma_har_write(base, j, 1140 idma_wins[j].remap); 1141 1142 /* Set protection RW on all channels */ 1143 idma_set_prot(base, j, 0x3); 1144 1145 /* Enable window */ 1146 idma_bare_write(base, j, 0); 1147 break; 1148 } 1149 } 1150} 1151 1152int 1153decode_win_idma_valid(void) 1154{ 1155 const struct decode_win *wintab; 1156 int c, i, j, rv; 1157 uint32_t b, e, s; 1158 1159 if (idma_wins_no > MV_WIN_IDMA_MAX) { 1160 printf("IDMA windows: too many entries: %d\n", idma_wins_no); 1161 return (0); 1162 } 1163 for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++) 1164 if (ddr_is_active(i)) 1165 c++; 1166 1167 if (idma_wins_no > (MV_WIN_IDMA_MAX - c)) { 1168 printf("IDMA windows: too many entries: %d, available: %d\n", 1169 idma_wins_no, MV_WIN_IDMA_MAX - c); 1170 return (0); 1171 } 1172 1173 wintab = idma_wins; 1174 rv = 1; 1175 for (i = 0; i < idma_wins_no; i++, wintab++) { 1176 1177 if (wintab->target == 0) { 1178 printf("IDMA window#%d: DDR target window is not " 1179 "supposed to be reprogrammed!\n", i); 1180 rv = 0; 1181 } 1182 1183 if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) { 1184 printf("IDMA window#%d: not capable of remapping, but " 1185 "val 0x%08x defined\n", i, wintab->remap); 1186 rv = 0; 1187 } 1188 1189 s = wintab->size; 1190 b = wintab->base; 1191 e = b + s - 1; 1192 if (s > (0xFFFFFFFF - b + 1)) { 1193 /* XXX this boundary check should account for 64bit and 1194 * remapping.. */ 1195 printf("IDMA window#%d: no space for size 0x%08x at " 1196 "0x%08x\n", i, s, b); 1197 rv = 0; 1198 continue; 1199 } 1200 1201 j = decode_win_overlap(i, idma_wins_no, &idma_wins[0]); 1202 if (j >= 0) { 1203 printf("IDMA window#%d: (0x%08x - 0x%08x) overlaps " 1204 "with #%d (0x%08x - 0x%08x)\n", i, b, e, j, 1205 idma_wins[j].base, 1206 idma_wins[j].base + idma_wins[j].size - 1); 1207 rv = 0; 1208 } 1209 } 1210 1211 return (rv); 1212} 1213 1214void 1215decode_win_idma_dump(u_long base) 1216{ 1217 int i; 1218 1219 if (pm_is_disabled(CPU_PM_CTRL_IDMA)) 1220 return; 1221 1222 for (i = 0; i < MV_WIN_IDMA_MAX; i++) { 1223 printf("IDMA window#%d: b 0x%08x, s 0x%08x", i, 1224 win_idma_br_read(base, i), win_idma_sz_read(base, i)); 1225 1226 if (win_idma_can_remap(i)) 1227 printf(", ha 0x%08x", win_idma_har_read(base, i)); 1228 1229 printf("\n"); 1230 } 1231 for (i = 0; i < MV_IDMA_CHAN_MAX; i++) 1232 printf("IDMA channel#%d: ap 0x%08x\n", i, 1233 win_idma_cap_read(base, i)); 1234 printf("IDMA windows: bare 0x%08x\n", win_idma_bare_read(base)); 1235} 1236#else 1237 1238/* Provide dummy functions to satisfy the build for SoCs not equipped with IDMA */ 1239int 1240decode_win_idma_valid(void) 1241{ 1242 1243 return (1); 1244} 1245 1246void 1247decode_win_idma_setup(u_long base) 1248{ 1249} 1250 1251void 1252decode_win_idma_dump(u_long base) 1253{ 1254} 1255#endif 1256 1257/************************************************************************** 1258 * XOR windows routines 1259 **************************************************************************/ 1260#if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY) 1261static int 1262xor_ctrl_read(u_long base, int i, int c, int e) 1263{ 1264 uint32_t v; 1265 v = win_xor_ctrl_read(base, c, e); 1266 v &= (1 << i); 1267 1268 return (v >> i); 1269} 1270 1271static void 1272xor_ctrl_write(u_long base, int i, int c, int e, int val) 1273{ 1274 uint32_t v; 1275 1276 v = win_xor_ctrl_read(base, c, e); 1277 v &= ~(1 << i); 1278 v |= (val << i); 1279 win_xor_ctrl_write(base, c, e, v); 1280} 1281 1282/* 1283 * Set channel protection 'val' for window 'w' on channel 'c' 1284 */ 1285 1286static void 1287xor_chan_write(u_long base, int c, int e, int w, int val) 1288{ 1289 uint32_t v; 1290 1291 v = win_xor_ctrl_read(base, c, e); 1292 v &= ~(0x3 << (w * 2 + 16)); 1293 v |= (val << (w * 2 + 16)); 1294 win_xor_ctrl_write(base, c, e, v); 1295} 1296 1297/* 1298 * Set protection 'val' on all channels for window 'w' on engine 'e' 1299 */ 1300static void 1301xor_set_prot(u_long base, int w, int e, int val) 1302{ 1303 int c; 1304 1305 for (c = 0; c < MV_XOR_CHAN_MAX; c++) 1306 xor_chan_write(base, c, e, w, val); 1307} 1308 1309static int 1310win_xor_can_remap(int i) 1311{ 1312 1313 /* XOR decode windows 0-3 have remap capability */ 1314 if (i < 4) 1315 return (1); 1316 1317 return (0); 1318} 1319 1320static int 1321xor_max_eng(void) 1322{ 1323 uint32_t dev, rev; 1324 1325 soc_id(&dev, &rev); 1326 if (dev == MV_DEV_88F6281) 1327 return (2); 1328 else if ((dev == MV_DEV_MV78100) || (dev == MV_DEV_MV78100_Z0)) 1329 return (1); 1330 else 1331 return (0); 1332} 1333 1334static void 1335xor_active_dram(u_long base, int c, int e, int *window) 1336{ 1337 uint32_t br, sz; 1338 int i, m, w; 1339 1340 /* 1341 * Set up access to all active DRAM banks 1342 */ 1343 m = xor_max_eng(); 1344 for (i = 0; i < m; i++) 1345 if (ddr_is_active(i)) { 1346 br = ddr_base(i) | (ddr_attr(i) << 8) | 1347 ddr_target(i); 1348 sz = ((ddr_size(i) - 1) & 0xffff0000); 1349 1350 /* Place DDR entries in non-remapped windows */ 1351 for (w = 0; w < MV_WIN_XOR_MAX; w++) 1352 if (win_xor_can_remap(w) != 1 && 1353 (xor_ctrl_read(base, w, c, e) == 0) && 1354 w > *window) { 1355 /* Configure window */ 1356 win_xor_br_write(base, w, e, br); 1357 win_xor_sz_write(base, w, e, sz); 1358 1359 /* Set protection RW on all channels */ 1360 xor_set_prot(base, w, e, 0x3); 1361 1362 /* Enable window */ 1363 xor_ctrl_write(base, w, c, e, 1); 1364 (*window)++; 1365 break; 1366 } 1367 } 1368} 1369 1370void 1371decode_win_xor_setup(u_long base) 1372{ 1373 uint32_t br, sz; 1374 int i, j, z, e = 1, m, window; 1375 1376 if (pm_is_disabled(CPU_PM_CTRL_XOR)) 1377 return; 1378 1379 /* 1380 * Disable and clear all XOR windows, revoke protection for all 1381 * channels 1382 */ 1383 m = xor_max_eng(); 1384 for (j = 0; j < m; j++, e--) { 1385 1386 /* Number of non-remaped windows */ 1387 window = MV_XOR_NON_REMAP - 1; 1388 1389 for (i = 0; i < MV_WIN_XOR_MAX; i++) { 1390 win_xor_br_write(base, i, e, 0); 1391 win_xor_sz_write(base, i, e, 0); 1392 } 1393 1394 if (win_xor_can_remap(i) == 1) 1395 win_xor_har_write(base, i, e, 0); 1396 1397 for (i = 0; i < MV_XOR_CHAN_MAX; i++) { 1398 win_xor_ctrl_write(base, i, e, 0); 1399 xor_active_dram(base, i, e, &window); 1400 } 1401 1402 /* 1403 * Remaining targets -- from a statically defined table 1404 */ 1405 for (i = 0; i < xor_wins_no; i++) 1406 if (xor_wins[i].target > 0) { 1407 br = (xor_wins[i].base & 0xffff0000) | 1408 (xor_wins[i].attr << 8) | 1409 xor_wins[i].target; 1410 sz = ((xor_wins[i].size - 1) & 0xffff0000); 1411 1412 /* Set the first free XOR window */ 1413 for (z = 0; z < MV_WIN_XOR_MAX; z++) { 1414 if (xor_ctrl_read(base, z, 0, e) && 1415 xor_ctrl_read(base, z, 1, e)) 1416 continue; 1417 1418 /* Configure window */ 1419 win_xor_br_write(base, z, e, br); 1420 win_xor_sz_write(base, z, e, sz); 1421 if (win_xor_can_remap(z) && 1422 xor_wins[z].remap >= 0) 1423 win_xor_har_write(base, z, e, 1424 xor_wins[z].remap); 1425 1426 /* Set protection RW on all channels */ 1427 xor_set_prot(base, z, e, 0x3); 1428 1429 /* Enable window */ 1430 xor_ctrl_write(base, z, 0, e, 1); 1431 xor_ctrl_write(base, z, 1, e, 1); 1432 break; 1433 } 1434 } 1435 } 1436} 1437 1438int 1439decode_win_xor_valid(void) 1440{ 1441 const struct decode_win *wintab; 1442 int c, i, j, rv; 1443 uint32_t b, e, s; 1444 1445 if (xor_wins_no > MV_WIN_XOR_MAX) { 1446 printf("XOR windows: too many entries: %d\n", xor_wins_no); 1447 return (0); 1448 } 1449 for (i = 0, c = 0; i < MV_WIN_DDR_MAX; i++) 1450 if (ddr_is_active(i)) 1451 c++; 1452 1453 if (xor_wins_no > (MV_WIN_XOR_MAX - c)) { 1454 printf("XOR windows: too many entries: %d, available: %d\n", 1455 xor_wins_no, MV_WIN_IDMA_MAX - c); 1456 return (0); 1457 } 1458 1459 wintab = xor_wins; 1460 rv = 1; 1461 for (i = 0; i < xor_wins_no; i++, wintab++) { 1462 1463 if (wintab->target == 0) { 1464 printf("XOR window#%d: DDR target window is not " 1465 "supposed to be reprogrammed!\n", i); 1466 rv = 0; 1467 } 1468 1469 if (wintab->remap >= 0 && win_cpu_can_remap(i) != 1) { 1470 printf("XOR window#%d: not capable of remapping, but " 1471 "val 0x%08x defined\n", i, wintab->remap); 1472 rv = 0; 1473 } 1474 1475 s = wintab->size; 1476 b = wintab->base; 1477 e = b + s - 1; 1478 if (s > (0xFFFFFFFF - b + 1)) { 1479 /* 1480 * XXX this boundary check should account for 64bit 1481 * and remapping.. 1482 */ 1483 printf("XOR window#%d: no space for size 0x%08x at " 1484 "0x%08x\n", i, s, b); 1485 rv = 0; 1486 continue; 1487 } 1488 1489 j = decode_win_overlap(i, xor_wins_no, &xor_wins[0]); 1490 if (j >= 0) { 1491 printf("XOR window#%d: (0x%08x - 0x%08x) overlaps " 1492 "with #%d (0x%08x - 0x%08x)\n", i, b, e, j, 1493 xor_wins[j].base, 1494 xor_wins[j].base + xor_wins[j].size - 1); 1495 rv = 0; 1496 } 1497 } 1498 1499 return (rv); 1500} 1501 1502void 1503decode_win_xor_dump(u_long base) 1504{ 1505 int i, j; 1506 int e = 1; 1507 1508 if (pm_is_disabled(CPU_PM_CTRL_XOR)) 1509 return; 1510 1511 for (j = 0; j < xor_max_eng(); j++, e--) { 1512 for (i = 0; i < MV_WIN_XOR_MAX; i++) { 1513 printf("XOR window#%d: b 0x%08x, s 0x%08x", i, 1514 win_xor_br_read(base, i, e), win_xor_sz_read(base, i, e)); 1515 1516 if (win_xor_can_remap(i)) 1517 printf(", ha 0x%08x", win_xor_har_read(base, i, e)); 1518 1519 printf("\n"); 1520 } 1521 for (i = 0; i < MV_XOR_CHAN_MAX; i++) 1522 printf("XOR control#%d: 0x%08x\n", i, 1523 win_xor_ctrl_read(base, i, e)); 1524 } 1525} 1526 1527#else 1528/* Provide dummy functions to satisfy the build for SoCs not equipped with XOR */ 1529static int 1530decode_win_xor_valid(void) 1531{ 1532 1533 return (1); 1534} 1535 1536static void 1537decode_win_xor_setup(u_long base) 1538{ 1539} 1540 1541static void 1542decode_win_xor_dump(u_long base) 1543{ 1544} 1545#endif 1546 1547/************************************************************************** 1548 * CESA TDMA windows routines 1549 **************************************************************************/ 1550#if defined(SOC_MV_KIRKWOOD) || defined(SOC_MV_DISCOVERY) 1551/* 1552 * Dump CESA TDMA decode windows. 1553 */ 1554static void 1555decode_win_cesa_dump(u_long base) 1556{ 1557 int i; 1558 1559 if (pm_is_disabled(CPU_PM_CTRL_CRYPTO)) 1560 return; 1561 1562 for (i = 0; i < MV_WIN_CESA_MAX; i++) 1563 printf("CESA window#%d: c 0x%08x, b 0x%08x\n", i, 1564 win_cesa_cr_read(base, i), win_cesa_br_read(base, i)); 1565} 1566 1567 1568/* 1569 * Set CESA TDMA decode windows. 1570 */ 1571static void 1572decode_win_cesa_setup(u_long base) 1573{ 1574 uint32_t br, cr; 1575 int i, j; 1576 1577 if (pm_is_disabled(CPU_PM_CTRL_CRYPTO)) 1578 return; 1579 1580 /* Disable and clear all CESA windows */ 1581 for (i = 0; i < MV_WIN_CESA_MAX; i++) { 1582 win_cesa_cr_write(base, i, 0); 1583 win_cesa_br_write(base, i, 0); 1584 } 1585 1586 /* Only access to active DRAM banks is required. */ 1587 for (i = 0; i < MV_WIN_DDR_MAX; i++) 1588 if (ddr_is_active(i)) { 1589 br = ddr_base(i); 1590 cr = (((ddr_size(i) - 1) & 0xffff0000) | 1591 (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1); 1592 1593 /* Set the first available CESA window */ 1594 for (j = 0; j < MV_WIN_CESA_MAX; j++) { 1595 if (win_cesa_cr_read(base, j) & 0x1) 1596 continue; 1597 1598 win_cesa_br_write(base, j, br); 1599 win_cesa_cr_write(base, j, cr); 1600 break; 1601 } 1602 } 1603} 1604 1605/* 1606 * Check CESA TDMA decode windows. 1607 */ 1608static int 1609decode_win_cesa_valid(void) 1610{ 1611 1612 return (decode_win_can_cover_ddr(MV_WIN_CESA_MAX)); 1613} 1614#else 1615 1616/* 1617 * Provide dummy functions to satisfy the build for SoCs not equipped with 1618 * CESA 1619 */ 1620 1621static int 1622decode_win_cesa_valid(void) 1623{ 1624 1625 return (1); 1626} 1627 1628static void 1629decode_win_cesa_setup(u_long base) 1630{ 1631} 1632 1633static void 1634decode_win_cesa_dump(u_long base) 1635{ 1636} 1637#endif 1638 1639/************************************************************************** 1640 * SATA windows routines 1641 **************************************************************************/ 1642static void 1643decode_win_sata_setup(u_long base) 1644{ 1645 uint32_t cr, br; 1646 int i, j; 1647 1648 if (pm_is_disabled(CPU_PM_CTRL_SATA)) 1649 return; 1650 1651 for (i = 0; i < MV_WIN_SATA_MAX; i++) { 1652 win_sata_cr_write(base, i, 0); 1653 win_sata_br_write(base, i, 0); 1654 } 1655 1656 for (i = 0; i < MV_WIN_DDR_MAX; i++) 1657 if (ddr_is_active(i)) { 1658 cr = ((ddr_size(i) - 1) & 0xffff0000) | 1659 (ddr_attr(i) << 8) | (ddr_target(i) << 4) | 1; 1660 br = ddr_base(i); 1661 1662 /* Use the first available SATA window */ 1663 for (j = 0; j < MV_WIN_SATA_MAX; j++) { 1664 if ((win_sata_cr_read(base, j) & 1) != 0) 1665 continue; 1666 1667 win_sata_br_write(base, j, br); 1668 win_sata_cr_write(base, j, cr); 1669 break; 1670 } 1671 } 1672} 1673 1674static int 1675decode_win_sata_valid(void) 1676{ 1677 uint32_t dev, rev; 1678 1679 soc_id(&dev, &rev); 1680 if (dev == MV_DEV_88F5281) 1681 return (1); 1682 1683 return (decode_win_can_cover_ddr(MV_WIN_SATA_MAX)); 1684} 1685 1686/************************************************************************** 1687 * FDT parsing routines. 1688 **************************************************************************/ 1689 1690static int 1691fdt_get_ranges(const char *nodename, void *buf, int size, int *tuples, 1692 int *tuplesize) 1693{ 1694 phandle_t node; 1695 pcell_t addr_cells, par_addr_cells, size_cells; 1696 int len, tuple_size, tuples_count; 1697 1698 node = OF_finddevice(nodename); 1699 if (node <= 0) 1700 return (EINVAL); 1701 1702 if ((fdt_addrsize_cells(node, &addr_cells, &size_cells)) != 0) 1703 return (ENXIO); 1704 1705 par_addr_cells = fdt_parent_addr_cells(node); 1706 if (par_addr_cells > 2) 1707 return (ERANGE); 1708 1709 tuple_size = sizeof(pcell_t) * (addr_cells + par_addr_cells + 1710 size_cells); 1711 1712 /* Note the OF_getprop_alloc() cannot be used at this early stage. */ 1713 len = OF_getprop(node, "ranges", buf, size); 1714 1715 /* 1716 * XXX this does not handle the empty 'ranges;' case, which is 1717 * legitimate and should be allowed. 1718 */ 1719 tuples_count = len / tuple_size; 1720 if (tuples_count <= 0) 1721 return (ERANGE); 1722 1723 if (fdt_ranges_verify(buf, tuples_count, par_addr_cells, 1724 addr_cells, size_cells) != 0) 1725 return (ERANGE); 1726 1727 *tuples = tuples_count; 1728 *tuplesize = tuple_size; 1729 return (0); 1730} 1731 1732static int 1733win_cpu_from_dt(void) 1734{ 1735 pcell_t ranges[48]; 1736 u_long sram_base, sram_size; 1737 phandle_t node; 1738 int i, entry_size, err, t, tuple_size, tuples; 1739 1740 /* Retrieve 'ranges' property of '/localbus' node. */ 1741 if ((err = fdt_get_ranges("/localbus", ranges, sizeof(ranges), 1742 &tuples, &tuple_size)) != 0) 1743 return (err); 1744 1745 /* 1746 * Fill CPU decode windows table. 1747 */ 1748 bzero((void *)&cpu_win_tbl, sizeof(cpu_win_tbl)); 1749 1750 entry_size = tuple_size / sizeof(pcell_t); 1751 cpu_wins_no = tuples; 1752 1753 for (i = 0, t = 0; t < tuples; i += entry_size, t++) { 1754 cpu_win_tbl[t].target = 1; 1755 cpu_win_tbl[t].attr = fdt32_to_cpu(ranges[i + 1]); 1756 cpu_win_tbl[t].base = fdt32_to_cpu(ranges[i + 2]); 1757 cpu_win_tbl[t].size = fdt32_to_cpu(ranges[i + 3]); 1758 cpu_win_tbl[t].remap = -1; 1759 debugf("target = 0x%0x attr = 0x%0x base = 0x%0x " 1760 "size = 0x%0x remap = %d\n", cpu_win_tbl[t].target, 1761 cpu_win_tbl[t].attr, cpu_win_tbl[t].base, 1762 cpu_win_tbl[t].size, cpu_win_tbl[t].remap); 1763 } 1764 1765 /* 1766 * Retrieve CESA SRAM data. 1767 */ 1768 if ((node = OF_finddevice("sram")) != 0) 1769 if (fdt_is_compatible(node, "mrvl,cesa-sram")) 1770 goto moveon; 1771 1772 if ((node = OF_finddevice("/")) == 0) 1773 return (ENXIO); 1774 1775 if ((node = fdt_find_compatible(node, "mrvl,cesa-sram", 0)) == 0) 1776 /* SRAM block is not always present. */ 1777 return (0); 1778moveon: 1779 sram_base = sram_size = 0; 1780 if (fdt_regsize(node, &sram_base, &sram_size) != 0) 1781 return (EINVAL); 1782 1783 cpu_win_tbl[++t].target = MV_WIN_CESA_TARGET; 1784 cpu_win_tbl[t].attr = MV_WIN_CESA_ATTR; 1785 cpu_win_tbl[t].base = sram_base; 1786 cpu_win_tbl[t].size = sram_size; 1787 cpu_win_tbl[t].remap = -1; 1788 debugf("sram: base = 0x%0lx size = 0x%0lx\n", sram_base, sram_size); 1789 1790 return (0); 1791} 1792 1793static int 1794fdt_win_setup(void) 1795{ 1796 phandle_t node, child; 1797 struct soc_node_spec *soc_node; 1798 u_long size, base; 1799 int err, i; 1800 1801 node = OF_finddevice("/"); 1802 if (node == 0) 1803 panic("fdt_win_setup: no root node"); 1804 1805 node = fdt_find_compatible(node, "simple-bus", 1); 1806 if (node == 0) 1807 return (ENXIO); 1808 1809 /* 1810 * Traverse through all children of simple-bus node, and retrieve 1811 * decode windows data for devices (if applicable). 1812 */ 1813 for (child = OF_child(node); child != 0; child = OF_peer(child)) 1814 for (i = 0; soc_nodes[i].compat != NULL; i++) { 1815 1816 soc_node = &soc_nodes[i]; 1817 1818 if (!fdt_is_compatible(child, soc_node->compat)) 1819 continue; 1820 1821 err = fdt_regsize(child, &base, &size); 1822 if (err != 0) 1823 return (err); 1824 1825 base += fdt_immr_va; 1826 if (soc_node->decode_handler != NULL) 1827 soc_node->decode_handler(base); 1828 else 1829 return (ENXIO); 1830 1831 if (MV_DUMP_WIN && (soc_node->dump_handler != NULL)) 1832 soc_node->dump_handler(base); 1833 } 1834 1835 return (0); 1836} 1837 1838static void 1839fdt_fixup_busfreq(phandle_t root) 1840{ 1841 phandle_t sb; 1842 pcell_t freq; 1843 1844 /* 1845 * This fixup sets the simple-bus bus-frequency property. 1846 */ 1847 1848 if ((sb = fdt_find_compatible(root, "simple-bus", 1)) == 0) 1849 return; 1850 1851 freq = cpu_to_fdt32(get_tclk()); 1852 OF_setprop(sb, "bus-frequency", (void *)&freq, sizeof(freq)); 1853} 1854 1855struct fdt_fixup_entry fdt_fixup_table[] = { 1856 { "mrvl,DB-88F6281", &fdt_fixup_busfreq }, 1857 { NULL, NULL } 1858}; 1859 1860static int 1861fdt_pic_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig, 1862 int *pol) 1863{ 1864 1865 if (!fdt_is_compatible(node, "mrvl,pic")) 1866 return (ENXIO); 1867 1868 *interrupt = fdt32_to_cpu(intr[0]); 1869 *trig = INTR_TRIGGER_CONFORM; 1870 *pol = INTR_POLARITY_CONFORM; 1871 1872 return (0); 1873} 1874 1875fdt_pic_decode_t fdt_pic_table[] = { 1876 &fdt_pic_decode_ic, 1877 NULL 1878}; 1879