1/*- 2 * Copyright (c) 2003-2009 RMI Corporation 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 * 3. Neither the name of RMI Corporation, nor the names of its contributors, 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * RMI_BSD */ 30#include <sys/cdefs.h> 31__FBSDID("$FreeBSD: releng/10.3/sys/mips/rmi/xlr_pci.c 227843 2011-11-22 21:28:20Z marius $"); 32 33#include <sys/param.h> 34#include <sys/systm.h> 35#include <sys/types.h> 36#include <sys/kernel.h> 37#include <sys/module.h> 38#include <sys/malloc.h> 39#include <sys/bus.h> 40#include <sys/endian.h> 41#include <sys/rman.h> 42 43#include <vm/vm.h> 44#include <vm/vm_param.h> 45#include <vm/pmap.h> 46 47#include <dev/pci/pcivar.h> 48#include <dev/pci/pcireg.h> 49 50#include <machine/bus.h> 51#include <machine/md_var.h> 52#include <machine/intr_machdep.h> 53#include <machine/cpuregs.h> 54 55#include <mips/rmi/rmi_mips_exts.h> 56#include <mips/rmi/interrupt.h> 57#include <mips/rmi/iomap.h> 58#include <mips/rmi/pic.h> 59#include <mips/rmi/board.h> 60#include <mips/rmi/pcibus.h> 61 62#include "pcib_if.h" 63 64#define pci_cfg_offset(bus,slot,devfn,where) (((bus)<<16) + ((slot) << 11)+((devfn)<<8)+(where)) 65#define PCIE_LINK_STATE 0x4000 66 67#define LSU_CFG0_REGID 0 68#define LSU_CERRLOG_REGID 9 69#define LSU_CERROVF_REGID 10 70#define LSU_CERRINT_REGID 11 71 72/* MSI support */ 73#define MSI_MIPS_ADDR_DEST 0x000ff000 74#define MSI_MIPS_ADDR_RH 0x00000008 75#define MSI_MIPS_ADDR_RH_OFF 0x00000000 76#define MSI_MIPS_ADDR_RH_ON 0x00000008 77#define MSI_MIPS_ADDR_DM 0x00000004 78#define MSI_MIPS_ADDR_DM_PHYSICAL 0x00000000 79#define MSI_MIPS_ADDR_DM_LOGICAL 0x00000004 80 81/* Fields in data for Intel MSI messages. */ 82#define MSI_MIPS_DATA_TRGRMOD 0x00008000 /* Trigger mode */ 83#define MSI_MIPS_DATA_TRGREDG 0x00000000 /* edge */ 84#define MSI_MIPS_DATA_TRGRLVL 0x00008000 /* level */ 85 86#define MSI_MIPS_DATA_LEVEL 0x00004000 /* Polarity. */ 87#define MSI_MIPS_DATA_DEASSERT 0x00000000 88#define MSI_MIPS_DATA_ASSERT 0x00004000 89 90#define MSI_MIPS_DATA_DELMOD 0x00000700 /* Delivery Mode */ 91#define MSI_MIPS_DATA_DELFIXED 0x00000000 /* fixed */ 92#define MSI_MIPS_DATA_DELLOPRI 0x00000100 /* lowest priority */ 93 94#define MSI_MIPS_DATA_INTVEC 0x000000ff 95 96/* 97 * Build Intel MSI message and data values from a source. AMD64 systems 98 * seem to be compatible, so we use the same function for both. 99 */ 100#define MIPS_MSI_ADDR(cpu) \ 101 (MSI_MIPS_ADDR_BASE | (cpu) << 12 | \ 102 MSI_MIPS_ADDR_RH_OFF | MSI_MIPS_ADDR_DM_PHYSICAL) 103 104#define MIPS_MSI_DATA(irq) \ 105 (MSI_MIPS_DATA_TRGRLVL | MSI_MIPS_DATA_DELFIXED | \ 106 MSI_MIPS_DATA_ASSERT | (irq)) 107 108struct xlr_pcib_softc { 109 bus_dma_tag_t sc_pci_dmat; /* PCI DMA tag pointer */ 110}; 111 112static devclass_t pcib_devclass; 113static void *xlr_pci_config_base; 114static struct rman irq_rman, port_rman, mem_rman; 115 116static void 117xlr_pci_init_resources(void) 118{ 119 120 irq_rman.rm_start = 0; 121 irq_rman.rm_end = 255; 122 irq_rman.rm_type = RMAN_ARRAY; 123 irq_rman.rm_descr = "PCI Mapped Interrupts"; 124 if (rman_init(&irq_rman) 125 || rman_manage_region(&irq_rman, 0, 255)) 126 panic("pci_init_resources irq_rman"); 127 128 port_rman.rm_start = 0; 129 port_rman.rm_end = ~0ul; 130 port_rman.rm_type = RMAN_ARRAY; 131 port_rman.rm_descr = "I/O ports"; 132 if (rman_init(&port_rman) 133 || rman_manage_region(&port_rman, 0x10000000, 0x1fffffff)) 134 panic("pci_init_resources port_rman"); 135 136 mem_rman.rm_start = 0; 137 mem_rman.rm_end = ~0ul; 138 mem_rman.rm_type = RMAN_ARRAY; 139 mem_rman.rm_descr = "I/O memory"; 140 if (rman_init(&mem_rman) 141 || rman_manage_region(&mem_rman, 0xd0000000, 0xdfffffff)) 142 panic("pci_init_resources mem_rman"); 143} 144 145static int 146xlr_pcib_probe(device_t dev) 147{ 148 149 if (xlr_board_info.is_xls) 150 device_set_desc(dev, "XLS PCIe bus"); 151 else 152 device_set_desc(dev, "XLR PCI bus"); 153 154 xlr_pci_init_resources(); 155 xlr_pci_config_base = (void *)MIPS_PHYS_TO_KSEG1(DEFAULT_PCI_CONFIG_BASE); 156 157 return (0); 158} 159 160static int 161xlr_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 162{ 163 164 switch (which) { 165 case PCIB_IVAR_DOMAIN: 166 *result = 0; 167 return (0); 168 case PCIB_IVAR_BUS: 169 *result = 0; 170 return (0); 171 } 172 return (ENOENT); 173} 174 175static int 176xlr_pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t result) 177{ 178 switch (which) { 179 case PCIB_IVAR_DOMAIN: 180 return (EINVAL); 181 case PCIB_IVAR_BUS: 182 return (EINVAL); 183 } 184 return (ENOENT); 185} 186 187static int 188xlr_pcib_maxslots(device_t dev) 189{ 190 191 return (PCI_SLOTMAX); 192} 193 194static __inline__ void 195disable_and_clear_cache_error(void) 196{ 197 uint64_t lsu_cfg0; 198 199 lsu_cfg0 = read_xlr_ctrl_register(CPU_BLOCKID_LSU, LSU_CFG0_REGID); 200 lsu_cfg0 = lsu_cfg0 & ~0x2e; 201 write_xlr_ctrl_register(CPU_BLOCKID_LSU, LSU_CFG0_REGID, lsu_cfg0); 202 /* Clear cache error log */ 203 write_xlr_ctrl_register(CPU_BLOCKID_LSU, LSU_CERRLOG_REGID, 0); 204} 205 206static __inline__ void 207clear_and_enable_cache_error(void) 208{ 209 uint64_t lsu_cfg0 = 0; 210 211 /* first clear the cache error logging register */ 212 write_xlr_ctrl_register(CPU_BLOCKID_LSU, LSU_CERRLOG_REGID, 0); 213 write_xlr_ctrl_register(CPU_BLOCKID_LSU, LSU_CERROVF_REGID, 0); 214 write_xlr_ctrl_register(CPU_BLOCKID_LSU, LSU_CERRINT_REGID, 0); 215 216 lsu_cfg0 = read_xlr_ctrl_register(CPU_BLOCKID_LSU, LSU_CFG0_REGID); 217 lsu_cfg0 = lsu_cfg0 | 0x2e; 218 write_xlr_ctrl_register(CPU_BLOCKID_LSU, LSU_CFG0_REGID, lsu_cfg0); 219} 220 221static uint32_t 222pci_cfg_read_32bit(uint32_t addr) 223{ 224 uint32_t temp = 0; 225 uint32_t *p = (uint32_t *)xlr_pci_config_base + addr / sizeof(uint32_t); 226 uint64_t cerr_cpu_log = 0; 227 228 disable_and_clear_cache_error(); 229 temp = bswap32(*p); 230 231 /* Read cache err log */ 232 cerr_cpu_log = read_xlr_ctrl_register(CPU_BLOCKID_LSU, 233 LSU_CERRLOG_REGID); 234 if (cerr_cpu_log) { 235 /* Device don't exist. */ 236 temp = ~0x0; 237 } 238 clear_and_enable_cache_error(); 239 return (temp); 240} 241 242static u_int32_t 243xlr_pcib_read_config(device_t dev, u_int b, u_int s, u_int f, 244 u_int reg, int width) 245{ 246 uint32_t data = 0; 247 248 if ((width == 2) && (reg & 1)) 249 return 0xFFFFFFFF; 250 else if ((width == 4) && (reg & 3)) 251 return 0xFFFFFFFF; 252 253 data = pci_cfg_read_32bit(pci_cfg_offset(b, s, f, reg)); 254 255 if (width == 1) 256 return ((data >> ((reg & 3) << 3)) & 0xff); 257 else if (width == 2) 258 return ((data >> ((reg & 3) << 3)) & 0xffff); 259 else 260 return (data); 261} 262 263static void 264xlr_pcib_write_config(device_t dev, u_int b, u_int s, u_int f, 265 u_int reg, u_int32_t val, int width) 266{ 267 uint32_t cfgaddr = pci_cfg_offset(b, s, f, reg); 268 uint32_t data = 0, *p; 269 270 if ((width == 2) && (reg & 1)) 271 return; 272 else if ((width == 4) && (reg & 3)) 273 return; 274 275 if (width == 1) { 276 data = pci_cfg_read_32bit(cfgaddr); 277 data = (data & ~(0xff << ((reg & 3) << 3))) | 278 (val << ((reg & 3) << 3)); 279 } else if (width == 2) { 280 data = pci_cfg_read_32bit(cfgaddr); 281 data = (data & ~(0xffff << ((reg & 3) << 3))) | 282 (val << ((reg & 3) << 3)); 283 } else { 284 data = val; 285 } 286 287 p = (uint32_t *)xlr_pci_config_base + cfgaddr / sizeof(uint32_t); 288 *p = bswap32(data); 289 290 return; 291} 292 293static int 294xlr_pcib_attach(device_t dev) 295{ 296 struct xlr_pcib_softc *sc; 297 sc = device_get_softc(dev); 298 299 /* 300 * XLR C revision chips cannot do DMA above 2G physical address 301 * create a parent tag with this lowaddr 302 */ 303 if (xlr_is_c_revision()) { 304 if (bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0, 305 0x7fffffff, ~0, NULL, NULL, 0x7fffffff, 306 0xff, 0x7fffffff, 0, NULL, NULL, &sc->sc_pci_dmat) != 0) 307 panic("%s: bus_dma_tag_create failed", __func__); 308 } 309 device_add_child(dev, "pci", 0); 310 bus_generic_attach(dev); 311 return (0); 312} 313 314static void 315xlr_pcib_identify(driver_t * driver, device_t parent) 316{ 317 318 BUS_ADD_CHILD(parent, 0, "pcib", 0); 319} 320 321/* 322 * XLS PCIe can have upto 4 links, and each link has its on IRQ 323 * Find the link on which the device is on 324 */ 325static int 326xls_pcie_link(device_t pcib, device_t dev) 327{ 328 device_t parent, tmp; 329 330 /* find the lane on which the slot is connected to */ 331 printf("xls_pcie_link : bus %s dev %s\n", device_get_nameunit(pcib), 332 device_get_nameunit(dev)); 333 tmp = dev; 334 while (1) { 335 parent = device_get_parent(tmp); 336 if (parent == NULL || parent == pcib) { 337 device_printf(dev, "Cannot find parent bus\n"); 338 return (-1); 339 } 340 if (strcmp(device_get_nameunit(parent), "pci0") == 0) 341 break; 342 tmp = parent; 343 } 344 return (pci_get_slot(tmp)); 345} 346 347/* 348 * Find the IRQ for the link, each link has a different interrupt 349 * at the XLS pic 350 */ 351static int 352xls_pcie_link_irq(int link) 353{ 354 355 switch (link) { 356 case 0: 357 return (PIC_PCIE_LINK0_IRQ); 358 case 1: 359 return (PIC_PCIE_LINK1_IRQ); 360 case 2: 361 if (xlr_is_xls_b0()) 362 return (PIC_PCIE_B0_LINK2_IRQ); 363 else 364 return (PIC_PCIE_LINK2_IRQ); 365 case 3: 366 if (xlr_is_xls_b0()) 367 return (PIC_PCIE_B0_LINK3_IRQ); 368 else 369 return (PIC_PCIE_LINK3_IRQ); 370 } 371 return (-1); 372} 373 374static int 375xlr_alloc_msi(device_t pcib, device_t dev, int count, int maxcount, int *irqs) 376{ 377 int i, link; 378 379 /* 380 * Each link has 32 MSIs that can be allocated, but for now 381 * we only support one device per link. 382 * msi_alloc() equivalent is needed when we start supporting 383 * bridges on the PCIe link. 384 */ 385 link = xls_pcie_link(pcib, dev); 386 if (link == -1) 387 return (ENXIO); 388 389 /* 390 * encode the irq so that we know it is a MSI interrupt when we 391 * setup interrupts 392 */ 393 for (i = 0; i < count; i++) 394 irqs[i] = 64 + link * 32 + i; 395 396 return (0); 397} 398 399static int 400xlr_release_msi(device_t pcib, device_t dev, int count, int *irqs) 401{ 402 device_printf(dev, "%s: msi release %d\n", device_get_nameunit(pcib), 403 count); 404 return (0); 405} 406 407static int 408xlr_map_msi(device_t pcib, device_t dev, int irq, uint64_t *addr, 409 uint32_t *data) 410{ 411 int msi; 412 413 if (irq >= 64) { 414 msi = irq - 64; 415 *addr = MIPS_MSI_ADDR(0); 416 *data = MIPS_MSI_DATA(msi); 417 return (0); 418 } else { 419 device_printf(dev, "%s: map_msi for irq %d - ignored", 420 device_get_nameunit(pcib), irq); 421 return (ENXIO); 422 } 423} 424 425static void 426bridge_pcix_ack(int irq) 427{ 428 429 (void)xlr_read_reg(xlr_io_mmio(XLR_IO_PCIX_OFFSET), 0x140 >> 2); 430} 431 432static void 433bridge_pcie_ack(int irq) 434{ 435 uint32_t reg; 436 xlr_reg_t *pcie_mmio_le = xlr_io_mmio(XLR_IO_PCIE_1_OFFSET); 437 438 switch (irq) { 439 case PIC_PCIE_LINK0_IRQ: 440 reg = PCIE_LINK0_MSI_STATUS; 441 break; 442 case PIC_PCIE_LINK1_IRQ: 443 reg = PCIE_LINK1_MSI_STATUS; 444 break; 445 case PIC_PCIE_LINK2_IRQ: 446 case PIC_PCIE_B0_LINK2_IRQ: 447 reg = PCIE_LINK2_MSI_STATUS; 448 break; 449 case PIC_PCIE_LINK3_IRQ: 450 case PIC_PCIE_B0_LINK3_IRQ: 451 reg = PCIE_LINK3_MSI_STATUS; 452 break; 453 default: 454 return; 455 } 456 xlr_write_reg(pcie_mmio_le, reg>>2, 0xffffffff); 457} 458 459static int 460mips_platform_pci_setup_intr(device_t dev, device_t child, 461 struct resource *irq, int flags, driver_filter_t *filt, 462 driver_intr_t *intr, void *arg, void **cookiep) 463{ 464 int error = 0; 465 int xlrirq; 466 467 error = rman_activate_resource(irq); 468 if (error) 469 return error; 470 if (rman_get_start(irq) != rman_get_end(irq)) { 471 device_printf(dev, "Interrupt allocation %lu != %lu\n", 472 rman_get_start(irq), rman_get_end(irq)); 473 return (EINVAL); 474 } 475 xlrirq = rman_get_start(irq); 476 477 if (strcmp(device_get_name(dev), "pcib") != 0) 478 return (0); 479 480 if (xlr_board_info.is_xls == 0) { 481 xlr_establish_intr(device_get_name(child), filt, 482 intr, arg, PIC_PCIX_IRQ, flags, cookiep, bridge_pcix_ack); 483 pic_setup_intr(PIC_IRT_PCIX_INDEX, PIC_PCIX_IRQ, 0x1, 1); 484 } else { 485 /* 486 * temporary hack for MSI, we support just one device per 487 * link, and assign the link interrupt to the device interrupt 488 */ 489 if (xlrirq >= 64) { 490 xlrirq -= 64; 491 if (xlrirq % 32 != 0) 492 return (0); 493 xlrirq = xls_pcie_link_irq(xlrirq / 32); 494 if (xlrirq == -1) 495 return (EINVAL); 496 } 497 xlr_establish_intr(device_get_name(child), filt, 498 intr, arg, xlrirq, flags, cookiep, bridge_pcie_ack); 499 pic_setup_intr(xlrirq - PIC_IRQ_BASE, xlrirq, 0x1, 1); 500 } 501 502 return (bus_generic_setup_intr(dev, child, irq, flags, filt, intr, 503 arg, cookiep)); 504} 505 506static int 507mips_platform_pci_teardown_intr(device_t dev, device_t child, 508 struct resource *irq, void *cookie) 509{ 510 if (strcmp(device_get_name(child), "pci") == 0) { 511 /* if needed reprogram the pic to clear pcix related entry */ 512 device_printf(dev, "teardown intr\n"); 513 } 514 return (bus_generic_teardown_intr(dev, child, irq, cookie)); 515} 516 517static struct resource * 518xlr_pci_alloc_resource(device_t bus, device_t child, int type, int *rid, 519 u_long start, u_long end, u_long count, u_int flags) 520{ 521 struct rman *rm; 522 struct resource *rv; 523 vm_offset_t va; 524 int needactivate = flags & RF_ACTIVE; 525 526 switch (type) { 527 case SYS_RES_IRQ: 528 rm = &irq_rman; 529 break; 530 531 case SYS_RES_IOPORT: 532 rm = &port_rman; 533 break; 534 535 case SYS_RES_MEMORY: 536 rm = &mem_rman; 537 break; 538 539 default: 540 return (0); 541 } 542 543 rv = rman_reserve_resource(rm, start, end, count, flags, child); 544 if (rv == 0) 545 return (0); 546 547 rman_set_rid(rv, *rid); 548 549 if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) { 550 va = (vm_offset_t)pmap_mapdev(start, count); 551 rman_set_bushandle(rv, va); 552 /* bushandle is same as virtual addr */ 553 rman_set_virtual(rv, (void *)va); 554 rman_set_bustag(rv, rmi_pci_bus_space); 555 } 556 557 if (needactivate) { 558 if (bus_activate_resource(child, type, *rid, rv)) { 559 rman_release_resource(rv); 560 return (NULL); 561 } 562 } 563 return (rv); 564} 565 566static int 567xlr_pci_release_resource(device_t bus, device_t child, int type, int rid, 568 struct resource *r) 569{ 570 571 return (rman_release_resource(r)); 572} 573 574static bus_dma_tag_t 575xlr_pci_get_dma_tag(device_t bus, device_t child) 576{ 577 struct xlr_pcib_softc *sc; 578 579 sc = device_get_softc(bus); 580 return (sc->sc_pci_dmat); 581} 582 583static int 584xlr_pci_activate_resource(device_t bus, device_t child, int type, int rid, 585 struct resource *r) 586{ 587 588 return (rman_activate_resource(r)); 589} 590 591static int 592xlr_pci_deactivate_resource(device_t bus, device_t child, int type, int rid, 593 struct resource *r) 594{ 595 596 return (rman_deactivate_resource(r)); 597} 598 599static int 600mips_pci_route_interrupt(device_t bus, device_t dev, int pin) 601{ 602 int irq, link; 603 604 /* 605 * Validate requested pin number. 606 */ 607 if ((pin < 1) || (pin > 4)) 608 return (255); 609 610 if (xlr_board_info.is_xls) { 611 link = xls_pcie_link(bus, dev); 612 irq = xls_pcie_link_irq(link); 613 if (irq != -1) 614 return (irq); 615 } else { 616 if (pin == 1) 617 return (PIC_PCIX_IRQ); 618 } 619 620 return (255); 621} 622 623static device_method_t xlr_pcib_methods[] = { 624 /* Device interface */ 625 DEVMETHOD(device_identify, xlr_pcib_identify), 626 DEVMETHOD(device_probe, xlr_pcib_probe), 627 DEVMETHOD(device_attach, xlr_pcib_attach), 628 629 /* Bus interface */ 630 DEVMETHOD(bus_read_ivar, xlr_pcib_read_ivar), 631 DEVMETHOD(bus_write_ivar, xlr_pcib_write_ivar), 632 DEVMETHOD(bus_alloc_resource, xlr_pci_alloc_resource), 633 DEVMETHOD(bus_release_resource, xlr_pci_release_resource), 634 DEVMETHOD(bus_get_dma_tag, xlr_pci_get_dma_tag), 635 DEVMETHOD(bus_activate_resource, xlr_pci_activate_resource), 636 DEVMETHOD(bus_deactivate_resource, xlr_pci_deactivate_resource), 637 DEVMETHOD(bus_setup_intr, mips_platform_pci_setup_intr), 638 DEVMETHOD(bus_teardown_intr, mips_platform_pci_teardown_intr), 639 640 /* pcib interface */ 641 DEVMETHOD(pcib_maxslots, xlr_pcib_maxslots), 642 DEVMETHOD(pcib_read_config, xlr_pcib_read_config), 643 DEVMETHOD(pcib_write_config, xlr_pcib_write_config), 644 DEVMETHOD(pcib_route_interrupt, mips_pci_route_interrupt), 645 646 DEVMETHOD(pcib_alloc_msi, xlr_alloc_msi), 647 DEVMETHOD(pcib_release_msi, xlr_release_msi), 648 DEVMETHOD(pcib_map_msi, xlr_map_msi), 649 650 DEVMETHOD_END 651}; 652 653static driver_t xlr_pcib_driver = { 654 "pcib", 655 xlr_pcib_methods, 656 sizeof(struct xlr_pcib_softc), 657}; 658 659DRIVER_MODULE(pcib, iodi, xlr_pcib_driver, pcib_devclass, 0, 0); 660