pci_machdep.c revision 1.14
11.87Spooka/*	$NetBSD: pci_machdep.c,v 1.14 2003/09/12 14:59:15 tsutsui Exp $	*/
21.1Spooka
31.1Spooka/*
41.71Spooka * Copyright (c) 2000 Soren S. Jorvang.  All rights reserved.
51.1Spooka *
61.1Spooka * Redistribution and use in source and binary forms, with or without
71.1Spooka * modification, are permitted provided that the following conditions
81.1Spooka * are met:
91.1Spooka * 1. Redistributions of source code must retain the above copyright
101.1Spooka *    notice, this list of conditions, and the following disclaimer.
111.1Spooka * 2. Redistributions in binary form must reproduce the above copyright
121.1Spooka *    notice, this list of conditions and the following disclaimer in the
131.1Spooka *    documentation and/or other materials provided with the distribution.
141.1Spooka *
151.1Spooka * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
161.1Spooka * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
171.1Spooka * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
181.1Spooka * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
191.1Spooka * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
201.1Spooka * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
211.1Spooka * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
221.1Spooka * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
231.1Spooka * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
241.1Spooka * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
251.1Spooka * SUCH DAMAGE.
261.1Spooka */
271.1Spooka
281.3Spooka#include <sys/cdefs.h>
291.87Spooka__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.14 2003/09/12 14:59:15 tsutsui Exp $");
301.3Spooka
311.1Spooka#include <sys/types.h>
321.24Spooka#include <sys/param.h>
331.71Spooka#include <sys/time.h>
341.33Spooka#include <sys/systm.h>
351.33Spooka#include <sys/errno.h>
361.24Spooka#include <sys/device.h>
371.24Spooka
381.1Spooka#define _COBALT_BUS_DMA_PRIVATE
391.24Spooka#include <machine/bus.h>
401.30Spooka#include <machine/intr.h>
411.24Spooka#include <machine/intr_machdep.h>
421.24Spooka
431.1Spooka#include <dev/pci/pcivar.h>
441.1Spooka#include <dev/pci/pcireg.h>
451.24Spooka#include <dev/pci/pcidevs.h>
461.1Spooka
471.1Spooka/*
481.24Spooka * PCI doesn't have any special needs; just use
491.70Spooka * the generic versions of these functions.
501.1Spooka */
511.1Spookastruct cobalt_bus_dma_tag pci_bus_dma_tag = {
521.1Spooka	_bus_dmamap_create,
531.1Spooka	_bus_dmamap_destroy,
541.68Spooka	_bus_dmamap_load,
551.1Spooka	_bus_dmamap_load_mbuf,
561.71Spooka	_bus_dmamap_load_uio,
571.71Spooka	_bus_dmamap_load_raw,
581.1Spooka	_bus_dmamap_unload,
591.1Spooka	_bus_dmamap_sync,
601.1Spooka	_bus_dmamem_alloc,
611.1Spooka	_bus_dmamem_free,
621.1Spooka	_bus_dmamem_map,
631.1Spooka	_bus_dmamem_unmap,
641.9Spooka	_bus_dmamem_mmap,
651.74Spooka};
661.14Spooka
671.51Snjolyvoid
681.72Spookapci_attach_hook(parent, self, pba)
691.19Spooka	struct device *parent, *self;
701.26Spooka	struct pcibus_attach_args *pba;
711.14Spooka{
721.12Spooka	/* XXX */
731.9Spooka
741.43Spooka	return;
751.19Spooka}
761.24Spooka
771.24Spookaint
781.24Spookapci_bus_maxdevs(pc, busno)
791.58Spooka	pci_chipset_tag_t pc;
801.58Spooka	int busno;
811.60Spooka{
821.70Spooka	return 32;
831.71Spooka}
841.71Spooka
851.82Skefrenpcitag_t
861.87Spookapci_make_tag(pc, bus, device, function)
871.1Spooka	pci_chipset_tag_t pc;
881.1Spooka	int bus, device, function;
891.1Spooka{
901.1Spooka	return (bus << 16) | (device << 11) | (function << 8);
911.1Spooka}
921.1Spooka
931.1Spookavoid
941.1Spookapci_decompose_tag(pc, tag, bp, dp, fp)
951.1Spooka	pci_chipset_tag_t pc;
961.1Spooka	pcitag_t tag;
971.1Spooka	int *bp, *dp, *fp;
981.1Spooka{
991.1Spooka	if (bp != NULL)
1001.9Spooka		*bp = (tag >> 16) & 0xff;
1011.74Spooka	if (dp != NULL)
1021.14Spooka		*dp = (tag >> 11) & 0x1f;
1031.51Snjoly	if (fp != NULL)
1041.72Spooka		*fp = (tag >> 8) & 0x07;
1051.19Spooka}
1061.26Spooka
1071.58Spooka#define PCI_CFG_ADDR	((volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x14000cf8))
1081.58Spooka#define PCI_CFG_DATA	((volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x14000cfc))
1091.87Spooka
1101.43Spookapcireg_t
1111.24Spookapci_conf_read(pc, tag, reg)
1121.24Spooka	pci_chipset_tag_t pc;
1131.24Spooka	pcitag_t tag;
1141.69Spooka	int reg;
1151.55Spooka{
1161.67Spooka	pcireg_t data;
1171.67Spooka	int bus, dev, func;
1181.60Spooka
1191.9Spooka	pci_decompose_tag(pc, tag, &bus, &dev, &func);
1201.1Spooka
1211.1Spooka	/*
1221.44Spooka	 * 2700 hardware wedges on accesses to device 6.
1231.14Spooka	 */
1241.12Spooka	if (bus == 0 && dev == 6)
1251.64Spooka		return 0;
1261.70Spooka	/*
1271.71Spooka	 * 2800 hardware wedges on accesses to device 31.
1281.71Spooka	 */
1291.82Skefren	if (bus == 0 && dev == 31)
1301.1Spooka		return 0;
1311.1Spooka
1321.1Spooka	*PCI_CFG_ADDR = 0x80000000 | tag | reg;
1331.1Spooka	data = *PCI_CFG_DATA;
1341.19Spooka	*PCI_CFG_ADDR = 0;
1351.19Spooka
1361.19Spooka	return data;
1371.19Spooka}
1381.19Spooka
1391.19Spookavoid
1401.19Spookapci_conf_write(pc, tag, reg, data)
1411.19Spooka	pci_chipset_tag_t pc;
1421.19Spooka	pcitag_t tag;
1431.1Spooka	int reg;
1441.1Spooka	pcireg_t data;
1451.19Spooka{
1461.1Spooka	*PCI_CFG_ADDR = 0x80000000 | tag | reg;
1471.1Spooka	*PCI_CFG_DATA = data;
1481.1Spooka	*PCI_CFG_ADDR = 0;
1491.86Spooka
1501.60Spooka	return;
1511.14Spooka}
1521.14Spooka
1531.50Spookaint
1541.14Spookapci_intr_map(pa, ihp)
1551.14Spooka	struct pci_attach_args *pa;
1561.14Spooka	pci_intr_handle_t *ihp;
1571.14Spooka{
1581.14Spooka	pci_chipset_tag_t pc = pa->pa_pc;
1591.68Spooka	pcitag_t intrtag = pa->pa_intrtag;
1601.68Spooka	int pin = pa->pa_intrpin;
1611.68Spooka	int line = pa->pa_intrline;
1621.68Spooka	int bus, dev, func;
1631.68Spooka
1641.68Spooka	pci_decompose_tag(pc, intrtag, &bus, &dev, &func);
1651.68Spooka
1661.68Spooka	/*
1671.68Spooka	 * The interrupt lines of the two Tulips are connected
1681.14Spooka	 * directly to the CPU.
1691.68Spooka	 */
1701.14Spooka
1711.14Spooka	if (bus == 0 && dev == 7 && pin == PCI_INTERRUPT_PIN_A)
1721.41Spooka		*ihp = 16 + 1;
1731.41Spooka	else if (bus == 0 && dev == 12 && pin == PCI_INTERRUPT_PIN_A)
1741.82Skefren		*ihp = 16 + 2;
1751.14Spooka	else
1761.24Spooka		*ihp = line;
1771.41Spooka
1781.24Spooka	return 0;
1791.24Spooka}
1801.27Spooka
1811.24Spookaconst char *
1821.71Spookapci_intr_string(pc, ih)
1831.71Spooka	pci_chipset_tag_t pc;
1841.71Spooka	pci_intr_handle_t ih;
1851.71Spooka{
1861.41Spooka	static char irqstr[8];
1871.41Spooka
1881.62Spooka	if (ih >= 16)
1891.41Spooka		sprintf(irqstr, "level %d", ih - 16);
1901.41Spooka	else
1911.58Spooka		sprintf(irqstr, "irq %d", ih);
1921.58Spooka
1931.58Spooka	return irqstr;
1941.58Spooka}
1951.24Spooka
1961.14Spookaconst struct evcnt *
1971.24Spookapci_intr_evcnt(pc, ih)
1981.24Spooka	pci_chipset_tag_t pc;
1991.27Spooka	pci_intr_handle_t ih;
2001.71Spooka{
2011.71Spooka
2021.41Spooka	/* XXX for now, no evcnt parent reported */
2031.62Spooka	return NULL;
2041.58Spooka}
2051.58Spooka
2061.41Spookavoid *
2071.41Spookapci_intr_establish(pc, ih, level, func, arg)
2081.41Spooka	pci_chipset_tag_t pc;
2091.41Spooka	pci_intr_handle_t ih;
2101.69Spooka	int level, (*func)(void *);
2111.14Spooka	void *arg;
2121.30Spooka{
2131.30Spooka	if (ih >= 16)
2141.30Spooka		return cpu_intr_establish(ih - 16, level, func, arg);
2151.30Spooka	else
2161.71Spooka		return icu_intr_establish(ih, IST_LEVEL, level, func, arg);
2171.21Spooka}
2181.21Spooka
2191.21Spookavoid
2201.21Spookapci_intr_disestablish(pc, cookie)
2211.21Spooka	pci_chipset_tag_t pc;
2221.21Spooka	void *cookie;
2231.21Spooka{
2241.21Spooka	/* Try both, only the valid one will disestablish. */
2251.21Spooka	cpu_intr_disestablish(cookie);
2261.21Spooka	icu_intr_disestablish(cookie);
2271.21Spooka}
2281.24Spooka