pci_machdep.c revision 1.16
11.16Stsutsui/*	$NetBSD: pci_machdep.c,v 1.16 2004/08/28 13:33:31 tsutsui Exp $	*/
21.1Ssoren
31.1Ssoren/*
41.1Ssoren * Copyright (c) 2000 Soren S. Jorvang.  All rights reserved.
51.1Ssoren *
61.1Ssoren * Redistribution and use in source and binary forms, with or without
71.1Ssoren * modification, are permitted provided that the following conditions
81.1Ssoren * are met:
91.1Ssoren * 1. Redistributions of source code must retain the above copyright
101.1Ssoren *    notice, this list of conditions, and the following disclaimer.
111.1Ssoren * 2. Redistributions in binary form must reproduce the above copyright
121.1Ssoren *    notice, this list of conditions and the following disclaimer in the
131.1Ssoren *    documentation and/or other materials provided with the distribution.
141.1Ssoren *
151.1Ssoren * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
161.1Ssoren * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
171.1Ssoren * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
181.1Ssoren * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
191.1Ssoren * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
201.1Ssoren * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
211.1Ssoren * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
221.1Ssoren * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
231.1Ssoren * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
241.1Ssoren * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
251.1Ssoren * SUCH DAMAGE.
261.1Ssoren */
271.13Slukem
281.13Slukem#include <sys/cdefs.h>
291.16Stsutsui__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.16 2004/08/28 13:33:31 tsutsui Exp $");
301.1Ssoren
311.1Ssoren#include <sys/types.h>
321.1Ssoren#include <sys/param.h>
331.1Ssoren#include <sys/time.h>
341.1Ssoren#include <sys/systm.h>
351.1Ssoren#include <sys/errno.h>
361.1Ssoren#include <sys/device.h>
371.1Ssoren
381.1Ssoren#define _COBALT_BUS_DMA_PRIVATE
391.1Ssoren#include <machine/bus.h>
401.4Ssoren#include <machine/intr.h>
411.1Ssoren
421.1Ssoren#include <dev/pci/pcivar.h>
431.1Ssoren#include <dev/pci/pcireg.h>
441.1Ssoren#include <dev/pci/pcidevs.h>
451.1Ssoren
461.16Stsutsui#include <cobalt/dev/gtreg.h>
471.16Stsutsui
481.1Ssoren/*
491.1Ssoren * PCI doesn't have any special needs; just use
501.1Ssoren * the generic versions of these functions.
511.1Ssoren */
521.1Ssorenstruct cobalt_bus_dma_tag pci_bus_dma_tag = {
531.14Stsutsui	_bus_dmamap_create,
541.1Ssoren	_bus_dmamap_destroy,
551.1Ssoren	_bus_dmamap_load,
561.1Ssoren	_bus_dmamap_load_mbuf,
571.1Ssoren	_bus_dmamap_load_uio,
581.1Ssoren	_bus_dmamap_load_raw,
591.1Ssoren	_bus_dmamap_unload,
601.1Ssoren	_bus_dmamap_sync,
611.1Ssoren	_bus_dmamem_alloc,
621.1Ssoren	_bus_dmamem_free,
631.1Ssoren	_bus_dmamem_map,
641.1Ssoren	_bus_dmamem_unmap,
651.1Ssoren	_bus_dmamem_mmap,
661.1Ssoren};
671.1Ssoren
681.1Ssorenvoid
691.1Ssorenpci_attach_hook(parent, self, pba)
701.1Ssoren	struct device *parent, *self;
711.1Ssoren	struct pcibus_attach_args *pba;
721.1Ssoren{
731.1Ssoren	/* XXX */
741.1Ssoren
751.1Ssoren	return;
761.1Ssoren}
771.1Ssoren
781.1Ssorenint
791.1Ssorenpci_bus_maxdevs(pc, busno)
801.1Ssoren	pci_chipset_tag_t pc;
811.1Ssoren	int busno;
821.1Ssoren{
831.6Ssoren	return 32;
841.1Ssoren}
851.1Ssoren
861.1Ssorenpcitag_t
871.1Ssorenpci_make_tag(pc, bus, device, function)
881.1Ssoren	pci_chipset_tag_t pc;
891.1Ssoren	int bus, device, function;
901.1Ssoren{
911.1Ssoren	return (bus << 16) | (device << 11) | (function << 8);
921.1Ssoren}
931.1Ssoren
941.1Ssorenvoid
951.1Ssorenpci_decompose_tag(pc, tag, bp, dp, fp)
961.1Ssoren	pci_chipset_tag_t pc;
971.1Ssoren	pcitag_t tag;
981.1Ssoren	int *bp, *dp, *fp;
991.1Ssoren{
1001.1Ssoren	if (bp != NULL)
1011.1Ssoren		*bp = (tag >> 16) & 0xff;
1021.1Ssoren	if (dp != NULL)
1031.1Ssoren		*dp = (tag >> 11) & 0x1f;
1041.1Ssoren	if (fp != NULL)
1051.1Ssoren		*fp = (tag >> 8) & 0x07;
1061.1Ssoren}
1071.1Ssoren
1081.1Ssorenpcireg_t
1091.1Ssorenpci_conf_read(pc, tag, reg)
1101.1Ssoren	pci_chipset_tag_t pc;
1111.1Ssoren	pcitag_t tag;
1121.1Ssoren	int reg;
1131.1Ssoren{
1141.1Ssoren	pcireg_t data;
1151.6Ssoren	int bus, dev, func;
1161.14Stsutsui
1171.6Ssoren	pci_decompose_tag(pc, tag, &bus, &dev, &func);
1181.6Ssoren
1191.6Ssoren	/*
1201.6Ssoren	 * 2700 hardware wedges on accesses to device 6.
1211.6Ssoren	 */
1221.6Ssoren	if (bus == 0 && dev == 6)
1231.6Ssoren		return 0;
1241.6Ssoren	/*
1251.6Ssoren	 * 2800 hardware wedges on accesses to device 31.
1261.6Ssoren	 */
1271.6Ssoren	if (bus == 0 && dev == 31)
1281.6Ssoren		return 0;
1291.1Ssoren
1301.16Stsutsui	bus_space_write_4(pc->pc_bst, pc->pc_bsh, GT_PCICFG_ADDR,
1311.16Stsutsui	    0x80000000 | tag | reg);
1321.16Stsutsui	data = bus_space_read_4(pc->pc_bst, pc->pc_bsh, GT_PCICFG_DATA);
1331.16Stsutsui	bus_space_write_4(pc->pc_bst, pc->pc_bsh, GT_PCICFG_ADDR, 0);
1341.1Ssoren
1351.1Ssoren	return data;
1361.1Ssoren}
1371.1Ssoren
1381.1Ssorenvoid
1391.1Ssorenpci_conf_write(pc, tag, reg, data)
1401.1Ssoren	pci_chipset_tag_t pc;
1411.1Ssoren	pcitag_t tag;
1421.1Ssoren	int reg;
1431.1Ssoren	pcireg_t data;
1441.1Ssoren{
1451.1Ssoren
1461.16Stsutsui	bus_space_write_4(pc->pc_bst, pc->pc_bsh, GT_PCICFG_ADDR,
1471.16Stsutsui	    0x80000000 | tag | reg);
1481.16Stsutsui	bus_space_write_4(pc->pc_bst, pc->pc_bsh, GT_PCICFG_DATA, data);
1491.16Stsutsui	bus_space_write_4(pc->pc_bst, pc->pc_bsh, GT_PCICFG_ADDR, 0);
1501.1Ssoren}
1511.1Ssoren
1521.1Ssorenint
1531.10Ssommerfepci_intr_map(pa, ihp)
1541.10Ssommerfe	struct pci_attach_args *pa;
1551.1Ssoren	pci_intr_handle_t *ihp;
1561.1Ssoren{
1571.10Ssommerfe	pci_chipset_tag_t pc = pa->pa_pc;
1581.11Stsutsui	pcitag_t intrtag = pa->pa_intrtag;
1591.10Ssommerfe	int pin = pa->pa_intrpin;
1601.10Ssommerfe	int line = pa->pa_intrline;
1611.5Ssoren	int bus, dev, func;
1621.1Ssoren
1631.5Ssoren	pci_decompose_tag(pc, intrtag, &bus, &dev, &func);
1641.5Ssoren
1651.5Ssoren	/*
1661.5Ssoren	 * The interrupt lines of the two Tulips are connected
1671.5Ssoren	 * directly to the CPU.
1681.5Ssoren	 */
1691.5Ssoren
1701.5Ssoren	if (bus == 0 && dev == 7 && pin == PCI_INTERRUPT_PIN_A)
1711.5Ssoren		*ihp = 16 + 1;
1721.5Ssoren	else if (bus == 0 && dev == 12 && pin == PCI_INTERRUPT_PIN_A)
1731.5Ssoren		*ihp = 16 + 2;
1741.5Ssoren	else
1751.5Ssoren		*ihp = line;
1761.1Ssoren
1771.1Ssoren	return 0;
1781.1Ssoren}
1791.1Ssoren
1801.1Ssorenconst char *
1811.1Ssorenpci_intr_string(pc, ih)
1821.1Ssoren	pci_chipset_tag_t pc;
1831.1Ssoren	pci_intr_handle_t ih;
1841.1Ssoren{
1851.4Ssoren	static char irqstr[8];
1861.4Ssoren
1871.5Ssoren	if (ih >= 16)
1881.5Ssoren		sprintf(irqstr, "level %d", ih - 16);
1891.4Ssoren	else
1901.4Ssoren		sprintf(irqstr, "irq %d", ih);
1911.1Ssoren
1921.1Ssoren	return irqstr;
1931.7Scgd}
1941.7Scgd
1951.7Scgdconst struct evcnt *
1961.7Scgdpci_intr_evcnt(pc, ih)
1971.7Scgd	pci_chipset_tag_t pc;
1981.7Scgd	pci_intr_handle_t ih;
1991.7Scgd{
2001.7Scgd
2011.7Scgd	/* XXX for now, no evcnt parent reported */
2021.7Scgd	return NULL;
2031.1Ssoren}
2041.1Ssoren
2051.1Ssorenvoid *
2061.1Ssorenpci_intr_establish(pc, ih, level, func, arg)
2071.1Ssoren	pci_chipset_tag_t pc;
2081.1Ssoren	pci_intr_handle_t ih;
2091.1Ssoren	int level, (*func)(void *);
2101.1Ssoren	void *arg;
2111.1Ssoren{
2121.5Ssoren	if (ih >= 16)
2131.5Ssoren		return cpu_intr_establish(ih - 16, level, func, arg);
2141.4Ssoren	else
2151.4Ssoren		return icu_intr_establish(ih, IST_LEVEL, level, func, arg);
2161.1Ssoren}
2171.1Ssoren
2181.1Ssorenvoid
2191.1Ssorenpci_intr_disestablish(pc, cookie)
2201.1Ssoren	pci_chipset_tag_t pc;
2211.1Ssoren	void *cookie;
2221.1Ssoren{
2231.12Saugustss	/* Try both, only the valid one will disestablish. */
2241.12Saugustss	cpu_intr_disestablish(cookie);
2251.12Saugustss	icu_intr_disestablish(cookie);
2261.1Ssoren}
227