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