ixp12x0.c revision 1.6 1 /* $NetBSD: ixp12x0.c,v 1.6 2003/02/17 20:51:52 ichiro Exp $ */
2 /*
3 * Copyright (c) 2002, 2003
4 * Ichiro FUKUHARA <ichiro (at) 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/param.h>
36 #include <sys/systm.h>
37 #include <sys/device.h>
38 #include <uvm/uvm.h>
39
40 #include <machine/bus.h>
41
42 #include <arm/ixp12x0/ixp12x0reg.h>
43 #include <arm/ixp12x0/ixp12x0var.h>
44 #include <arm/ixp12x0/ixp12x0_pcireg.h>
45
46 int ixp12x0_pcibus_print(void *, const char *);
47
48 static struct ixp12x0_softc *ixp12x0_softc;
49
50 void
51 ixp12x0_attach(sc)
52 struct ixp12x0_softc *sc;
53 {
54 struct pcibus_attach_args pba;
55 pcireg_t reg;
56
57 ixp12x0_softc = sc;
58
59 printf("\n");
60 /*
61 * Subregion for PCI Configuration Spase Registers
62 */
63 if (bus_space_subregion(sc->sc_iot, sc->sc_ioh,
64 IXP12X0_PCI_VBASE - IXP12X0_IO_VBASE,
65 IXP12X0_PCI_SIZE, &sc->sc_pci_ioh))
66 panic("%s: unable to subregion PCI registers",
67 sc->sc_dev.dv_xname);
68
69 if (bus_space_subregion(sc->sc_iot, sc->sc_ioh,
70 IXP12X0_PCI_TYPE0_VBASE - IXP12X0_IO_VBASE,
71 IXP12X0_PCI_TYPE0_SIZE, &sc->sc_conf0_ioh))
72 panic("%s: unable to subregion PCI Configutation 0\n",
73 sc->sc_dev.dv_xname);
74
75 if (bus_space_subregion(sc->sc_iot, sc->sc_ioh,
76 IXP12X0_PCI_TYPE1_VBASE - IXP12X0_IO_VBASE,
77 IXP12X0_PCI_TYPE1_SIZE, &sc->sc_conf1_ioh))
78 panic("%s: unable to subregion PCI Configutation 1\n",
79 sc->sc_dev.dv_xname);
80 /*
81 * PCI bus reset
82 */
83 /* disable PCI command */
84 bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
85 PCI_COMMAND_STATUS_REG, 0xffff0000);
86 /* XXX assert PCI reset Mode */
87 reg = bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh,
88 SA_CONTROL) &~ SA_CONTROL_PNR;
89 bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
90 SA_CONTROL, reg);
91 DELAY(10);
92
93 /* XXX Disable door bell and outbound interrupt */
94 bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
95 PCI_CAP_PTR, 0xc);
96 /* Disable door bell int to PCI */
97 bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
98 DBELL_PCI_MASK, 0x0);
99 /* Disable door bell int to SA-core */
100 bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
101 DBELL_SA_MASK, 0x0);
102
103 /* We setup a 1:1 memory map of bus<->physical addresses */
104 bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
105 PCI_ADDR_EXT,
106 PCI_ADDR_EXT_PMSA(IXP12X0_PCI_MEM_HWBASE));
107
108 /* XXX Negate PCI reset */
109 reg = bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh,
110 SA_CONTROL) | SA_CONTROL_PNR;
111 bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
112 SA_CONTROL, reg);
113 DELAY(10);
114 /*
115 * specify window size of memory access and SDRAM.
116 */
117 bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh, IXP_PCI_MEM_BAR,
118 IXP1200_PCI_MEM_BAR & IXP_PCI_MEM_BAR_MASK);
119
120 bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh, IXP_PCI_IO_BAR,
121 IXP1200_PCI_IO_BAR & IXP_PCI_IO_BAR_MASK);
122
123 bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh, IXP_PCI_DRAM_BAR,
124 IXP1200_PCI_DRAM_BAR & IXP_PCI_DRAM_BAR_MASK);
125
126 bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
127 CSR_BASE_ADDR_MASK, CSR_BASE_ADDR_MASK_1M);
128 bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
129 DRAM_BASE_ADDR_MASK, DRAM_BASE_ADDR_MASK_256MB);
130
131 #ifdef PCI_DEBUG
132 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",
133 bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, IXP_PCI_MEM_BAR),
134 bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, IXP_PCI_IO_BAR),
135 bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, IXP_PCI_DRAM_BAR),
136 bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, PCI_ADDR_EXT),
137 bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, CSR_BASE_ADDR_MASK),
138 bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, DRAM_BASE_ADDR_MASK));
139 #endif
140 /* Initialize complete */
141 reg = bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh,
142 SA_CONTROL) | 0x1;
143 bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
144 SA_CONTROL, reg);
145 #if DEBUG
146 printf("SA_CONTROL = 0x%08x\n",
147 bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, SA_CONTROL));
148 #endif
149 /*
150 * Enable bus mastering and I/O,memory access
151 */
152 /* host only */
153 reg = bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh,
154 PCI_COMMAND_STATUS_REG) |
155 PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE |
156 PCI_COMMAND_PARITY_ENABLE | PCI_COMMAND_SERR_ENABLE |
157 PCI_COMMAND_MASTER_ENABLE | PCI_COMMAND_INVALIDATE_ENABLE;
158 bus_space_write_4(sc->sc_iot, sc->sc_pci_ioh,
159 PCI_COMMAND_STATUS_REG, reg);
160 #ifdef PCI_DEBUG
161 printf("PCI_COMMAND_STATUS_REG = 0x%08x\n",
162 bus_space_read_4(sc->sc_iot, sc->sc_pci_ioh, PCI_COMMAND_STATUS_REG));
163 #endif
164 /*
165 * Initialize the bus space and DMA tags and the PCI chipset tag.
166 */
167 ixp12x0_io_bs_init(&sc->ia_pci_iot, sc);
168 ixp12x0_mem_bs_init(&sc->ia_pci_memt, sc);
169 ixp12x0_pci_init(&sc->ia_pci_chipset, sc);
170
171 /*
172 * Initialize the DMA tags.
173 */
174 ixp12x0_pci_dma_init(sc);
175
176 /*
177 * Attach the PCI bus.
178 */
179 pba.pba_busname = "pci";
180 pba.pba_pc = &sc->ia_pci_chipset;
181 pba.pba_iot = &sc->ia_pci_iot;
182 pba.pba_memt = &sc->ia_pci_memt;
183 pba.pba_dmat = &sc->ia_pci_dmat;
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 /*
206 * IXP12x0 specific I/O registers mapping table
207 */
208 static struct pmap_ent map_tbl_ixp12x0[] = {
209 { "StrongARM System and Peripheral Registers",
210 IXP12X0_SYS_VBASE, IXP12X0_SYS_HWBASE,
211 IXP12X0_SYS_SIZE,
212 VM_PROT_READ|VM_PROT_WRITE,
213 PTE_NOCACHE, },
214
215 { "PCI Registers Accessible Through StrongARM Core",
216 IXP12X0_PCI_VBASE, IXP12X0_PCI_HWBASE,
217 IXP12X0_PCI_SIZE,
218 VM_PROT_READ|VM_PROT_WRITE,
219 PTE_NOCACHE, },
220
221 { "PCI Registers Accessible Through I/O Cycle Access",
222 IXP12X0_PCI_IO_VBASE, IXP12X0_PCI_IO_HWBASE,
223 IXP12X0_PCI_IO_SIZE,
224 VM_PROT_READ|VM_PROT_WRITE,
225 PTE_NOCACHE, },
226
227 { "PCI Registers Accessible Through Memory Cycle Access",
228 IXP12X0_PCI_MEM_VBASE, IXP12X0_PCI_MEM_HWBASE,
229 IXP12X0_PCI_MEM_SIZE,
230 VM_PROT_READ|VM_PROT_WRITE,
231 PTE_NOCACHE, },
232
233 { "PCI Type0 Configuration Space",
234 IXP12X0_PCI_TYPE0_VBASE, IXP12X0_PCI_TYPE0_HWBASE,
235 IXP12X0_PCI_TYPE0_SIZE,
236 VM_PROT_READ|VM_PROT_WRITE,
237 PTE_NOCACHE, },
238
239 { "PCI Type1 Configuration Space",
240 IXP12X0_PCI_TYPE1_VBASE, IXP12X0_PCI_TYPE1_HWBASE,
241 IXP12X0_PCI_TYPE1_SIZE,
242 VM_PROT_READ|VM_PROT_WRITE,
243 PTE_NOCACHE, },
244
245 { NULL, 0, 0, 0, 0, 0 },
246 };
247
248 /*
249 * mapping virtual memories
250 */
251 void
252 ixp12x0_pmap_chunk_table(vaddr_t l1pt, struct pmap_ent* m)
253 {
254 int loop;
255
256 loop = 0;
257 while (m[loop].msg) {
258 printf("mapping %s...\n", m[loop].msg);
259 pmap_map_chunk(l1pt, m[loop].va, m[loop].pa,
260 m[loop].sz, m[loop].prot, m[loop].cache);
261 ++loop;
262 }
263 }
264
265 /*
266 * mapping I/O registers
267 */
268 void
269 ixp12x0_pmap_io_reg(vaddr_t l1pt)
270 {
271 ixp12x0_pmap_chunk_table(l1pt, map_tbl_ixp12x0);
272 }
273
274 void
275 ixp12x0_reset(void)
276 {
277 bus_space_write_4(ixp12x0_softc->sc_iot, ixp12x0_softc->sc_pci_ioh,
278 IXPPCI_IXP1200_RESET, RESET_FULL);
279 }
280