1/*- 2 * Copyright 2006-2007 by Juniper Networks. 3 * Copyright 2008 Semihalf. 4 * Copyright 2010 The FreeBSD Foundation 5 * All rights reserved. 6 * 7 * Portions of this software were developed by Semihalf 8 * under sponsorship from the FreeBSD Foundation. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 3. The name of the author may not be used to endorse or promote products 19 * derived from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 22 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 23 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 24 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 28 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * From: FreeBSD: src/sys/powerpc/mpc85xx/pci_ocp.c,v 1.9 2010/03/23 23:46:28 marcel 34 */ 35 36#include <sys/cdefs.h> 37__FBSDID("$FreeBSD$"); 38 39#include <sys/param.h> 40#include <sys/systm.h> 41#include <sys/ktr.h> 42#include <sys/sockio.h> 43#include <sys/mbuf.h> 44#include <sys/malloc.h> 45#include <sys/kernel.h> 46#include <sys/module.h> 47#include <sys/socket.h> 48#include <sys/queue.h> 49#include <sys/bus.h> 50#include <sys/lock.h> 51#include <sys/mutex.h> 52#include <sys/rman.h> 53#include <sys/endian.h> 54 55#include <vm/vm.h> 56#include <vm/pmap.h> 57 58#include <dev/ofw/ofw_pci.h> 59#include <dev/ofw/ofw_bus.h> 60#include <dev/ofw/ofw_bus_subr.h> 61#include <dev/pci/pcivar.h> 62#include <dev/pci/pcireg.h> 63#include <dev/pci/pcib_private.h> 64 65#include <powerpc/ofw/ofw_pci.h> 66 67#include "ofw_bus_if.h" 68#include "pcib_if.h" 69 70#include <machine/resource.h> 71#include <machine/bus.h> 72#include <machine/intr_machdep.h> 73 74#include <powerpc/mpc85xx/mpc85xx.h> 75 76#define REG_CFG_ADDR 0x0000 77#define CONFIG_ACCESS_ENABLE 0x80000000 78 79#define REG_CFG_DATA 0x0004 80#define REG_INT_ACK 0x0008 81 82#define REG_POTAR(n) (0x0c00 + 0x20 * (n)) 83#define REG_POTEAR(n) (0x0c04 + 0x20 * (n)) 84#define REG_POWBAR(n) (0x0c08 + 0x20 * (n)) 85#define REG_POWAR(n) (0x0c10 + 0x20 * (n)) 86 87#define REG_PITAR(n) (0x0e00 - 0x20 * (n)) 88#define REG_PIWBAR(n) (0x0e08 - 0x20 * (n)) 89#define REG_PIWBEAR(n) (0x0e0c - 0x20 * (n)) 90#define REG_PIWAR(n) (0x0e10 - 0x20 * (n)) 91 92#define REG_PEX_MES_DR 0x0020 93#define REG_PEX_MES_IER 0x0028 94#define REG_PEX_ERR_DR 0x0e00 95#define REG_PEX_ERR_EN 0x0e08 96 97#define PCIR_LTSSM 0x404 98#define LTSSM_STAT_L0 0x16 99 100#define DEVFN(b, s, f) ((b << 16) | (s << 8) | f) 101 102struct fsl_pcib_softc { 103 struct ofw_pci_softc pci_sc; 104 device_t sc_dev; 105 106 int sc_iomem_target; 107 bus_addr_t sc_iomem_alloc, sc_iomem_start, sc_iomem_end; 108 int sc_ioport_target; 109 bus_addr_t sc_ioport_alloc, sc_ioport_start, sc_ioport_end; 110 111 struct resource *sc_res; 112 bus_space_handle_t sc_bsh; 113 bus_space_tag_t sc_bst; 114 int sc_rid; 115 116 int sc_busnr; 117 int sc_pcie; 118 uint8_t sc_pcie_capreg; /* PCI-E Capability Reg Set */ 119 120 /* Devices that need special attention. */ 121 int sc_devfn_tundra; 122 int sc_devfn_via_ide; 123}; 124 125/* Local forward declerations. */ 126static uint32_t fsl_pcib_cfgread(struct fsl_pcib_softc *, u_int, u_int, u_int, 127 u_int, int); 128static void fsl_pcib_cfgwrite(struct fsl_pcib_softc *, u_int, u_int, u_int, 129 u_int, uint32_t, int); 130static int fsl_pcib_decode_win(phandle_t, struct fsl_pcib_softc *); 131static void fsl_pcib_err_init(device_t); 132static void fsl_pcib_inbound(struct fsl_pcib_softc *, int, int, u_long, 133 u_long, u_long); 134static int fsl_pcib_init(struct fsl_pcib_softc *, int, int); 135static void fsl_pcib_outbound(struct fsl_pcib_softc *, int, int, u_long, 136 u_long, u_long); 137 138/* Forward declerations. */ 139static int fsl_pcib_attach(device_t); 140static int fsl_pcib_detach(device_t); 141static int fsl_pcib_probe(device_t); 142 143static int fsl_pcib_maxslots(device_t); 144static uint32_t fsl_pcib_read_config(device_t, u_int, u_int, u_int, u_int, int); 145static void fsl_pcib_write_config(device_t, u_int, u_int, u_int, u_int, 146 uint32_t, int); 147 148/* Configuration r/w mutex. */ 149struct mtx pcicfg_mtx; 150static int mtx_initialized = 0; 151 152/* 153 * Bus interface definitions. 154 */ 155static device_method_t fsl_pcib_methods[] = { 156 /* Device interface */ 157 DEVMETHOD(device_probe, fsl_pcib_probe), 158 DEVMETHOD(device_attach, fsl_pcib_attach), 159 DEVMETHOD(device_detach, fsl_pcib_detach), 160 161 /* pcib interface */ 162 DEVMETHOD(pcib_maxslots, fsl_pcib_maxslots), 163 DEVMETHOD(pcib_read_config, fsl_pcib_read_config), 164 DEVMETHOD(pcib_write_config, fsl_pcib_write_config), 165 166 DEVMETHOD_END 167}; 168 169static devclass_t fsl_pcib_devclass; 170 171DEFINE_CLASS_1(pcib, fsl_pcib_driver, fsl_pcib_methods, 172 sizeof(struct fsl_pcib_softc), ofw_pci_driver); 173DRIVER_MODULE(pcib, ofwbus, fsl_pcib_driver, fsl_pcib_devclass, 0, 0); 174 175static int 176fsl_pcib_probe(device_t dev) 177{ 178 179 if (ofw_bus_get_type(dev) == NULL || 180 strcmp(ofw_bus_get_type(dev), "pci") != 0) 181 return (ENXIO); 182 183 if (!(ofw_bus_is_compatible(dev, "fsl,mpc8540-pci") || 184 ofw_bus_is_compatible(dev, "fsl,mpc8548-pcie"))) 185 return (ENXIO); 186 187 device_set_desc(dev, "Freescale Integrated PCI/PCI-E Controller"); 188 return (BUS_PROBE_DEFAULT); 189} 190 191static int 192fsl_pcib_attach(device_t dev) 193{ 194 struct fsl_pcib_softc *sc; 195 phandle_t node; 196 uint32_t cfgreg; 197 int maxslot, error; 198 uint8_t ltssm, capptr; 199 200 sc = device_get_softc(dev); 201 sc->sc_dev = dev; 202 203 sc->sc_rid = 0; 204 sc->sc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->sc_rid, 205 RF_ACTIVE); 206 if (sc->sc_res == NULL) { 207 device_printf(dev, "could not map I/O memory\n"); 208 return (ENXIO); 209 } 210 sc->sc_bst = rman_get_bustag(sc->sc_res); 211 sc->sc_bsh = rman_get_bushandle(sc->sc_res); 212 sc->sc_busnr = 0; 213 214 if (!mtx_initialized) { 215 mtx_init(&pcicfg_mtx, "pcicfg", NULL, MTX_SPIN); 216 mtx_initialized = 1; 217 } 218 219 cfgreg = fsl_pcib_cfgread(sc, 0, 0, 0, PCIR_VENDOR, 2); 220 if (cfgreg != 0x1057 && cfgreg != 0x1957) 221 goto err; 222 223 capptr = fsl_pcib_cfgread(sc, 0, 0, 0, PCIR_CAP_PTR, 1); 224 while (capptr != 0) { 225 cfgreg = fsl_pcib_cfgread(sc, 0, 0, 0, capptr, 2); 226 switch (cfgreg & 0xff) { 227 case PCIY_PCIX: 228 break; 229 case PCIY_EXPRESS: 230 sc->sc_pcie = 1; 231 sc->sc_pcie_capreg = capptr; 232 break; 233 } 234 capptr = (cfgreg >> 8) & 0xff; 235 } 236 237 node = ofw_bus_get_node(dev); 238 239 /* 240 * Initialize generic OF PCI interface (ranges, etc.) 241 */ 242 243 error = ofw_pci_init(dev); 244 if (error) 245 return (error); 246 247 /* 248 * Configure decode windows for PCI(E) access. 249 */ 250 if (fsl_pcib_decode_win(node, sc) != 0) 251 goto err; 252 253 cfgreg = fsl_pcib_cfgread(sc, 0, 0, 0, PCIR_COMMAND, 2); 254 cfgreg |= PCIM_CMD_SERRESPEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN | 255 PCIM_CMD_PORTEN; 256 fsl_pcib_cfgwrite(sc, 0, 0, 0, PCIR_COMMAND, cfgreg, 2); 257 258 sc->sc_devfn_tundra = -1; 259 sc->sc_devfn_via_ide = -1; 260 261 262 /* 263 * Scan bus using firmware configured, 0 based bus numbering. 264 */ 265 sc->sc_busnr = 0; 266 maxslot = (sc->sc_pcie) ? 0 : PCI_SLOTMAX; 267 fsl_pcib_init(sc, sc->sc_busnr, maxslot); 268 269 if (sc->sc_pcie) { 270 ltssm = fsl_pcib_cfgread(sc, 0, 0, 0, PCIR_LTSSM, 1); 271 if (ltssm < LTSSM_STAT_L0) { 272 if (bootverbose) 273 printf("PCI %d: no PCIE link, skipping\n", 274 device_get_unit(dev)); 275 return (0); 276 } 277 } 278 279 fsl_pcib_err_init(dev); 280 281 return (ofw_pci_attach(dev)); 282 283err: 284 return (ENXIO); 285} 286 287static uint32_t 288fsl_pcib_cfgread(struct fsl_pcib_softc *sc, u_int bus, u_int slot, u_int func, 289 u_int reg, int bytes) 290{ 291 uint32_t addr, data; 292 293 if (bus == sc->sc_busnr - 1) 294 bus = 0; 295 296 addr = CONFIG_ACCESS_ENABLE; 297 addr |= (bus & 0xff) << 16; 298 addr |= (slot & 0x1f) << 11; 299 addr |= (func & 0x7) << 8; 300 addr |= reg & 0xfc; 301 if (sc->sc_pcie) 302 addr |= (reg & 0xf00) << 16; 303 304 mtx_lock_spin(&pcicfg_mtx); 305 bus_space_write_4(sc->sc_bst, sc->sc_bsh, REG_CFG_ADDR, addr); 306 307 switch (bytes) { 308 case 1: 309 data = bus_space_read_1(sc->sc_bst, sc->sc_bsh, 310 REG_CFG_DATA + (reg & 3)); 311 break; 312 case 2: 313 data = le16toh(bus_space_read_2(sc->sc_bst, sc->sc_bsh, 314 REG_CFG_DATA + (reg & 2))); 315 break; 316 case 4: 317 data = le32toh(bus_space_read_4(sc->sc_bst, sc->sc_bsh, 318 REG_CFG_DATA)); 319 break; 320 default: 321 data = ~0; 322 break; 323 } 324 mtx_unlock_spin(&pcicfg_mtx); 325 return (data); 326} 327 328static void 329fsl_pcib_cfgwrite(struct fsl_pcib_softc *sc, u_int bus, u_int slot, u_int func, 330 u_int reg, uint32_t data, int bytes) 331{ 332 uint32_t addr; 333 334 if (bus == sc->sc_busnr - 1) 335 bus = 0; 336 337 addr = CONFIG_ACCESS_ENABLE; 338 addr |= (bus & 0xff) << 16; 339 addr |= (slot & 0x1f) << 11; 340 addr |= (func & 0x7) << 8; 341 addr |= reg & 0xfc; 342 if (sc->sc_pcie) 343 addr |= (reg & 0xf00) << 16; 344 345 mtx_lock_spin(&pcicfg_mtx); 346 bus_space_write_4(sc->sc_bst, sc->sc_bsh, REG_CFG_ADDR, addr); 347 348 switch (bytes) { 349 case 1: 350 bus_space_write_1(sc->sc_bst, sc->sc_bsh, 351 REG_CFG_DATA + (reg & 3), data); 352 break; 353 case 2: 354 bus_space_write_2(sc->sc_bst, sc->sc_bsh, 355 REG_CFG_DATA + (reg & 2), htole16(data)); 356 break; 357 case 4: 358 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 359 REG_CFG_DATA, htole32(data)); 360 break; 361 } 362 mtx_unlock_spin(&pcicfg_mtx); 363} 364 365#if 0 366static void 367dump(struct fsl_pcib_softc *sc) 368{ 369 unsigned int i; 370 371#define RD(o) bus_space_read_4(sc->sc_bst, sc->sc_bsh, o) 372 for (i = 0; i < 5; i++) { 373 printf("POTAR%u =0x%08x\n", i, RD(REG_POTAR(i))); 374 printf("POTEAR%u =0x%08x\n", i, RD(REG_POTEAR(i))); 375 printf("POWBAR%u =0x%08x\n", i, RD(REG_POWBAR(i))); 376 printf("POWAR%u =0x%08x\n", i, RD(REG_POWAR(i))); 377 } 378 printf("\n"); 379 for (i = 1; i < 4; i++) { 380 printf("PITAR%u =0x%08x\n", i, RD(REG_PITAR(i))); 381 printf("PIWBAR%u =0x%08x\n", i, RD(REG_PIWBAR(i))); 382 printf("PIWBEAR%u=0x%08x\n", i, RD(REG_PIWBEAR(i))); 383 printf("PIWAR%u =0x%08x\n", i, RD(REG_PIWAR(i))); 384 } 385 printf("\n"); 386#undef RD 387 388 for (i = 0; i < 0x48; i += 4) { 389 printf("cfg%02x=0x%08x\n", i, fsl_pcib_cfgread(sc, 0, 0, 0, 390 i, 4)); 391 } 392} 393#endif 394 395static int 396fsl_pcib_maxslots(device_t dev) 397{ 398 struct fsl_pcib_softc *sc = device_get_softc(dev); 399 400 return ((sc->sc_pcie) ? 0 : PCI_SLOTMAX); 401} 402 403static uint32_t 404fsl_pcib_read_config(device_t dev, u_int bus, u_int slot, u_int func, 405 u_int reg, int bytes) 406{ 407 struct fsl_pcib_softc *sc = device_get_softc(dev); 408 u_int devfn; 409 410 if (bus == sc->sc_busnr && !sc->sc_pcie && slot < 10) 411 return (~0); 412 devfn = DEVFN(bus, slot, func); 413 if (devfn == sc->sc_devfn_tundra) 414 return (~0); 415 if (devfn == sc->sc_devfn_via_ide && reg == PCIR_INTPIN) 416 return (1); 417 return (fsl_pcib_cfgread(sc, bus, slot, func, reg, bytes)); 418} 419 420static void 421fsl_pcib_write_config(device_t dev, u_int bus, u_int slot, u_int func, 422 u_int reg, uint32_t val, int bytes) 423{ 424 struct fsl_pcib_softc *sc = device_get_softc(dev); 425 426 if (bus == sc->sc_busnr && !sc->sc_pcie && slot < 10) 427 return; 428 fsl_pcib_cfgwrite(sc, bus, slot, func, reg, val, bytes); 429} 430 431static void 432fsl_pcib_init_via(struct fsl_pcib_softc *sc, uint16_t device, int bus, 433 int slot, int fn) 434{ 435 436 if (device == 0x0686) { 437 fsl_pcib_write_config(sc->sc_dev, bus, slot, fn, 0x52, 0x34, 1); 438 fsl_pcib_write_config(sc->sc_dev, bus, slot, fn, 0x77, 0x00, 1); 439 fsl_pcib_write_config(sc->sc_dev, bus, slot, fn, 0x83, 0x98, 1); 440 fsl_pcib_write_config(sc->sc_dev, bus, slot, fn, 0x85, 0x03, 1); 441 } else if (device == 0x0571) { 442 sc->sc_devfn_via_ide = DEVFN(bus, slot, fn); 443 fsl_pcib_write_config(sc->sc_dev, bus, slot, fn, 0x40, 0x0b, 1); 444 } 445} 446 447static int 448fsl_pcib_init_bar(struct fsl_pcib_softc *sc, int bus, int slot, int func, 449 int barno) 450{ 451 bus_addr_t *allocp; 452 uint32_t addr, mask, size; 453 int reg, width; 454 455 reg = PCIR_BAR(barno); 456 457 if (DEVFN(bus, slot, func) == sc->sc_devfn_via_ide) { 458 switch (barno) { 459 case 0: addr = 0x1f0; break; 460 case 1: addr = 0x3f4; break; 461 case 2: addr = 0x170; break; 462 case 3: addr = 0x374; break; 463 case 4: addr = 0xcc0; break; 464 default: return (1); 465 } 466 fsl_pcib_write_config(sc->sc_dev, bus, slot, func, reg, addr, 4); 467 return (1); 468 } 469 470 fsl_pcib_write_config(sc->sc_dev, bus, slot, func, reg, ~0, 4); 471 size = fsl_pcib_read_config(sc->sc_dev, bus, slot, func, reg, 4); 472 if (size == 0) 473 return (1); 474 width = ((size & 7) == 4) ? 2 : 1; 475 476 if (size & 1) { /* I/O port */ 477 allocp = &sc->sc_ioport_alloc; 478 size &= ~3; 479 if ((size & 0xffff0000) == 0) 480 size |= 0xffff0000; 481 } else { /* memory */ 482 allocp = &sc->sc_iomem_alloc; 483 size &= ~15; 484 } 485 mask = ~size; 486 size = mask + 1; 487 /* Sanity check (must be a power of 2). */ 488 if (size & mask) 489 return (width); 490 491 addr = (*allocp + mask) & ~mask; 492 *allocp = addr + size; 493 494 if (bootverbose) 495 printf("PCI %u:%u:%u:%u: reg %x: size=%08x: addr=%08x\n", 496 device_get_unit(sc->sc_dev), bus, slot, func, reg, 497 size, addr); 498 499 fsl_pcib_write_config(sc->sc_dev, bus, slot, func, reg, addr, 4); 500 if (width == 2) 501 fsl_pcib_write_config(sc->sc_dev, bus, slot, func, reg + 4, 502 0, 4); 503 return (width); 504} 505 506static int 507fsl_pcib_init(struct fsl_pcib_softc *sc, int bus, int maxslot) 508{ 509 int secbus; 510 int old_pribus, old_secbus, old_subbus; 511 int new_pribus, new_secbus, new_subbus; 512 int slot, func, maxfunc; 513 int bar, maxbar; 514 uint16_t vendor, device; 515 uint8_t command, hdrtype, class, subclass; 516 517 secbus = bus; 518 for (slot = 0; slot <= maxslot; slot++) { 519 maxfunc = 0; 520 for (func = 0; func <= maxfunc; func++) { 521 hdrtype = fsl_pcib_read_config(sc->sc_dev, bus, slot, 522 func, PCIR_HDRTYPE, 1); 523 524 if ((hdrtype & PCIM_HDRTYPE) > PCI_MAXHDRTYPE) 525 continue; 526 527 if (func == 0 && (hdrtype & PCIM_MFDEV)) 528 maxfunc = PCI_FUNCMAX; 529 530 vendor = fsl_pcib_read_config(sc->sc_dev, bus, slot, 531 func, PCIR_VENDOR, 2); 532 device = fsl_pcib_read_config(sc->sc_dev, bus, slot, 533 func, PCIR_DEVICE, 2); 534 535 if (vendor == 0x1957 && device == 0x3fff) { 536 sc->sc_devfn_tundra = DEVFN(bus, slot, func); 537 continue; 538 } 539 540 command = fsl_pcib_read_config(sc->sc_dev, bus, slot, 541 func, PCIR_COMMAND, 1); 542 command &= ~(PCIM_CMD_MEMEN | PCIM_CMD_PORTEN); 543 fsl_pcib_write_config(sc->sc_dev, bus, slot, func, 544 PCIR_COMMAND, command, 1); 545 546 if (vendor == 0x1106) 547 fsl_pcib_init_via(sc, device, bus, slot, func); 548 549 /* Program the base address registers. */ 550 maxbar = (hdrtype & PCIM_HDRTYPE) ? 1 : 6; 551 bar = 0; 552 while (bar < maxbar) 553 bar += fsl_pcib_init_bar(sc, bus, slot, func, 554 bar); 555 556 /* Put a placeholder interrupt value */ 557 fsl_pcib_write_config(sc->sc_dev, bus, slot, func, 558 PCIR_INTLINE, PCI_INVALID_IRQ, 1); 559 560 command |= PCIM_CMD_MEMEN | PCIM_CMD_PORTEN; 561 fsl_pcib_write_config(sc->sc_dev, bus, slot, func, 562 PCIR_COMMAND, command, 1); 563 564 /* 565 * Handle PCI-PCI bridges 566 */ 567 class = fsl_pcib_read_config(sc->sc_dev, bus, slot, 568 func, PCIR_CLASS, 1); 569 subclass = fsl_pcib_read_config(sc->sc_dev, bus, slot, 570 func, PCIR_SUBCLASS, 1); 571 572 /* Allow only proper PCI-PCI briges */ 573 if (class != PCIC_BRIDGE) 574 continue; 575 if (subclass != PCIS_BRIDGE_PCI) 576 continue; 577 578 secbus++; 579 580 /* Program I/O decoder. */ 581 fsl_pcib_write_config(sc->sc_dev, bus, slot, func, 582 PCIR_IOBASEL_1, sc->sc_ioport_start >> 8, 1); 583 fsl_pcib_write_config(sc->sc_dev, bus, slot, func, 584 PCIR_IOLIMITL_1, sc->sc_ioport_end >> 8, 1); 585 fsl_pcib_write_config(sc->sc_dev, bus, slot, func, 586 PCIR_IOBASEH_1, sc->sc_ioport_start >> 16, 2); 587 fsl_pcib_write_config(sc->sc_dev, bus, slot, func, 588 PCIR_IOLIMITH_1, sc->sc_ioport_end >> 16, 2); 589 590 /* Program (non-prefetchable) memory decoder. */ 591 fsl_pcib_write_config(sc->sc_dev, bus, slot, func, 592 PCIR_MEMBASE_1, sc->sc_iomem_start >> 16, 2); 593 fsl_pcib_write_config(sc->sc_dev, bus, slot, func, 594 PCIR_MEMLIMIT_1, sc->sc_iomem_end >> 16, 2); 595 596 /* Program prefetchable memory decoder. */ 597 fsl_pcib_write_config(sc->sc_dev, bus, slot, func, 598 PCIR_PMBASEL_1, 0x0010, 2); 599 fsl_pcib_write_config(sc->sc_dev, bus, slot, func, 600 PCIR_PMLIMITL_1, 0x000f, 2); 601 fsl_pcib_write_config(sc->sc_dev, bus, slot, func, 602 PCIR_PMBASEH_1, 0x00000000, 4); 603 fsl_pcib_write_config(sc->sc_dev, bus, slot, func, 604 PCIR_PMLIMITH_1, 0x00000000, 4); 605 606 /* Read currect bus register configuration */ 607 old_pribus = fsl_pcib_read_config(sc->sc_dev, bus, 608 slot, func, PCIR_PRIBUS_1, 1); 609 old_secbus = fsl_pcib_read_config(sc->sc_dev, bus, 610 slot, func, PCIR_SECBUS_1, 1); 611 old_subbus = fsl_pcib_read_config(sc->sc_dev, bus, 612 slot, func, PCIR_SUBBUS_1, 1); 613 614 if (bootverbose) 615 printf("PCI: reading firmware bus numbers for " 616 "secbus = %d (bus/sec/sub) = (%d/%d/%d)\n", 617 secbus, old_pribus, old_secbus, old_subbus); 618 619 new_pribus = bus; 620 new_secbus = secbus; 621 622 secbus = fsl_pcib_init(sc, secbus, 623 (subclass == PCIS_BRIDGE_PCI) ? PCI_SLOTMAX : 0); 624 625 new_subbus = secbus; 626 627 if (bootverbose) 628 printf("PCI: translate firmware bus numbers " 629 "for secbus %d (%d/%d/%d) -> (%d/%d/%d)\n", 630 secbus, old_pribus, old_secbus, old_subbus, 631 new_pribus, new_secbus, new_subbus); 632 633 fsl_pcib_write_config(sc->sc_dev, bus, slot, func, 634 PCIR_PRIBUS_1, new_pribus, 1); 635 fsl_pcib_write_config(sc->sc_dev, bus, slot, func, 636 PCIR_SECBUS_1, new_secbus, 1); 637 fsl_pcib_write_config(sc->sc_dev, bus, slot, func, 638 PCIR_SUBBUS_1, new_subbus, 1); 639 } 640 } 641 642 return (secbus); 643} 644 645static void 646fsl_pcib_inbound(struct fsl_pcib_softc *sc, int wnd, int tgt, u_long start, 647 u_long size, u_long pci_start) 648{ 649 uint32_t attr, bar, tar; 650 651 KASSERT(wnd > 0, ("%s: inbound window 0 is invalid", __func__)); 652 653 switch (tgt) { 654 /* XXX OCP85XX_TGTIF_RAM2, OCP85XX_TGTIF_RAM_INTL should be handled */ 655 case OCP85XX_TGTIF_RAM1: 656 attr = 0xa0f55000 | (ffsl(size) - 2); 657 break; 658 default: 659 attr = 0; 660 break; 661 } 662 tar = start >> 12; 663 bar = pci_start >> 12; 664 665 bus_space_write_4(sc->sc_bst, sc->sc_bsh, REG_PITAR(wnd), tar); 666 bus_space_write_4(sc->sc_bst, sc->sc_bsh, REG_PIWBEAR(wnd), 0); 667 bus_space_write_4(sc->sc_bst, sc->sc_bsh, REG_PIWBAR(wnd), bar); 668 bus_space_write_4(sc->sc_bst, sc->sc_bsh, REG_PIWAR(wnd), attr); 669} 670 671static void 672fsl_pcib_outbound(struct fsl_pcib_softc *sc, int wnd, int res, u_long start, 673 u_long size, u_long pci_start) 674{ 675 uint32_t attr, bar, tar; 676 677 switch (res) { 678 case SYS_RES_MEMORY: 679 attr = 0x80044000 | (ffsl(size) - 2); 680 break; 681 case SYS_RES_IOPORT: 682 attr = 0x80088000 | (ffsl(size) - 2); 683 break; 684 default: 685 attr = 0x0004401f; 686 break; 687 } 688 bar = start >> 12; 689 tar = pci_start >> 12; 690 691 bus_space_write_4(sc->sc_bst, sc->sc_bsh, REG_POTAR(wnd), tar); 692 bus_space_write_4(sc->sc_bst, sc->sc_bsh, REG_POTEAR(wnd), 0); 693 bus_space_write_4(sc->sc_bst, sc->sc_bsh, REG_POWBAR(wnd), bar); 694 bus_space_write_4(sc->sc_bst, sc->sc_bsh, REG_POWAR(wnd), attr); 695} 696 697 698static void 699fsl_pcib_err_init(device_t dev) 700{ 701 struct fsl_pcib_softc *sc; 702 uint16_t sec_stat, dsr; 703 uint32_t dcr, err_en; 704 705 sc = device_get_softc(dev); 706 707 sec_stat = fsl_pcib_cfgread(sc, 0, 0, 0, PCIR_SECSTAT_1, 2); 708 if (sec_stat) 709 fsl_pcib_cfgwrite(sc, 0, 0, 0, PCIR_SECSTAT_1, 0xffff, 2); 710 if (sc->sc_pcie) { 711 /* Clear error bits */ 712 bus_space_write_4(sc->sc_bst, sc->sc_bsh, REG_PEX_MES_IER, 713 0xffffffff); 714 bus_space_write_4(sc->sc_bst, sc->sc_bsh, REG_PEX_MES_DR, 715 0xffffffff); 716 bus_space_write_4(sc->sc_bst, sc->sc_bsh, REG_PEX_ERR_DR, 717 0xffffffff); 718 719 dsr = fsl_pcib_cfgread(sc, 0, 0, 0, 720 sc->sc_pcie_capreg + PCIER_DEVICE_STA, 2); 721 if (dsr) 722 fsl_pcib_cfgwrite(sc, 0, 0, 0, 723 sc->sc_pcie_capreg + PCIER_DEVICE_STA, 724 0xffff, 2); 725 726 /* Enable all errors reporting */ 727 err_en = 0x00bfff00; 728 bus_space_write_4(sc->sc_bst, sc->sc_bsh, REG_PEX_ERR_EN, 729 err_en); 730 731 /* Enable error reporting: URR, FER, NFER */ 732 dcr = fsl_pcib_cfgread(sc, 0, 0, 0, 733 sc->sc_pcie_capreg + PCIER_DEVICE_CTL, 4); 734 dcr |= PCIEM_CTL_URR_ENABLE | PCIEM_CTL_FER_ENABLE | 735 PCIEM_CTL_NFER_ENABLE; 736 fsl_pcib_cfgwrite(sc, 0, 0, 0, 737 sc->sc_pcie_capreg + PCIER_DEVICE_CTL, dcr, 4); 738 } 739} 740 741static int 742fsl_pcib_detach(device_t dev) 743{ 744 745 if (mtx_initialized) { 746 mtx_destroy(&pcicfg_mtx); 747 mtx_initialized = 0; 748 } 749 return (bus_generic_detach(dev)); 750} 751 752static int 753fsl_pcib_decode_win(phandle_t node, struct fsl_pcib_softc *sc) 754{ 755 device_t dev; 756 int error, i, trgt; 757 758 dev = sc->sc_dev; 759 760 fsl_pcib_outbound(sc, 0, -1, 0, 0, 0); 761 762 /* 763 * Configure LAW decode windows. 764 */ 765 error = law_pci_target(sc->sc_res, &sc->sc_iomem_target, 766 &sc->sc_ioport_target); 767 if (error != 0) { 768 device_printf(dev, "could not retrieve PCI LAW target info\n"); 769 return (error); 770 } 771 772 for (i = 0; i < sc->pci_sc.sc_nrange; i++) { 773 switch (sc->pci_sc.sc_range[i].pci_hi & 774 OFW_PCI_PHYS_HI_SPACEMASK) { 775 case OFW_PCI_PHYS_HI_SPACE_CONFIG: 776 continue; 777 case OFW_PCI_PHYS_HI_SPACE_IO: 778 trgt = sc->sc_ioport_target; 779 fsl_pcib_outbound(sc, 2, SYS_RES_IOPORT, 780 sc->pci_sc.sc_range[i].host, 781 sc->pci_sc.sc_range[i].size, 782 sc->pci_sc.sc_range[i].pci); 783 sc->sc_ioport_start = sc->pci_sc.sc_range[i].host; 784 sc->sc_ioport_end = sc->pci_sc.sc_range[i].host + 785 sc->pci_sc.sc_range[i].size; 786 sc->sc_ioport_alloc = 0x1000 + sc->pci_sc.sc_range[i].pci; 787 break; 788 case OFW_PCI_PHYS_HI_SPACE_MEM32: 789 case OFW_PCI_PHYS_HI_SPACE_MEM64: 790 trgt = sc->sc_iomem_target; 791 fsl_pcib_outbound(sc, 1, SYS_RES_MEMORY, 792 sc->pci_sc.sc_range[i].host, 793 sc->pci_sc.sc_range[i].size, 794 sc->pci_sc.sc_range[i].pci); 795 sc->sc_iomem_start = sc->pci_sc.sc_range[i].host; 796 sc->sc_iomem_end = sc->pci_sc.sc_range[i].host + 797 sc->pci_sc.sc_range[i].size; 798 sc->sc_iomem_alloc = sc->pci_sc.sc_range[i].pci; 799 break; 800 default: 801 panic("Unknown range type %#x\n", 802 sc->pci_sc.sc_range[i].pci_hi & 803 OFW_PCI_PHYS_HI_SPACEMASK); 804 } 805 error = law_enable(trgt, sc->pci_sc.sc_range[i].host, 806 sc->pci_sc.sc_range[i].size); 807 if (error != 0) { 808 device_printf(dev, "could not program LAW for range " 809 "%d\n", i); 810 return (error); 811 } 812 } 813 814 /* 815 * Set outbout and inbound windows. 816 */ 817 fsl_pcib_outbound(sc, 3, -1, 0, 0, 0); 818 fsl_pcib_outbound(sc, 4, -1, 0, 0, 0); 819 820 fsl_pcib_inbound(sc, 1, -1, 0, 0, 0); 821 fsl_pcib_inbound(sc, 2, -1, 0, 0, 0); 822 fsl_pcib_inbound(sc, 3, OCP85XX_TGTIF_RAM1, 0, 823 2U * 1024U * 1024U * 1024U, 0); 824 825 return (0); 826} 827 828