footbridge.c revision 1.2.6.4 1 1.2.6.4 nathanw /* $NetBSD: footbridge.c,v 1.2.6.4 2002/02/28 04:07:27 nathanw Exp $ */
2 1.2.6.2 nathanw
3 1.2.6.2 nathanw /*
4 1.2.6.2 nathanw * Copyright (c) 1997,1998 Mark Brinicombe.
5 1.2.6.2 nathanw * Copyright (c) 1997,1998 Causality Limited
6 1.2.6.2 nathanw * All rights reserved.
7 1.2.6.2 nathanw *
8 1.2.6.2 nathanw * Redistribution and use in source and binary forms, with or without
9 1.2.6.2 nathanw * modification, are permitted provided that the following conditions
10 1.2.6.2 nathanw * are met:
11 1.2.6.2 nathanw * 1. Redistributions of source code must retain the above copyright
12 1.2.6.2 nathanw * notice, this list of conditions and the following disclaimer.
13 1.2.6.2 nathanw * 2. Redistributions in binary form must reproduce the above copyright
14 1.2.6.2 nathanw * notice, this list of conditions and the following disclaimer in the
15 1.2.6.2 nathanw * documentation and/or other materials provided with the distribution.
16 1.2.6.2 nathanw * 3. All advertising materials mentioning features or use of this software
17 1.2.6.2 nathanw * must display the following acknowledgement:
18 1.2.6.2 nathanw * This product includes software developed by Mark Brinicombe
19 1.2.6.2 nathanw * for the NetBSD Project.
20 1.2.6.2 nathanw * 4. The name of the company nor the name of the author may be used to
21 1.2.6.2 nathanw * endorse or promote products derived from this software without specific
22 1.2.6.2 nathanw * prior written permission.
23 1.2.6.2 nathanw *
24 1.2.6.2 nathanw * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
25 1.2.6.2 nathanw * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
26 1.2.6.2 nathanw * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 1.2.6.2 nathanw * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
28 1.2.6.2 nathanw * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 1.2.6.2 nathanw * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 1.2.6.2 nathanw * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 1.2.6.2 nathanw * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 1.2.6.2 nathanw * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 1.2.6.2 nathanw * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 1.2.6.2 nathanw * SUCH DAMAGE.
35 1.2.6.2 nathanw */
36 1.2.6.2 nathanw
37 1.2.6.2 nathanw #include "opt_cputypes.h"
38 1.2.6.2 nathanw
39 1.2.6.2 nathanw #include <sys/param.h>
40 1.2.6.2 nathanw #include <sys/systm.h>
41 1.2.6.2 nathanw #include <sys/kernel.h>
42 1.2.6.2 nathanw #include <sys/conf.h>
43 1.2.6.2 nathanw #include <sys/malloc.h>
44 1.2.6.2 nathanw #include <sys/device.h>
45 1.2.6.2 nathanw
46 1.2.6.2 nathanw #include <dev/pci/pcivar.h>
47 1.2.6.2 nathanw #define _ARM32_BUS_DMA_PRIVATE
48 1.2.6.2 nathanw #include <machine/bus.h>
49 1.2.6.2 nathanw #include <machine/intr.h>
50 1.2.6.2 nathanw
51 1.2.6.2 nathanw #include <arm/cpufunc.h>
52 1.2.6.2 nathanw
53 1.2.6.2 nathanw #include <arm/footbridge/footbridgevar.h>
54 1.2.6.2 nathanw #include <arm/footbridge/dc21285reg.h>
55 1.2.6.2 nathanw #include <arm/footbridge/dc21285mem.h>
56 1.2.6.3 nathanw #include <arm/footbridge/footbridge.h>
57 1.2.6.3 nathanw
58 1.2.6.2 nathanw /*
59 1.2.6.2 nathanw * DC21285 'Footbridge' device
60 1.2.6.2 nathanw *
61 1.2.6.2 nathanw * This probes and attaches the footbridge device
62 1.2.6.2 nathanw * It then configures any children
63 1.2.6.2 nathanw */
64 1.2.6.2 nathanw
65 1.2.6.2 nathanw /* Declare prototypes */
66 1.2.6.2 nathanw
67 1.2.6.2 nathanw static int footbridge_match __P((struct device *parent, struct cfdata *cf,
68 1.2.6.2 nathanw void *aux));
69 1.2.6.2 nathanw static void footbridge_attach __P((struct device *parent, struct device *self,
70 1.2.6.2 nathanw void *aux));
71 1.2.6.2 nathanw static int footbridge_print __P((void *aux, const char *pnp));
72 1.2.6.2 nathanw static int footbridge_intr __P((void *arg));
73 1.2.6.2 nathanw
74 1.2.6.2 nathanw /* Driver and attach structures */
75 1.2.6.2 nathanw struct cfattach footbridge_ca = {
76 1.2.6.2 nathanw sizeof(struct footbridge_softc), footbridge_match, footbridge_attach
77 1.2.6.2 nathanw };
78 1.2.6.2 nathanw
79 1.2.6.2 nathanw /* Various bus space tags */
80 1.2.6.2 nathanw extern struct bus_space footbridge_bs_tag;
81 1.2.6.2 nathanw extern void footbridge_create_io_bs_tag(bus_space_tag_t t, void *cookie);
82 1.2.6.2 nathanw extern void footbridge_create_mem_bs_tag(bus_space_tag_t t, void *cookie);
83 1.2.6.2 nathanw struct bus_space footbridge_csr_tag;
84 1.2.6.2 nathanw struct bus_space footbridge_pci_io_bs_tag;
85 1.2.6.2 nathanw struct bus_space footbridge_pci_mem_bs_tag;
86 1.2.6.2 nathanw extern struct arm32_pci_chipset footbridge_pci_chipset;
87 1.2.6.2 nathanw extern struct arm32_bus_dma_tag footbridge_pci_bus_dma_tag;
88 1.2.6.2 nathanw
89 1.2.6.2 nathanw /* Used in footbridge_clock.c */
90 1.2.6.2 nathanw struct footbridge_softc *clock_sc;
91 1.2.6.2 nathanw
92 1.2.6.2 nathanw /* Set to non-zero to enable verbose reporting of footbridge system ints */
93 1.2.6.2 nathanw int footbridge_intr_report = 0;
94 1.2.6.2 nathanw
95 1.2.6.2 nathanw int footbridge_found;
96 1.2.6.2 nathanw
97 1.2.6.2 nathanw void
98 1.2.6.2 nathanw footbridge_pci_bs_tag_init(void)
99 1.2.6.2 nathanw {
100 1.2.6.2 nathanw /* Set up the PCI bus tags */
101 1.2.6.2 nathanw footbridge_create_io_bs_tag(&footbridge_pci_io_bs_tag,
102 1.2.6.2 nathanw (void *)DC21285_PCI_IO_VBASE);
103 1.2.6.2 nathanw footbridge_create_mem_bs_tag(&footbridge_pci_mem_bs_tag,
104 1.2.6.2 nathanw (void *)DC21285_PCI_MEM_BASE);
105 1.2.6.2 nathanw }
106 1.2.6.2 nathanw
107 1.2.6.2 nathanw /*
108 1.2.6.2 nathanw * int footbridgeprint(void *aux, const char *name)
109 1.2.6.2 nathanw *
110 1.2.6.2 nathanw * print configuration info for children
111 1.2.6.2 nathanw */
112 1.2.6.2 nathanw
113 1.2.6.2 nathanw static int
114 1.2.6.2 nathanw footbridge_print(aux, pnp)
115 1.2.6.2 nathanw void *aux;
116 1.2.6.2 nathanw const char *pnp;
117 1.2.6.2 nathanw {
118 1.2.6.2 nathanw union footbridge_attach_args *fba = aux;
119 1.2.6.2 nathanw
120 1.2.6.2 nathanw if (pnp)
121 1.2.6.2 nathanw printf("%s at %s", fba->fba_name, pnp);
122 1.2.6.2 nathanw if (strcmp(fba->fba_name, "pci") == 0)
123 1.2.6.2 nathanw printf(" bus %d", fba->fba_pba.pba_bus);
124 1.2.6.2 nathanw return(UNCONF);
125 1.2.6.2 nathanw }
126 1.2.6.2 nathanw
127 1.2.6.2 nathanw /*
128 1.2.6.2 nathanw * int footbridge_match(struct device *parent, struct cfdata *cf, void *aux)
129 1.2.6.2 nathanw *
130 1.2.6.2 nathanw * Just return ok for this if it is device 0
131 1.2.6.2 nathanw */
132 1.2.6.2 nathanw
133 1.2.6.2 nathanw static int
134 1.2.6.2 nathanw footbridge_match(parent, cf, aux)
135 1.2.6.2 nathanw struct device *parent;
136 1.2.6.2 nathanw struct cfdata *cf;
137 1.2.6.2 nathanw void *aux;
138 1.2.6.2 nathanw {
139 1.2.6.2 nathanw if (footbridge_found)
140 1.2.6.2 nathanw return(0);
141 1.2.6.2 nathanw return(1);
142 1.2.6.2 nathanw }
143 1.2.6.2 nathanw
144 1.2.6.2 nathanw
145 1.2.6.2 nathanw /*
146 1.2.6.2 nathanw * void footbridge_attach(struct device *parent, struct device *dev, void *aux)
147 1.2.6.2 nathanw *
148 1.2.6.2 nathanw */
149 1.2.6.2 nathanw
150 1.2.6.2 nathanw static void
151 1.2.6.2 nathanw footbridge_attach(parent, self, aux)
152 1.2.6.2 nathanw struct device *parent;
153 1.2.6.2 nathanw struct device *self;
154 1.2.6.2 nathanw void *aux;
155 1.2.6.2 nathanw {
156 1.2.6.2 nathanw struct footbridge_softc *sc = (struct footbridge_softc *)self;
157 1.2.6.2 nathanw union footbridge_attach_args fba;
158 1.2.6.2 nathanw int vendor, device, rev;
159 1.2.6.2 nathanw
160 1.2.6.2 nathanw /* There can only be 1 footbridge. */
161 1.2.6.2 nathanw footbridge_found = 1;
162 1.2.6.2 nathanw
163 1.2.6.2 nathanw clock_sc = sc;
164 1.2.6.2 nathanw
165 1.2.6.2 nathanw sc->sc_iot = &footbridge_bs_tag;
166 1.2.6.2 nathanw
167 1.2.6.2 nathanw /* Map the Footbridge */
168 1.2.6.2 nathanw if (bus_space_map(sc->sc_iot, DC21285_ARMCSR_VBASE,
169 1.2.6.2 nathanw DC21285_ARMCSR_VSIZE, 0, &sc->sc_ioh))
170 1.2.6.2 nathanw panic("%s: Cannot map registers\n", self->dv_xname);
171 1.2.6.2 nathanw
172 1.2.6.2 nathanw /* Read the ID to make sure it is what we think it is */
173 1.2.6.2 nathanw vendor = bus_space_read_2(sc->sc_iot, sc->sc_ioh, VENDOR_ID);
174 1.2.6.2 nathanw device = bus_space_read_2(sc->sc_iot, sc->sc_ioh, DEVICE_ID);
175 1.2.6.2 nathanw rev = bus_space_read_1(sc->sc_iot, sc->sc_ioh, REVISION);
176 1.2.6.2 nathanw if (vendor != DC21285_VENDOR_ID && device != DC21285_DEVICE_ID)
177 1.2.6.2 nathanw panic("%s: Unrecognised ID\n", self->dv_xname);
178 1.2.6.2 nathanw
179 1.2.6.2 nathanw printf(": DC21285 rev %d\n", rev);
180 1.2.6.2 nathanw
181 1.2.6.2 nathanw /* Disable all interrupts from the footbridge */
182 1.2.6.2 nathanw bus_space_write_4(sc->sc_iot, sc->sc_ioh, IRQ_ENABLE_CLEAR, 0xffffffff);
183 1.2.6.2 nathanw bus_space_write_4(sc->sc_iot, sc->sc_ioh, FIQ_ENABLE_CLEAR, 0xffffffff);
184 1.2.6.2 nathanw
185 1.2.6.2 nathanw /* bus_space_write_4(sc->sc_iot, sc->sc_ioh, 0x18, 0x40000000);*/
186 1.2.6.2 nathanw
187 1.2.6.2 nathanw /* Install a generic handler to catch a load of system interrupts */
188 1.2.6.2 nathanw sc->sc_serr_ih = intr_claim(IRQ_SERR, IPL_NONE,
189 1.2.6.2 nathanw "serr", footbridge_intr, sc);
190 1.2.6.2 nathanw sc->sc_sdram_par_ih = intr_claim(IRQ_SDRAM_PARITY, IPL_NONE,
191 1.2.6.2 nathanw "sdram parity", footbridge_intr, sc);
192 1.2.6.2 nathanw sc->sc_data_par_ih = intr_claim(IRQ_DATA_PARITY, IPL_NONE,
193 1.2.6.2 nathanw "data parity", footbridge_intr, sc);
194 1.2.6.2 nathanw sc->sc_master_abt_ih = intr_claim(IRQ_MASTER_ABORT, IPL_NONE,
195 1.2.6.2 nathanw "mast abt", footbridge_intr, sc);
196 1.2.6.2 nathanw sc->sc_target_abt_ih = intr_claim(IRQ_TARGET_ABORT, IPL_NONE,
197 1.2.6.2 nathanw "targ abt", footbridge_intr, sc);
198 1.2.6.2 nathanw sc->sc_parity_ih = intr_claim(IRQ_PARITY, IPL_NONE,
199 1.2.6.2 nathanw "parity", footbridge_intr, sc);
200 1.2.6.2 nathanw
201 1.2.6.2 nathanw /* Set up the PCI bus tags */
202 1.2.6.2 nathanw footbridge_create_io_bs_tag(&footbridge_pci_io_bs_tag,
203 1.2.6.2 nathanw (void *)DC21285_PCI_IO_VBASE);
204 1.2.6.2 nathanw footbridge_create_mem_bs_tag(&footbridge_pci_mem_bs_tag,
205 1.2.6.2 nathanw (void *)DC21285_PCI_MEM_BASE);
206 1.2.6.2 nathanw
207 1.2.6.2 nathanw /* Attach the PCI bus */
208 1.2.6.2 nathanw fba.fba_pba.pba_busname = "pci";
209 1.2.6.2 nathanw fba.fba_pba.pba_pc = &footbridge_pci_chipset;
210 1.2.6.2 nathanw fba.fba_pba.pba_iot = &footbridge_pci_io_bs_tag;
211 1.2.6.2 nathanw fba.fba_pba.pba_memt = &footbridge_pci_mem_bs_tag;
212 1.2.6.2 nathanw fba.fba_pba.pba_dmat = &footbridge_pci_bus_dma_tag;
213 1.2.6.2 nathanw fba.fba_pba.pba_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED;
214 1.2.6.2 nathanw fba.fba_pba.pba_bus = 0;
215 1.2.6.2 nathanw config_found(self, &fba.fba_pba, footbridge_print);
216 1.2.6.2 nathanw
217 1.2.6.2 nathanw /* Attach a time-of-day clock device */
218 1.2.6.2 nathanw fba.fba_tca.ta_name = "todclock";
219 1.2.6.2 nathanw fba.fba_tca.ta_rtc_arg = NULL;
220 1.2.6.2 nathanw fba.fba_tca.ta_rtc_write = NULL;
221 1.2.6.2 nathanw fba.fba_tca.ta_rtc_read = NULL;
222 1.2.6.2 nathanw fba.fba_tca.ta_flags = TODCLOCK_FLAG_FAKE;
223 1.2.6.2 nathanw config_found(self, &fba.fba_tca, footbridge_print);
224 1.2.6.2 nathanw
225 1.2.6.2 nathanw /* Attach uart device */
226 1.2.6.2 nathanw fba.fba_fca.fca_name = "fcom";
227 1.2.6.2 nathanw fba.fba_fca.fca_iot = sc->sc_iot;
228 1.2.6.2 nathanw fba.fba_fca.fca_ioh = sc->sc_ioh;
229 1.2.6.2 nathanw fba.fba_fca.fca_rx_irq = IRQ_SERIAL_RX;
230 1.2.6.2 nathanw fba.fba_fca.fca_tx_irq = IRQ_SERIAL_TX;
231 1.2.6.2 nathanw config_found(self, &fba.fba_fca, footbridge_print);
232 1.2.6.2 nathanw
233 1.2.6.2 nathanw /* Setup fast SA110 cache clean area */
234 1.2.6.2 nathanw #ifdef CPU_SA110
235 1.2.6.2 nathanw if (cputype == CPU_ID_SA110)
236 1.2.6.2 nathanw footbridge_sa110_cc_setup();
237 1.2.6.2 nathanw #endif /* CPU_SA110 */
238 1.2.6.2 nathanw
239 1.2.6.2 nathanw }
240 1.2.6.2 nathanw
241 1.2.6.2 nathanw /* Generic footbridge interrupt handler */
242 1.2.6.2 nathanw
243 1.2.6.2 nathanw int
244 1.2.6.2 nathanw footbridge_intr(arg)
245 1.2.6.2 nathanw void *arg;
246 1.2.6.2 nathanw {
247 1.2.6.2 nathanw struct footbridge_softc *sc = arg;
248 1.2.6.2 nathanw u_int ctrl, intr;
249 1.2.6.2 nathanw
250 1.2.6.2 nathanw /*
251 1.2.6.2 nathanw * Read the footbridge control register and check for
252 1.2.6.2 nathanw * SERR and parity errors
253 1.2.6.2 nathanw */
254 1.2.6.2 nathanw ctrl = bus_space_read_4(sc->sc_iot, sc->sc_ioh, SA_CONTROL);
255 1.2.6.2 nathanw intr = ctrl & (RECEIVED_SERR | SA_SDRAM_PARITY_ERROR |
256 1.2.6.2 nathanw PCI_SDRAM_PARITY_ERROR | DMA_SDRAM_PARITY_ERROR);
257 1.2.6.2 nathanw if (intr) {
258 1.2.6.2 nathanw /* Report the interrupt if reporting is enabled */
259 1.2.6.2 nathanw if (footbridge_intr_report)
260 1.2.6.2 nathanw printf("footbridge_intr: ctrl=%08x\n", intr);
261 1.2.6.2 nathanw /* Clear the interrupt state */
262 1.2.6.2 nathanw bus_space_write_4(sc->sc_iot, sc->sc_ioh, SA_CONTROL,
263 1.2.6.2 nathanw ctrl | intr);
264 1.2.6.2 nathanw }
265 1.2.6.2 nathanw /*
266 1.2.6.2 nathanw * Read the PCI status register and check for errors
267 1.2.6.2 nathanw */
268 1.2.6.2 nathanw ctrl = bus_space_read_4(sc->sc_iot, sc->sc_ioh, PCI_COMMAND_STATUS_REG);
269 1.2.6.2 nathanw intr = ctrl & (PCI_STATUS_PARITY_ERROR | PCI_STATUS_MASTER_TARGET_ABORT
270 1.2.6.2 nathanw | PCI_STATUS_MASTER_ABORT | PCI_STATUS_SPECIAL_ERROR
271 1.2.6.2 nathanw | PCI_STATUS_PARITY_DETECT);
272 1.2.6.2 nathanw if (intr) {
273 1.2.6.2 nathanw /* Report the interrupt if reporting is enabled */
274 1.2.6.2 nathanw if (footbridge_intr_report)
275 1.2.6.2 nathanw printf("footbridge_intr: pcistat=%08x\n", intr);
276 1.2.6.2 nathanw /* Clear the interrupt state */
277 1.2.6.2 nathanw bus_space_write_4(sc->sc_iot, sc->sc_ioh,
278 1.2.6.2 nathanw PCI_COMMAND_STATUS_REG, ctrl | intr);
279 1.2.6.2 nathanw }
280 1.2.6.2 nathanw return(0);
281 1.2.6.2 nathanw }
282 1.2.6.2 nathanw
283 1.2.6.2 nathanw /* End of footbridge.c */
284