pci_machdep.c revision 1.19
11.19Sgdamore/* $NetBSD: pci_machdep.c,v 1.19 2006/02/10 20:52:56 gdamore 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.19Sgdamore__KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.19 2006/02/10 20:52:56 gdamore 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.17Stsutsui#include <sys/extent.h> 381.1Ssoren 391.1Ssoren#define _COBALT_BUS_DMA_PRIVATE 401.1Ssoren#include <machine/bus.h> 411.4Ssoren#include <machine/intr.h> 421.1Ssoren 431.1Ssoren#include <dev/pci/pcivar.h> 441.1Ssoren#include <dev/pci/pcireg.h> 451.1Ssoren#include <dev/pci/pcidevs.h> 461.17Stsutsui#include <dev/pci/pciconf.h> 471.1Ssoren 481.16Stsutsui#include <cobalt/dev/gtreg.h> 491.16Stsutsui 501.1Ssoren/* 511.1Ssoren * PCI doesn't have any special needs; just use 521.1Ssoren * the generic versions of these functions. 531.1Ssoren */ 541.1Ssorenstruct cobalt_bus_dma_tag pci_bus_dma_tag = { 551.14Stsutsui _bus_dmamap_create, 561.1Ssoren _bus_dmamap_destroy, 571.1Ssoren _bus_dmamap_load, 581.1Ssoren _bus_dmamap_load_mbuf, 591.1Ssoren _bus_dmamap_load_uio, 601.1Ssoren _bus_dmamap_load_raw, 611.1Ssoren _bus_dmamap_unload, 621.1Ssoren _bus_dmamap_sync, 631.1Ssoren _bus_dmamem_alloc, 641.1Ssoren _bus_dmamem_free, 651.1Ssoren _bus_dmamem_map, 661.1Ssoren _bus_dmamem_unmap, 671.1Ssoren _bus_dmamem_mmap, 681.1Ssoren}; 691.1Ssoren 701.1Ssorenvoid 711.1Ssorenpci_attach_hook(parent, self, pba) 721.1Ssoren struct device *parent, *self; 731.1Ssoren struct pcibus_attach_args *pba; 741.1Ssoren{ 751.1Ssoren /* XXX */ 761.1Ssoren 771.1Ssoren return; 781.1Ssoren} 791.1Ssoren 801.1Ssorenint 811.1Ssorenpci_bus_maxdevs(pc, busno) 821.1Ssoren pci_chipset_tag_t pc; 831.1Ssoren int busno; 841.1Ssoren{ 851.6Ssoren return 32; 861.1Ssoren} 871.1Ssoren 881.1Ssorenpcitag_t 891.1Ssorenpci_make_tag(pc, bus, device, function) 901.1Ssoren pci_chipset_tag_t pc; 911.1Ssoren int bus, device, function; 921.1Ssoren{ 931.1Ssoren return (bus << 16) | (device << 11) | (function << 8); 941.1Ssoren} 951.1Ssoren 961.1Ssorenvoid 971.1Ssorenpci_decompose_tag(pc, tag, bp, dp, fp) 981.1Ssoren pci_chipset_tag_t pc; 991.1Ssoren pcitag_t tag; 1001.1Ssoren int *bp, *dp, *fp; 1011.1Ssoren{ 1021.1Ssoren if (bp != NULL) 1031.1Ssoren *bp = (tag >> 16) & 0xff; 1041.1Ssoren if (dp != NULL) 1051.1Ssoren *dp = (tag >> 11) & 0x1f; 1061.1Ssoren if (fp != NULL) 1071.1Ssoren *fp = (tag >> 8) & 0x07; 1081.1Ssoren} 1091.1Ssoren 1101.1Ssorenpcireg_t 1111.1Ssorenpci_conf_read(pc, tag, reg) 1121.1Ssoren pci_chipset_tag_t pc; 1131.1Ssoren pcitag_t tag; 1141.1Ssoren int reg; 1151.1Ssoren{ 1161.1Ssoren pcireg_t data; 1171.6Ssoren int bus, dev, func; 1181.14Stsutsui 1191.6Ssoren pci_decompose_tag(pc, tag, &bus, &dev, &func); 1201.6Ssoren 1211.6Ssoren /* 1221.6Ssoren * 2700 hardware wedges on accesses to device 6. 1231.6Ssoren */ 1241.6Ssoren if (bus == 0 && dev == 6) 1251.6Ssoren return 0; 1261.6Ssoren /* 1271.6Ssoren * 2800 hardware wedges on accesses to device 31. 1281.6Ssoren */ 1291.6Ssoren if (bus == 0 && dev == 31) 1301.6Ssoren return 0; 1311.1Ssoren 1321.16Stsutsui bus_space_write_4(pc->pc_bst, pc->pc_bsh, GT_PCICFG_ADDR, 1331.16Stsutsui 0x80000000 | tag | reg); 1341.16Stsutsui data = bus_space_read_4(pc->pc_bst, pc->pc_bsh, GT_PCICFG_DATA); 1351.16Stsutsui bus_space_write_4(pc->pc_bst, pc->pc_bsh, GT_PCICFG_ADDR, 0); 1361.1Ssoren 1371.1Ssoren return data; 1381.1Ssoren} 1391.1Ssoren 1401.1Ssorenvoid 1411.1Ssorenpci_conf_write(pc, tag, reg, data) 1421.1Ssoren pci_chipset_tag_t pc; 1431.1Ssoren pcitag_t tag; 1441.1Ssoren int reg; 1451.1Ssoren pcireg_t data; 1461.1Ssoren{ 1471.1Ssoren 1481.16Stsutsui bus_space_write_4(pc->pc_bst, pc->pc_bsh, GT_PCICFG_ADDR, 1491.16Stsutsui 0x80000000 | tag | reg); 1501.16Stsutsui bus_space_write_4(pc->pc_bst, pc->pc_bsh, GT_PCICFG_DATA, data); 1511.16Stsutsui bus_space_write_4(pc->pc_bst, pc->pc_bsh, GT_PCICFG_ADDR, 0); 1521.1Ssoren} 1531.1Ssoren 1541.1Ssorenint 1551.10Ssommerfepci_intr_map(pa, ihp) 1561.10Ssommerfe struct pci_attach_args *pa; 1571.1Ssoren pci_intr_handle_t *ihp; 1581.1Ssoren{ 1591.10Ssommerfe pci_chipset_tag_t pc = pa->pa_pc; 1601.11Stsutsui pcitag_t intrtag = pa->pa_intrtag; 1611.10Ssommerfe int pin = pa->pa_intrpin; 1621.10Ssommerfe int line = pa->pa_intrline; 1631.5Ssoren int bus, dev, func; 1641.1Ssoren 1651.5Ssoren pci_decompose_tag(pc, intrtag, &bus, &dev, &func); 1661.5Ssoren 1671.5Ssoren /* 1681.5Ssoren * The interrupt lines of the two Tulips are connected 1691.5Ssoren * directly to the CPU. 1701.5Ssoren */ 1711.5Ssoren 1721.5Ssoren if (bus == 0 && dev == 7 && pin == PCI_INTERRUPT_PIN_A) 1731.5Ssoren *ihp = 16 + 1; 1741.5Ssoren else if (bus == 0 && dev == 12 && pin == PCI_INTERRUPT_PIN_A) 1751.5Ssoren *ihp = 16 + 2; 1761.5Ssoren else 1771.5Ssoren *ihp = line; 1781.1Ssoren 1791.1Ssoren return 0; 1801.1Ssoren} 1811.1Ssoren 1821.1Ssorenconst char * 1831.1Ssorenpci_intr_string(pc, ih) 1841.1Ssoren pci_chipset_tag_t pc; 1851.1Ssoren pci_intr_handle_t ih; 1861.1Ssoren{ 1871.4Ssoren static char irqstr[8]; 1881.4Ssoren 1891.5Ssoren if (ih >= 16) 1901.5Ssoren sprintf(irqstr, "level %d", ih - 16); 1911.4Ssoren else 1921.4Ssoren sprintf(irqstr, "irq %d", ih); 1931.1Ssoren 1941.1Ssoren return irqstr; 1951.7Scgd} 1961.7Scgd 1971.7Scgdconst struct evcnt * 1981.7Scgdpci_intr_evcnt(pc, ih) 1991.7Scgd pci_chipset_tag_t pc; 2001.7Scgd pci_intr_handle_t ih; 2011.7Scgd{ 2021.7Scgd 2031.7Scgd /* XXX for now, no evcnt parent reported */ 2041.7Scgd return NULL; 2051.1Ssoren} 2061.1Ssoren 2071.1Ssorenvoid * 2081.1Ssorenpci_intr_establish(pc, ih, level, func, arg) 2091.1Ssoren pci_chipset_tag_t pc; 2101.1Ssoren pci_intr_handle_t ih; 2111.1Ssoren int level, (*func)(void *); 2121.1Ssoren void *arg; 2131.1Ssoren{ 2141.5Ssoren if (ih >= 16) 2151.5Ssoren return cpu_intr_establish(ih - 16, level, func, arg); 2161.4Ssoren else 2171.4Ssoren return icu_intr_establish(ih, IST_LEVEL, level, func, arg); 2181.1Ssoren} 2191.1Ssoren 2201.1Ssorenvoid 2211.1Ssorenpci_intr_disestablish(pc, cookie) 2221.1Ssoren pci_chipset_tag_t pc; 2231.1Ssoren void *cookie; 2241.1Ssoren{ 2251.12Saugustss /* Try both, only the valid one will disestablish. */ 2261.12Saugustss cpu_intr_disestablish(cookie); 2271.12Saugustss icu_intr_disestablish(cookie); 2281.1Ssoren} 2291.17Stsutsui 2301.17Stsutsuivoid 2311.17Stsutsuipci_conf_interrupt(pci_chipset_tag_t pc, int bus, int dev, int pin, int swiz, 2321.17Stsutsui int *iline) 2331.17Stsutsui{ 2341.17Stsutsui 2351.17Stsutsui /* not yet... */ 2361.17Stsutsui} 2371.17Stsutsui 2381.17Stsutsuiint 2391.17Stsutsuipci_conf_hook(pci_chipset_tag_t pc, int bus, int dev, int func, pcireg_t id) 2401.17Stsutsui{ 2411.17Stsutsui 2421.17Stsutsui /* Don't configure the bridge and PCI probe. */ 2431.17Stsutsui if (PCI_VENDOR(id) == PCI_VENDOR_GALILEO && 2441.17Stsutsui PCI_PRODUCT(id) == PCI_PRODUCT_GALILEO_GT64011) 2451.17Stsutsui return 0; 2461.17Stsutsui 2471.17Stsutsui /* Don't configure device 9 */ 2481.17Stsutsui if (dev == 9) 2491.17Stsutsui return 0; 2501.17Stsutsui 2511.19Sgdamore return PCI_CONF_DEFAULT & ~(PCI_COMMAND_SERR_ENABLE | 2521.19Sgdamore PCI_COMMAND_PARITY_ENABLE); 2531.17Stsutsui} 254