1 /* $NetBSD: ixp12x0.c,v 1.12 2003/09/15 05:11:31 ichiro Exp $ */ 2 /* 3 * Copyright (c) 2002, 2003 4 * Ichiro FUKUHARA <ichiro@ichiro.org>. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Ichiro FUKUHARA. 18 * 4. The name of the company nor the name of the author may be used to 19 * endorse or promote products derived from this software without specific 20 * prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY ICHIRO FUKUHARA ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL ICHIRO FUKUHARA OR THE VOICES IN HIS HEAD BE LIABLE FOR 26 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 */ 34 35 #include <sys/cdefs.h> 36 __KERNEL_RCSID(0, "$NetBSD: ixp12x0.c,v 1.12 2003/09/15 05:11:31 ichiro Exp $"); 37 38 #include <sys/param.h> 39 #include <sys/systm.h> 40 #include <sys/device.h> 41 #include <uvm/uvm.h> 42 43 #include <machine/bus.h> 44 45 #include <arm/ixp12x0/ixp12x0reg.h> 46 #include <arm/ixp12x0/ixp12x0var.h> 47 #include <arm/ixp12x0/ixp12x0_pcireg.h> 48 49 int ixp12x0_pcibus_print(void *, const char *); 50 51 static struct ixp12x0_softc *ixp12x0_softc; 52 53 void 54 ixp12x0_attach(sc) 55 struct ixp12x0_softc *sc; 56 { 57 struct pcibus_attach_args pba; 58 pcireg_t reg; 59 60 ixp12x0_softc = sc; 61 62 printf("\n"); 63 64 sc->sc_iot = &ixp12x0_bs_tag; 65 66 /* 67 * Mapping for PCI Configuration Spase Registers 68 */ 69 if (bus_space_map(sc->sc_iot, IXP12X0_PCI_HWBASE, IXP12X0_PCI_SIZE, 70 0, &sc->sc_pci_ioh)) 71 panic("%s: unable to map PCI registers", sc->sc_dev.dv_xname); 72 if (bus_space_map(sc->sc_iot, IXP12X0_PCI_TYPE0_HWBASE, 73 IXP12X0_PCI_TYPE0_SIZE, 0, &sc->sc_conf0_ioh)) 74 panic("%s: unable to map PCI Configutation 0\n", 75 sc->sc_dev.dv_xname); 76 if (bus_space_map(sc->sc_iot, IXP12X0_PCI_TYPE1_HWBASE, 77 IXP12X0_PCI_TYPE0_SIZE, 1, &sc->sc_conf1_ioh)) 78 panic("%s: unable to map PCI Configutation 1\n", 79 sc->sc_dev.dv_xname); 80 81 /* 82 * PCI bus reset 83 */ 84 /* disable PCI command */ 85 bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh, 86 PCI_COMMAND_STATUS_REG, 0xffff0000); 87 /* XXX assert PCI reset Mode */ 88 reg = bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, 89 SA_CONTROL) &~ SA_CONTROL_PNR; 90 bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh, 91 SA_CONTROL, reg); 92 DELAY(10); 93 94 /* XXX Disable door bell and outbound interrupt */ 95 bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh, 96 PCI_CAP_PTR, 0xc); 97 /* Disable door bell int to PCI */ 98 bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh, 99 DBELL_PCI_MASK, 0x0); 100 /* Disable door bell int to SA-core */ 101 bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh, 102 DBELL_SA_MASK, 0x0); 103 104 /* We setup a 1:1 memory map of bus<->physical addresses */ 105 bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh, 106 PCI_ADDR_EXT, 107 PCI_ADDR_EXT_PMSA(IXP12X0_PCI_MEM_HWBASE)); 108 109 /* XXX Negate PCI reset */ 110 reg = bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, 111 SA_CONTROL) | SA_CONTROL_PNR; 112 bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh, 113 SA_CONTROL, reg); 114 DELAY(10); 115 /* 116 * specify window size of memory access and SDRAM. 117 */ 118 bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh, IXP_PCI_MEM_BAR, 119 IXP1200_PCI_MEM_BAR & IXP_PCI_MEM_BAR_MASK); 120 121 bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh, IXP_PCI_IO_BAR, 122 IXP1200_PCI_IO_BAR & IXP_PCI_IO_BAR_MASK); 123 124 bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh, IXP_PCI_DRAM_BAR, 125 IXP1200_PCI_DRAM_BAR & IXP_PCI_DRAM_BAR_MASK); 126 127 bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh, 128 CSR_BASE_ADDR_MASK, CSR_BASE_ADDR_MASK_1M); 129 bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh, 130 DRAM_BASE_ADDR_MASK, DRAM_BASE_ADDR_MASK_256MB); 131 132 #ifdef PCI_DEBUG 133 printf("IXP_PCI_MEM_BAR = 0x%08x\nIXP_PCI_IO_BAR = 0x%08x\nIXP_PCI_DRAM_BAR = 0x%08x\nPCI_ADDR_EXT = 0x%08x\nCSR_BASE_ADDR_MASK = 0x%08x\nDRAM_BASE_ADDR_MASK = 0x%08x\n", 134 bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, IXP_PCI_MEM_BAR), 135 bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, IXP_PCI_IO_BAR), 136 bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, IXP_PCI_DRAM_BAR), 137 bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, PCI_ADDR_EXT), 138 bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, CSR_BASE_ADDR_MASK), 139 bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, DRAM_BASE_ADDR_MASK)); 140 #endif 141 /* Initialize complete */ 142 reg = bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, 143 SA_CONTROL) | 0x1; 144 bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh, 145 SA_CONTROL, reg); 146 #ifdef PCI_DEBUG 147 printf("SA_CONTROL = 0x%08x\n", 148 bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, SA_CONTROL)); 149 #endif 150 /* 151 * Enable bus mastering and I/O,memory access 152 */ 153 /* host only */ 154 reg = bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, 155 PCI_COMMAND_STATUS_REG) | 156 PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE | 157 PCI_COMMAND_PARITY_ENABLE | PCI_COMMAND_SERR_ENABLE | 158 PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_INVALIDATE_ENABLE; 159 bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh, 160 PCI_COMMAND_STATUS_REG, reg); 161 #ifdef PCI_DEBUG 162 printf("PCI_COMMAND_STATUS_REG = 0x%08x\n", 163 bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, PCI_COMMAND_STATUS_REG)); 164 #endif 165 /* 166 * Initialize the PCI chipset tag. 167 */ 168 ixp12x0_pci_init(&sc->ia_pci_chipset, sc); 169 170 /* 171 * Initialize the DMA tags. 172 */ 173 ixp12x0_pci_dma_init(sc); 174 175 /* 176 * Attach the PCI bus. 177 */ 178 pba.pba_busname = "pci"; 179 pba.pba_pc = &sc->ia_pci_chipset; 180 pba.pba_iot = &ixp12x0_bs_tag; 181 pba.pba_memt = &ixp12x0_bs_tag; 182 pba.pba_dmat = &sc->ia_pci_dmat; 183 pba.pba_dmat64 = NULL; 184 pba.pba_bus = 0; /* bus number = 0 */ 185 pba.pba_intrswiz = 0; /* XXX */ 186 pba.pba_intrtag = 0; 187 pba.pba_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED | 188 PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY; 189 (void) config_found(&sc->sc_dev, &pba, ixp12x0_pcibus_print); 190 } 191 192 int 193 ixp12x0_pcibus_print(void *aux, const char *pnp) 194 { 195 struct pcibus_attach_args *pba = aux; 196 197 if (pnp) 198 aprint_normal("%s at %s", pba->pba_busname, pnp); 199 200 aprint_normal(" bus %d", pba->pba_bus); 201 202 return (UNCONF); 203 } 204 205 void 206 ixp12x0_reset(void) 207 { 208 bus_space_write_4(ixp12x0_softc->sc_iot, ixp12x0_softc->sc_pci_ioh, 209 IXPPCI_IXP1200_RESET, RESET_FULL); 210 } 211