ofw_pci.c revision 115417
186231Stmm/* 286231Stmm * Copyright (c) 1999, 2000 Matthew R. Green 386231Stmm * All rights reserved. 486231Stmm * Copyright 2001 by Thomas Moestl <tmm@FreeBSD.org>. All rights reserved. 586231Stmm * 686231Stmm * Redistribution and use in source and binary forms, with or without 786231Stmm * modification, are permitted provided that the following conditions 886231Stmm * are met: 986231Stmm * 1. Redistributions of source code must retain the above copyright 1086231Stmm * notice, this list of conditions and the following disclaimer. 1186231Stmm * 2. Redistributions in binary form must reproduce the above copyright 1286231Stmm * notice, this list of conditions and the following disclaimer in the 1386231Stmm * documentation and/or other materials provided with the distribution. 1486231Stmm * 3. The name of the author may not be used to endorse or promote products 1586231Stmm * derived from this software without specific prior written permission. 1686231Stmm * 1786231Stmm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1886231Stmm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1986231Stmm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2086231Stmm * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2186231Stmm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 2286231Stmm * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 2386231Stmm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 2486231Stmm * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 2586231Stmm * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2686231Stmm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2786231Stmm * SUCH DAMAGE. 2886231Stmm * 2986231Stmm * from: NetBSD: psycho.c,v 1.35 2001/09/10 16:17:06 eeh Exp 3086231Stmm * 3186231Stmm * $FreeBSD: head/sys/sparc64/pci/ofw_pci.c 115417 2003-05-30 20:48:05Z tmm $ 3286231Stmm */ 3386231Stmm 3486231Stmm#include "opt_ofw_pci.h" 3586231Stmm 3686231Stmm#include <sys/param.h> 3786231Stmm#include <sys/kernel.h> 3886231Stmm#include <sys/systm.h> 3986231Stmm#include <sys/bus.h> 4086231Stmm 4186231Stmm#include <dev/pci/pcivar.h> 4286231Stmm#include <dev/pci/pcireg.h> 4386231Stmm 4486231Stmm#include <dev/ofw/ofw_pci.h> 4586231Stmm#include <dev/ofw/openfirm.h> 4686231Stmm 4786231Stmm#include <sparc64/pci/ofw_pci.h> 4886231Stmm 49115417Stmm#include <machine/bus.h> 50108805Stmm#include <machine/cache.h> 51108805Stmm#include <machine/iommureg.h> 5286231Stmm#include <machine/ofw_bus.h> 53106555Stmm#include <machine/ver.h> 5486231Stmm 5586231Stmm#include "pcib_if.h" 56115417Stmm#include "sparcbus_if.h" 5786231Stmm 5898148Stmmu_int8_t pci_bus_cnt; 5998148Stmmphandle_t *pci_bus_map; 6098148Stmmint pci_bus_map_sz; 6198148Stmm 62115417Stmm/* Do not swizzle on a PCI bus node with no interrupt-map propery. */ 63115417Stmm#define OPQ_NO_SWIZZLE 1 64115417Stmm/* 65115417Stmm * INOs < 255 are really intpin numbers; use a driver method to figure out 66115417Stmm * the real INO. 67115417Stmm */ 68115417Stmm#define OPQ_INO_CALLBACK 2 69115417Stmm/* 70115417Stmm * Do not map EBus interrupts at PCI buses, but assume that they are fully 71115417Stmm * specified already. 72115417Stmm */ 73115417Stmm#define OPQ_EBUS_NOMAP 4 74115417Stmm 75106555Stmmstatic struct ofw_pci_quirk { 76106555Stmm char *opq_model; 77106555Stmm int opq_quirks; 78106555Stmm} ofw_pci_quirks[] = { 79115417Stmm { "SUNW,Ultra-4", OPQ_INO_CALLBACK | OPQ_EBUS_NOMAP }, 80115417Stmm { "SUNW,Ultra-1-Engine", OPQ_NO_SWIZZLE }, 81106555Stmm}; 82106555Stmm#define OPQ_NENT (sizeof(ofw_pci_quirks) / sizeof(ofw_pci_quirks[0])) 83106555Stmm 84106555Stmmstatic int pci_quirks; 85106555Stmm 86106555Stmm#define OFW_PCI_PCIBUS "pci" 87115417Stmm#define OFW_PCI_EBUS "ebus" 8898148Stmm#define PCI_BUS_MAP_INC 10 8998148Stmm 90106555Stmmint 91106555Stmmofw_pci_orb_callback(phandle_t node, u_int8_t *pintptr, int pintsz, 92115417Stmm u_int8_t *pregptr, int pregsz, u_int8_t **rintr, int *terminate, 93115417Stmm void *cookie) 94106555Stmm{ 95115417Stmm device_t dev = cookie; 96106555Stmm struct ofw_pci_register preg; 97106555Stmm u_int32_t pintr, intr; 98115417Stmm u_int slot; 99106555Stmm char type[32]; 100115417Stmm int found = 0; 101106555Stmm 102115417Stmm if ((pci_quirks & OPQ_EBUS_NOMAP) != 0 && 103115417Stmm OF_getprop(node, "name", type, sizeof(type)) != -1 && 104115417Stmm strcmp(type, OFW_PCI_EBUS) == 0) { 105115417Stmm *terminate = 1; 106107472Stmm return (-1); 107115417Stmm } 108115417Stmm if (pintsz != sizeof(u_int32_t) || pregsz < sizeof(preg)) 109115417Stmm return (-1); 110107472Stmm bcopy(pintptr, &pintr, sizeof(pintr)); 111115417Stmm bcopy(pregptr, &preg, sizeof(preg)); 112115417Stmm slot = OFW_PCI_PHYS_HI_DEVICE(preg.phys_hi); 113115417Stmm 114115417Stmm if ((pci_quirks & OPQ_INO_CALLBACK) != 0 && pintr <= 255) { 115115417Stmm /* 116115417Stmm * The e450 has no interrupt maps at all, and it usually has 117115417Stmm * full interrupt numbers, including IGN, in the interrupt 118115417Stmm * properties. There is one exception, however: the property 119115417Stmm * values for external PCI devices seem to always be below 255 120115417Stmm * and describe the interrupt pin to be used on the slot, while 121115417Stmm * we have to figure out the base INO by looking at the slot 122115417Stmm * number (which we do using a sparcbus method). 123115417Stmm * 124115417Stmm * Of course, there is an exception to that nice rule: 125115417Stmm * in the ebus case, the interrupt property has the correct 126115417Stmm * INO (but without IGN). This is dealt with above. 127115417Stmm */ 128115417Stmm intr = SPARCBUS_GUESS_INO(dev, node, slot, pintr); 129115417Stmm found = intr != 255; 130115417Stmm *terminate = found; 131115417Stmm } 132115417Stmm if (!found && (pci_quirks & OPQ_NO_SWIZZLE) == 0 && 133106555Stmm OF_getprop(node, "device_type", type, sizeof(type)) != -1 && 134107472Stmm strcmp(type, OFW_PCI_PCIBUS) == 0 && pintr >= 1 && pintr <= 4) { 135106555Stmm /* 136106555Stmm * Handle a quirk found on some Netra t1 models: there exist 137106555Stmm * PCI bridges without interrupt maps, where we apparently must 138106555Stmm * do the PCI swizzle and continue to map on at the parent. 139106555Stmm */ 140115417Stmm intr = (slot + pintr + 3) % 4 + 1; 141115417Stmm *terminate = 0; 142115417Stmm found = 1; 143115417Stmm } 144115417Stmm 145115417Stmm if (found) { 146111119Simp *rintr = malloc(sizeof(intr), M_OFWPROP, M_WAITOK); 147106555Stmm bcopy(&intr, *rintr, sizeof(intr)); 148106555Stmm return (sizeof(intr)); 149115417Stmm } else 150115417Stmm return (-1); 151106555Stmm} 152106555Stmm 153115417Stmmstatic u_int32_t 154115417Stmmofw_pci_route_intr(device_t dev, phandle_t node, u_int32_t ign) 15586231Stmm{ 15693067Stmm u_int32_t rv; 15786231Stmm 158115417Stmm rv = ofw_bus_route_intr(node, ORIP_NOINT, ofw_pci_orb_callback, dev); 15993067Stmm if (rv == ORIR_NOTFOUND) 16086231Stmm return (255); 161106555Stmm /* 162115417Stmm * Some machines (notably the SPARCengine Ultra AX and the e450) have 163115417Stmm * no mappings at all, but use complete interrupt vector number 164115417Stmm * including the IGN. Catch this case and remove the IGN. 165106555Stmm */ 166106555Stmm if (rv > ign) 167106555Stmm rv -= ign; 16893067Stmm return (rv); 16986231Stmm} 17086231Stmm 17198148Stmmu_int8_t 17298148Stmmofw_pci_alloc_busno(phandle_t node) 17398148Stmm{ 17498148Stmm phandle_t *om; 17598148Stmm int osz; 17698148Stmm u_int8_t n; 17798148Stmm 17898148Stmm n = pci_bus_cnt++; 17998148Stmm /* Establish a mapping between bus numbers and device nodes. */ 18098148Stmm if (n >= pci_bus_map_sz) { 18198148Stmm osz = pci_bus_map_sz; 18298148Stmm om = pci_bus_map; 18398148Stmm pci_bus_map_sz = n + PCI_BUS_MAP_INC; 18498148Stmm pci_bus_map = malloc(sizeof(*pci_bus_map) * pci_bus_map_sz, 185111119Simp M_DEVBUF, M_WAITOK | M_ZERO); 18698148Stmm if (om != NULL) { 18798148Stmm bcopy(om, pci_bus_map, sizeof(*om) * osz); 18898148Stmm free(om, M_DEVBUF); 18998148Stmm } 19098148Stmm } 19198148Stmm pci_bus_map[n] = node; 19298148Stmm return (n); 19398148Stmm} 19498148Stmm 19598148Stmm/* 19698148Stmm * Initialize bridge bus numbers for bridges that implement the primary, 19798148Stmm * secondary and subordinate bus number registers. 19898148Stmm */ 19998148Stmmvoid 20098148Stmmofw_pci_binit(device_t busdev, struct ofw_pci_bdesc *obd) 20198148Stmm{ 20298148Stmm 20398148Stmm#ifdef OFW_PCI_DEBUG 20498148Stmm printf("PCI-PCI bridge at %u/%u/%u: setting bus #s to %u/%u/%u\n", 20598148Stmm obd->obd_bus, obd->obd_slot, obd->obd_func, obd->obd_bus, 20698148Stmm obd->obd_secbus, obd->obd_subbus); 20798148Stmm#endif /* OFW_PCI_DEBUG */ 20898148Stmm PCIB_WRITE_CONFIG(busdev, obd->obd_bus, obd->obd_slot, obd->obd_func, 20998148Stmm PCIR_PRIBUS_1, obd->obd_bus, 1); 21098148Stmm PCIB_WRITE_CONFIG(busdev, obd->obd_bus, obd->obd_slot, obd->obd_func, 21198148Stmm PCIR_SECBUS_1, obd->obd_secbus, 1); 21298148Stmm PCIB_WRITE_CONFIG(busdev, obd->obd_bus, obd->obd_slot, obd->obd_func, 21398148Stmm PCIR_SUBBUS_1, obd->obd_subbus, 1); 21498148Stmm} 21598148Stmm 21686231Stmm/* 21786231Stmm * Walk the PCI bus hierarchy, starting with the root PCI bus and descending 21898148Stmm * through bridges, and initialize the interrupt line and latency timer 21998148Stmm * configuration registers of attached devices using firmware information, 22098148Stmm * as well as the the bus numbers and ranges of the bridges. 22186231Stmm */ 22286231Stmmvoid 223106555Stmmofw_pci_init(device_t dev, phandle_t bushdl, u_int32_t ign, 224106555Stmm struct ofw_pci_bdesc *obd) 22586231Stmm{ 22686231Stmm struct ofw_pci_register pcir; 22798148Stmm struct ofw_pci_bdesc subobd, *tobd; 22886231Stmm phandle_t node; 22986231Stmm char type[32]; 230106555Stmm int i, intr, freemap; 23198148Stmm u_int slot, busno, func, sub, lat; 232108805Stmm u_int8_t clnsz; 23386231Stmm 234106555Stmm /* Initialize the quirk list. */ 235106555Stmm for (i = 0; i < OPQ_NENT; i++) { 236106555Stmm if (strcmp(sparc64_model, ofw_pci_quirks[i].opq_model) == 0) { 237106555Stmm pci_quirks = ofw_pci_quirks[i].opq_quirks; 238106555Stmm break; 239106555Stmm } 240106555Stmm } 241106555Stmm 24298148Stmm if ((node = OF_child(bushdl)) == 0) 24386231Stmm return; 24486231Stmm freemap = 0; 24598148Stmm busno = obd->obd_secbus; 246108805Stmm /* 247108805Stmm * Compute the value to write into the cache line size register. 248108805Stmm * The role of the streaming cache is unclear in write invalidate 249108805Stmm * transfers, so it is made sure that it's line size is always reached. 250108805Stmm */ 251108805Stmm clnsz = imax(cache.ec_linesize, STRBUF_LINESZ); 252108805Stmm KASSERT((clnsz / STRBUF_LINESZ) * STRBUF_LINESZ == clnsz && 253108805Stmm (clnsz / cache.ec_linesize) * cache.ec_linesize == clnsz && 254108805Stmm (clnsz / 4) * 4 == clnsz, ("bogus cache line size %d", clnsz)); 255108805Stmm 25686231Stmm do { 25786231Stmm if (node == -1) 25886231Stmm panic("ofw_pci_init_intr: OF_child failed"); 25986231Stmm if (OF_getprop(node, "device_type", type, sizeof(type)) == -1) 26086231Stmm type[0] = '\0'; 26186231Stmm else 26286231Stmm type[sizeof(type) - 1] = '\0'; 26398148Stmm if (OF_getprop(node, "reg", &pcir, sizeof(pcir)) == -1) 264106555Stmm panic("ofw_pci_init: OF_getprop failed"); 26598148Stmm slot = OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi); 26698148Stmm func = OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi); 267112696Sjake PCIB_WRITE_CONFIG(dev, busno, slot, func, PCIR_CACHELNSZ, 268112696Sjake clnsz / 4, 1); 26986231Stmm if (strcmp(type, OFW_PCI_PCIBUS) == 0) { 27086231Stmm /* 27198148Stmm * This is a pci-pci bridge, initalize the bus number and 27298148Stmm * recurse to initialize the child bus. The hierarchy is 27398148Stmm * usually at most 2 levels deep, so recursion is 27498148Stmm * feasible. 27586231Stmm */ 27698148Stmm subobd.obd_bus = busno; 27798148Stmm subobd.obd_slot = slot; 27898148Stmm subobd.obd_func = func; 27998148Stmm sub = ofw_pci_alloc_busno(node); 28098148Stmm subobd.obd_secbus = subobd.obd_subbus = sub; 28198148Stmm /* Assume this bridge is mostly standard conforming. */ 28298148Stmm subobd.obd_init = ofw_pci_binit; 28398148Stmm subobd.obd_super = obd; 28498148Stmm /* 28598148Stmm * Need to change all subordinate bus registers of the 28698148Stmm * bridges above this one now so that configuration 28798148Stmm * transactions will get through. 28898148Stmm */ 28998148Stmm for (tobd = obd; tobd != NULL; tobd = tobd->obd_super) { 29098148Stmm tobd->obd_subbus = sub; 29198148Stmm tobd->obd_init(dev, tobd); 29298148Stmm } 29398148Stmm subobd.obd_init(dev, &subobd); 29486231Stmm#ifdef OFW_PCI_DEBUG 29593067Stmm device_printf(dev, "%s: descending to " 29693067Stmm "subordinate PCI bus\n", __func__); 29798148Stmm#endif /* OFW_PCI_DEBUG */ 298106555Stmm ofw_pci_init(dev, node, ign, &subobd); 29986231Stmm } else { 30098148Stmm /* 30198148Stmm * Initialize the latency timer register for 30298148Stmm * busmaster devices to work properly. This is another 30398148Stmm * task which the firmware does not always perform. 30498148Stmm * The Min_Gnt register can be used to compute it's 30598148Stmm * recommended value: it contains the desired latency 30698148Stmm * in units of 1/4 us. To calculate the correct latency 30798148Stmm * timer value, a bus clock of 33 and no wait states 30898148Stmm * should be assumed. 30998148Stmm */ 31098148Stmm lat = PCIB_READ_CONFIG(dev, busno, slot, func, 31198148Stmm PCIR_MINGNT, 1) * 33 / 4; 31298148Stmm if (lat != 0) { 31398148Stmm#ifdef OFW_PCI_DEBUG 31498148Stmm printf("device %d/%d/%d: latency timer %d -> " 31598148Stmm "%d\n", busno, slot, func, 31698148Stmm PCIB_READ_CONFIG(dev, busno, slot, func, 31798148Stmm PCIR_LATTIMER, 1), lat); 31898148Stmm#endif /* OFW_PCI_DEBUG */ 31998148Stmm PCIB_WRITE_CONFIG(dev, busno, slot, func, 32098148Stmm PCIR_LATTIMER, imin(lat, 255), 1); 32198148Stmm } 32293067Stmm 32398148Stmm /* Initialize the intline registers. */ 324115417Stmm if ((intr = ofw_pci_route_intr(dev, node, ign)) != 255) { 32586231Stmm#ifdef OFW_PCI_DEBUG 32693067Stmm device_printf(dev, "%s: mapping intr for " 32786231Stmm "%d/%d/%d to %d (preset was %d)\n", 32898148Stmm __func__, busno, slot, func, intr, 32998148Stmm (int)PCIB_READ_CONFIG(dev, busno, slot, 33098148Stmm func, PCIR_INTLINE, 1)); 33186231Stmm#endif /* OFW_PCI_DEBUG */ 33298148Stmm PCIB_WRITE_CONFIG(dev, busno, slot, func, 33386231Stmm PCIR_INTLINE, intr, 1); 33486231Stmm } else { 33586231Stmm#ifdef OFW_PCI_DEBUG 33693067Stmm device_printf(dev, "%s: no interrupt " 33786231Stmm "mapping found for %d/%d/%d (preset %d)\n", 33898148Stmm __func__, busno, slot, func, 33998148Stmm (int)PCIB_READ_CONFIG(dev, busno, slot, 34098148Stmm func, PCIR_INTLINE, 1)); 34186231Stmm#endif /* OFW_PCI_DEBUG */ 34298148Stmm /* 34398148Stmm * The firmware initializes to 0 instead of 34498148Stmm * 255. 34598148Stmm */ 34698148Stmm PCIB_WRITE_CONFIG(dev, busno, slot, func, 34786231Stmm PCIR_INTLINE, 255, 1); 34886231Stmm } 34986231Stmm } 35086231Stmm } while ((node = OF_peer(node)) != 0); 35186231Stmm} 35286231Stmm 35386231Stmmphandle_t 35486231Stmmofw_pci_find_node(int bus, int slot, int func) 35586231Stmm{ 35698148Stmm phandle_t node, bnode; 35786231Stmm struct ofw_pci_register pcir; 35886231Stmm 35998148Stmm /* 36098148Stmm * Retrieve the bus node from the mapping that was created on 36198148Stmm * initialization. The bus numbers the firmware uses cannot be trusted, 36298148Stmm * so they might have needed to be changed and this is necessary. 36398148Stmm */ 36498148Stmm if (bus >= pci_bus_map_sz) 36598148Stmm return (0); 36698148Stmm bnode = pci_bus_map[bus]; 36786231Stmm if (bnode == 0) 36886231Stmm return (0); 36986231Stmm for (node = OF_child(bnode); node != 0 && node != -1; 37086231Stmm node = OF_peer(node)) { 37186231Stmm if (OF_getprop(node, "reg", &pcir, sizeof(pcir)) == -1) 37286231Stmm continue; 37386231Stmm if (OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi) == slot && 37498148Stmm OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi) == func) 37586231Stmm return (node); 37686231Stmm } 37786231Stmm return (0); 37886231Stmm} 37993067Stmm 38093067Stmmphandle_t 38193067Stmmofw_pci_node(device_t dev) 38293067Stmm{ 38393067Stmm 38493067Stmm return (ofw_pci_find_node(pci_get_bus(dev), pci_get_slot(dev), 38593067Stmm pci_get_function(dev))); 38693067Stmm} 387