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