1117119Stmm/*-
2117119Stmm * Copyright (c) 1997, Stefan Esser <se@freebsd.org>
3117119Stmm * Copyright (c) 2000, Michael Smith <msmith@freebsd.org>
4117119Stmm * Copyright (c) 2000, BSDi
5117119Stmm * Copyright (c) 2003, Thomas Moestl <tmm@FreeBSD.org>
6200921Smarius * Copyright (c) 2005 - 2009 Marius Strobl <marius@FreeBSD.org>
7117119Stmm * All rights reserved.
8117119Stmm *
9117119Stmm * Redistribution and use in source and binary forms, with or without
10117119Stmm * modification, are permitted provided that the following conditions
11117119Stmm * are met:
12117119Stmm * 1. Redistributions of source code must retain the above copyright
13117119Stmm *    notice unmodified, this list of conditions, and the following
14117119Stmm *    disclaimer.
15117119Stmm * 2. Redistributions in binary form must reproduce the above copyright
16117119Stmm *    notice, this list of conditions and the following disclaimer in the
17117119Stmm *    documentation and/or other materials provided with the distribution.
18117119Stmm *
19117119Stmm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20117119Stmm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21117119Stmm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22117119Stmm * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23117119Stmm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24117119Stmm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25117119Stmm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26117119Stmm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27117119Stmm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28117119Stmm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29117119Stmm */
30117119Stmm
31152684Smarius#include <sys/cdefs.h>
32152684Smarius__FBSDID("$FreeBSD$");
33152684Smarius
34117119Stmm#include "opt_ofw_pci.h"
35133589Smarius
36117119Stmm#include <sys/param.h>
37117119Stmm#include <sys/bus.h>
38117119Stmm#include <sys/kernel.h>
39117119Stmm#include <sys/libkern.h>
40117119Stmm#include <sys/module.h>
41117119Stmm#include <sys/pciio.h>
42117119Stmm
43133589Smarius#include <dev/ofw/ofw_bus.h>
44133589Smarius#include <dev/ofw/ofw_pci.h>
45117119Stmm#include <dev/ofw/openfirm.h>
46117119Stmm
47117119Stmm#include <machine/bus.h>
48178728Smarius#ifndef SUN4V
49117119Stmm#include <machine/bus_common.h>
50169793Smarius#include <machine/iommureg.h>
51163146Skmacy#endif
52117119Stmm#include <machine/resource.h>
53117119Stmm
54117119Stmm#include <dev/pci/pcireg.h>
55117119Stmm#include <dev/pci/pcivar.h>
56117119Stmm#include <dev/pci/pci_private.h>
57117119Stmm
58117119Stmm#include <sparc64/pci/ofw_pci.h>
59117119Stmm
60117119Stmm#include "pcib_if.h"
61117119Stmm#include "pci_if.h"
62117119Stmm
63182020Smarius/* Helper functions */
64182108Smariusstatic void ofw_pcibus_setup_device(device_t bridge, uint32_t clock,
65182108Smarius    u_int busno, u_int slot, u_int func);
66117119Stmm
67182020Smarius/* Methods */
68200920Smariusstatic bus_child_pnpinfo_str_t ofw_pcibus_pnpinfo_str;
69200920Smariusstatic device_attach_t ofw_pcibus_attach;
70117119Stmmstatic device_probe_t ofw_pcibus_probe;
71200920Smariusstatic ofw_bus_get_devinfo_t ofw_pcibus_get_devinfo;
72117119Stmmstatic pci_assign_interrupt_t ofw_pcibus_assign_interrupt;
73117119Stmm
74117119Stmmstatic device_method_t ofw_pcibus_methods[] = {
75117119Stmm	/* Device interface */
76117119Stmm	DEVMETHOD(device_probe,		ofw_pcibus_probe),
77117119Stmm	DEVMETHOD(device_attach,	ofw_pcibus_attach),
78117119Stmm
79117119Stmm	/* Bus interface */
80190113Smarius	DEVMETHOD(bus_child_pnpinfo_str, ofw_pcibus_pnpinfo_str),
81117119Stmm
82117119Stmm	/* PCI interface */
83117119Stmm	DEVMETHOD(pci_assign_interrupt, ofw_pcibus_assign_interrupt),
84117119Stmm
85133589Smarius	/* ofw_bus interface */
86152684Smarius	DEVMETHOD(ofw_bus_get_devinfo,	ofw_pcibus_get_devinfo),
87152684Smarius	DEVMETHOD(ofw_bus_get_compat,	ofw_bus_gen_get_compat),
88152684Smarius	DEVMETHOD(ofw_bus_get_model,	ofw_bus_gen_get_model),
89152684Smarius	DEVMETHOD(ofw_bus_get_name,	ofw_bus_gen_get_name),
90152684Smarius	DEVMETHOD(ofw_bus_get_node,	ofw_bus_gen_get_node),
91152684Smarius	DEVMETHOD(ofw_bus_get_type,	ofw_bus_gen_get_type),
92117119Stmm
93227848Smarius	DEVMETHOD_END
94117119Stmm};
95117119Stmm
96117119Stmmstruct ofw_pcibus_devinfo {
97117119Stmm	struct pci_devinfo	opd_dinfo;
98152684Smarius	struct ofw_bus_devinfo	opd_obdinfo;
99117119Stmm};
100117119Stmm
101154600Sjhbstatic devclass_t pci_devclass;
102117119Stmm
103232403SjhbDEFINE_CLASS_1(pci, ofw_pcibus_driver, ofw_pcibus_methods,
104232403Sjhb    sizeof(struct pci_softc), pci_driver);
105200874SmariusEARLY_DRIVER_MODULE(ofw_pcibus, pcib, ofw_pcibus_driver, pci_devclass, 0, 0,
106200874Smarius    BUS_PASS_BUS);
107117119StmmMODULE_VERSION(ofw_pcibus, 1);
108117119StmmMODULE_DEPEND(ofw_pcibus, pci, 1, 1, 1);
109117119Stmm
110117119Stmmstatic int
111117119Stmmofw_pcibus_probe(device_t dev)
112117119Stmm{
113117119Stmm
114233018Snwhitehorn	if (ofw_bus_get_node(dev) == -1)
115117119Stmm		return (ENXIO);
116117119Stmm	device_set_desc(dev, "OFW PCI bus");
117117119Stmm
118117119Stmm	return (0);
119117119Stmm}
120117119Stmm
121117119Stmm/*
122117119Stmm * Perform miscellaneous setups the firmware usually does not do for us.
123117119Stmm */
124117119Stmmstatic void
125182108Smariusofw_pcibus_setup_device(device_t bridge, uint32_t clock, u_int busno,
126182108Smarius    u_int slot, u_int func)
127117119Stmm{
128200920Smarius#define	CS_READ(n, w)							\
129200920Smarius	PCIB_READ_CONFIG(bridge, busno, slot, func, (n), (w))
130200920Smarius#define	CS_WRITE(n, v, w)						\
131200920Smarius	PCIB_WRITE_CONFIG(bridge, busno, slot, func, (n), (v), (w))
132200920Smarius
133182108Smarius#ifndef SUN4V
134172333Smarius	uint32_t reg;
135172333Smarius
136117119Stmm	/*
137182020Smarius	 * Initialize the latency timer register for busmaster devices to
138182020Smarius	 * work properly.  This is another task which the firmware doesn't
139182020Smarius	 * always perform.  The Min_Gnt register can be used to compute its
140182020Smarius	 * recommended value: it contains the desired latency in units of
141182108Smarius	 * 1/4 us assuming a clock rate of 33MHz.  To calculate the correct
142182108Smarius	 * latency timer value, the clock frequency of the bus (defaulting
143182108Smarius	 * to 33MHz) should be used and no wait states assumed.
144182108Smarius	 * For bridges, we additionally set up the bridge control and the
145182108Smarius	 * secondary latency registers.
146117119Stmm	 */
147200920Smarius	if ((CS_READ(PCIR_HDRTYPE, 1) & PCIM_HDRTYPE) ==
148200920Smarius	    PCIM_HDRTYPE_BRIDGE) {
149200920Smarius		reg = CS_READ(PCIR_BRIDGECTL_1, 1);
150182108Smarius		reg |= PCIB_BCR_MASTER_ABORT_MODE | PCIB_BCR_SERR_ENABLE |
151182108Smarius		    PCIB_BCR_PERR_ENABLE;
152117119Stmm#ifdef OFW_PCI_DEBUG
153182108Smarius		device_printf(bridge,
154182108Smarius		    "bridge %d/%d/%d: control 0x%x -> 0x%x\n",
155200920Smarius		    busno, slot, func, CS_READ(PCIR_BRIDGECTL_1, 1), reg);
156117119Stmm#endif /* OFW_PCI_DEBUG */
157200920Smarius		CS_WRITE(PCIR_BRIDGECTL_1, reg, 1);
158182108Smarius
159182108Smarius		reg = OFW_PCI_LATENCY;
160182108Smarius#ifdef OFW_PCI_DEBUG
161182108Smarius		device_printf(bridge,
162182108Smarius		    "bridge %d/%d/%d: latency timer %d -> %d\n",
163200920Smarius		    busno, slot, func, CS_READ(PCIR_SECLAT_1, 1), reg);
164182108Smarius#endif /* OFW_PCI_DEBUG */
165200920Smarius		CS_WRITE(PCIR_SECLAT_1, reg, 1);
166182108Smarius	} else {
167200920Smarius		reg = CS_READ(PCIR_MINGNT, 1);
168219780Smarius		if ((int)reg > 0) {
169182108Smarius			switch (clock) {
170182108Smarius			case 33000000:
171182108Smarius				reg *= 8;
172182108Smarius				break;
173182108Smarius			case 66000000:
174182108Smarius				reg *= 4;
175182108Smarius				break;
176182108Smarius			}
177182108Smarius			reg = min(reg, 255);
178182108Smarius		} else
179182108Smarius			reg = OFW_PCI_LATENCY;
180117119Stmm	}
181182108Smarius#ifdef OFW_PCI_DEBUG
182182108Smarius	device_printf(bridge, "device %d/%d/%d: latency timer %d -> %d\n",
183200920Smarius	    busno, slot, func, CS_READ(PCIR_LATTIMER, 1), reg);
184182108Smarius#endif /* OFW_PCI_DEBUG */
185200920Smarius	CS_WRITE(PCIR_LATTIMER, reg, 1);
186117119Stmm
187117119Stmm	/*
188117119Stmm	 * Compute a value to write into the cache line size register.
189117119Stmm	 * The role of the streaming cache is unclear in write invalidate
190182020Smarius	 * transfers, so it is made sure that it's line size is always
191182020Smarius	 * reached.  Generally, the cache line size is fixed at 64 bytes
192182020Smarius	 * by Fireplane/Safari, JBus and UPA.
193117119Stmm	 */
194200920Smarius	CS_WRITE(PCIR_CACHELNSZ, STRBUF_LINESZ / sizeof(uint32_t), 1);
195169793Smarius#endif
196117119Stmm
197117119Stmm	/*
198200921Smarius	 * Ensure that ALi M5229 report the actual content of PCIR_PROGIF
199200921Smarius	 * and that IDE I/O is force enabled.  The former is done in order
200200921Smarius	 * to have unique behavior across revisions as some default to
201200921Smarius	 * hiding bits 4-6 for compliance with PCI 2.3.  The latter is done
202200921Smarius	 * as at least revision 0xc8 requires the PCIM_CMD_PORTEN bypass
203200921Smarius	 * to be always enabled as otherwise even enabling PCIM_CMD_PORTEN
204200921Smarius	 * results in an instant data access trap on Fire-based machines.
205200921Smarius	 * Thus these quirks have to be handled before pci(4) adds the maps.
206200921Smarius	 * Note that for older revisions bit 0 of register 0x50 enables the
207200921Smarius	 * internal IDE function instead of force enabling IDE I/O.
208200921Smarius	 */
209200921Smarius	if ((CS_READ(PCIR_VENDOR, 2) == 0x10b9 &&
210200921Smarius	    CS_READ(PCIR_DEVICE, 2) == 0x5229))
211200921Smarius		CS_WRITE(0x50, CS_READ(0x50, 1) | 0x3, 1);
212200921Smarius
213200921Smarius	/*
214182020Smarius	 * The preset in the intline register is usually wrong.  Reset
215182020Smarius	 * it to 255, so that the PCI code will reroute the interrupt if
216182020Smarius	 * needed.
217117119Stmm	 */
218200920Smarius	CS_WRITE(PCIR_INTLINE, PCI_INVALID_IRQ, 1);
219200920Smarius
220200920Smarius#undef CS_READ
221200920Smarius#undef CS_WRITE
222117119Stmm}
223117119Stmm
224117119Stmmstatic int
225117119Stmmofw_pcibus_attach(device_t dev)
226117119Stmm{
227153057Smarius	device_t pcib;
228117119Stmm	struct ofw_pci_register pcir;
229117119Stmm	struct ofw_pcibus_devinfo *dinfo;
230117119Stmm	phandle_t node, child;
231182108Smarius	uint32_t clock;
232172394Smarius	u_int busno, domain, func, slot;
233232403Sjhb	int error;
234117119Stmm
235232403Sjhb	error = pci_attach_common(dev);
236232403Sjhb	if (error)
237232403Sjhb		return (error);
238153057Smarius	pcib = device_get_parent(dev);
239172394Smarius	domain = pcib_get_domain(dev);
240117119Stmm	busno = pcib_get_bus(dev);
241133589Smarius	node = ofw_bus_get_node(dev);
242174117Smarius
243200921Smarius	/*
244200921Smarius	 * Add the PCI side of the host-PCI bridge itself to the bus.
245200921Smarius	 * Note that we exclude the host-PCIe bridges here as these
246200921Smarius	 * have no configuration space implemented themselves.
247200921Smarius	 */
248174117Smarius	if (strcmp(device_get_name(device_get_parent(pcib)), "nexus") == 0 &&
249200921Smarius	    ofw_bus_get_type(pcib) != NULL &&
250200921Smarius	    strcmp(ofw_bus_get_type(pcib), OFW_TYPE_PCIE) != 0 &&
251174117Smarius	    (dinfo = (struct ofw_pcibus_devinfo *)pci_read_device(pcib,
252174117Smarius	    domain, busno, 0, 0, sizeof(*dinfo))) != NULL) {
253174117Smarius		if (ofw_bus_gen_setup_devinfo(&dinfo->opd_obdinfo, node) != 0)
254174117Smarius			pci_freecfg((struct pci_devinfo *)dinfo);
255174117Smarius		else
256174117Smarius			pci_add_child(dev, (struct pci_devinfo *)dinfo);
257174117Smarius	}
258174117Smarius
259182108Smarius	if (OF_getprop(ofw_bus_get_node(pcib), "clock-frequency", &clock,
260182108Smarius	    sizeof(clock)) == -1)
261182108Smarius		clock = 33000000;
262117119Stmm	for (child = OF_child(node); child != 0; child = OF_peer(child)) {
263152684Smarius		if (OF_getprop(child, "reg", &pcir, sizeof(pcir)) == -1)
264140512Smarius			continue;
265117119Stmm		slot = OFW_PCI_PHYS_HI_DEVICE(pcir.phys_hi);
266117119Stmm		func = OFW_PCI_PHYS_HI_FUNCTION(pcir.phys_hi);
267172394Smarius		/* Some OFW device trees contain dupes. */
268172394Smarius		if (pci_find_dbsf(domain, busno, slot, func) != NULL)
269165885Smarius			continue;
270182108Smarius		ofw_pcibus_setup_device(pcib, clock, busno, slot, func);
271117119Stmm		dinfo = (struct ofw_pcibus_devinfo *)pci_read_device(pcib,
272172394Smarius		    domain, busno, slot, func, sizeof(*dinfo));
273152684Smarius		if (dinfo == NULL)
274152684Smarius			continue;
275152684Smarius		if (ofw_bus_gen_setup_devinfo(&dinfo->opd_obdinfo, child) !=
276152684Smarius		    0) {
277152684Smarius			pci_freecfg((struct pci_devinfo *)dinfo);
278152684Smarius			continue;
279152684Smarius		}
280152684Smarius		pci_add_child(dev, (struct pci_devinfo *)dinfo);
281220038Smarius		OFW_PCI_SETUP_DEVICE(pcib, dinfo->opd_dinfo.cfg.dev);
282117119Stmm	}
283117119Stmm
284117119Stmm	return (bus_generic_attach(dev));
285117119Stmm}
286117119Stmm
287117119Stmmstatic int
288117119Stmmofw_pcibus_assign_interrupt(device_t dev, device_t child)
289117119Stmm{
290117119Stmm	ofw_pci_intr_t intr;
291117119Stmm	int isz;
292117119Stmm
293152684Smarius	isz = OF_getprop(ofw_bus_get_node(child), "interrupts", &intr,
294152684Smarius	    sizeof(intr));
295117119Stmm	if (isz != sizeof(intr)) {
296117119Stmm		/* No property; our best guess is the intpin. */
297152684Smarius		intr = pci_get_intpin(child);
298178728Smarius#ifndef SUN4V
299117119Stmm	} else if (intr >= 255) {
300117119Stmm		/*
301117119Stmm		 * A fully specified interrupt (including IGN), as present on
302182020Smarius		 * SPARCengine Ultra AX and E450.  Extract the INO and return
303182020Smarius		 * it.
304117119Stmm		 */
305117119Stmm		return (INTINO(intr));
306178728Smarius#endif
307117119Stmm	}
308117119Stmm	/*
309117119Stmm	 * If we got intr from a property, it may or may not be an intpin.
310117119Stmm	 * For on-board devices, it frequently is not, and is completely out
311182020Smarius	 * of the valid intpin range.  For PCI slots, it hopefully is,
312182020Smarius	 * otherwise we will have trouble interfacing with non-OFW buses
313182020Smarius	 * such as cardbus.
314117119Stmm	 * Since we cannot tell which it is without violating layering, we
315182020Smarius	 * will always use the route_interrupt method, and treat exceptions
316182020Smarius	 * on the level they become apparent.
317117119Stmm	 */
318117119Stmm	return (PCIB_ROUTE_INTERRUPT(device_get_parent(dev), child, intr));
319117119Stmm}
320117119Stmm
321152684Smariusstatic const struct ofw_bus_devinfo *
322152684Smariusofw_pcibus_get_devinfo(device_t bus, device_t dev)
323133589Smarius{
324133589Smarius	struct ofw_pcibus_devinfo *dinfo;
325133589Smarius
326133589Smarius	dinfo = device_get_ivars(dev);
327152684Smarius	return (&dinfo->opd_obdinfo);
328133589Smarius}
329186128Snwhitehorn
330186128Snwhitehornstatic int
331190113Smariusofw_pcibus_pnpinfo_str(device_t dev, device_t child, char *buf,
332186128Snwhitehorn    size_t buflen)
333186128Snwhitehorn{
334186128Snwhitehorn
335190113Smarius	pci_child_pnpinfo_str_method(dev, child, buf, buflen);
336186128Snwhitehorn	if (ofw_bus_get_node(child) != -1)  {
337190113Smarius		strlcat(buf, " ", buflen); /* Separate info. */
338190113Smarius		ofw_bus_gen_child_pnpinfo_str(dev, child, buf, buflen);
339186128Snwhitehorn	}
340186128Snwhitehorn
341186128Snwhitehorn	return (0);
342186128Snwhitehorn}
343