1 /* $NetBSD: pci_machdep.c,v 1.59 2008/05/30 19:26:35 ad Exp $ */ 2 3 /* 4 * Copyright (c) 1999, 2000 Matthew R. Green 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * 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 copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 /* 30 * functions expected by the MI PCI code. 31 */ 32 33 #include <sys/cdefs.h> 34 __KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.59 2008/05/30 19:26:35 ad Exp $"); 35 36 #include <sys/types.h> 37 #include <sys/param.h> 38 #include <sys/time.h> 39 #include <sys/systm.h> 40 #include <sys/errno.h> 41 #include <sys/device.h> 42 #include <sys/malloc.h> 43 44 #define _SPARC_BUS_DMA_PRIVATE 45 #include <machine/bus.h> 46 #include <machine/autoconf.h> 47 #include <machine/openfirm.h> 48 #include <dev/pci/pcivar.h> 49 #include <dev/pci/pcireg.h> 50 51 #include <dev/ofw/ofw_pci.h> 52 53 #include <sparc64/dev/iommureg.h> 54 #include <sparc64/dev/iommuvar.h> 55 #include <sparc64/dev/psychoreg.h> 56 #include <sparc64/dev/psychovar.h> 57 #include <sparc64/sparc64/cache.h> 58 59 #include "locators.h" 60 61 #ifdef DEBUG 62 #define SPDB_CONF 0x01 63 #define SPDB_INTR 0x04 64 #define SPDB_INTMAP 0x08 65 #define SPDB_PROBE 0x20 66 int sparc_pci_debug = 0x0; 67 #define DPRINTF(l, s) do { if (sparc_pci_debug & l) printf s; } while (0) 68 #else 69 #define DPRINTF(l, s) 70 #endif 71 72 /* this is a base to be copied */ 73 struct sparc_pci_chipset _sparc_pci_chipset = { 74 .cookie = NULL, 75 }; 76 77 static int pci_find_ino(struct pci_attach_args *, pci_intr_handle_t *); 78 79 static pcitag_t 80 ofpci_make_tag(pci_chipset_tag_t pc, int node, int b, int d, int f) 81 { 82 pcitag_t tag; 83 84 tag = PCITAG_CREATE(node, b, d, f); 85 86 /* Enable all the different spaces for this device */ 87 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, 88 PCI_COMMAND_MEM_ENABLE|PCI_COMMAND_MASTER_ENABLE| 89 PCI_COMMAND_IO_ENABLE); 90 return (tag); 91 } 92 93 /* 94 * functions provided to the MI code. 95 */ 96 97 void 98 pci_attach_hook(struct device *parent, struct device *self, 99 struct pcibus_attach_args *pba) 100 { 101 } 102 103 int 104 pci_bus_maxdevs(pci_chipset_tag_t pc, int busno) 105 { 106 107 return 32; 108 } 109 110 pcitag_t 111 pci_make_tag(pci_chipset_tag_t pc, int b, int d, int f) 112 { 113 struct psycho_pbm *pp = pc->cookie; 114 struct ofw_pci_register reg; 115 pcitag_t tag; 116 int (*valid)(void *); 117 int node, len; 118 #ifdef DEBUG 119 char name[80]; 120 memset(name, 0, sizeof(name)); 121 #endif 122 123 /* 124 * Refer to the PCI/CardBus bus node first. 125 * It returns a tag if node is present and bus is valid. 126 */ 127 if (0 <= b && b < 256) { 128 node = (*pp->pp_busnode)[b].node; 129 valid = (*pp->pp_busnode)[b].valid; 130 if (node != 0 && d == 0 && 131 (valid == NULL || (*valid)((*pp->pp_busnode)[b].arg))) 132 return ofpci_make_tag(pc, node, b, d, f); 133 } 134 135 /* 136 * Hunt for the node that corresponds to this device 137 * 138 * We could cache this info in an array in the parent 139 * device... except then we have problems with devices 140 * attached below pci-pci bridges, and we would need to 141 * add special code to the pci-pci bridge to cache this 142 * info. 143 */ 144 145 tag = PCITAG_CREATE(-1, b, d, f); 146 node = pc->rootnode; 147 /* 148 * First make sure we're on the right bus. If our parent 149 * has a bus-range property and we're not in the range, 150 * then we're obviously on the wrong bus. So go up one 151 * level. 152 */ 153 #ifdef DEBUG 154 if (sparc_pci_debug & SPDB_PROBE) { 155 printf("curnode %x %s\n", node, 156 prom_getpropstringA(node, "name", name, sizeof(name))); 157 } 158 #endif 159 #if 0 160 while ((OF_getprop(OF_parent(node), "bus-range", (void *)&busrange, 161 sizeof(busrange)) == sizeof(busrange)) && 162 (b < busrange[0] || b > busrange[1])) { 163 /* Out of range, go up one */ 164 node = OF_parent(node); 165 #ifdef DEBUG 166 if (sparc_pci_debug & SPDB_PROBE) { 167 printf("going up to node %x %s\n", node, 168 prom_getpropstringA(node, "name", name, sizeof(name))); 169 } 170 #endif 171 } 172 #endif 173 /* 174 * Now traverse all peers until we find the node or we find 175 * the right bridge. 176 * 177 * XXX We go up one and down one to make sure nobody's missed. 178 * but this should not be necessary. 179 */ 180 for (node = ((node)); node; node = prom_nextsibling(node)) { 181 182 #ifdef DEBUG 183 if (sparc_pci_debug & SPDB_PROBE) { 184 printf("checking node %x %s\n", node, 185 prom_getpropstringA(node, "name", name, sizeof(name))); 186 187 } 188 #endif 189 190 #if 1 191 /* 192 * Check for PCI-PCI bridges. If the device we want is 193 * in the bus-range for that bridge, work our way down. 194 */ 195 while (1) { 196 int busrange[2], *brp; 197 len = 2; 198 brp = busrange; 199 if (prom_getprop(node, "bus-range", sizeof(*brp), 200 &len, &brp) != 0) 201 break; 202 if (len != 2 || b < busrange[0] || b > busrange[1]) 203 break; 204 /* Go down 1 level */ 205 node = prom_firstchild(node); 206 #ifdef DEBUG 207 if (sparc_pci_debug & SPDB_PROBE) { 208 printf("going down to node %x %s\n", node, 209 prom_getpropstringA(node, "name", 210 name, sizeof(name))); 211 } 212 #endif 213 } 214 #endif /*1*/ 215 /* 216 * We only really need the first `reg' property. 217 * 218 * For simplicity, we'll query the `reg' when we 219 * need it. Otherwise we could malloc() it, but 220 * that gets more complicated. 221 */ 222 len = prom_getproplen(node, "reg"); 223 if (len < sizeof(reg)) 224 continue; 225 if (OF_getprop(node, "reg", (void *)®, sizeof(reg)) != len) 226 panic("pci_probe_bus: OF_getprop len botch"); 227 228 if (b != OFW_PCI_PHYS_HI_BUS(reg.phys_hi)) 229 continue; 230 if (d != OFW_PCI_PHYS_HI_DEVICE(reg.phys_hi)) 231 continue; 232 if (f != OFW_PCI_PHYS_HI_FUNCTION(reg.phys_hi)) 233 continue; 234 235 /* Got a match */ 236 tag = ofpci_make_tag(pc, node, b, d, f); 237 238 return (tag); 239 } 240 /* No device found -- return a dead tag */ 241 return (tag); 242 } 243 244 void 245 pci_decompose_tag(pci_chipset_tag_t pc, pcitag_t tag, int *bp, int *dp, int *fp) 246 { 247 248 if (bp != NULL) 249 *bp = PCITAG_BUS(tag); 250 if (dp != NULL) 251 *dp = PCITAG_DEV(tag); 252 if (fp != NULL) 253 *fp = PCITAG_FUN(tag); 254 } 255 256 int 257 sparc64_pci_enumerate_bus(struct pci_softc *sc, const int *locators, 258 int (*match)(struct pci_attach_args *), struct pci_attach_args *pap) 259 { 260 struct ofw_pci_register reg; 261 pci_chipset_tag_t pc = sc->sc_pc; 262 pcitag_t tag; 263 pcireg_t class, csr, bhlc, ic; 264 int node, b, d, f, ret; 265 int bus_frequency, lt, cl, cacheline; 266 char name[30]; 267 extern int pci_config_dump; 268 269 if (sc->sc_bridgetag) 270 node = PCITAG_NODE(*sc->sc_bridgetag); 271 else 272 node = pc->rootnode; 273 274 bus_frequency = 275 prom_getpropint(node, "clock-frequency", 33000000) / 1000000; 276 277 /* 278 * Make sure the cache line size is at least as big as the 279 * ecache line and the streaming cache (64 byte). 280 */ 281 cacheline = max(ecache_min_line_size, 64); 282 KASSERT((cacheline/64)*64 == cacheline && 283 (cacheline/ecache_min_line_size)*ecache_min_line_size == cacheline && 284 (cacheline/4)*4 == cacheline); 285 286 /* Turn on parity for the bus. */ 287 tag = ofpci_make_tag(pc, node, sc->sc_bus, 0, 0); 288 csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); 289 csr |= PCI_COMMAND_PARITY_ENABLE; 290 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, csr); 291 292 /* 293 * Initialize the latency timer register. 294 * The value 0x40 is from Solaris. 295 */ 296 bhlc = pci_conf_read(pc, tag, PCI_BHLC_REG); 297 bhlc &= ~(PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT); 298 bhlc |= 0x40 << PCI_LATTIMER_SHIFT; 299 pci_conf_write(pc, tag, PCI_BHLC_REG, bhlc); 300 301 if (pci_config_dump) pci_conf_print(pc, tag, NULL); 302 303 for (node = prom_firstchild(node); node != 0 && node != -1; 304 node = prom_nextsibling(node)) { 305 name[0] = name[29] = 0; 306 prom_getpropstringA(node, "name", name, sizeof(name)); 307 308 if (OF_getprop(node, "class-code", &class, sizeof(class)) != 309 sizeof(class)) 310 continue; 311 if (OF_getprop(node, "reg", ®, sizeof(reg)) < sizeof(reg)) 312 panic("pci_enumerate_bus: \"%s\" regs too small", name); 313 314 b = OFW_PCI_PHYS_HI_BUS(reg.phys_hi); 315 d = OFW_PCI_PHYS_HI_DEVICE(reg.phys_hi); 316 f = OFW_PCI_PHYS_HI_FUNCTION(reg.phys_hi); 317 318 if (sc->sc_bus != b) { 319 aprint_error_dev(sc->sc_dev, "WARNING: incorrect " 320 "bus # for \"%s\" (%d/%d/%d)\n", name, b, d, f); 321 continue; 322 } 323 if ((locators[PCICF_DEV] != PCICF_DEV_DEFAULT) && 324 (locators[PCICF_DEV] != d)) 325 continue; 326 if ((locators[PCICF_FUNCTION] != PCICF_FUNCTION_DEFAULT) && 327 (locators[PCICF_FUNCTION] != f)) 328 continue; 329 330 tag = ofpci_make_tag(pc, node, b, d, f); 331 332 /* 333 * Turn on parity and fast-back-to-back for the device. 334 */ 335 csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); 336 if (csr & PCI_STATUS_BACKTOBACK_SUPPORT) 337 csr |= PCI_COMMAND_BACKTOBACK_ENABLE; 338 csr |= PCI_COMMAND_PARITY_ENABLE; 339 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, csr); 340 341 /* 342 * Initialize the latency timer register for busmaster 343 * devices to work properly. 344 * latency-timer = min-grant * bus-freq / 4 (from FreeBSD) 345 * Also initialize the cache line size register. 346 * Solaris anytime sets this register to the value 0x10. 347 */ 348 bhlc = pci_conf_read(pc, tag, PCI_BHLC_REG); 349 ic = pci_conf_read(pc, tag, PCI_INTERRUPT_REG); 350 351 lt = min(PCI_MIN_GNT(ic) * bus_frequency / 4, 255); 352 if (lt == 0 || lt < PCI_LATTIMER(bhlc)) 353 lt = PCI_LATTIMER(bhlc); 354 355 cl = PCI_CACHELINE(bhlc); 356 if (cl == 0) 357 cl = cacheline; 358 359 bhlc &= ~((PCI_LATTIMER_MASK << PCI_LATTIMER_SHIFT) | 360 (PCI_CACHELINE_MASK << PCI_CACHELINE_SHIFT)); 361 bhlc |= (lt << PCI_LATTIMER_SHIFT) | 362 (cl << PCI_CACHELINE_SHIFT); 363 pci_conf_write(pc, tag, PCI_BHLC_REG, bhlc); 364 365 ret = pci_probe_device(sc, tag, match, pap); 366 if (match != NULL && ret != 0) 367 return (ret); 368 } 369 return (0); 370 } 371 372 /* assume we are mapped little-endian/side-effect */ 373 pcireg_t 374 pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg) 375 { 376 struct psycho_pbm *pp = pc->cookie; 377 struct psycho_softc *sc = pp->pp_sc; 378 pcireg_t val = (pcireg_t)~0; 379 380 DPRINTF(SPDB_CONF, ("pci_conf_read: tag %lx reg %x ", 381 (long)tag, reg)); 382 if (PCITAG_NODE(tag) != -1) { 383 DPRINTF(SPDB_CONF, ("asi=%x addr=%qx (offset=%x) ...", 384 sc->sc_configaddr._asi, 385 (long long)(sc->sc_configaddr._ptr + 386 PCITAG_OFFSET(tag) + reg), 387 (int)PCITAG_OFFSET(tag) + reg)); 388 389 val = bus_space_read_4(sc->sc_configtag, sc->sc_configaddr, 390 PCITAG_OFFSET(tag) + reg); 391 } 392 #ifdef DEBUG 393 else DPRINTF(SPDB_CONF, ("pci_conf_read: bogus pcitag %x\n", 394 (int)PCITAG_OFFSET(tag))); 395 #endif 396 DPRINTF(SPDB_CONF, (" returning %08x\n", (u_int)val)); 397 398 return (val); 399 } 400 401 void 402 pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, pcireg_t data) 403 { 404 struct psycho_pbm *pp = pc->cookie; 405 struct psycho_softc *sc = pp->pp_sc; 406 407 DPRINTF(SPDB_CONF, ("pci_conf_write: tag %lx; reg %x; data %x; ", 408 (long)PCITAG_OFFSET(tag), reg, (int)data)); 409 DPRINTF(SPDB_CONF, ("asi = %x; readaddr = %qx (offset = %x)\n", 410 sc->sc_configaddr._asi, 411 (long long)(sc->sc_configaddr._ptr + PCITAG_OFFSET(tag) + reg), 412 (int)PCITAG_OFFSET(tag) + reg)); 413 414 /* If we don't know it, just punt it. */ 415 if (PCITAG_NODE(tag) == -1) { 416 DPRINTF(SPDB_CONF, ("pci_conf_write: bad addr")); 417 return; 418 } 419 420 bus_space_write_4(sc->sc_configtag, sc->sc_configaddr, 421 PCITAG_OFFSET(tag) + reg, data); 422 } 423 424 /* 425 * XXX: This code assumes we're on a psycho host bridge. 426 */ 427 static int 428 pci_find_ino(struct pci_attach_args *pa, pci_intr_handle_t *ihp) 429 { 430 struct psycho_pbm *pp = pa->pa_pc->cookie; 431 struct psycho_softc *sc = pp->pp_sc; 432 u_int bus; 433 u_int dev; 434 u_int pin; 435 436 DPRINTF(SPDB_INTMAP, ("pci_find_ino: pa_tag: node %x, %d:%d:%d\n", 437 PCITAG_NODE(pa->pa_tag), (int)PCITAG_BUS(pa->pa_tag), 438 (int)PCITAG_DEV(pa->pa_tag), 439 (int)PCITAG_FUN(pa->pa_tag))); 440 DPRINTF(SPDB_INTMAP, 441 ("pci_find_ino: intrswiz %d, intrpin %d, intrline %d, rawintrpin %d\n", 442 pa->pa_intrswiz, pa->pa_intrpin, pa->pa_intrline, pa->pa_rawintrpin)); 443 DPRINTF(SPDB_INTMAP, ("pci_find_ino: pa_intrtag: node %x, %d:%d:%d\n", 444 PCITAG_NODE(pa->pa_intrtag), 445 (int)PCITAG_BUS(pa->pa_intrtag), 446 (int)PCITAG_DEV(pa->pa_intrtag), 447 (int)PCITAG_FUN(pa->pa_intrtag))); 448 449 bus = (pp->pp_id == PSYCHO_PBM_B); 450 /* 451 * If we are on a ppb, use the devno on the underlying bus when forming 452 * the ivec. 453 */ 454 if (pa->pa_intrswiz != 0 && PCITAG_NODE(pa->pa_intrtag) != 0) 455 dev = PCITAG_DEV(pa->pa_intrtag); 456 else 457 dev = pa->pa_device; 458 dev--; 459 460 if (sc->sc_mode == PSYCHO_MODE_PSYCHO && 461 pp->pp_id == PSYCHO_PBM_B) 462 dev--; 463 464 pin = pa->pa_intrpin - 1; 465 DPRINTF(SPDB_INTMAP, ("pci_find_ino: mode %d, pbm %d, dev %d, pin %d\n", 466 sc->sc_mode, pp->pp_id, dev, pin)); 467 468 *ihp = sc->sc_ign | ((bus << 4) & INTMAP_PCIBUS) | 469 ((dev << 2) & INTMAP_PCISLOT) | (pin & INTMAP_PCIINT); 470 471 return (0); 472 } 473 474 /* 475 * interrupt mapping foo. 476 * XXX: how does this deal with multiple interrupts for a device? 477 */ 478 int 479 pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp) 480 { 481 pcitag_t tag = pa->pa_tag; 482 int interrupts, *intp; 483 int len, node = PCITAG_NODE(tag); 484 char devtype[30]; 485 486 intp = &interrupts; 487 len = 1; 488 if (prom_getprop(node, "interrupts", sizeof(interrupts), 489 &len, &intp) != 0 || len != 1) { 490 DPRINTF(SPDB_INTMAP, 491 ("pci_intr_map: could not read interrupts\n")); 492 return (ENODEV); 493 } 494 495 if (OF_mapintr(node, &interrupts, sizeof(interrupts), 496 sizeof(interrupts)) < 0) { 497 printf("OF_mapintr failed\n"); 498 pci_find_ino(pa, &interrupts); 499 } 500 501 /* Try to find an IPL for this type of device. */ 502 prom_getpropstringA(node, "device_type", devtype, sizeof(devtype)); 503 for (len = 0; intrmap[len].in_class != NULL; len++) 504 if (strcmp(intrmap[len].in_class, devtype) == 0) { 505 interrupts |= INTLEVENCODE(intrmap[len].in_lev); 506 break; 507 } 508 509 /* XXXX -- we use the ino. What if there is a valid IGN? */ 510 *ihp = interrupts; 511 return (0); 512 } 513 514 const char * 515 pci_intr_string(pci_chipset_tag_t pc, pci_intr_handle_t ih) 516 { 517 static char str[16]; 518 519 DPRINTF(SPDB_INTR, ("pci_intr_string: ih %u", ih)); 520 sprintf(str, "ivec %x", ih); 521 DPRINTF(SPDB_INTR, ("; returning %s\n", str)); 522 523 return (str); 524 } 525 526 const struct evcnt * 527 pci_intr_evcnt(pci_chipset_tag_t pc, pci_intr_handle_t ih) 528 { 529 530 /* XXX for now, no evcnt parent reported */ 531 return NULL; 532 } 533 534 int 535 pci_intr_setattr(pci_chipset_tag_t pc, pci_intr_handle_t *ih, 536 int attr, uint64_t data) 537 { 538 539 switch (attr) { 540 case PCI_INTR_MPSAFE: 541 return 0; 542 default: 543 return ENODEV; 544 } 545 } 546 547 void * 548 pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, int level, 549 int (*func)(void *), void *arg) 550 { 551 void *cookie; 552 struct psycho_pbm *pp = (struct psycho_pbm *)pc->cookie; 553 554 DPRINTF(SPDB_INTR, ("pci_intr_establish: ih %lu; level %d", (u_long)ih, level)); 555 cookie = bus_intr_establish(pp->pp_memt, ih, level, func, arg); 556 557 DPRINTF(SPDB_INTR, ("; returning handle %p\n", cookie)); 558 return (cookie); 559 } 560 561 void 562 pci_intr_disestablish(pci_chipset_tag_t pc, void *cookie) 563 { 564 565 DPRINTF(SPDB_INTR, ("pci_intr_disestablish: cookie %p\n", cookie)); 566 567 /* XXX */ 568 /* panic("can't disestablish PCI interrupts yet"); */ 569 } 570