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