1 /* $NetBSD: i80312.c,v 1.7 2002/01/04 22:39:47 briggs Exp $ */ 2 3 /* 4 * Copyright (c) 2001 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 i80312 Companion I/O chip. 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/i80312reg.h> 49 #include <arm/xscale/i80312var.h> 50 51 #include <dev/pci/ppbreg.h> 52 53 /* 54 * Statically-allocated bus_space stucture used to access the 55 * i80312's own registers. 56 */ 57 struct bus_space i80312_bs_tag; 58 59 /* 60 * There can be only one i80312, so we keep a global pointer to 61 * the softc, so board-specific code can use features of the 62 * i80312 without having to have a handle on the softc itself. 63 */ 64 struct i80312_softc *i80312_softc; 65 66 int i80312_pcibus_print(void *, const char *); 67 68 /* 69 * i80312_attach: 70 * 71 * Board-independent attach routine for the i80312. 72 */ 73 void 74 i80312_attach(struct i80312_softc *sc) 75 { 76 struct pcibus_attach_args pba; 77 uint32_t atucr; 78 pcireg_t preg; 79 80 /* 81 * Slice off some useful subregion handles. 82 */ 83 84 if (bus_space_subregion(sc->sc_st, sc->sc_sh, I80312_PPB_BASE, 85 I80312_PPB_SIZE, &sc->sc_ppb_sh)) 86 panic("%s: unable to subregion PPB registers\n", 87 sc->sc_dev.dv_xname); 88 89 if (bus_space_subregion(sc->sc_st, sc->sc_sh, I80312_ATU_BASE, 90 I80312_ATU_SIZE, &sc->sc_atu_sh)) 91 panic("%s: unable to subregion ATU registers\n", 92 sc->sc_dev.dv_xname); 93 94 if (bus_space_subregion(sc->sc_st, sc->sc_sh, I80312_INTC_BASE, 95 I80312_INTC_SIZE, &sc->sc_intc_sh)) 96 panic("%s: unable to subregion INTC registers\n", 97 sc->sc_dev.dv_xname); 98 99 /* We expect the Memory Controller to be already sliced off. */ 100 101 /* 102 * Disable the private space decode. 103 */ 104 sc->sc_sder = bus_space_read_1(sc->sc_st, sc->sc_ppb_sh, 105 I80312_PPB_SDER); 106 sc->sc_sder &= ~PPB_SDER_PMSE; 107 bus_space_write_1(sc->sc_st, sc->sc_ppb_sh, 108 I80312_PPB_SDER, sc->sc_sder); 109 110 /* 111 * Program the Secondary ID Select register. 112 */ 113 bus_space_write_2(sc->sc_st, sc->sc_ppb_sh, 114 I80312_PPB_SISR, sc->sc_sisr); 115 116 /* 117 * Program the private secondary bus spaces. 118 */ 119 if (sc->sc_privmem_size && sc->sc_privio_size) { 120 bus_space_write_1(sc->sc_st, sc->sc_ppb_sh, I80312_PPB_SIOBR, 121 (sc->sc_privio_base >> 12) << 4); 122 bus_space_write_1(sc->sc_st, sc->sc_ppb_sh, I80312_PPB_SIOLR, 123 ((sc->sc_privio_base + sc->sc_privio_size - 1) 124 >> 12) << 4); 125 126 bus_space_write_2(sc->sc_st, sc->sc_ppb_sh, I80312_PPB_SMBR, 127 (sc->sc_privmem_base >> 20) << 4); 128 bus_space_write_2(sc->sc_st, sc->sc_ppb_sh, I80312_PPB_SMLR, 129 ((sc->sc_privmem_base + sc->sc_privmem_size - 1) 130 >> 20) << 4); 131 132 sc->sc_sder |= PPB_SDER_PMSE; 133 bus_space_write_1(sc->sc_st, sc->sc_ppb_sh, I80312_PPB_SDER, 134 sc->sc_sder); 135 } else if (sc->sc_privmem_size || sc->sc_privio_size) { 136 printf("%s: WARNING: privmem_size 0x%08x privio_size 0x%08x\n", 137 sc->sc_dev.dv_xname, sc->sc_privmem_size, 138 sc->sc_privio_size); 139 printf("%s: private bus spaces not enabled\n", 140 sc->sc_dev.dv_xname); 141 } 142 143 /* 144 * Program the Primary Inbound window. 145 */ 146 if (sc->sc_is_host) 147 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 148 PCI_MAPREG_START, sc->sc_pin_base); 149 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 150 I80312_ATU_PIAL, ATU_LIMIT(sc->sc_pin_size)); 151 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 152 I80312_ATU_PIATV, sc->sc_pin_xlate); 153 154 /* 155 * Program the Secondary Inbound window. 156 */ 157 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 158 I80312_ATU_SIAM, sc->sc_sin_base); 159 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 160 I80312_ATU_SIAL, ATU_LIMIT(sc->sc_sin_size)); 161 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 162 I80312_ATU_SIATV, sc->sc_sin_xlate); 163 164 /* 165 * Mask (disable) the ATU interrupt sources. 166 * XXX May want to revisit this if we encounter 167 * XXX an application that wants it. 168 */ 169 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 170 I80312_ATU_PAIM, 171 ATU_AIM_MPEIM | ATU_AIM_TATIM | ATU_AIM_TAMIM | 172 ATU_AIM_MAIM | ATU_AIM_SAIM | ATU_AIM_DPEIM | 173 ATU_AIM_PSTIM); 174 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 175 I80312_ATU_SAIM, 176 ATU_AIM_MPEIM | ATU_AIM_TATIM | ATU_AIM_TAMIM | 177 ATU_AIM_MAIM | ATU_AIM_SAIM | ATU_AIM_DPEIM); 178 179 /* 180 * Clear: 181 * 182 * Primary Outbound ATU Enable 183 * Secondary Outbound ATU Enable 184 * Secondary Direct Addressing Select 185 * Direct Addressing Enable 186 */ 187 atucr = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, I80312_ATU_ACR); 188 atucr &= ~(ATU_ACR_POAE|ATU_ACR_SOAE|ATU_ACR_SDAS|ATU_ACR_DAE); 189 190 /* 191 * Program the Primary Outbound windows. 192 */ 193 if (sc->sc_pmemout_size) 194 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 195 I80312_ATU_POMWV, sc->sc_pmemout_base); 196 if (sc->sc_pioout_size) 197 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 198 I80312_ATU_POIOWV, sc->sc_pioout_base); 199 if (sc->sc_pmemout_size || sc->sc_pioout_size) 200 atucr |= ATU_ACR_POAE; 201 202 /* 203 * Program the Secondary Outbound windows. 204 */ 205 if (sc->sc_smemout_size) 206 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 207 I80312_ATU_SOMWV, sc->sc_smemout_base); 208 if (sc->sc_sioout_size) 209 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 210 I80312_ATU_SOIOWV, sc->sc_sioout_base); 211 if (sc->sc_smemout_size || sc->sc_sioout_size) 212 atucr |= ATU_ACR_SOAE; 213 214 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, I80312_ATU_ACR, atucr); 215 216 /* 217 * Enable bus mastering, memory access, SERR, and parity 218 * checking on the ATU. 219 */ 220 if (sc->sc_is_host) { 221 preg = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, 222 PCI_COMMAND_STATUS_REG); 223 preg |= PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE | 224 PCI_COMMAND_PARITY_ENABLE | PCI_COMMAND_SERR_ENABLE; 225 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 226 PCI_COMMAND_STATUS_REG, preg); 227 } 228 preg = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, 229 I80312_ATU_SACS); 230 preg |= PCI_COMMAND_MEM_ENABLE | PCI_COMMAND_MASTER_ENABLE | 231 PCI_COMMAND_PARITY_ENABLE | PCI_COMMAND_SERR_ENABLE; 232 bus_space_write_4(sc->sc_st, sc->sc_atu_sh, 233 I80312_ATU_SACS, preg); 234 235 /* 236 * Configure the bridge. If we're a host, set the primary 237 * bus to bus #0 and the secondary bus to bus #1. We also 238 * set the PPB's subordinate bus # to 1. It will be fixed 239 * up later when we fully configure the bus. 240 * 241 * If we're a slave, just use the bus #'s that the host 242 * provides. 243 */ 244 if (sc->sc_is_host) { 245 bus_space_write_4(sc->sc_st, sc->sc_ppb_sh, 246 PPB_REG_BUSINFO, 247 (0 << PCI_BRIDGE_BUS_PRIMARY_SHIFT) | 248 (1 << PCI_BRIDGE_BUS_SECONDARY_SHIFT) | 249 (1 << PCI_BRIDGE_BUS_SUBORDINATE_SHIFT)); 250 } 251 252 /* 253 * Initialize the bus space and DMA tags and the PCI chipset tag. 254 */ 255 i80312_io_bs_init(&sc->sc_pci_iot, sc); 256 i80312_mem_bs_init(&sc->sc_pci_memt, sc); 257 i80312_pci_dma_init(&sc->sc_pci_dmat, sc); 258 i80312_pci_init(&sc->sc_pci_chipset, sc); 259 260 /* 261 * Attach the PCI bus. 262 * 263 * Note: We only probe the Secondary PCI bus, since that 264 * is the only bus on which we can have a private device 265 * space. 266 */ 267 preg = bus_space_read_4(sc->sc_st, sc->sc_ppb_sh, PPB_REG_BUSINFO); 268 pba.pba_busname = "pci"; 269 pba.pba_iot = &sc->sc_pci_iot; 270 pba.pba_memt = &sc->sc_pci_memt; 271 pba.pba_dmat = &sc->sc_pci_dmat; 272 pba.pba_pc = &sc->sc_pci_chipset; 273 pba.pba_bus = PPB_BUSINFO_SECONDARY(preg); 274 pba.pba_intrswiz = 3; 275 pba.pba_intrtag = 0; 276 /* XXX MRL/MRM/MWI seem to have problems, at the moment. */ 277 pba.pba_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED /* | 278 PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY */; 279 (void) config_found(&sc->sc_dev, &pba, i80312_pcibus_print); 280 } 281 282 /* 283 * i80312_pcibus_print: 284 * 285 * Autoconfiguration cfprint routine when attaching 286 * to the "pcibus" attribute. 287 */ 288 int 289 i80312_pcibus_print(void *aux, const char *pnp) 290 { 291 struct pcibus_attach_args *pba = aux; 292 293 if (pnp) 294 printf("%s at %s", pba->pba_busname, pnp); 295 296 printf(" bus %d", pba->pba_bus); 297 298 return (UNCONF); 299 } 300