i81342_pci.c revision 331722
1/*- 2 * Copyright (c) 2006 Olivier Houchard 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 16 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 18 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 22 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 23 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 24 * POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h> 28__FBSDID("$FreeBSD: stable/11/sys/arm/xscale/i8134x/i81342_pci.c 331722 2018-03-29 02:50:57Z eadler $"); 29 30#include <sys/param.h> 31#include <sys/systm.h> 32#include <sys/bus.h> 33#include <sys/kernel.h> 34#include <sys/module.h> 35#include <sys/types.h> 36#include <sys/rman.h> 37 38#include <machine/bus.h> 39#include <machine/cpu.h> 40#include <machine/pcb.h> 41#include <vm/vm.h> 42#include <vm/pmap.h> 43#include <vm/vm_extern.h> 44 45#include <arm/xscale/i8134x/i81342reg.h> 46#include <arm/xscale/i8134x/i81342var.h> 47 48#include <dev/pci/pcivar.h> 49#include <dev/pci/pcib_private.h> 50#include "pcib_if.h" 51 52#include <dev/pci/pcireg.h> 53 54static pcib_read_config_t i81342_pci_read_config; 55static pcib_write_config_t i81342_pci_write_config; 56 57static int 58i81342_pci_probe(device_t dev) 59{ 60 struct i81342_pci_softc *sc; 61 62 sc = device_get_softc(dev); 63 if (device_get_unit(dev) == 0) { 64 device_set_desc(dev, "i81342 PCI-X bus"); 65 sc->sc_is_atux = 1; 66 } else { 67 device_set_desc(dev, "i81342 PCIe bus"); 68 sc->sc_is_atux = 0; 69 } 70 return (0); 71} 72 73#define PCI_MAPREG_MEM_PREFETCHABLE_MASK 0x00000008 74#define PCI_MAPREG_MEM_TYPE_64BIT 0x00000004 75 76static int 77i81342_pci_attach(device_t dev) 78{ 79 struct i81342_softc *parent_sc; 80 struct i81342_pci_softc *sc; 81 uint32_t memsize, memstart; 82 uint32_t reg; 83 int func; 84 uint32_t busno; 85 86 sc = device_get_softc(dev); 87 parent_sc = device_get_softc(device_get_parent(dev)); 88 sc->sc_atu_sh = sc->sc_is_atux ? parent_sc->sc_atux_sh : 89 parent_sc->sc_atue_sh; 90 sc->sc_st = parent_sc->sc_st; 91 if (bus_space_read_4(sc->sc_st, parent_sc->sc_sh, IOP34X_ESSTSR0) 92 & IOP34X_INT_SEL_PCIX) { 93 if (sc->sc_is_atux) 94 func = 5; 95 else 96 func = 0; 97 } else { 98 if (sc->sc_is_atux) 99 func = 0; 100 else 101 func = 5; 102 } 103 i81342_io_bs_init(&sc->sc_pciio, sc); 104 i81342_mem_bs_init(&sc->sc_pcimem, sc); 105 i81342_sdram_bounds(sc->sc_st, IOP34X_VADDR, &memstart, &memsize); 106 if (sc->sc_is_atux) { 107 reg = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCSR); 108 if (reg & ATUX_P_RSTOUT) { 109 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_PCSR, 110 reg &~ ATUX_P_RSTOUT); 111 DELAY(200); 112 } 113 } 114 /* Setup the Inbound windows. */ 115 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IABAR0, 0); 116 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IAUBAR0, 0); 117 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR0, 0); 118 119 /* Set the mapping Physical address <=> PCI address */ 120 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IABAR1, 121 memstart | PCI_MAPREG_MEM_PREFETCHABLE_MASK | 122 PCI_MAPREG_MEM_TYPE_64BIT); 123 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IAUBAR1, 0); 124 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR1, 125 rounddown2(~(0xfff), memsize)); 126 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IATVR1, memstart); 127 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IAUTVR1, 0); 128 129 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IABAR2, 0); 130 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IAUBAR2, 0); 131 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR2, 0); 132 133 /* Setup the Outbound IO Bar */ 134 if (sc->sc_is_atux) 135 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OIOBAR, 136 (IOP34X_PCIX_OIOBAR >> 4) | func); 137 else 138 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OIOBAR, 139 (IOP34X_PCIE_OIOBAR >> 4) | func); 140 141 /* Setup the Outbound windows */ 142 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMBAR0, 0); 143 if (sc->sc_is_atux) 144 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMBAR1, 145 (IOP34X_PCIX_OMBAR >> 32) | (func << ATU_OUMBAR_FUNC) | 146 ATU_OUMBAR_EN); 147 else 148 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMBAR1, 149 (IOP34X_PCIE_OMBAR >> 32) | (func << ATU_OUMBAR_FUNC) | 150 ATU_OUMBAR_EN); 151 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMWTVR1, 0); 152 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMBAR2, 0); 153 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OUMBAR3, 0); 154 155 /* Enable the outbound windows. */ 156 reg = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_CR); 157 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_CR, 158 reg | ATU_CR_OUT_EN); 159 160 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR, 161 bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR) & ATUX_ISR_ERRMSK); 162 /* 163 * Enable bus mastering, memory access, SERR, and parity 164 * checking on the ATU. 165 */ 166 if (sc->sc_is_atux) { 167 busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR); 168 busno = PCIXSR_BUSNO(busno); 169 } else { 170 busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCSR); 171 busno = PCIE_BUSNO(busno); 172 } 173 reg = bus_space_read_2(sc->sc_st, sc->sc_atu_sh, ATU_CMD); 174 reg |= PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN | PCIM_CMD_PERRESPEN | 175 PCIM_CMD_SERRESPEN; 176 bus_space_write_2(sc->sc_st, sc->sc_atu_sh, ATU_CMD, reg); 177 sc->sc_busno = busno; 178 /* Initialize memory and i/o rmans. */ 179 sc->sc_io_rman.rm_type = RMAN_ARRAY; 180 sc->sc_io_rman.rm_descr = "I81342 PCI I/O Ports"; 181 if (rman_init(&sc->sc_io_rman) != 0 || 182 rman_manage_region(&sc->sc_io_rman, 183 sc->sc_is_atux ? IOP34X_PCIX_OIOBAR_VADDR : 184 IOP34X_PCIE_OIOBAR_VADDR, 185 (sc->sc_is_atux ? IOP34X_PCIX_OIOBAR_VADDR : 186 IOP34X_PCIE_OIOBAR_VADDR) + IOP34X_OIOBAR_SIZE) != 0) { 187 panic("i81342_pci_probe: failed to set up I/O rman"); 188 } 189 sc->sc_mem_rman.rm_type = RMAN_ARRAY; 190 sc->sc_mem_rman.rm_descr = "I81342 PCI Memory"; 191 if (rman_init(&sc->sc_mem_rman) != 0 || 192 rman_manage_region(&sc->sc_mem_rman, 193 0, 0xffffffff) != 0) { 194 panic("i81342_pci_attach: failed to set up memory rman"); 195 } 196 sc->sc_irq_rman.rm_type = RMAN_ARRAY; 197 sc->sc_irq_rman.rm_descr = "i81342 PCI IRQs"; 198 if (sc->sc_is_atux) { 199 if (rman_init(&sc->sc_irq_rman) != 0 || 200 rman_manage_region(&sc->sc_irq_rman, ICU_INT_XINT0, 201 ICU_INT_XINT3) != 0) 202 panic("i83142_pci_attach: failed to set up IRQ rman"); 203 } else { 204 if (rman_init(&sc->sc_irq_rman) != 0 || 205 rman_manage_region(&sc->sc_irq_rman, ICU_INT_ATUE_MA, 206 ICU_INT_ATUE_MD) != 0) 207 panic("i81342_pci_attach: failed to set up IRQ rman"); 208 209 } 210 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR, 211 bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR) & ATUX_ISR_ERRMSK); 212 device_add_child(dev, "pci", -1); 213 return (bus_generic_attach(dev)); 214} 215 216static int 217i81342_pci_maxslots(device_t dev) 218{ 219 220 return (PCI_SLOTMAX); 221} 222 223static void 224i81342_pci_conf_setup(struct i81342_pci_softc *sc, int bus, int slot, int func, 225 int reg, uint32_t *addr) 226{ 227 uint32_t busno; 228 229 if (sc->sc_is_atux) { 230 busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR); 231 busno = PCIXSR_BUSNO(busno); 232 } else { 233 busno = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCSR); 234 busno = PCIE_BUSNO(busno); 235 } 236 bus &= 0xff; 237 slot &= 0x1f; 238 func &= 0x7; 239 if (sc->sc_is_atux) { 240 if (busno == bus) 241 *addr = (1 << (slot + 16)) | (slot << 11) | 242 (func << 8) | reg; 243 else 244 *addr = (bus << 16) | (slot << 11) | (func << 11) | 245 reg | 1; 246 } else { 247 *addr = (bus << 24) | (slot << 19) | (func << 16) | reg; 248 if (bus != busno) 249 *addr |= 1; 250 } 251} 252 253static u_int32_t 254i81342_pci_read_config(device_t dev, u_int bus, u_int slot, u_int func, 255 u_int reg, int bytes) 256{ 257 struct i81342_pci_softc *sc = device_get_softc(dev); 258 uint32_t addr; 259 uint32_t ret = 0; 260 uint32_t isr; 261 int err = 0; 262 vm_offset_t va; 263 264 i81342_pci_conf_setup(sc, bus, slot, func, reg & ~3, &addr); 265 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, sc->sc_is_atux ? 266 ATUX_OCCAR : ATUE_OCCAR, addr); 267 if (sc->sc_is_atux) 268 va = sc->sc_atu_sh + ATUX_OCCDR; 269 else 270 va = sc->sc_atu_sh + ATUE_OCCDR; 271 switch (bytes) { 272 case 1: 273 err = badaddr_read((void*)(va + (reg & 3)), 1, &ret); 274 break; 275 case 2: 276 err = badaddr_read((void*)(va + (reg & 3)), 2, &ret); 277 break; 278 case 4: 279 err = badaddr_read((void *)(va) , 4, &ret); 280 break; 281 default: 282 printf("i81342_read_config: invalid size %d\n", bytes); 283 ret = -1; 284 } 285 if (err) { 286 isr = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR); 287 if (sc->sc_is_atux) 288 isr &= ATUX_ISR_ERRMSK; 289 else 290 isr &= ATUE_ISR_ERRMSK; 291 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_ISR, isr); 292 ret = -1; 293 } 294 295 return (ret); 296} 297 298static void 299i81342_pci_write_config(device_t dev, u_int bus, u_int slot, u_int func, 300 u_int reg, u_int32_t data, int bytes) 301{ 302 struct i81342_pci_softc *sc = device_get_softc(dev); 303 uint32_t addr; 304 vm_offset_t va; 305 306 i81342_pci_conf_setup(sc, bus, slot, func, reg & ~3, &addr); 307 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, sc->sc_is_atux ? 308 ATUX_OCCAR : ATUE_OCCAR, addr); 309 va = sc->sc_is_atux ? ATUX_OCCDR : ATUE_OCCDR; 310 switch (bytes) { 311 case 1: 312 bus_space_write_1(sc->sc_st, sc->sc_atu_sh, va + (reg & 3) 313 , data); 314 break; 315 case 2: 316 bus_space_write_2(sc->sc_st, sc->sc_atu_sh, va + (reg & 3) 317 , data); 318 break; 319 case 4: 320 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, va, data); 321 break; 322 default: 323 printf("i81342_pci_write_config: Invalid size : %d\n", bytes); 324 } 325 326 327} 328 329static struct resource * 330i81342_pci_alloc_resource(device_t bus, device_t child, int type, int *rid, 331 rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) 332{ 333 struct i81342_pci_softc *sc = device_get_softc(bus); 334 struct resource *rv; 335 struct rman *rm; 336 bus_space_tag_t bt = NULL; 337 bus_space_handle_t bh = 0; 338 339 switch (type) { 340 case SYS_RES_IRQ: 341 rm = &sc->sc_irq_rman; 342 break; 343 case SYS_RES_MEMORY: 344 rm = &sc->sc_mem_rman; 345 bt = &sc->sc_pcimem; 346 bh = 0; 347 break; 348 case SYS_RES_IOPORT: 349 rm = &sc->sc_io_rman; 350 bt = &sc->sc_pciio; 351 bh = sc->sc_is_atux ? IOP34X_PCIX_OIOBAR_VADDR : 352 IOP34X_PCIE_OIOBAR_VADDR; 353 start += bh; 354 end += bh; 355 break; 356 default: 357 return (NULL); 358 } 359 360 rv = rman_reserve_resource(rm, start, end, count, flags, child); 361 if (rv == NULL) 362 return (NULL); 363 rman_set_rid(rv, *rid); 364 if (type != SYS_RES_IRQ) { 365 if (type == SYS_RES_MEMORY) 366 bh += (rman_get_start(rv)); 367 rman_set_bustag(rv, bt); 368 rman_set_bushandle(rv, bh); 369 if (flags & RF_ACTIVE) { 370 if (bus_activate_resource(child, type, *rid, rv)) { 371 rman_release_resource(rv); 372 return (NULL); 373 } 374 } 375 } 376 return (rv); 377 378 379 return (NULL); 380} 381 382static int 383i81342_pci_activate_resource(device_t bus, device_t child, int type, int rid, 384 struct resource *r) 385{ 386 bus_space_handle_t p; 387 int error; 388 389 if (type == SYS_RES_MEMORY) { 390 error = bus_space_map(rman_get_bustag(r), 391 rman_get_bushandle(r), rman_get_size(r), 0, &p); 392 if (error) 393 return (error); 394 rman_set_bushandle(r, p); 395 396 } 397 return (rman_activate_resource(r)); 398} 399 400static int 401i81342_pci_setup_intr(device_t dev, device_t child, struct resource *ires, 402 int flags, driver_filter_t *filt, driver_intr_t *intr, void *arg, 403 void **cookiep) 404{ 405 406 return (BUS_SETUP_INTR(device_get_parent(dev), child, ires, flags, 407 filt, intr, arg, cookiep)); 408} 409 410 411 412static int 413i81342_pci_teardown_intr(device_t dev, device_t child, struct resource *res, 414 void *cookie) 415{ 416 return (BUS_TEARDOWN_INTR(device_get_parent(dev), child, res, cookie)); 417} 418 419static int 420i81342_pci_route_interrupt(device_t pcib, device_t dev, int pin) 421{ 422 struct i81342_pci_softc *sc; 423 int device; 424 425 device = pci_get_slot(dev); 426 sc = device_get_softc(pcib); 427 /* XXX: Is board specific */ 428 if (sc->sc_is_atux) { 429 /* PCI-X */ 430 switch(device) { 431 case 1: 432 switch (pin) { 433 case 1: 434 return (ICU_INT_XINT1); 435 case 2: 436 return (ICU_INT_XINT2); 437 case 3: 438 return (ICU_INT_XINT3); 439 case 4: 440 return (ICU_INT_XINT0); 441 default: 442 break; 443 } 444 case 2: 445 switch (pin) { 446 case 1: 447 return (ICU_INT_XINT2); 448 case 2: 449 return (ICU_INT_XINT3); 450 case 3: 451 return (ICU_INT_XINT2); 452 case 4: 453 return (ICU_INT_XINT3); 454 default: 455 break; 456 } 457 } 458 459 } else { 460 switch (pin) { 461 case 1: 462 return (ICU_INT_ATUE_MA); 463 case 2: 464 return (ICU_INT_ATUE_MB); 465 case 3: 466 return (ICU_INT_ATUE_MC); 467 case 4: 468 return (ICU_INT_ATUE_MD); 469 default: 470 break; 471 } 472 } 473 printf("Warning: couldn't map %s IRQ for device %d pin %d\n", 474 sc->sc_is_atux ? "PCI-X" : "PCIe", device, pin); 475 return (-1); 476} 477 478static int 479i81342_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 480{ 481 struct i81342_pci_softc *sc = device_get_softc(dev); 482 switch (which) { 483 case PCIB_IVAR_DOMAIN: 484 *result = 0; 485 return (0); 486 case PCIB_IVAR_BUS: 487 *result = sc->sc_busno; 488 return (0); 489 490 } 491 return (ENOENT); 492} 493 494static int 495i81342_write_ivar(device_t dev, device_t child, int which, uintptr_t result) 496{ 497 struct i81342_pci_softc * sc = device_get_softc(dev); 498 499 switch (which) { 500 case PCIB_IVAR_DOMAIN: 501 return (EINVAL); 502 case PCIB_IVAR_BUS: 503 sc->sc_busno = result; 504 return (0); 505 } 506 return (ENOENT); 507} 508 509static device_method_t i81342_pci_methods[] = { 510 /* Device interface */ 511 DEVMETHOD(device_probe, i81342_pci_probe), 512 DEVMETHOD(device_attach, i81342_pci_attach), 513 DEVMETHOD(device_shutdown, bus_generic_shutdown), 514 DEVMETHOD(device_suspend, bus_generic_suspend), 515 DEVMETHOD(device_resume, bus_generic_resume), 516 517 /* Bus interface */ 518 DEVMETHOD(bus_read_ivar, i81342_read_ivar), 519 DEVMETHOD(bus_write_ivar, i81342_write_ivar), 520 DEVMETHOD(bus_alloc_resource, i81342_pci_alloc_resource), 521 DEVMETHOD(bus_release_resource, bus_generic_release_resource), 522 DEVMETHOD(bus_activate_resource, i81342_pci_activate_resource), 523 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 524 DEVMETHOD(bus_setup_intr, i81342_pci_setup_intr), 525 DEVMETHOD(bus_teardown_intr, i81342_pci_teardown_intr), 526 527 /* pcib interface */ 528 DEVMETHOD(pcib_maxslots, i81342_pci_maxslots), 529 DEVMETHOD(pcib_read_config, i81342_pci_read_config), 530 DEVMETHOD(pcib_write_config, i81342_pci_write_config), 531 DEVMETHOD(pcib_route_interrupt, i81342_pci_route_interrupt), 532 533 DEVMETHOD_END 534}; 535 536static driver_t i81342_pci_driver = { 537 "pcib", 538 i81342_pci_methods, 539 sizeof(struct i81342_pci_softc), 540}; 541 542static devclass_t i81342_pci_devclass; 543 544DRIVER_MODULE(ipci, iq, i81342_pci_driver, i81342_pci_devclass, 0, 0); 545