ofw_pci.c revision 117119
133965Sjdp/*
233965Sjdp * Copyright (c) 1999, 2000 Matthew R. Green
333965Sjdp * Copyright (c) 2001 - 2003 by Thomas Moestl <tmm@FreeBSD.org>
433965Sjdp * All rights reserved.
533965Sjdp *
633965Sjdp * Redistribution and use in source and binary forms, with or without
733965Sjdp * modification, are permitted provided that the following conditions
833965Sjdp * are met:
933965Sjdp * 1. Redistributions of source code must retain the above copyright
1033965Sjdp *    notice, this list of conditions and the following disclaimer.
1133965Sjdp * 2. Redistributions in binary form must reproduce the above copyright
1233965Sjdp *    notice, this list of conditions and the following disclaimer in the
1333965Sjdp *    documentation and/or other materials provided with the distribution.
1433965Sjdp * 3. The name of the author may not be used to endorse or promote products
1533965Sjdp *    derived from this software without specific prior written permission.
1633965Sjdp *
17218822Sdim * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1833965Sjdp * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
1933965Sjdp * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2033965Sjdp * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2133965Sjdp * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
2233965Sjdp * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
2333965Sjdp * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
2433965Sjdp * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2533965Sjdp * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2633965Sjdp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2733965Sjdp * SUCH DAMAGE.
2833965Sjdp *
2933965Sjdp *	from: NetBSD: psycho.c,v 1.35 2001/09/10 16:17:06 eeh Exp
3033965Sjdp *
3133965Sjdp * $FreeBSD: head/sys/sparc64/pci/ofw_pci.c 117119 2003-07-01 14:52:47Z tmm $
3233965Sjdp */
3333965Sjdp
3433965Sjdp#include "opt_ofw_pci.h"
3533965Sjdp
3633965Sjdp#include <sys/param.h>
3733965Sjdp#include <sys/kernel.h>
3833965Sjdp#include <sys/systm.h>
3933965Sjdp#include <sys/bus.h>
4033965Sjdp
4133965Sjdp#include <dev/pci/pcireg.h>
4233965Sjdp#include <dev/pci/pcivar.h>
4333965Sjdp
4433965Sjdp#include <dev/ofw/ofw_pci.h>
4533965Sjdp#include <dev/ofw/openfirm.h>
4633965Sjdp
4733965Sjdp#include <machine/bus.h>
4833965Sjdp#include <machine/cache.h>
4933965Sjdp#include <machine/iommureg.h>
5033965Sjdp#include <machine/ofw_bus.h>
5133965Sjdp#include <machine/ver.h>
5233965Sjdp
5333965Sjdp#include <sparc64/pci/ofw_pci.h>
5433965Sjdp
5533965Sjdp#include "pcib_if.h"
5633965Sjdp
5733965Sjdpu_int8_t pci_bus_cnt;
5833965Sjdpphandle_t *pci_bus_map;
5933965Sjdpint pci_bus_map_sz;
6033965Sjdp
6133965Sjdp#define	PCI_BUS_MAP_INC	10
6233965Sjdp
6333965Sjdp#ifndef OFW_NEWPCI
6433965Sjdp/* Do not swizzle on a PCI bus node with no interrupt-map propery. */
6533965Sjdp#define	OPQ_NO_SWIZZLE		1
6633965Sjdp/*
6733965Sjdp * INOs < 255 are really intpin numbers; use a driver method to figure out
6833965Sjdp * the real INO.
6933965Sjdp */
7033965Sjdp#define	OPQ_INO_CALLBACK	2
7133965Sjdp/*
7233965Sjdp * Do not map EBus interrupts at PCI buses, but assume that they are fully
7333965Sjdp * specified already.
7433965Sjdp */
7533965Sjdp#define	OPQ_EBUS_NOMAP		4
7633965Sjdp
7733965Sjdpstatic struct ofw_pci_quirk {
7833965Sjdp	char	*opq_model;
7933965Sjdp	int	opq_quirks;
8033965Sjdp} ofw_pci_quirks[] = {
8133965Sjdp	{ "SUNW,Ultra-4",		OPQ_INO_CALLBACK | OPQ_EBUS_NOMAP },
8233965Sjdp	{ "SUNW,Ultra-1-Engine",	OPQ_NO_SWIZZLE },
8333965Sjdp};
8433965Sjdp#define	OPQ_NENT	(sizeof(ofw_pci_quirks) / sizeof(ofw_pci_quirks[0]))
8533965Sjdp
8633965Sjdpstatic int pci_quirks;
8733965Sjdp
8833965Sjdp#define	OFW_PCI_PCIBUS	"pci"
8933965Sjdp#define	OFW_PCI_EBUS	"ebus"
9033965Sjdp
9133965Sjdpint
92ofw_pci_orb_callback(phandle_t node, u_int8_t *pintptr, int pintsz,
93    u_int8_t *pregptr, int pregsz, u_int8_t **rintr, int *terminate,
94    void *cookie)
95{
96	device_t dev = cookie;
97	struct ofw_pci_register preg;
98	ofw_pci_intr_t pintr, intr;
99	u_int slot;
100	char type[32];
101	int found = 0;
102
103	if ((pci_quirks & OPQ_EBUS_NOMAP) != 0 &&
104	    OF_getprop(node, "name", type, sizeof(type)) != -1 &&
105	    strcmp(type, OFW_PCI_EBUS) == 0) {
106		*terminate = 1;
107		return (-1);
108	}
109	if (pintsz != sizeof(pintr) || pregsz < sizeof(preg))
110		return (-1);
111	bcopy(pintptr, &pintr, sizeof(pintr));
112	bcopy(pregptr, &preg, sizeof(preg));
113	slot = OFW_PCI_PHYS_HI_DEVICE(preg.phys_hi);
114
115	if ((pci_quirks & OPQ_INO_CALLBACK) != 0 && pintr <= 255) {
116		/*
117		 * The e450 has no interrupt maps at all, and it usually has
118		 * full interrupt numbers, including IGN, in the interrupt
119		 * properties. There is one exception, however: the property
120		 * values for external PCI devices seem to always be below 255
121		 * and describe the interrupt pin to be used on the slot, while
122		 * we have to figure out the base INO by looking at the slot
123		 * number (which we do using an ofw_pci method).
124		 *
125		 * Of course, there is an exception to that nice rule:
126		 * in the ebus case, the interrupt property has the correct
127		 * INO (but without IGN). This is dealt with above.
128		 */
129		intr = OFW_PCI_GUESS_INO(dev, node, slot, pintr);
130		found = intr != 255;
131		*terminate = found;
132	}
133	if (!found && (pci_quirks & OPQ_NO_SWIZZLE) == 0 &&
134	    OF_getprop(node, "device_type", type, sizeof(type)) != -1 &&
135	    strcmp(type, OFW_PCI_PCIBUS) == 0 && pintr >= 1 && pintr <= 4) {
136		/*
137		 * Handle a quirk found on some Netra t1 models: there exist
138		 * PCI bridges without interrupt maps, where we apparently must
139		 * do the PCI swizzle and continue to map on at the parent.
140		 */
141		intr = (slot + pintr + 3) % 4 + 1;
142		*terminate = 0;
143		found = 1;
144	}
145
146	if (found) {
147		*rintr = malloc(sizeof(intr), M_OFWPROP, M_WAITOK);
148		bcopy(&intr, *rintr, sizeof(intr));
149		return (sizeof(intr));
150	} else
151		return (-1);
152}
153
154static ofw_pci_intr_t
155ofw_pci_route_intr(device_t dev, phandle_t node, ofw_pci_intr_t ign)
156{
157	u_int32_t rv;
158
159	rv = ofw_bus_route_intr(node, ORIP_NOINT, ofw_pci_orb_callback, dev);
160	if (rv == ORIR_NOTFOUND)
161		return (PCI_INVALID_IRQ);
162	/*
163	 * Some machines (notably the SPARCengine Ultra AX and the e450) have
164	 * no mappings at all, but use complete interrupt vector number
165	 * including the IGN. Catch this case and remove the IGN.
166	 */
167	if (rv > ign)
168		rv -= ign;
169	return (rv);
170}
171#endif /* !OFW_NEWCPI */
172
173u_int8_t
174ofw_pci_alloc_busno(phandle_t node)
175{
176	phandle_t *om;
177	int osz;
178	u_int8_t n;
179
180	n = pci_bus_cnt++;
181	/* Establish a mapping between bus numbers and device nodes. */
182	if (n >= pci_bus_map_sz) {
183		osz = pci_bus_map_sz;
184		om = pci_bus_map;
185		pci_bus_map_sz = n + PCI_BUS_MAP_INC;
186		pci_bus_map = malloc(sizeof(*pci_bus_map) * pci_bus_map_sz,
187		    M_DEVBUF, M_WAITOK | M_ZERO);
188		if (om != NULL) {
189			bcopy(om, pci_bus_map, sizeof(*om) * osz);
190			free(om, M_DEVBUF);
191		}
192	}
193	pci_bus_map[n] = node;
194	return (n);
195}
196
197#ifndef OFW_NEWPCI
198/*
199 * Initialize bridge bus numbers for bridges that implement the primary,
200 * secondary and subordinate bus number registers.
201 */
202void
203ofw_pci_binit(device_t busdev, struct ofw_pci_bdesc *obd)
204{
205
206#ifdef OFW_PCI_DEBUG
207	printf("PCI-PCI bridge at %u/%u/%u: setting bus #s to %u/%u/%u\n",
208	    obd->obd_bus, obd->obd_slot, obd->obd_func, obd->obd_bus,
209	    obd->obd_secbus, obd->obd_subbus);
210#endif /* OFW_PCI_DEBUG */
211	PCIB_WRITE_CONFIG(busdev, obd->obd_bus, obd->obd_slot, obd->obd_func,
212	    PCIR_PRIBUS_1, obd->obd_bus, 1);
213	PCIB_WRITE_CONFIG(busdev, obd->obd_bus, obd->obd_slot, obd->obd_func,
214	    PCIR_SECBUS_1, obd->obd_secbus, 1);
215	PCIB_WRITE_CONFIG(busdev, obd->obd_bus, obd->obd_slot, obd->obd_func,
216	    PCIR_SUBBUS_1, obd->obd_subbus, 1);
217}
218
219/*
220 * Walk the PCI bus hierarchy, starting with the root PCI bus and descending
221 * through bridges, and initialize the interrupt line and latency timer
222 * configuration registers of attached devices using firmware information,
223 * as well as the the bus numbers and ranges of the bridges.
224 */
225void
226ofw_pci_init(device_t dev, phandle_t bushdl, ofw_pci_intr_t ign,
227    struct ofw_pci_bdesc *obd)
228{
229	struct ofw_pci_register pcir;
230	struct ofw_pci_bdesc subobd, *tobd;
231	phandle_t node;
232	char type[32];
233	int i, intr, freemap;
234	u_int slot, busno, func, sub, lat;
235	u_int8_t clnsz;
236
237	/* Initialize the quirk list. */
238	for (i = 0; i < OPQ_NENT; i++) {
239		if (strcmp(sparc64_model, ofw_pci_quirks[i].opq_model) == 0) {
240			pci_quirks = ofw_pci_quirks[i].opq_quirks;
241			break;
242		}
243	}
244
245	if ((node = OF_child(bushdl)) == 0)
246		return;
247	freemap = 0;
248	busno = obd->obd_secbus;
249	/*
250	 * Compute the value to write into the cache line size register.
251	 * The role of the streaming cache is unclear in write invalidate
252	 * transfers, so it is made sure that it's line size is always reached.
253	 */
254	clnsz = imax(cache.ec_linesize, STRBUF_LINESZ);
255	KASSERT((clnsz / STRBUF_LINESZ) * STRBUF_LINESZ == clnsz &&
256	    (clnsz / cache.ec_linesize) * cache.ec_linesize == clnsz &&
257	    (clnsz / 4) * 4 == clnsz, ("bogus cache line size %d", clnsz));
258
259	do {
260		if (node == -1)
261			panic("ofw_pci_init_intr: OF_child failed");
262		if (OF_getprop(node, "device_type", type, sizeof(type)) == -1)
263			type[0] = '\0';
264		else
265			type[sizeof(type) - 1] = '\0';
266		if (OF_getprop(node, "reg", &pcir, sizeof(pcir)) == -1)
267			panic("ofw_pci_init: OF_getprop failed");
268		slot = OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi);
269		func = OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi);
270		PCIB_WRITE_CONFIG(dev, busno, slot, func, PCIR_CACHELNSZ,
271		    clnsz / 4, 1);
272		if (strcmp(type, OFW_PCI_PCIBUS) == 0) {
273			/*
274			 * This is a pci-pci bridge, initalize the bus number and
275			 * recurse to initialize the child bus. The hierarchy is
276			 * usually at most 2 levels deep, so recursion is
277			 * feasible.
278			 */
279			subobd.obd_bus = busno;
280			subobd.obd_slot = slot;
281			subobd.obd_func = func;
282			sub = ofw_pci_alloc_busno(node);
283			subobd.obd_secbus = subobd.obd_subbus = sub;
284			/* Assume this bridge is mostly standard conforming. */
285			subobd.obd_init = ofw_pci_binit;
286			subobd.obd_super = obd;
287			/*
288			 * Need to change all subordinate bus registers of the
289			 * bridges above this one now so that configuration
290			 * transactions will get through.
291			 */
292			for (tobd = obd; tobd != NULL; tobd = tobd->obd_super) {
293				tobd->obd_subbus = sub;
294				tobd->obd_init(dev, tobd);
295			}
296			subobd.obd_init(dev, &subobd);
297#ifdef OFW_PCI_DEBUG
298			device_printf(dev, "%s: descending to "
299			    "subordinate PCI bus\n", __func__);
300#endif /* OFW_PCI_DEBUG */
301			ofw_pci_init(dev, node, ign, &subobd);
302		} else {
303			/*
304			 * Initialize the latency timer register for
305			 * busmaster devices to work properly. This is another
306			 * task which the firmware does not always perform.
307			 * The Min_Gnt register can be used to compute it's
308			 * recommended value: it contains the desired latency
309			 * in units of 1/4 us. To calculate the correct latency
310			 * timer value, a bus clock of 33 and no wait states
311			 * should be assumed.
312			 */
313			lat = PCIB_READ_CONFIG(dev, busno, slot, func,
314			    PCIR_MINGNT, 1) * 33 / 4;
315			if (lat != 0) {
316#ifdef OFW_PCI_DEBUG
317				printf("device %d/%d/%d: latency timer %d -> "
318				    "%d\n", busno, slot, func,
319				    PCIB_READ_CONFIG(dev, busno, slot, func,
320					PCIR_LATTIMER, 1), lat);
321#endif /* OFW_PCI_DEBUG */
322				PCIB_WRITE_CONFIG(dev, busno, slot, func,
323				    PCIR_LATTIMER, imin(lat, 255), 1);
324			}
325
326			/* Initialize the intline registers. */
327			if ((intr = ofw_pci_route_intr(dev, node, ign)) !=
328			    PCI_INVALID_IRQ) {
329#ifdef OFW_PCI_DEBUG
330				device_printf(dev, "%s: mapping intr for "
331				    "%d/%d/%d to %d (preset was %d)\n",
332				    __func__, busno, slot, func, intr,
333				    (int)PCIB_READ_CONFIG(dev, busno, slot,
334					func, PCIR_INTLINE, 1));
335#endif /* OFW_PCI_DEBUG */
336				PCIB_WRITE_CONFIG(dev, busno, slot, func,
337				    PCIR_INTLINE, intr, 1);
338			} else {
339#ifdef OFW_PCI_DEBUG
340				device_printf(dev, "%s: no interrupt "
341				    "mapping found for %d/%d/%d (preset %d)\n",
342				    __func__, busno, slot, func,
343				    (int)PCIB_READ_CONFIG(dev, busno, slot,
344					func, PCIR_INTLINE, 1));
345#endif /* OFW_PCI_DEBUG */
346				/*
347				 * The firmware initializes to 0 instead of
348				 * 255.
349				 */
350				PCIB_WRITE_CONFIG(dev, busno, slot, func,
351				    PCIR_INTLINE, PCI_INVALID_IRQ, 1);
352			}
353		}
354	} while ((node = OF_peer(node)) != 0);
355}
356
357phandle_t
358ofw_pci_find_node(int bus, int slot, int func)
359{
360	phandle_t node, bnode;
361	struct ofw_pci_register pcir;
362
363	/*
364	 * Retrieve the bus node from the mapping that was created on
365	 * initialization. The bus numbers the firmware uses cannot be trusted,
366	 * so they might have needed to be changed and this is necessary.
367	 */
368	if (bus >= pci_bus_map_sz)
369		return (0);
370	bnode = pci_bus_map[bus];
371	if (bnode == 0)
372		return (0);
373	for (node = OF_child(bnode); node != 0 && node != -1;
374	     node = OF_peer(node)) {
375		if (OF_getprop(node, "reg", &pcir, sizeof(pcir)) == -1)
376			continue;
377		if (OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi) == slot &&
378		    OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi) == func)
379			return (node);
380	}
381	return (0);
382}
383
384phandle_t
385ofw_pci_node(device_t dev)
386{
387
388	return (ofw_pci_find_node(pci_get_bus(dev), pci_get_slot(dev),
389	    pci_get_function(dev)));
390}
391#endif /* OFW_NEWPCI */
392