vrc4172pci.c revision 1.2
11.2Stakemura/* $NetBSD: vrc4172pci.c,v 1.2 2002/04/14 08:00:00 takemura Exp $ */ 21.1Stakemura 31.1Stakemura/*- 41.1Stakemura * Copyright (c) 2002 TAKEMURA Shin 51.1Stakemura * All rights reserved. 61.1Stakemura * 71.1Stakemura * Redistribution and use in source and binary forms, with or without 81.1Stakemura * modification, are permitted provided that the following conditions 91.1Stakemura * are met: 101.1Stakemura * 1. Redistributions of source code must retain the above copyright 111.1Stakemura * notice, this list of conditions and the following disclaimer. 121.1Stakemura * 2. Redistributions in binary form must reproduce the above copyright 131.1Stakemura * notice, this list of conditions and the following disclaimer in the 141.1Stakemura * documentation and/or other materials provided with the distribution. 151.1Stakemura * 3. Neither the name of the project nor the names of its contributors 161.1Stakemura * may be used to endorse or promote products derived from this software 171.1Stakemura * without specific prior written permission. 181.1Stakemura * 191.1Stakemura * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 201.1Stakemura * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 211.1Stakemura * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 221.1Stakemura * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 231.1Stakemura * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 241.1Stakemura * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 251.1Stakemura * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 261.1Stakemura * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 271.1Stakemura * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 281.1Stakemura * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 291.1Stakemura * SUCH DAMAGE. 301.1Stakemura */ 311.1Stakemura 321.1Stakemura#include <sys/param.h> 331.1Stakemura#include <sys/systm.h> 341.1Stakemura#include <sys/device.h> 351.1Stakemura 361.1Stakemura#include <machine/bus.h> 371.1Stakemura#include <machine/bus_space_hpcmips.h> 381.1Stakemura#include <machine/bus_dma_hpcmips.h> 391.1Stakemura#include <machine/config_hook.h> 401.1Stakemura#include <machine/platid.h> 411.1Stakemura#include <machine/platid_mask.h> 421.1Stakemura 431.1Stakemura#include <dev/pci/pcivar.h> 441.1Stakemura#include <dev/pci/pcidevs.h> 451.1Stakemura#include <dev/pci/pciidereg.h> 461.1Stakemura 471.1Stakemura#include <hpcmips/vr/icureg.h> 481.1Stakemura#include <hpcmips/vr/vripif.h> 491.1Stakemura#include <hpcmips/vr/vrc4172pcireg.h> 501.1Stakemura 511.1Stakemura#include "pci.h" 521.1Stakemura 531.1Stakemura#ifdef DEBUG 541.1Stakemura#define DPRINTF(args) printf args 551.1Stakemura#else 561.1Stakemura#define DPRINTF(args) 571.1Stakemura#endif 581.1Stakemura 591.1Stakemurastruct vrc4172pci_softc { 601.1Stakemura struct device sc_dev; 611.1Stakemura 621.1Stakemura bus_space_tag_t sc_iot; 631.1Stakemura bus_space_handle_t sc_ioh; 641.1Stakemura 651.1Stakemura struct hpcmips_pci_chipset sc_pc; 661.1Stakemura}; 671.1Stakemura 681.1Stakemurastatic int vrc4172pci_match(struct device *, struct cfdata *, void *); 691.1Stakemurastatic void vrc4172pci_attach(struct device *, struct device *, void *); 701.1Stakemura#if NPCI > 0 711.1Stakemurastatic int vrc4172pci_print(void *, const char *); 721.1Stakemura#endif 731.1Stakemurastatic void vrc4172pci_attach_hook(struct device *, struct device *, 741.1Stakemura struct pcibus_attach_args *); 751.1Stakemurastatic int vrc4172pci_bus_maxdevs(pci_chipset_tag_t, int); 761.1Stakemurastatic int vrc4172pci_bus_devorder(pci_chipset_tag_t, int, char *); 771.1Stakemurastatic pcitag_t vrc4172pci_make_tag(pci_chipset_tag_t, int, int, int); 781.1Stakemurastatic void vrc4172pci_decompose_tag(pci_chipset_tag_t, pcitag_t, int *, 791.1Stakemura int *, int *); 801.1Stakemurastatic pcireg_t vrc4172pci_conf_read(pci_chipset_tag_t, pcitag_t, int); 811.1Stakemurastatic void vrc4172pci_conf_write(pci_chipset_tag_t, pcitag_t, int, 821.1Stakemura pcireg_t); 831.1Stakemurastatic int vrc4172pci_intr_map(struct pci_attach_args *, 841.1Stakemura pci_intr_handle_t *); 851.1Stakemurastatic const char *vrc4172pci_intr_string(pci_chipset_tag_t,pci_intr_handle_t); 861.1Stakemurastatic const struct evcnt *vrc4172pci_intr_evcnt(pci_chipset_tag_t, 871.1Stakemura pci_intr_handle_t); 881.1Stakemurastatic void *vrc4172pci_intr_establish(pci_chipset_tag_t, 891.1Stakemura pci_intr_handle_t, int, int (*)(void *), void *); 901.1Stakemurastatic void vrc4172pci_intr_disestablish(pci_chipset_tag_t, void *); 911.1Stakemura 921.1Stakemurastruct cfattach vrc4172pci_ca = { 931.1Stakemura sizeof(struct vrc4172pci_softc), vrc4172pci_match, vrc4172pci_attach 941.1Stakemura}; 951.1Stakemura 961.1Stakemurastatic inline void 971.1Stakemuravrc4172pci_write(struct vrc4172pci_softc *sc, int offset, u_int32_t val) 981.1Stakemura{ 991.1Stakemura 1001.1Stakemura bus_space_write_4(sc->sc_iot, sc->sc_ioh, offset, val); 1011.1Stakemura} 1021.1Stakemura 1031.1Stakemurastatic inline u_int32_t 1041.1Stakemuravrc4172pci_read(struct vrc4172pci_softc *sc, int offset) 1051.1Stakemura{ 1061.2Stakemura u_int32_t res; 1071.1Stakemura 1081.2Stakemura if (bus_space_peek(sc->sc_iot, sc->sc_ioh, offset, 4, &res) < 0) { 1091.2Stakemura res = 0xffffffff; 1101.2Stakemura } 1111.2Stakemura 1121.2Stakemura return (res); 1131.1Stakemura} 1141.1Stakemura 1151.1Stakemurastatic int 1161.1Stakemuravrc4172pci_match(struct device *parent, struct cfdata *match, void *aux) 1171.1Stakemura{ 1181.1Stakemura 1191.1Stakemura return (1); 1201.1Stakemura} 1211.1Stakemura 1221.1Stakemurastatic void 1231.1Stakemuravrc4172pci_attach(struct device *parent, struct device *self, void *aux) 1241.1Stakemura{ 1251.1Stakemura struct vrc4172pci_softc *sc = (struct vrc4172pci_softc *)self; 1261.1Stakemura pci_chipset_tag_t pc = &sc->sc_pc; 1271.1Stakemura struct vrip_attach_args *va = aux; 1281.1Stakemura#if NPCI > 0 1291.1Stakemura struct pcibus_attach_args pba; 1301.1Stakemura#endif 1311.1Stakemura 1321.1Stakemura sc->sc_iot = va->va_iot; 1331.1Stakemura if (bus_space_map(sc->sc_iot, va->va_addr, va->va_size, 0, 1341.1Stakemura &sc->sc_ioh)) { 1351.1Stakemura printf(": couldn't map io space\n"); 1361.1Stakemura return; 1371.1Stakemura } 1381.1Stakemura printf("\n"); 1391.1Stakemura 1401.1Stakemura pc->pc_dev = &sc->sc_dev; 1411.1Stakemura pc->pc_attach_hook = vrc4172pci_attach_hook; 1421.1Stakemura pc->pc_bus_maxdevs = vrc4172pci_bus_maxdevs; 1431.1Stakemura pc->pc_bus_devorder = vrc4172pci_bus_devorder; 1441.1Stakemura pc->pc_make_tag = vrc4172pci_make_tag; 1451.1Stakemura pc->pc_decompose_tag = vrc4172pci_decompose_tag; 1461.1Stakemura pc->pc_conf_read = vrc4172pci_conf_read; 1471.1Stakemura pc->pc_conf_write = vrc4172pci_conf_write; 1481.1Stakemura pc->pc_intr_map = vrc4172pci_intr_map; 1491.1Stakemura pc->pc_intr_string = vrc4172pci_intr_string; 1501.1Stakemura pc->pc_intr_evcnt = vrc4172pci_intr_evcnt; 1511.1Stakemura pc->pc_intr_establish = vrc4172pci_intr_establish; 1521.1Stakemura pc->pc_intr_disestablish = vrc4172pci_intr_disestablish; 1531.1Stakemura 1541.1Stakemura#if 0 1551.1Stakemura { 1561.1Stakemura int i; 1571.1Stakemura 1581.1Stakemura for (i = 0; i < 2; i++) 1591.1Stakemura printf("%s: ID_REG(0, 0, %d) = 0x%08x\n", 1601.1Stakemura sc->sc_dev.dv_xname, i, 1611.1Stakemura pci_conf_read(pc, pci_make_tag(pc, 0, 0, i), 1621.1Stakemura PCI_ID_REG)); 1631.1Stakemura } 1641.1Stakemura#endif 1651.1Stakemura 1661.1Stakemura#if NPCI > 0 1671.1Stakemura memset(&pba, 0, sizeof(pba)); 1681.1Stakemura pba.pba_busname = "pci"; 1691.1Stakemura pba.pba_iot = sc->sc_iot; 1701.1Stakemura pba.pba_memt = sc->sc_iot; 1711.1Stakemura pba.pba_dmat = &hpcmips_default_bus_dma_tag.bdt; 1721.1Stakemura pba.pba_bus = 0; 1731.1Stakemura pba.pba_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED | 1741.1Stakemura PCI_FLAGS_MRL_OKAY; 1751.1Stakemura pba.pba_pc = pc; 1761.1Stakemura 1771.1Stakemura config_found(self, &pba, vrc4172pci_print); 1781.1Stakemura#endif 1791.1Stakemura} 1801.1Stakemura 1811.1Stakemura#if NPCI > 0 1821.1Stakemurastatic int 1831.1Stakemuravrc4172pci_print(void *aux, const char *pnp) 1841.1Stakemura{ 1851.1Stakemura struct pcibus_attach_args *pba = aux; 1861.1Stakemura 1871.1Stakemura if (pnp != NULL) 1881.1Stakemura printf("%s at %s", pba->pba_busname, pnp); 1891.1Stakemura else 1901.1Stakemura printf(" bus %d", pba->pba_bus); 1911.1Stakemura 1921.1Stakemura return (UNCONF); 1931.1Stakemura} 1941.1Stakemura#endif 1951.1Stakemura 1961.1Stakemuravoid 1971.1Stakemuravrc4172pci_attach_hook(struct device *parent, struct device *self, 1981.1Stakemura struct pcibus_attach_args *pba) 1991.1Stakemura{ 2001.1Stakemura 2011.1Stakemura return; 2021.1Stakemura} 2031.1Stakemura 2041.1Stakemuraint 2051.1Stakemuravrc4172pci_bus_maxdevs(pci_chipset_tag_t pc, int busno) 2061.1Stakemura{ 2071.1Stakemura 2081.1Stakemura return (1); /* Vrc4172 has only one device */ 2091.1Stakemura} 2101.1Stakemura 2111.1Stakemuraint 2121.1Stakemuravrc4172pci_bus_devorder(pci_chipset_tag_t pc, int busno, char *devs) 2131.1Stakemura{ 2141.1Stakemura int i; 2151.1Stakemura 2161.1Stakemura *devs++ = 0; 2171.1Stakemura for (i = 1; i < 32; i++) 2181.1Stakemura *devs++ = -1; 2191.1Stakemura 2201.1Stakemura return (1); 2211.1Stakemura} 2221.1Stakemura 2231.1Stakemurapcitag_t 2241.1Stakemuravrc4172pci_make_tag(pci_chipset_tag_t pc, int bus, int device, int function) 2251.1Stakemura{ 2261.1Stakemura 2271.1Stakemura return ((bus << 16) | (device << 11) | (function << 8)); 2281.1Stakemura} 2291.1Stakemura 2301.1Stakemuravoid 2311.1Stakemuravrc4172pci_decompose_tag(pci_chipset_tag_t pc, pcitag_t tag, int *bp, int *dp, 2321.1Stakemura int *fp) 2331.1Stakemura{ 2341.1Stakemura 2351.1Stakemura if (bp != NULL) 2361.1Stakemura *bp = (tag >> 16) & 0xff; 2371.1Stakemura if (dp != NULL) 2381.1Stakemura *dp = (tag >> 11) & 0x1f; 2391.1Stakemura if (fp != NULL) 2401.1Stakemura *fp = (tag >> 8) & 0x07; 2411.1Stakemura} 2421.1Stakemura 2431.1Stakemurapcireg_t 2441.1Stakemuravrc4172pci_conf_read(pci_chipset_tag_t pc, pcitag_t tag, int reg) 2451.1Stakemura{ 2461.1Stakemura struct vrc4172pci_softc *sc = (struct vrc4172pci_softc *)pc->pc_dev; 2471.1Stakemura u_int32_t val; 2481.1Stakemura 2491.1Stakemura tag |= VRC4172PCI_CONFADDR_CONFIGEN; 2501.1Stakemura 2511.1Stakemura vrc4172pci_write(sc, VRC4172PCI_CONFAREG, tag | reg); 2521.1Stakemura val = vrc4172pci_read(sc, VRC4172PCI_CONFDREG); 2531.2Stakemura DPRINTF(("%s: conf_read: tag = 0x%08x, reg = 0x%x, val = 0x%08x\n", 2541.2Stakemura sc->sc_dev.dv_xname, (u_int32_t)tag, reg, val)); 2551.1Stakemura 2561.1Stakemura return (val); 2571.1Stakemura} 2581.1Stakemura 2591.1Stakemuravoid 2601.1Stakemuravrc4172pci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, 2611.1Stakemura pcireg_t data) 2621.1Stakemura{ 2631.1Stakemura struct vrc4172pci_softc *sc = (struct vrc4172pci_softc *)pc->pc_dev; 2641.1Stakemura 2651.2Stakemura DPRINTF(("%s: conf_write: tag = 0x%08x, reg = 0x%x, val = 0x%08x\n", 2661.2Stakemura sc->sc_dev.dv_xname, (u_int32_t)tag, reg, (u_int32_t)data)); 2671.1Stakemura tag |= VRC4172PCI_CONFADDR_CONFIGEN; 2681.1Stakemura 2691.1Stakemura vrc4172pci_write(sc, VRC4172PCI_CONFAREG, tag | reg); 2701.1Stakemura vrc4172pci_write(sc, VRC4172PCI_CONFDREG, data); 2711.1Stakemura} 2721.1Stakemura 2731.1Stakemuraint 2741.1Stakemuravrc4172pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp) 2751.1Stakemura{ 2761.1Stakemura pci_chipset_tag_t pc = pa->pa_pc; 2771.1Stakemura pcitag_t intrtag = pa->pa_intrtag; 2781.1Stakemura int bus, dev, func; 2791.1Stakemura 2801.1Stakemura pci_decompose_tag(pc, intrtag, &bus, &dev, &func); 2811.1Stakemura DPRINTF(("%s(%d, %d, %d): line = %d, pin = %d\n", pc->pc_dev->dv_xname, 2821.1Stakemura bus, dev, func, pa->pa_intrline, pa->pa_intrpin)); 2831.1Stakemura 2841.1Stakemura *ihp = CONFIG_HOOK_PCIINTR_ID(bus, dev, func); 2851.1Stakemura 2861.1Stakemura return (0); 2871.1Stakemura} 2881.1Stakemura 2891.1Stakemuraconst char * 2901.1Stakemuravrc4172pci_intr_string(pci_chipset_tag_t pc, pci_intr_handle_t ih) 2911.1Stakemura{ 2921.1Stakemura static char irqstr[sizeof("pciintr") + 16]; 2931.1Stakemura 2941.1Stakemura snprintf(irqstr, sizeof(irqstr), "pciintr %d:%d:%d", 2951.1Stakemura CONFIG_HOOK_PCIINTR_BUS((int)ih), 2961.1Stakemura CONFIG_HOOK_PCIINTR_DEVICE((int)ih), 2971.1Stakemura CONFIG_HOOK_PCIINTR_FUNCTION((int)ih)); 2981.1Stakemura 2991.1Stakemura return (irqstr); 3001.1Stakemura} 3011.1Stakemura 3021.1Stakemuraconst struct evcnt * 3031.1Stakemuravrc4172pci_intr_evcnt(pci_chipset_tag_t pc, pci_intr_handle_t ih) 3041.1Stakemura{ 3051.1Stakemura 3061.1Stakemura return (NULL); 3071.1Stakemura} 3081.1Stakemura 3091.1Stakemuravoid * 3101.1Stakemuravrc4172pci_intr_establish(pci_chipset_tag_t pc, pci_intr_handle_t ih, 3111.1Stakemura int level, int (*func)(void *), void *arg) 3121.1Stakemura{ 3131.1Stakemura 3141.1Stakemura if (ih == -1) 3151.1Stakemura return (NULL); 3161.1Stakemura DPRINTF(("vrc4172pci_intr_establish: %lx\n", ih)); 3171.1Stakemura 3181.1Stakemura return (config_hook(CONFIG_HOOK_PCIINTR, ih, CONFIG_HOOK_EXCLUSIVE, 3191.1Stakemura (int (*)(void *, int, long, void *))func, arg)); 3201.1Stakemura} 3211.1Stakemura 3221.1Stakemuravoid 3231.1Stakemuravrc4172pci_intr_disestablish(pci_chipset_tag_t pc, void *cookie) 3241.1Stakemura{ 3251.1Stakemura 3261.1Stakemura DPRINTF(("vrc4172pci_intr_disestablish: %p\n", cookie)); 3271.1Stakemura config_unhook(cookie); 3281.1Stakemura} 329