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