Sync usage with man page.
[netbsd-mini2440.git] / sys / arch / arm / gemini / gemini_obio.c
blob805a9a913fae0d5eae066b0a71c0d1267043da4f
1 /* $NetBSD: gemini_obio.c,v 1.7 2008/11/20 20:23:05 cliff Exp $ */
3 /* adapted from:
4 * NetBSD: omap2_obio.c,v 1.5 2008/10/21 18:50:25 matt Exp
5 */
7 /*
8 * Autoconfiguration support for the Gemini "On Board" I/O.
10 * Based on arm/omap/omap2_obio.c which in turn was derived
11 * Based on arm/omap/omap_emifs.c which in turn was derived
12 * Based on arm/xscale/pxa2x0.c which in turn was derived
13 * from arm/sa11x0/sa11x0.c
15 * Copyright (c) 2002, 2005 Genetec Corporation. All rights reserved.
16 * Written by Hiroyuki Bessho for Genetec Corporation.
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in the
25 * documentation and/or other materials provided with the distribution.
26 * 3. All advertising materials mentioning features or use of this software
27 * must display the following acknowledgement:
28 * This product includes software developed for the NetBSD Project by
29 * Genetec Corporation.
30 * 4. The name of Genetec Corporation may not be used to endorse or
31 * promote products derived from this software without specific prior
32 * written permission.
34 * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
35 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
36 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
37 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION
38 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
39 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
40 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
41 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
42 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
43 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
44 * POSSIBILITY OF SUCH DAMAGE.
46 * Copyright (c) 1997,1998, 2001, The NetBSD Foundation, Inc.
47 * All rights reserved.
49 * This code is derived from software contributed to The NetBSD Foundation
50 * by IWAMOTO Toshihiro, Ichiro FUKUHARA and Paul Kranenburg.
52 * Redistribution and use in source and binary forms, with or without
53 * modification, are permitted provided that the following conditions
54 * are met:
55 * 1. Redistributions of source code must retain the above copyright
56 * notice, this list of conditions and the following disclaimer.
57 * 2. Redistributions in binary form must reproduce the above copyright
58 * notice, this list of conditions and the following disclaimer in the
59 * documentation and/or other materials provided with the distribution.
61 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
62 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
63 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
64 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
65 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
66 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
67 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
68 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
69 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
70 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
71 * POSSIBILITY OF SUCH DAMAGE.
73 * Copyright (c) 1999
74 * Shin Takemura and PocketBSD Project. All rights reserved.
76 * Redistribution and use in source and binary forms, with or without
77 * modification, are permitted provided that the following conditions
78 * are met:
79 * 1. Redistributions of source code must retain the above copyright
80 * notice, this list of conditions and the following disclaimer.
81 * 2. Redistributions in binary form must reproduce the above copyright
82 * notice, this list of conditions and the following disclaimer in the
83 * documentation and/or other materials provided with the distribution.
84 * 3. All advertising materials mentioning features or use of this software
85 * must display the following acknowledgement:
86 * This product includes software developed by the PocketBSD project
87 * and its contributors.
88 * 4. Neither the name of the project nor the names of its contributors
89 * may be used to endorse or promote products derived from this software
90 * without specific prior written permission.
92 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
93 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
95 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
96 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
97 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
98 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
99 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
100 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
101 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
102 * SUCH DAMAGE.
105 #include "opt_gemini.h"
106 #include <sys/cdefs.h>
107 __KERNEL_RCSID(0, "$NetBSD: gemini_obio.c,v 1.7 2008/11/20 20:23:05 cliff Exp $");
109 #include "locators.h"
110 #include "obio.h"
111 #include "geminiicu.h"
112 #include "pci.h"
114 #include <sys/param.h>
115 #include <sys/systm.h>
116 #include <sys/device.h>
117 #include <sys/kernel.h>
118 #include <sys/reboot.h>
120 #include <machine/cpu.h>
121 #include <machine/bus.h>
123 #include <arm/cpufunc.h>
124 #include <arm/mainbus/mainbus.h>
125 #include <arm/gemini/gemini_var.h>
126 #include <arm/gemini/gemini_reg.h>
128 #include <arm/gemini/gemini_obiovar.h>
130 typedef struct {
131 boolean_t cs_valid;
132 ulong cs_addr;
133 ulong cs_size;
134 } obio_csconfig_t;
136 /* prototypes */
137 static int obio_match(device_t, cfdata_t, void *);
138 static void obio_attach(device_t, device_t, void *);
139 static int obio_search(device_t, cfdata_t, const int *, void *);
140 static int obio_find(device_t, cfdata_t, const int *, void *);
141 static int obio_print(void *, const char *);
142 static void obio_attach_critical(struct obio_softc *);
144 /* attach structures */
145 CFATTACH_DECL_NEW(obio, sizeof(struct obio_softc),
146 obio_match, obio_attach, NULL, NULL);
149 static int
150 obio_match(device_t parent, cfdata_t match, void *aux)
152 return 1;
155 static void
156 obio_attach(device_t parent, device_t self, void *aux)
158 struct obio_softc *sc = device_private(self);
159 struct mainbus_attach_args *mb = (struct mainbus_attach_args *)aux;
160 #if NPCI > 0
161 struct pcibus_attach_args pba;
162 #endif
164 sc->sc_dev = self;
166 sc->sc_iot = &gemini_bs_tag;
168 aprint_normal(": On-Board IO\n");
170 #if (GEMINI_BUSBASE != 0)
171 sc->sc_dmarange.dr_sysbase = 0;
172 sc->sc_dmarange.dr_busbase = (GEMINI_BUSBASE * 1024 * 1024);
173 sc->sc_dmarange.dr_len = MEMSIZE * 1024 * 1024;
174 gemini_bus_dma_tag._ranges = &sc->sc_dmarange;
175 gemini_bus_dma_tag._nranges = 1;
176 #endif
178 sc->sc_ioh = 0;
179 sc->sc_dmat = &gemini_bus_dma_tag;
180 sc->sc_base = mb->mb_iobase;
181 sc->sc_size = mb->mb_iosize;
184 * Attach critical devices first.
186 obio_attach_critical(sc);
188 #if NPCI > 0
190 * map PCI controller registers
192 if (bus_space_map(sc->sc_iot, GEMINI_PCICFG_BASE,
193 GEMINI_PCI_CFG_DATA+4, 0, &sc->sc_pcicfg_ioh)) {
194 aprint_error("cannot map PCI controller at %#x\n",
195 GEMINI_PCICFG_BASE);
196 return;
199 * initialize the PCI chipset tag
201 gemini_pci_init(&sc->sc_pci_chipset, sc);
202 #endif /* NPCI */
205 * attach the rest of our devices
207 config_search_ia(obio_search, self, "obio", NULL);
209 #if NPCI > 0
211 * attach the PCI bus
213 pba.pba_memt = sc->sc_iot;
214 pba.pba_iot = sc->sc_iot;
215 pba.pba_dmat = sc->sc_dmat;
216 pba.pba_dmat64 = NULL;
217 pba.pba_pc = &sc->sc_pci_chipset;
218 pba.pba_bus = 0;
219 pba.pba_bridgetag = NULL;
220 pba.pba_intrswiz = 0;
221 pba.pba_intrtag = 0;
222 pba.pba_flags = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED |
223 PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY;
225 (void) config_found_ia(sc->sc_dev, "pcibus", &pba, pcibusprint);
226 #endif /* NPCI */
230 static int
231 obio_search(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
233 struct obio_softc * const sc = device_private(parent);
234 struct obio_attach_args oa;
236 /* Set up the attach args. */
237 if (cf->cf_loc[OBIOCF_NOBYTEACC] == 1) {
238 #if 0
239 if (cf->cf_loc[OBIOCF_MULT] == 1)
240 oa.obio_iot = &nobyteacc_bs_tag;
241 else
242 #endif
243 panic("nobyteacc specified for device with "
244 "non-byte multiplier\n");
245 } else {
246 switch (cf->cf_loc[OBIOCF_MULT]) {
247 case 1:
248 oa.obio_iot = &gemini_bs_tag;
249 break;
250 #if 0
251 case 2:
252 oa.obio_iot = &gemini_a2x_bs_tag;
253 break;
254 #endif
255 case 4:
256 oa.obio_iot = &gemini_a4x_bs_tag;
257 break;
258 default:
259 panic("Unsupported obio bus multiplier.");
260 break;
264 oa.obio_dmat = sc->sc_dmat;
265 oa.obio_addr = cf->cf_loc[OBIOCF_ADDR];
266 oa.obio_size = cf->cf_loc[OBIOCF_SIZE];
267 oa.obio_intr = cf->cf_loc[OBIOCF_INTR];
268 oa.obio_intrbase = cf->cf_loc[OBIOCF_INTRBASE];
270 if (config_match(parent, cf, &oa)) {
271 config_attach(parent, cf, &oa, obio_print);
272 return 0; /* love it */
275 return UNCONF; /* NG */
278 static int
279 obio_find(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
281 struct obio_attach_args * const oa = aux;
283 if (oa->obio_addr != OBIOCF_ADDR_DEFAULT
284 && oa->obio_addr != cf->cf_loc[OBIOCF_ADDR])
285 return 0;
286 if (oa->obio_size != OBIOCF_SIZE_DEFAULT
287 && oa->obio_size != cf->cf_loc[OBIOCF_SIZE])
288 return 0;
289 if (oa->obio_intr != OBIOCF_INTR_DEFAULT
290 && oa->obio_intr != cf->cf_loc[OBIOCF_INTR])
291 return 0;
292 if (oa->obio_intrbase != OBIOCF_INTRBASE_DEFAULT
293 && oa->obio_intrbase != cf->cf_loc[OBIOCF_INTRBASE])
294 return 0;
296 /* Set up the attach args. */
297 if (cf->cf_loc[OBIOCF_NOBYTEACC] == 1) {
298 #if 0
299 if (cf->cf_loc[OBIOCF_MULT] == 1)
300 oa->obio_iot = &nobyteacc_bs_tag;
301 else
302 #endif
303 panic("nobyteacc specified for device with "
304 "non-byte multiplier\n");
305 } else {
306 switch (cf->cf_loc[OBIOCF_MULT]) {
307 case 1:
308 oa->obio_iot = &gemini_bs_tag;
309 break;
310 #if 0
311 case 2:
312 oa->obio_iot = &gemini_a2x_bs_tag;
313 break;
314 #endif
315 case 4:
316 oa->obio_iot = &gemini_a4x_bs_tag;
317 break;
318 default:
319 panic("Unsupported obio bus multiplier.");
320 break;
323 oa->obio_addr = cf->cf_loc[OBIOCF_ADDR];
324 oa->obio_size = cf->cf_loc[OBIOCF_SIZE];
325 oa->obio_intr = cf->cf_loc[OBIOCF_INTR];
326 oa->obio_intrbase = cf->cf_loc[OBIOCF_INTRBASE];
328 return config_match(parent, cf, oa);
331 #if NGEMINIICU == 0
332 #error no geminiicu present in config file
333 #endif
335 static const struct {
336 const char *name;
337 bus_addr_t addr;
338 bool required;
339 } critical_devs[] = {
340 #if defined(GEMINI_MASTER) || defined(GEMINI_SINGLE)
341 { .name = "geminiicu0", .addr = 0x48000000, .required = true },
342 { .name = "geminiwdt0", .addr = 0x41000000, .required = true },
343 { .name = "geminitmr0", .addr = 0x43000000, .required = true },
344 { .name = "geminitmr2", .addr = 0x43000000, .required = true },
345 { .name = "com0", .addr = 0x42000000, .required = true },
346 #elif defined(GEMINI_SLAVE)
347 { .name = "geminiicu1", .addr = 0x49000000, .required = true },
348 { .name = "geminitmr1", .addr = 0x43000000, .required = true },
349 { .name = "geminitmr2", .addr = 0x43000000, .required = true },
350 { .name = "geminilpchc0", .addr = 0x47000000, .required = true },
351 #endif
354 static void
355 obio_attach_critical(struct obio_softc *sc)
357 struct obio_attach_args oa;
358 cfdata_t cf;
359 size_t i;
361 for (i = 0; i < __arraycount(critical_devs); i++) {
362 oa.obio_iot = sc->sc_iot;
363 oa.obio_dmat = sc->sc_dmat;
365 oa.obio_addr = critical_devs[i].addr;
366 oa.obio_size = OBIOCF_SIZE_DEFAULT;
367 oa.obio_intr = OBIOCF_INTR_DEFAULT;
368 oa.obio_intrbase = OBIOCF_INTRBASE_DEFAULT;
370 #if 0
371 if (oa.obio_addr != OBIOCF_ADDR_DEFAULT
372 && (oa.obio_addr < sc->sc_base
373 || oa.obio_addr >= sc->sc_base + sc->sc_size))
374 continue;
375 #endif
377 cf = config_search_ia(obio_find, sc->sc_dev, "obio", &oa);
378 if (cf == NULL && critical_devs[i].required)
379 panic("obio_attach_critical: failed to find %s!",
380 critical_devs[i].name);
382 oa.obio_addr = cf->cf_loc[OBIOCF_ADDR];
383 oa.obio_size = cf->cf_loc[OBIOCF_SIZE];
384 oa.obio_intr = cf->cf_loc[OBIOCF_INTR];
385 oa.obio_intrbase = cf->cf_loc[OBIOCF_INTRBASE];
386 config_attach(sc->sc_dev, cf, &oa, obio_print);
390 static int
391 obio_print(void *aux, const char *name)
393 struct obio_attach_args *oa = (struct obio_attach_args*)aux;
395 if (oa->obio_addr != OBIOCF_ADDR_DEFAULT) {
396 aprint_normal(" addr 0x%08lx", oa->obio_addr);
397 if (oa->obio_size != OBIOCF_SIZE_DEFAULT)
398 aprint_normal("-0x%08lx",
399 oa->obio_addr + oa->obio_size-1);
401 if (oa->obio_intr != OBIOCF_INTR_DEFAULT)
402 aprint_normal(" intr %d", oa->obio_intr);
403 if (oa->obio_intrbase != OBIOCF_INTRBASE_DEFAULT)
404 aprint_normal(" intrbase %d", oa->obio_intrbase);
406 return UNCONF;