1 /* $NetBSD: i80321.c,v 1.2 2002/05/16 01:01:34 thorpej Exp $ */ 2 3 /* 4 * Copyright (c) 2002 Wasabi Systems, Inc. 5 * All rights reserved. 6 * 7 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed for the NetBSD Project by 20 * Wasabi Systems, Inc. 21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 22 * or promote products derived from this software without specific prior 23 * written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38 /* 39 * Autoconfiguration support for the Intel i80321 I/O Processor. 40 */ 41 42 #include <sys/param.h> 43 #include <sys/systm.h> 44 #include <sys/device.h> 45 46 #include <machine/bus.h> 47 48 #include <arm/xscale/i80321reg.h> 49 #include <arm/xscale/i80321var.h> 50 51 /* 52 * Statically-allocated bus_space stucture used to access the 53 * i80321's own registers. 54 */ 55 struct bus_space i80321_bs_tag; 56 57 /* 58 * There can be only one i80321, so we keep a global pointer to 59 * the softc, so board-specific code can use features of the 60 * i80321 without having to have a handle on the softc itself. 61 */ 62 struct i80321_softc *i80321_softc; 63 64 int i80321_pcibus_print(void *, const char *); 65 66 /* 67 * i80321_attach: 68 * 69 * Board-independent attach routine for the i80321. 70 */ 71 void 72 i80321_attach(struct i80321_softc *sc) 73 { 74 struct pcibus_attach_args pba; 75 pcireg_t preg; 76 77 i80321_softc = sc; 78 79 /* 80 * Slice off some useful subregion handles. 81 */ 82 83 if (bus_space_subregion(sc->sc_st, sc->sc_sh, VERDE_ATU_BASE, 84 VERDE_ATU_SIZE, &sc->sc_atu_sh)) 85 panic("%s: unable to subregion ATU registers\n", 86 sc->sc_dev.dv_xname); 87 88 /* We expect the Memory Controller to be already sliced off. */ 89 90 /* 91 * Program the Inbound windows. 92 */ 93 if (sc->sc_is_host) { 94 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 95 PCI_MAPREG_START, sc->sc_iwin[0].iwin_base_lo); 96 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 97 PCI_MAPREG_START + 0x04, sc->sc_iwin[0].iwin_base_hi); 98 } 99 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR0, 100 (0xffffffff - (sc->sc_iwin[0].iwin_size - 1)) & 0xffffffc0); 101 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IATVR0, 102 sc->sc_iwin[0].iwin_xlate); 103 104 if (sc->sc_is_host) { 105 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 106 PCI_MAPREG_START + 0x08, sc->sc_iwin[1].iwin_base_lo); 107 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 108 PCI_MAPREG_START + 0x0c, sc->sc_iwin[1].iwin_base_hi); 109 } 110 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR1, 111 (0xffffffff - (sc->sc_iwin[1].iwin_size - 1)) & 0xffffffc0); 112 /* no xlate for window 1 */ 113 114 if (sc->sc_is_host) { 115 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 116 PCI_MAPREG_START + 0x10, sc->sc_iwin[2].iwin_base_lo); 117 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 118 PCI_MAPREG_START + 0x14, sc->sc_iwin[2].iwin_base_hi); 119 } 120 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR2, 121 (0xffffffff - (sc->sc_iwin[2].iwin_size - 1)) & 0xffffffc0); 122 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IATVR2, 123 sc->sc_iwin[2].iwin_xlate); 124 125 if (sc->sc_is_host) { 126 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 127 ATU_IABAR3, sc->sc_iwin[3].iwin_base_lo); 128 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 129 ATU_IAUBAR3, sc->sc_iwin[3].iwin_base_hi); 130 } 131 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IALR3, 132 (0xffffffff - (sc->sc_iwin[3].iwin_size - 1)) & 0xffffffc0); 133 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_IATVR3, 134 sc->sc_iwin[3].iwin_xlate); 135 136 /* 137 * Mask (disable) the ATU interrupt sources. 138 * XXX May want to revisit this if we encounter 139 * XXX an application that wants it. 140 */ 141 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 142 ATU_ATUIMR, 143 ATUIMR_IMW1BU|ATUIMR_ISCEM|ATUIMR_RSCEM|ATUIMR_PST| 144 ATUIMR_DPE|ATUIMR_P_SERR_ASRT|ATUIMR_PMA|ATUIMR_PTAM| 145 ATUIMR_PTAT|ATUIMR_PMPE); 146 147 /* 148 * Program the outbound windows. 149 */ 150 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 151 ATU_OIOWTVR, sc->sc_ioout_xlate); 152 153 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 154 ATU_OMWTVR0, sc->sc_owin[0].owin_xlate_lo); 155 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 156 ATU_OUMWTVR0, sc->sc_owin[0].owin_xlate_hi); 157 158 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 159 ATU_OMWTVR1, sc->sc_owin[1].owin_xlate_lo); 160 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 161 ATU_OUMWTVR1, sc->sc_owin[1].owin_xlate_hi); 162 163 /* 164 * Set up the ATU configuration register. All we do 165 * right now is enable Outbound Windows. 166 */ 167 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_ATUCR, 168 ATUCR_OUT_EN); 169 170 /* 171 * Enable bus mastering, memory access, SERR, and parity 172 * checking on the ATU. 173 */ 174 if (sc->sc_is_host) { 175 preg = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, 176 PCI_COMMAND_STATUS_REG); 177 preg |= PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE | 178 PCI_COMMAND_PARITY_ENABLE | PCI_COMMAND_SERR_ENABLE; 179 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 180 PCI_COMMAND_STATUS_REG, preg); 181 } 182 183 /* 184 * Initialize the bus space and DMA tags and the PCI chipset tag. 185 */ 186 i80321_io_bs_init(&sc->sc_pci_iot, sc); 187 i80321_mem_bs_init(&sc->sc_pci_memt, sc); 188 i80321_pci_dma_init(&sc->sc_pci_dmat, sc); 189 i80321_pci_init(&sc->sc_pci_chipset, sc); 190 191 /* 192 * Attach the PCI bus. 193 */ 194 preg = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_PCIXSR); 195 preg = PCIXSR_BUSNO(preg); 196 if (preg == 0xff) 197 preg = 0; 198 pba.pba_busname = "pci"; 199 pba.pba_iot = &sc->sc_pci_iot; 200 pba.pba_memt = &sc->sc_pci_memt; 201 pba.pba_dmat = &sc->sc_pci_dmat; 202 pba.pba_pc = &sc->sc_pci_chipset; 203 pba.pba_bus = preg; 204 pba.pba_bridgetag = NULL; 205 pba.pba_intrswiz = 0; /* XXX what if busno != 0? */ 206 pba.pba_intrtag = 0; 207 pba.pba_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED | 208 PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY; 209 (void) config_found(&sc->sc_dev, &pba, i80321_pcibus_print); 210 } 211 212 /* 213 * i80321_pcibus_print: 214 * 215 * Autoconfiguration cfprint routine when attaching 216 * to the "pcibus" attribute. 217 */ 218 int 219 i80321_pcibus_print(void *aux, const char *pnp) 220 { 221 struct pcibus_attach_args *pba = aux; 222 223 if (pnp) 224 printf("%s at %s", pba->pba_busname, pnp); 225 226 printf(" bus %d", pba->pba_bus); 227 228 return (UNCONF); 229 } 230