pcib.c revision 1.8
11.8Srin/*	$NetBSD: pcib.c,v 1.8 2020/07/06 09:34:17 rin Exp $	*/
21.2Sgarbled
31.2Sgarbled/*-
41.2Sgarbled * Copyright (c) 1996, 1998 The NetBSD Foundation, Inc.
51.2Sgarbled * All rights reserved.
61.2Sgarbled *
71.2Sgarbled * This code is derived from software contributed to The NetBSD Foundation
81.2Sgarbled * by Jason R. Thorpe.
91.2Sgarbled *
101.2Sgarbled * Redistribution and use in source and binary forms, with or without
111.2Sgarbled * modification, are permitted provided that the following conditions
121.2Sgarbled * are met:
131.2Sgarbled * 1. Redistributions of source code must retain the above copyright
141.2Sgarbled *    notice, this list of conditions and the following disclaimer.
151.2Sgarbled * 2. Redistributions in binary form must reproduce the above copyright
161.2Sgarbled *    notice, this list of conditions and the following disclaimer in the
171.2Sgarbled *    documentation and/or other materials provided with the distribution.
181.2Sgarbled *
191.2Sgarbled * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
201.2Sgarbled * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
211.2Sgarbled * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
221.5Smartin * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
231.5Smartin * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
241.2Sgarbled * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
251.2Sgarbled * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
261.2Sgarbled * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
271.2Sgarbled * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
281.2Sgarbled * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
291.2Sgarbled * POSSIBILITY OF SUCH DAMAGE.
301.2Sgarbled */
311.2Sgarbled
321.2Sgarbled#include <sys/cdefs.h>
331.8Srin__KERNEL_RCSID(0, "$NetBSD: pcib.c,v 1.8 2020/07/06 09:34:17 rin Exp $");
341.8Srin
351.8Srin#include "isa.h"
361.8Srin#include "isadma.h"
371.2Sgarbled
381.2Sgarbled#include <sys/types.h>
391.2Sgarbled#include <sys/param.h>
401.2Sgarbled#include <sys/systm.h>
411.2Sgarbled#include <sys/device.h>
421.2Sgarbled
431.7Sdyoung#include <sys/bus.h>
441.2Sgarbled
451.2Sgarbled#include <dev/isa/isavar.h>
461.2Sgarbled
471.2Sgarbled#include <dev/pci/pcivar.h>
481.2Sgarbled#include <dev/pci/pcireg.h>
491.2Sgarbled
501.2Sgarbled#include <dev/pci/pcidevs.h>
511.2Sgarbled
521.4Smattint	pcibmatch(device_t, cfdata_t, void *);
531.4Smattvoid	pcibattach(device_t, device_t, void *);
541.2Sgarbled
551.2Sgarbledstruct pcib_softc {
561.4Smatt	device_t sc_dev;
571.2Sgarbled	struct powerpc_isa_chipset *sc_chipset;
581.2Sgarbled};
591.2Sgarbled
601.2Sgarbledextern struct powerpc_isa_chipset genppc_ict;
611.2Sgarbledextern struct genppc_pci_chipset *genppc_pct;
621.2Sgarbled
631.4SmattCFATTACH_DECL_NEW(pcib, sizeof(struct pcib_softc),
641.2Sgarbled    pcibmatch, pcibattach, NULL, NULL);
651.2Sgarbled
661.4Smattvoid	pcib_callback(device_t);
671.2Sgarbled
681.2Sgarbledint
691.4Smattpcibmatch(device_t parent, cfdata_t cf, void *aux)
701.2Sgarbled{
711.2Sgarbled	struct pci_attach_args *pa = aux;
721.2Sgarbled
731.2Sgarbled	/*
741.2Sgarbled	 * Match PCI-ISA bridge.
751.2Sgarbled	 */
761.2Sgarbled	if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE &&
771.2Sgarbled	    PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_ISA) {
781.2Sgarbled		return (1);
791.2Sgarbled	}
801.2Sgarbled
811.2Sgarbled	/*
821.2Sgarbled	 * some special cases:
831.2Sgarbled	 */
841.2Sgarbled	switch (PCI_VENDOR(pa->pa_id)) {
851.2Sgarbled	case PCI_VENDOR_INTEL:
861.2Sgarbled		switch (PCI_PRODUCT(pa->pa_id)) {
871.2Sgarbled		case PCI_PRODUCT_INTEL_SIO:
881.2Sgarbled			/*
891.2Sgarbled			 * The Intel SIO identifies itself as a
901.2Sgarbled			 * miscellaneous prehistoric.
911.2Sgarbled			 */
921.2Sgarbled			return (1);
931.2Sgarbled		}
941.2Sgarbled		break;
951.2Sgarbled	}
961.2Sgarbled
971.2Sgarbled	return (0);
981.2Sgarbled}
991.2Sgarbled
1001.2Sgarbledvoid
1011.4Smattpcibattach(device_t parent, device_t self, void *aux)
1021.2Sgarbled{
1031.2Sgarbled	struct pci_attach_args *pa = aux;
1041.4Smatt	struct pcib_softc *sc = device_private(self);
1051.2Sgarbled	char devinfo[256];
1061.2Sgarbled	u_int32_t v;
1071.2Sgarbled	int lvlmask = 0;
1081.2Sgarbled#ifdef prep
1091.2Sgarbled	prop_bool_t rav;
1101.2Sgarbled#endif
1111.2Sgarbled
1121.4Smatt	sc->sc_dev = self;
1131.4Smatt
1141.2Sgarbled	/*
1151.2Sgarbled	 * Just print out a description and defer configuration
1161.2Sgarbled	 * until all PCI devices have been attached.
1171.2Sgarbled	 */
1181.2Sgarbled	pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo, sizeof(devinfo));
1191.2Sgarbled	aprint_normal(": %s (rev. 0x%02x)\n", devinfo,
1201.2Sgarbled	    PCI_REVISION(pa->pa_class));
1211.2Sgarbled
1221.2Sgarbled	v = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x40);
1231.2Sgarbled	if ((v & 0x20) == 0) {
1241.6Smatt		aprint_verbose_dev(self, "PIRQ[0-3] not used\n");
1251.2Sgarbled	} else {
1261.2Sgarbled		v = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x60);
1271.2Sgarbled		if ((v & 0x80808080) == 0x80808080) {
1281.6Smatt			aprint_verbose_dev(self, "PIRQ[0-3] disabled\n");
1291.2Sgarbled		} else {
1301.2Sgarbled			int i;
1311.4Smatt			aprint_verbose("%s:", device_xname(self));
1321.2Sgarbled			for (i = 0; i < 4; i++, v >>= 8) {
1331.2Sgarbled				if ((v & 0x80) == 0 && (v & 0x0f) != 0) {
1341.2Sgarbled					aprint_verbose(" PIRQ[%d]=%d", i,
1351.2Sgarbled					    v & 0x0f);
1361.2Sgarbled					lvlmask |= (1 << (v & 0x0f));
1371.2Sgarbled				}
1381.2Sgarbled			}
1391.2Sgarbled			aprint_verbose("\n");
1401.2Sgarbled		}
1411.2Sgarbled	}
1421.2Sgarbled
1431.2Sgarbled	/*
1441.2Sgarbled	 * If we have an 83C553F-G sitting on a RAVEN host bridge,
1451.2Sgarbled	 * then we need to rewire some interrupts.
1461.2Sgarbled	 * The IDE Interrupt Routing Control Register lives at 0x43,
1471.2Sgarbled	 * and defaults to 0xEF, which means the primary controller
1481.2Sgarbled	 * interrupts on ivr-14, and the secondary on ivr-15. We
1491.2Sgarbled	 * reset it to 0xEE to fire them both at ivr-14.
1501.2Sgarbled	 * We have to rewrite the interrupt map, because the bridge map told
1511.2Sgarbled	 * us that the interrupt is MPIC 0, which is the bridge intr for
1521.2Sgarbled	 * the 8259.
1531.2Sgarbled	 * Additionally, sometimes the PCI Interrupt Routing Control Register
1541.2Sgarbled	 * is improperly initialized, causing all sorts of wierd interrupt
1551.2Sgarbled	 * issues on the machine.  The manual says it should default to
1561.2Sgarbled	 * 0000h (index 45-44h) however it would appear that PPCBUG is
1571.2Sgarbled	 * setting it up differently.  Reset it to 0000h.
1581.2Sgarbled	 */
1591.2Sgarbled
1601.3Sgarbled	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_SYMPHONY &&
1611.3Sgarbled	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SYMPHONY_83C553) {
1621.3Sgarbled		v = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x44) & 0xffff0000;
1631.3Sgarbled		pci_conf_write(pa->pa_pc, pa->pa_tag, 0x44, v);
1641.3Sgarbled	}
1651.3Sgarbled
1661.2Sgarbled#ifdef prep
1671.2Sgarbled	rav = prop_dictionary_get(device_properties(parent),
1681.2Sgarbled	    "prep-raven-pchb");
1691.2Sgarbled
1701.2Sgarbled	if (rav != NULL && prop_bool_true(rav) &&
1711.2Sgarbled	    PCI_VENDOR(pa->pa_id) == PCI_VENDOR_SYMPHONY &&
1721.2Sgarbled	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SYMPHONY_83C553) {
1731.2Sgarbled
1741.2Sgarbled		prop_dictionary_t dict, devsub;
1751.2Sgarbled		prop_number_t pinsub;
1761.2Sgarbled		struct genppc_pci_chipset_businfo *pbi;
1771.2Sgarbled
1781.2Sgarbled		v = pci_conf_read(pa->pa_pc, pa->pa_tag, 0x40) & 0x00ffffff;
1791.2Sgarbled		v |= 0xee000000;
1801.2Sgarbled		pci_conf_write(pa->pa_pc, pa->pa_tag, 0x40, v);
1811.2Sgarbled
1821.2Sgarbled		pbi = SIMPLEQ_FIRST(&genppc_pct->pc_pbi);
1831.2Sgarbled		dict = prop_dictionary_get(pbi->pbi_properties,
1841.2Sgarbled		    "prep-pci-intrmap");
1851.2Sgarbled		devsub = prop_dictionary_get(dict, "devfunc-11");
1861.2Sgarbled		pinsub = prop_number_create_integer(14);
1871.2Sgarbled		prop_dictionary_set(devsub, "pin-A", pinsub);
1881.2Sgarbled		prop_object_release(pinsub);
1891.4Smatt		aprint_verbose_dev(self, "setting pciide irq to 14\n");
1901.2Sgarbled		/* irq 14 is level */
1911.2Sgarbled		lvlmask = 0x0040;
1921.2Sgarbled	}
1931.2Sgarbled#endif /* prep */
1941.2Sgarbled
1951.2Sgarbled	config_defer(self, pcib_callback);
1961.2Sgarbled}
1971.2Sgarbled
1981.2Sgarbledvoid
1991.4Smattpcib_callback(device_t self)
2001.2Sgarbled{
2011.4Smatt	struct pcib_softc *sc = device_private(self);
2021.2Sgarbled#if NISA > 0
2031.2Sgarbled	struct isabus_attach_args iba;
2041.2Sgarbled
2051.2Sgarbled	/*
2061.2Sgarbled	 * Attach the ISA bus behind this bridge.
2071.2Sgarbled	 */
2081.2Sgarbled	memset(&iba, 0, sizeof(iba));
2091.2Sgarbled	sc->sc_chipset = &genppc_ict;
2101.2Sgarbled	iba.iba_ic = sc->sc_chipset;
2111.2Sgarbled	iba.iba_iot = &genppc_isa_io_space_tag;
2121.2Sgarbled	iba.iba_memt = &genppc_isa_mem_space_tag;
2131.2Sgarbled#if NISADMA > 0
2141.2Sgarbled	iba.iba_dmat = &isa_bus_dma_tag;
2151.2Sgarbled#endif
2161.4Smatt	config_found_ia(sc->sc_dev, "isabus", &iba, isabusprint);
2171.2Sgarbled#endif
2181.2Sgarbled}
219