1/* $NetBSD: idtpci.c,v 1.1 2007/03/20 08:52:02 dyoung Exp $ */ 2 3/*- 4 * Copyright (c) 2007 David Young. 5 * Copyright (c) 2007 Oleskandr Tymoshenko. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or 8 * without modification, are permitted provided that the following 9 * conditions 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 13 * copyright notice, this list of conditions and the following 14 * disclaimer in the documentation and/or other materials provided 15 * with the distribution. 16 * 3. The name of the author may not be used to endorse or promote 17 * products derived from this software without specific prior 18 * written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY 21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 23 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 25 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 27 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 29 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 30 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY 31 * OF SUCH DAMAGE. 32 */ 33/*- 34 * Copyright (c) 2006 Itronix Inc. 35 * All rights reserved. 36 * 37 * Written by Garrett D'Amore for Itronix Inc. 38 * 39 * Redistribution and use in source and binary forms, with or without 40 * modification, are permitted provided that the following conditions 41 * are met: 42 * 1. Redistributions of source code must retain the above copyright 43 * notice, this list of conditions and the following disclaimer. 44 * 2. Redistributions in binary form must reproduce the above copyright 45 * notice, this list of conditions and the following disclaimer in the 46 * documentation and/or other materials provided with the distribution. 47 * 3. The name of Itronix Inc. may not be used to endorse 48 * or promote products derived from this software without specific 49 * prior written permission. 50 * 51 * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND 52 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 53 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 54 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY 55 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 56 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 57 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 58 * ON ANY THEORY OF LIABILITY, WHETHER IN 59 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 60 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 61 * POSSIBILITY OF SUCH DAMAGE. 62 */ 63 64#include <sys/cdefs.h> 65__FBSDID("$FreeBSD$"); 66 67#include <sys/param.h> 68#include <sys/systm.h> 69 70#include <sys/bus.h> 71#include <sys/interrupt.h> 72#include <sys/malloc.h> 73#include <sys/kernel.h> 74#include <sys/module.h> 75#include <sys/rman.h> 76 77#include <vm/vm.h> 78#include <vm/pmap.h> 79#include <vm/vm_extern.h> 80 81#include <machine/bus.h> 82#include <machine/cpu.h> 83 84#include <dev/pci/pcivar.h> 85#include <dev/pci/pcireg.h> 86 87#include <dev/pci/pcib_private.h> 88#include "pcib_if.h" 89 90#include <mips/idt/idtreg.h> 91 92#ifdef IDTPCI_DEBUG 93int idtpci_debug = 1; 94#define IDTPCI_DPRINTF(__fmt, ...) \ 95do { \ 96 if (idtpci_debug) \ 97 printf((__fmt), __VA_ARGS__); \ 98} while (/*CONSTCOND*/0) 99#else /* !IDTPCI_DEBUG */ 100#define IDTPCI_DPRINTF(__fmt, ...) do { } while (/*CONSTCOND*/0) 101#endif /* IDTPCI_DEBUG */ 102 103#define IDTPCI_TAG_BUS_MASK 0x007f0000 104#define IDTPCI_TAG_DEVICE_MASK 0x00007800 105#define IDTPCI_TAG_FUNCTION_MASK 0x00000300 106#define IDTPCI_TAG_REGISTER_MASK 0x0000007c 107 108#define IDTPCI_MAX_DEVICE 109 110#define REG_READ(o) *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1(IDT_BASE_PCI + (o))) 111#define REG_WRITE(o,v) (REG_READ(o)) = (v) 112 113unsigned int korina_fixup[24] = { 114 0x00000157, 0x00000000, 0x00003c04, 0x00000008, 0x18800001, 0x18000001, 115 0x48000008, 0x00000000, 0x00000000, 0x00000000, 0x011d0214, 0x00000000, 116 0x00000000, 0x00000000, 0x38080101, 0x00008080, 0x00000d6e, 0x00000000, 117 0x00000051, 0x00000000, 0x00000055, 0x18000000, 0x00000000, 0x00000000 118}; 119 120struct idtpci_softc { 121 device_t sc_dev; 122 123 int sc_busno; 124 struct rman sc_mem_rman[2]; 125 struct rman sc_io_rman[2]; 126 struct rman sc_irq_rman; 127}; 128 129static uint32_t 130idtpci_make_addr(int bus, int slot, int func, int reg) 131{ 132 133 return 0x80000000 | (bus << 16) | (slot << 11) | (func << 8) | reg; 134} 135 136static int 137idtpci_probe(device_t dev) 138{ 139 140 return (0); 141} 142 143static int 144idtpci_attach(device_t dev) 145{ 146 int busno = 0; 147 struct idtpci_softc *sc = device_get_softc(dev); 148 unsigned int pci_data, force_endianess = 0; 149 int i; 150 bus_addr_t addr; 151 152 sc->sc_dev = dev; 153 sc->sc_busno = busno; 154 155 /* TODO: Check for host mode */ 156 157 /* Enabled PCI, IG mode, EAP mode */ 158 REG_WRITE(IDT_PCI_CNTL, IDT_PCI_CNTL_IGM | IDT_PCI_CNTL_EAP | 159 IDT_PCI_CNTL_EN); 160 /* Wait while "Reset in progress bit" set */ 161 while(1) { 162 pci_data = REG_READ(IDT_PCI_STATUS); 163 if((pci_data & IDT_PCI_STATUS_RIP) == 0) 164 break; 165 } 166 167 /* Reset status register */ 168 REG_WRITE(IDT_PCI_STATUS, 0); 169 /* Mask interrupts related to status register */ 170 REG_WRITE(IDT_PCI_STATUS_MASK, 0xffffffff); 171 172 /* Disable PCI decoupled access */ 173 REG_WRITE(IDT_PCI_DAC, 0); 174 /* Zero status and mask DA interrupts */ 175 REG_WRITE(IDT_PCI_DAS, 0); 176 REG_WRITE(IDT_PCI_DASM, 0x7f); 177 178 /* Init PCI messaging unit */ 179 /* Disable messaging interrupts */ 180 REG_WRITE(IDT_PCI_IIC, 0); 181 REG_WRITE(IDT_PCI_IIM, 0xffffffff); 182 REG_WRITE(IDT_PCI_OIC, 0); 183 REG_WRITE(IDT_PCI_OIM, 0); 184 185#ifdef __MIPSEB__ 186 force_endianess = IDT_PCI_LBA_FE; 187#endif 188 189 /* LBA0 -- memory window */ 190 REG_WRITE(IDT_PCI_LBA0, IDT_PCIMEM0_BASE); 191 REG_WRITE(IDT_PCI_LBA0_MAP, IDT_PCIMEM0_BASE); 192 REG_WRITE(IDT_PCI_LBA0_CNTL, IDT_PCI_LBA_SIZE_16MB | force_endianess); 193 pci_data = REG_READ(IDT_PCI_LBA0_CNTL); 194 195 /* LBA1 -- memory window */ 196 REG_WRITE(IDT_PCI_LBA1, IDT_PCIMEM1_BASE); 197 REG_WRITE(IDT_PCI_LBA1_MAP, IDT_PCIMEM1_BASE); 198 REG_WRITE(IDT_PCI_LBA1_CNTL, IDT_PCI_LBA_SIZE_256MB | force_endianess); 199 pci_data = REG_READ(IDT_PCI_LBA1_CNTL); 200 201 /* LBA2 -- IO window */ 202 REG_WRITE(IDT_PCI_LBA2, IDT_PCIMEM2_BASE); 203 REG_WRITE(IDT_PCI_LBA2_MAP, IDT_PCIMEM2_BASE); 204 REG_WRITE(IDT_PCI_LBA2_CNTL, IDT_PCI_LBA_SIZE_4MB | IDT_PCI_LBA_MSI | 205 force_endianess); 206 pci_data = REG_READ(IDT_PCI_LBA2_CNTL); 207 208 /* LBA3 -- IO window */ 209 REG_WRITE(IDT_PCI_LBA3, IDT_PCIMEM3_BASE); 210 REG_WRITE(IDT_PCI_LBA3_MAP, IDT_PCIMEM3_BASE); 211 REG_WRITE(IDT_PCI_LBA3_CNTL, IDT_PCI_LBA_SIZE_1MB | IDT_PCI_LBA_MSI | 212 force_endianess); 213 pci_data = REG_READ(IDT_PCI_LBA3_CNTL); 214 215 216 pci_data = REG_READ(IDT_PCI_CNTL) & ~IDT_PCI_CNTL_TNR; 217 REG_WRITE(IDT_PCI_CNTL, pci_data); 218 pci_data = REG_READ(IDT_PCI_CNTL); 219 220 /* Rewrite Target Control register with default values */ 221 REG_WRITE(IDT_PCI_TC, (IDT_PCI_TC_DTIMER << 8) | IDT_PCI_TC_RTIMER); 222 223 /* Perform Korina fixup */ 224 addr = idtpci_make_addr(0, 0, 0, 4); 225 for (i = 0; i < 24; i++) { 226 227 REG_WRITE(IDT_PCI_CFG_ADDR, addr); 228 REG_WRITE(IDT_PCI_CFG_DATA, korina_fixup[i]); 229 __asm__ volatile ("sync"); 230 231 REG_WRITE(IDT_PCI_CFG_ADDR, 0); 232 REG_WRITE(IDT_PCI_CFG_DATA, 0); 233 addr += 4; 234 } 235 236 /* Use KSEG1 to access IO ports for it is uncached */ 237 sc->sc_io_rman[0].rm_type = RMAN_ARRAY; 238 sc->sc_io_rman[0].rm_descr = "IDTPCI I/O Ports window 1"; 239 if (rman_init(&sc->sc_io_rman[0]) != 0 || 240 rman_manage_region(&sc->sc_io_rman[0], 241 IDT_PCIMEM2_BASE, IDT_PCIMEM2_BASE + IDT_PCIMEM2_SIZE - 1) != 0) { 242 panic("idtpci_attach: failed to set up I/O rman"); 243 } 244 245 sc->sc_io_rman[1].rm_type = RMAN_ARRAY; 246 sc->sc_io_rman[1].rm_descr = "IDTPCI I/O Ports window 2"; 247 if (rman_init(&sc->sc_io_rman[1]) != 0 || 248 rman_manage_region(&sc->sc_io_rman[1], 249 IDT_PCIMEM3_BASE, IDT_PCIMEM3_BASE + IDT_PCIMEM3_SIZE - 1) != 0) { 250 panic("idtpci_attach: failed to set up I/O rman"); 251 } 252 253 /* Use KSEG1 to access PCI memory for it is uncached */ 254 sc->sc_mem_rman[0].rm_type = RMAN_ARRAY; 255 sc->sc_mem_rman[0].rm_descr = "IDTPCI PCI Memory window 1"; 256 if (rman_init(&sc->sc_mem_rman[0]) != 0 || 257 rman_manage_region(&sc->sc_mem_rman[0], 258 IDT_PCIMEM0_BASE, IDT_PCIMEM0_BASE + IDT_PCIMEM0_SIZE) != 0) { 259 panic("idtpci_attach: failed to set up memory rman"); 260 } 261 262 sc->sc_mem_rman[1].rm_type = RMAN_ARRAY; 263 sc->sc_mem_rman[1].rm_descr = "IDTPCI PCI Memory window 2"; 264 if (rman_init(&sc->sc_mem_rman[1]) != 0 || 265 rman_manage_region(&sc->sc_mem_rman[1], 266 IDT_PCIMEM1_BASE, IDT_PCIMEM1_BASE + IDT_PCIMEM1_SIZE) != 0) { 267 panic("idtpci_attach: failed to set up memory rman"); 268 } 269 270 sc->sc_irq_rman.rm_type = RMAN_ARRAY; 271 sc->sc_irq_rman.rm_descr = "IDTPCI PCI IRQs"; 272 if (rman_init(&sc->sc_irq_rman) != 0 || 273 rman_manage_region(&sc->sc_irq_rman, PCI_IRQ_BASE, 274 PCI_IRQ_END) != 0) 275 panic("idtpci_attach: failed to set up IRQ rman"); 276 277 device_add_child(dev, "pci", -1); 278 return (bus_generic_attach(dev)); 279} 280 281static int 282idtpci_maxslots(device_t dev) 283{ 284 285 return (PCI_SLOTMAX); 286} 287 288static uint32_t 289idtpci_read_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg, 290 int bytes) 291{ 292 uint32_t data; 293 uint32_t shift, mask; 294 bus_addr_t addr; 295 296 IDTPCI_DPRINTF("%s: tag (%x, %x, %x) reg %d(%d)\n", __func__, 297 bus, slot, func, reg, bytes); 298 299 addr = idtpci_make_addr(bus, slot, func, reg); 300 301 REG_WRITE(IDT_PCI_CFG_ADDR, addr); 302 data = REG_READ(IDT_PCI_CFG_DATA); 303 304 switch (reg % 4) { 305 case 3: 306 shift = 24; 307 break; 308 case 2: 309 shift = 16; 310 break; 311 case 1: 312 shift = 8; 313 break; 314 default: 315 shift = 0; 316 break; 317 } 318 319 switch (bytes) { 320 case 1: 321 mask = 0xff; 322 data = (data >> shift) & mask; 323 break; 324 case 2: 325 mask = 0xffff; 326 if (reg % 4 == 0) 327 data = data & mask; 328 else 329 data = (data >> 16) & mask; 330 break; 331 case 4: 332 break; 333 default: 334 panic("%s: wrong bytes count", __func__); 335 break; 336 } 337 338 __asm__ volatile ("sync"); 339 IDTPCI_DPRINTF("%s: read 0x%x\n", __func__, data); 340 341 return (data); 342} 343 344static void 345idtpci_write_config(device_t dev, u_int bus, u_int slot, u_int func, u_int reg, 346 uint32_t data, int bytes) 347{ 348 bus_addr_t addr; 349 uint32_t reg_data; 350 uint32_t shift, mask; 351 352 IDTPCI_DPRINTF("%s: tag (%x, %x, %x) reg %d(%d) data %08x\n", __func__, 353 bus, slot, func, reg, bytes, data); 354 355 if (bytes != 4) { 356 reg_data = idtpci_read_config(dev, bus, slot, func, reg, 4); 357 358 switch (reg % 4) { 359 case 3: 360 shift = 24; 361 break; 362 case 2: 363 shift = 16; 364 break; 365 case 1: 366 shift = 8; 367 break; 368 default: 369 shift = 0; 370 break; 371 } 372 373 switch (bytes) { 374 case 1: 375 mask = 0xff; 376 data = (reg_data & ~ (mask << shift)) | (data << shift); 377 break; 378 case 2: 379 mask = 0xffff; 380 if (reg % 4 == 0) 381 data = (reg_data & ~mask) | data; 382 else 383 data = (reg_data & ~ (mask << shift)) | 384 (data << shift); 385 break; 386 case 4: 387 break; 388 default: 389 panic("%s: wrong bytes count", __func__); 390 break; 391 } 392 } 393 394 addr = idtpci_make_addr(bus, slot, func, reg); 395 396 397 REG_WRITE(IDT_PCI_CFG_ADDR, addr); 398 REG_WRITE(IDT_PCI_CFG_DATA, data); 399 __asm__ volatile ("sync"); 400 401 REG_WRITE(IDT_PCI_CFG_ADDR, 0); 402 REG_WRITE(IDT_PCI_CFG_DATA, 0); 403} 404 405static int 406idtpci_route_interrupt(device_t pcib, device_t device, int pin) 407{ 408 static int idt_pci_table[2][12] = 409 { 410 { 0, 0, 2, 3, 2, 3, 0, 0, 0, 0, 0, 1 }, 411 { 0, 0, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3 } 412 }; 413 int dev, bus, irq; 414 415 dev = pci_get_slot(device); 416 bus = pci_get_bus(device); 417 if (bootverbose) 418 device_printf(pcib, "routing pin %d for %s\n", pin, 419 device_get_nameunit(device)); 420 if (bus >= 0 && bus <= 1 && 421 dev >= 0 && dev <= 11) { 422 irq = IP_IRQ(6, idt_pci_table[bus][dev] + 4); 423 if (bootverbose) 424 printf("idtpci: %d/%d/%d -> IRQ%d\n", 425 pci_get_bus(device), dev, pci_get_function(device), 426 irq); 427 return (irq); 428 } else 429 printf("idtpci: no mapping for %d/%d/%d\n", 430 pci_get_bus(device), dev, pci_get_function(device)); 431 432 return (-1); 433} 434 435static int 436idtpci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 437{ 438 struct idtpci_softc *sc = device_get_softc(dev); 439 440 switch (which) { 441 case PCIB_IVAR_DOMAIN: 442 *result = 0; 443 return (0); 444 case PCIB_IVAR_BUS: 445 *result = sc->sc_busno; 446 return (0); 447 } 448 449 return (ENOENT); 450} 451 452static int 453idtpci_write_ivar(device_t dev, device_t child, int which, uintptr_t result) 454{ 455 struct idtpci_softc * sc = device_get_softc(dev); 456 457 switch (which) { 458 case PCIB_IVAR_BUS: 459 sc->sc_busno = result; 460 return (0); 461 } 462 return (ENOENT); 463} 464 465static struct resource * 466idtpci_alloc_resource(device_t bus, device_t child, int type, int *rid, 467 rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) 468{ 469 470 struct idtpci_softc *sc = device_get_softc(bus); 471 struct resource *rv = NULL; 472 struct rman *rm1, *rm2; 473 474 switch (type) { 475 case SYS_RES_IRQ: 476 rm1 = &sc->sc_irq_rman; 477 rm2 = NULL; 478 break; 479 case SYS_RES_MEMORY: 480 rm1 = &sc->sc_mem_rman[0]; 481 rm2 = &sc->sc_mem_rman[1]; 482 break; 483 case SYS_RES_IOPORT: 484 rm1 = &sc->sc_io_rman[0]; 485 rm2 = &sc->sc_io_rman[1]; 486 break; 487 default: 488 return (NULL); 489 } 490 491 rv = rman_reserve_resource(rm1, start, end, count, flags, child); 492 493 /* Try second window if it exists */ 494 if ((rv == NULL) && (rm2 != NULL)) 495 rv = rman_reserve_resource(rm2, start, end, count, flags, 496 child); 497 498 if (rv == NULL) 499 return (NULL); 500 501 rman_set_rid(rv, *rid); 502 503 if (flags & RF_ACTIVE) { 504 if (bus_activate_resource(child, type, *rid, rv)) { 505 rman_release_resource(rv); 506 return (NULL); 507 } 508 } 509 510 return (rv); 511} 512 513static int 514idtpci_teardown_intr(device_t dev, device_t child, struct resource *res, 515 void *cookie) 516{ 517 518 return (intr_event_remove_handler(cookie)); 519} 520 521static device_method_t idtpci_methods[] = { 522 /* Device interface */ 523 DEVMETHOD(device_probe, idtpci_probe), 524 DEVMETHOD(device_attach, idtpci_attach), 525 DEVMETHOD(device_shutdown, bus_generic_shutdown), 526 DEVMETHOD(device_suspend, bus_generic_suspend), 527 DEVMETHOD(device_resume, bus_generic_resume), 528 529 /* Bus interface */ 530 DEVMETHOD(bus_read_ivar, idtpci_read_ivar), 531 DEVMETHOD(bus_write_ivar, idtpci_write_ivar), 532 DEVMETHOD(bus_alloc_resource, idtpci_alloc_resource), 533 DEVMETHOD(bus_release_resource, bus_generic_release_resource), 534 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), 535 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource), 536 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 537 DEVMETHOD(bus_teardown_intr, idtpci_teardown_intr), 538 539 /* pcib interface */ 540 DEVMETHOD(pcib_maxslots, idtpci_maxslots), 541 DEVMETHOD(pcib_read_config, idtpci_read_config), 542 DEVMETHOD(pcib_write_config, idtpci_write_config), 543 DEVMETHOD(pcib_route_interrupt, idtpci_route_interrupt), 544 545 DEVMETHOD_END 546}; 547 548static driver_t idtpci_driver = { 549 "pcib", 550 idtpci_methods, 551 sizeof(struct idtpci_softc), 552}; 553 554static devclass_t idtpci_devclass; 555 556DRIVER_MODULE(idtpci, obio, idtpci_driver, idtpci_devclass, 0, 0); 557