ar71xx_pci.c revision 221256
1/*- 2 * Copyright (c) 2009, Oleksandr Tymoshenko <gonzo@FreeBSD.org> 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 unmodified, this list of conditions, and the following 10 * disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 28#include <sys/cdefs.h> 29__FBSDID("$FreeBSD: head/sys/mips/atheros/ar71xx_pci.c 221256 2011-04-30 11:56:04Z adrian $"); 30 31#include <sys/param.h> 32#include <sys/systm.h> 33 34#include <sys/bus.h> 35#include <sys/interrupt.h> 36#include <sys/malloc.h> 37#include <sys/kernel.h> 38#include <sys/module.h> 39#include <sys/rman.h> 40 41#include <vm/vm.h> 42#include <vm/pmap.h> 43#include <vm/vm_extern.h> 44 45#include <machine/bus.h> 46#include <machine/cpu.h> 47#include <machine/intr_machdep.h> 48#include <machine/pmap.h> 49 50#include <dev/pci/pcivar.h> 51#include <dev/pci/pcireg.h> 52 53#include <dev/pci/pcib_private.h> 54#include "pcib_if.h" 55 56#include <mips/atheros/ar71xxreg.h> 57#include <mips/atheros/ar71xx_pci_bus_space.h> 58 59#include <mips/atheros/ar71xx_cpudef.h> 60 61#undef AR71XX_PCI_DEBUG 62#ifdef AR71XX_PCI_DEBUG 63#define dprintf printf 64#else 65#define dprintf(x, arg...) 66#endif 67 68struct ar71xx_pci_softc { 69 device_t sc_dev; 70 71 int sc_busno; 72 struct rman sc_mem_rman; 73 struct rman sc_irq_rman; 74 75 struct intr_event *sc_eventstab[AR71XX_PCI_NIRQS]; 76 mips_intrcnt_t sc_intr_counter[AR71XX_PCI_NIRQS]; 77 struct resource *sc_irq; 78 void *sc_ih; 79}; 80 81static int ar71xx_pci_setup_intr(device_t, device_t, struct resource *, int, 82 driver_filter_t *, driver_intr_t *, void *, void **); 83static int ar71xx_pci_teardown_intr(device_t, device_t, struct resource *, 84 void *); 85static int ar71xx_pci_intr(void *); 86 87static void 88ar71xx_pci_mask_irq(void *source) 89{ 90 uint32_t reg; 91 unsigned int irq = (unsigned int)source; 92 93 reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK); 94 /* flush */ 95 reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK); 96 ATH_WRITE_REG(AR71XX_PCI_INTR_MASK, reg & ~(1 << irq)); 97} 98 99static void 100ar71xx_pci_unmask_irq(void *source) 101{ 102 uint32_t reg; 103 unsigned int irq = (unsigned int)source; 104 105 reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK); 106 ATH_WRITE_REG(AR71XX_PCI_INTR_MASK, reg | (1 << irq)); 107 /* flush */ 108 reg = ATH_READ_REG(AR71XX_PCI_INTR_MASK); 109} 110 111/* 112 * get bitmask for bytes of interest: 113 * 0 - we want this byte, 1 - ignore it. e.g: we read 1 byte 114 * from register 7. Bitmask would be: 0111 115 */ 116static uint32_t 117ar71xx_get_bytes_to_read(int reg, int bytes) 118{ 119 uint32_t bytes_to_read = 0; 120 if ((bytes % 4) == 0) 121 bytes_to_read = 0; 122 else if ((bytes % 4) == 1) 123 bytes_to_read = (~(1 << (reg % 4))) & 0xf; 124 else if ((bytes % 4) == 2) 125 bytes_to_read = (~(3 << (reg % 4))) & 0xf; 126 else 127 panic("%s: wrong combination", __func__); 128 129 return (bytes_to_read); 130} 131 132static int 133ar71xx_pci_check_bus_error(void) 134{ 135 uint32_t error, addr, has_errors = 0; 136 error = ATH_READ_REG(AR71XX_PCI_ERROR) & 0x3; 137 dprintf("%s: PCI error = %02x\n", __func__, error); 138 if (error) { 139 addr = ATH_READ_REG(AR71XX_PCI_ERROR_ADDR); 140 141 /* Do not report it yet */ 142#if 0 143 printf("PCI bus error %d at addr 0x%08x\n", error, addr); 144#endif 145 ATH_WRITE_REG(AR71XX_PCI_ERROR, error); 146 has_errors = 1; 147 } 148 149 error = ATH_READ_REG(AR71XX_PCI_AHB_ERROR) & 0x1; 150 dprintf("%s: AHB error = %02x\n", __func__, error); 151 if (error) { 152 addr = ATH_READ_REG(AR71XX_PCI_AHB_ERROR_ADDR); 153 /* Do not report it yet */ 154#if 0 155 printf("AHB bus error %d at addr 0x%08x\n", error, addr); 156#endif 157 ATH_WRITE_REG(AR71XX_PCI_AHB_ERROR, error); 158 has_errors = 1; 159 } 160 161 return (has_errors); 162} 163 164static uint32_t 165ar71xx_pci_make_addr(int bus, int slot, int func, int reg) 166{ 167 if (bus == 0) { 168 return ((1 << slot) | (func << 8) | (reg & ~3)); 169 } else { 170 return ((bus << 16) | (slot << 11) | (func << 8) 171 | (reg & ~3) | 1); 172 } 173} 174 175static int 176ar71xx_pci_conf_setup(int bus, int slot, int func, int reg, int bytes, 177 uint32_t cmd) 178{ 179 uint32_t addr = ar71xx_pci_make_addr(bus, slot, func, (reg & ~3)); 180 cmd |= (ar71xx_get_bytes_to_read(reg, bytes) << 4); 181 182 ATH_WRITE_REG(AR71XX_PCI_CONF_ADDR, addr); 183 ATH_WRITE_REG(AR71XX_PCI_CONF_CMD, cmd); 184 185 dprintf("%s: tag (%x, %x, %x) %d/%d addr=%08x, cmd=%08x\n", __func__, 186 bus, slot, func, reg, bytes, addr, cmd); 187 188 return ar71xx_pci_check_bus_error(); 189} 190 191static uint32_t 192ar71xx_pci_read_config(device_t dev, u_int bus, u_int slot, u_int func, 193 u_int reg, int bytes) 194{ 195 uint32_t data; 196 uint32_t cmd, shift, mask; 197 198 /* register access is 32-bit aligned */ 199 shift = (reg & 3) * 8; 200 if (shift) 201 mask = (1 << shift) - 1; 202 else 203 mask = 0xffffffff; 204 205 dprintf("%s: tag (%x, %x, %x) reg %d(%d)\n", __func__, bus, slot, 206 func, reg, bytes); 207 208 if ((bus == 0) && (slot == 0) && (func == 0)) { 209 cmd = PCI_LCONF_CMD_READ | (reg & ~3); 210 ATH_WRITE_REG(AR71XX_PCI_LCONF_CMD, cmd); 211 data = ATH_READ_REG(AR71XX_PCI_LCONF_READ_DATA); 212 } else { 213 if (ar71xx_pci_conf_setup(bus, slot, func, reg, bytes, 214 PCI_CONF_CMD_READ) == 0) 215 data = ATH_READ_REG(AR71XX_PCI_CONF_READ_DATA); 216 else 217 data = -1; 218 } 219 220 /* get request bytes from 32-bit word */ 221 data = (data >> shift) & mask; 222 223 dprintf("%s: read 0x%x\n", __func__, data); 224 225 return (data); 226} 227 228static void 229ar71xx_pci_write_config(device_t dev, u_int bus, u_int slot, u_int func, 230 u_int reg, uint32_t data, int bytes) 231{ 232 uint32_t cmd; 233 234 dprintf("%s: tag (%x, %x, %x) reg %d(%d)\n", __func__, bus, slot, 235 func, reg, bytes); 236 237 data = data << (8*(reg % 4)); 238 239 if ((bus == 0) && (slot == 0) && (func == 0)) { 240 cmd = PCI_LCONF_CMD_WRITE | (reg & ~3); 241 cmd |= ar71xx_get_bytes_to_read(reg, bytes) << 20; 242 ATH_WRITE_REG(AR71XX_PCI_LCONF_CMD, cmd); 243 ATH_WRITE_REG(AR71XX_PCI_LCONF_WRITE_DATA, data); 244 } else { 245 if (ar71xx_pci_conf_setup(bus, slot, func, reg, bytes, 246 PCI_CONF_CMD_WRITE) == 0) 247 ATH_WRITE_REG(AR71XX_PCI_CONF_WRITE_DATA, data); 248 } 249} 250 251static int 252ar71xx_pci_probe(device_t dev) 253{ 254 255 return (0); 256} 257 258static int 259ar71xx_pci_attach(device_t dev) 260{ 261 int busno = 0; 262 int rid = 0; 263 struct ar71xx_pci_softc *sc = device_get_softc(dev); 264 265 sc->sc_mem_rman.rm_type = RMAN_ARRAY; 266 sc->sc_mem_rman.rm_descr = "ar71xx PCI memory window"; 267 if (rman_init(&sc->sc_mem_rman) != 0 || 268 rman_manage_region(&sc->sc_mem_rman, AR71XX_PCI_MEM_BASE, 269 AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1) != 0) { 270 panic("ar71xx_pci_attach: failed to set up I/O rman"); 271 } 272 273 sc->sc_irq_rman.rm_type = RMAN_ARRAY; 274 sc->sc_irq_rman.rm_descr = "ar71xx PCI IRQs"; 275 if (rman_init(&sc->sc_irq_rman) != 0 || 276 rman_manage_region(&sc->sc_irq_rman, AR71XX_PCI_IRQ_START, 277 AR71XX_PCI_IRQ_END) != 0) 278 panic("ar71xx_pci_attach: failed to set up IRQ rman"); 279 280 281 ATH_WRITE_REG(AR71XX_PCI_INTR_STATUS, 0); 282 ATH_WRITE_REG(AR71XX_PCI_INTR_MASK, 0); 283 284 /* Hook up our interrupt handler. */ 285 if ((sc->sc_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 286 RF_SHAREABLE | RF_ACTIVE)) == NULL) { 287 device_printf(dev, "unable to allocate IRQ resource\n"); 288 return ENXIO; 289 } 290 291 if ((bus_setup_intr(dev, sc->sc_irq, INTR_TYPE_MISC, 292 ar71xx_pci_intr, NULL, sc, &sc->sc_ih))) { 293 device_printf(dev, 294 "WARNING: unable to register interrupt handler\n"); 295 return ENXIO; 296 } 297 298 /* reset PCI core and PCI bus */ 299 ar71xx_device_stop(RST_RESET_PCI_CORE | RST_RESET_PCI_BUS); 300 DELAY(100000); 301 302 ar71xx_device_start(RST_RESET_PCI_CORE | RST_RESET_PCI_BUS); 303 DELAY(100000); 304 305 /* Init PCI windows */ 306 ATH_WRITE_REG(AR71XX_PCI_WINDOW0, PCI_WINDOW0_ADDR); 307 ATH_WRITE_REG(AR71XX_PCI_WINDOW1, PCI_WINDOW1_ADDR); 308 ATH_WRITE_REG(AR71XX_PCI_WINDOW2, PCI_WINDOW2_ADDR); 309 ATH_WRITE_REG(AR71XX_PCI_WINDOW3, PCI_WINDOW3_ADDR); 310 ATH_WRITE_REG(AR71XX_PCI_WINDOW4, PCI_WINDOW4_ADDR); 311 ATH_WRITE_REG(AR71XX_PCI_WINDOW5, PCI_WINDOW5_ADDR); 312 ATH_WRITE_REG(AR71XX_PCI_WINDOW6, PCI_WINDOW6_ADDR); 313 ATH_WRITE_REG(AR71XX_PCI_WINDOW7, PCI_WINDOW7_CONF_ADDR); 314 DELAY(100000); 315 316 ar71xx_pci_check_bus_error(); 317 318 /* Fixup internal PCI bridge */ 319 ar71xx_pci_write_config(dev, 0, 0, 0, PCIR_COMMAND, 320 PCIM_CMD_BUSMASTEREN | PCIM_CMD_MEMEN 321 | PCIM_CMD_SERRESPEN | PCIM_CMD_BACKTOBACK 322 | PCIM_CMD_PERRESPEN | PCIM_CMD_MWRICEN, 2); 323 324 device_add_child(dev, "pci", busno); 325 return (bus_generic_attach(dev)); 326} 327 328static int 329ar71xx_pci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 330{ 331 struct ar71xx_pci_softc *sc = device_get_softc(dev); 332 333 switch (which) { 334 case PCIB_IVAR_DOMAIN: 335 *result = 0; 336 return (0); 337 case PCIB_IVAR_BUS: 338 *result = sc->sc_busno; 339 return (0); 340 } 341 342 return (ENOENT); 343} 344 345static int 346ar71xx_pci_write_ivar(device_t dev, device_t child, int which, uintptr_t result) 347{ 348 struct ar71xx_pci_softc * sc = device_get_softc(dev); 349 350 switch (which) { 351 case PCIB_IVAR_BUS: 352 sc->sc_busno = result; 353 return (0); 354 } 355 356 return (ENOENT); 357} 358 359static struct resource * 360ar71xx_pci_alloc_resource(device_t bus, device_t child, int type, int *rid, 361 u_long start, u_long end, u_long count, u_int flags) 362{ 363 364 struct ar71xx_pci_softc *sc = device_get_softc(bus); 365 struct resource *rv; 366 struct rman *rm; 367 368 switch (type) { 369 case SYS_RES_IRQ: 370 rm = &sc->sc_irq_rman; 371 break; 372 case SYS_RES_MEMORY: 373 rm = &sc->sc_mem_rman; 374 break; 375 default: 376 return (NULL); 377 } 378 379 rv = rman_reserve_resource(rm, start, end, count, flags, child); 380 381 if (rv == NULL) 382 return (NULL); 383 384 rman_set_rid(rv, *rid); 385 386 if (flags & RF_ACTIVE) { 387 if (bus_activate_resource(child, type, *rid, rv)) { 388 rman_release_resource(rv); 389 return (NULL); 390 } 391 } 392 393 394 return (rv); 395} 396 397 398static int 399ar71xx_pci_activate_resource(device_t bus, device_t child, int type, int rid, 400 struct resource *r) 401{ 402 int res = (BUS_ACTIVATE_RESOURCE(device_get_parent(bus), 403 child, type, rid, r)); 404 405 if (!res) { 406 switch(type) { 407 case SYS_RES_MEMORY: 408 case SYS_RES_IOPORT: 409 rman_set_bustag(r, ar71xx_bus_space_pcimem); 410 break; 411 } 412 } 413 414 return (res); 415} 416 417 418 419static int 420ar71xx_pci_setup_intr(device_t bus, device_t child, struct resource *ires, 421 int flags, driver_filter_t *filt, driver_intr_t *handler, 422 void *arg, void **cookiep) 423{ 424 struct ar71xx_pci_softc *sc = device_get_softc(bus); 425 struct intr_event *event; 426 int irq, error; 427 428 irq = rman_get_start(ires); 429 430 if (irq > AR71XX_PCI_IRQ_END) 431 panic("%s: bad irq %d", __func__, irq); 432 433 event = sc->sc_eventstab[irq]; 434 if (event == NULL) { 435 error = intr_event_create(&event, (void *)irq, 0, irq, 436 ar71xx_pci_mask_irq, ar71xx_pci_unmask_irq, NULL, NULL, 437 "pci intr%d:", irq); 438 439 if (error == 0) { 440 sc->sc_eventstab[irq] = event; 441 sc->sc_intr_counter[irq] = 442 mips_intrcnt_create(event->ie_name); 443 } 444 else 445 return error; 446 } 447 448 intr_event_add_handler(event, device_get_nameunit(child), filt, 449 handler, arg, intr_priority(flags), flags, cookiep); 450 mips_intrcnt_setname(sc->sc_intr_counter[irq], event->ie_fullname); 451 452 ar71xx_pci_unmask_irq((void*)irq); 453 454 return (0); 455} 456 457static int 458ar71xx_pci_teardown_intr(device_t dev, device_t child, struct resource *ires, 459 void *cookie) 460{ 461 struct ar71xx_pci_softc *sc = device_get_softc(dev); 462 int irq, result; 463 464 irq = rman_get_start(ires); 465 if (irq > AR71XX_PCI_IRQ_END) 466 panic("%s: bad irq %d", __func__, irq); 467 468 if (sc->sc_eventstab[irq] == NULL) 469 panic("Trying to teardown unoccupied IRQ"); 470 471 ar71xx_pci_mask_irq((void*)irq); 472 473 result = intr_event_remove_handler(cookie); 474 if (!result) 475 sc->sc_eventstab[irq] = NULL; 476 477 return (result); 478} 479 480static int 481ar71xx_pci_intr(void *arg) 482{ 483 struct ar71xx_pci_softc *sc = arg; 484 struct intr_event *event; 485 uint32_t reg, irq, mask; 486 487 reg = ATH_READ_REG(AR71XX_PCI_INTR_STATUS); 488 mask = ATH_READ_REG(AR71XX_PCI_INTR_MASK); 489 /* 490 * Handle only unmasked interrupts 491 */ 492 reg &= mask; 493 for (irq = AR71XX_PCI_IRQ_START; irq <= AR71XX_PCI_IRQ_END; irq++) { 494 if (reg & (1 << irq)) { 495 event = sc->sc_eventstab[irq]; 496 if (!event || TAILQ_EMPTY(&event->ie_handlers)) { 497 /* Ignore timer interrupts */ 498 if (irq != 0) 499 printf("Stray IRQ %d\n", irq); 500 continue; 501 } 502 503 /* Flush DDR FIFO for IP2 */ 504 ar71xx_device_ddr_flush_ip2(); 505 506 /* TODO: frame instead of NULL? */ 507 intr_event_handle(event, NULL); 508 mips_intrcnt_inc(sc->sc_intr_counter[irq]); 509 } 510 } 511 512 return (FILTER_HANDLED); 513} 514 515static int 516ar71xx_pci_maxslots(device_t dev) 517{ 518 519 return (PCI_SLOTMAX); 520} 521 522static int 523ar71xx_pci_route_interrupt(device_t pcib, device_t device, int pin) 524{ 525 if (pci_get_slot(device) < AR71XX_PCI_BASE_SLOT) 526 panic("%s: PCI slot %d is less then AR71XX_PCI_BASE_SLOT", 527 __func__, pci_get_slot(device)); 528 529 return (pci_get_slot(device) - AR71XX_PCI_BASE_SLOT); 530} 531 532static device_method_t ar71xx_pci_methods[] = { 533 /* Device interface */ 534 DEVMETHOD(device_probe, ar71xx_pci_probe), 535 DEVMETHOD(device_attach, ar71xx_pci_attach), 536 DEVMETHOD(device_shutdown, bus_generic_shutdown), 537 DEVMETHOD(device_suspend, bus_generic_suspend), 538 DEVMETHOD(device_resume, bus_generic_resume), 539 540 /* Bus interface */ 541 DEVMETHOD(bus_print_child, bus_generic_print_child), 542 DEVMETHOD(bus_read_ivar, ar71xx_pci_read_ivar), 543 DEVMETHOD(bus_write_ivar, ar71xx_pci_write_ivar), 544 DEVMETHOD(bus_alloc_resource, ar71xx_pci_alloc_resource), 545 DEVMETHOD(bus_release_resource, bus_generic_release_resource), 546 DEVMETHOD(bus_activate_resource, ar71xx_pci_activate_resource), 547 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 548 DEVMETHOD(bus_setup_intr, ar71xx_pci_setup_intr), 549 DEVMETHOD(bus_teardown_intr, ar71xx_pci_teardown_intr), 550 551 /* pcib interface */ 552 DEVMETHOD(pcib_maxslots, ar71xx_pci_maxslots), 553 DEVMETHOD(pcib_read_config, ar71xx_pci_read_config), 554 DEVMETHOD(pcib_write_config, ar71xx_pci_write_config), 555 DEVMETHOD(pcib_route_interrupt, ar71xx_pci_route_interrupt), 556 557 {0, 0} 558}; 559 560static driver_t ar71xx_pci_driver = { 561 "pcib", 562 ar71xx_pci_methods, 563 sizeof(struct ar71xx_pci_softc), 564}; 565 566static devclass_t ar71xx_pci_devclass; 567 568DRIVER_MODULE(ar71xx_pci, nexus, ar71xx_pci_driver, ar71xx_pci_devclass, 0, 0); 569