No empty .Rs/.Re
[netbsd-mini2440.git] / sys / arch / arm / omap / omap2_obio.c
blobc3588b8527fef32ed7ceeac39b3afd82195eab76
1 /* $Id: omap2_obio.c,v 1.7 2008/12/12 17:36:14 matt Exp $ */
3 /* adapted from: */
4 /* $NetBSD: omap2_obio.c,v 1.6 2008/11/21 17:13:07 matt Exp $ */
7 /*
8 * Autoconfiguration support for the Texas Instruments OMAP "On Board" I/O.
10 * Based on arm/omap/omap_emifs.c which in turn was derived
11 * Based on arm/xscale/pxa2x0.c which in turn was derived
12 * from arm/sa11x0/sa11x0.c
14 * Copyright (c) 2002, 2005 Genetec Corporation. All rights reserved.
15 * Written by Hiroyuki Bessho for Genetec Corporation.
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions
19 * are met:
20 * 1. Redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer.
22 * 2. Redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution.
25 * 3. All advertising materials mentioning features or use of this software
26 * must display the following acknowledgement:
27 * This product includes software developed for the NetBSD Project by
28 * Genetec Corporation.
29 * 4. The name of Genetec Corporation may not be used to endorse or
30 * promote products derived from this software without specific prior
31 * written permission.
33 * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
34 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
35 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
36 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GENETEC CORPORATION
37 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
38 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
39 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
40 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
41 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
42 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
43 * POSSIBILITY OF SUCH DAMAGE.
45 * Copyright (c) 1997,1998, 2001, The NetBSD Foundation, Inc.
46 * All rights reserved.
48 * This code is derived from software contributed to The NetBSD Foundation
49 * by IWAMOTO Toshihiro, Ichiro FUKUHARA and Paul Kranenburg.
51 * Redistribution and use in source and binary forms, with or without
52 * modification, are permitted provided that the following conditions
53 * are met:
54 * 1. Redistributions of source code must retain the above copyright
55 * notice, this list of conditions and the following disclaimer.
56 * 2. Redistributions in binary form must reproduce the above copyright
57 * notice, this list of conditions and the following disclaimer in the
58 * documentation and/or other materials provided with the distribution.
60 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
61 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
62 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
63 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
64 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
65 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
66 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
67 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
68 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
69 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
70 * POSSIBILITY OF SUCH DAMAGE.
72 * Copyright (c) 1999
73 * Shin Takemura and PocketBSD Project. All rights reserved.
75 * Redistribution and use in source and binary forms, with or without
76 * modification, are permitted provided that the following conditions
77 * are met:
78 * 1. Redistributions of source code must retain the above copyright
79 * notice, this list of conditions and the following disclaimer.
80 * 2. Redistributions in binary form must reproduce the above copyright
81 * notice, this list of conditions and the following disclaimer in the
82 * documentation and/or other materials provided with the distribution.
83 * 3. All advertising materials mentioning features or use of this software
84 * must display the following acknowledgement:
85 * This product includes software developed by the PocketBSD project
86 * and its contributors.
87 * 4. Neither the name of the project nor the names of its contributors
88 * may be used to endorse or promote products derived from this software
89 * without specific prior written permission.
91 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
92 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
94 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
95 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
96 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
97 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
98 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
99 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
100 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
101 * SUCH DAMAGE.
104 #include "opt_omap.h"
105 #include <sys/cdefs.h>
106 __KERNEL_RCSID(0, "$NetBSD: omap2_obio.c,v 1.6 2008/11/21 17:13:07 matt Exp $");
108 #include "locators.h"
109 #include "obio.h"
111 #include <sys/param.h>
112 #include <sys/systm.h>
113 #include <sys/device.h>
114 #include <sys/kernel.h>
115 #include <sys/reboot.h>
117 #include <machine/cpu.h>
118 #include <machine/bus.h>
120 #include <arm/cpufunc.h>
121 #include <arm/mainbus/mainbus.h>
122 #include <arm/omap/omap_var.h>
124 #include <arm/omap/omap2_obioreg.h>
125 #include <arm/omap/omap2_obiovar.h>
127 typedef struct {
128 boolean_t cs_valid;
129 ulong cs_addr;
130 ulong cs_size;
131 } obio_csconfig_t;
133 struct obio_softc {
134 device_t sc_dev;
135 bus_dma_tag_t sc_dmat;
136 bus_space_tag_t sc_iot;
137 bus_space_handle_t sc_ioh;
138 bus_addr_t sc_base;
139 bus_size_t sc_size;
143 /* prototypes */
144 static int obio_match(device_t, cfdata_t, void *);
145 static void obio_attach(device_t, device_t, void *);
146 static int obio_search(device_t, cfdata_t, const int *, void *);
147 static int obio_find(device_t, cfdata_t, const int *, void *);
148 static int obio_print(void *, const char *);
149 static void obio_attach_critical(struct obio_softc *);
151 /* attach structures */
152 CFATTACH_DECL_NEW(obio, sizeof(struct obio_softc),
153 obio_match, obio_attach, NULL, NULL);
155 static uint8_t obio_attached;
157 static int
158 obio_match(device_t parent, cfdata_t match, void *aux)
160 struct mainbus_attach_args *mb = aux;
162 #ifdef OMAP2_OBIO_0_BASE
163 if (mb->mb_iobase == OMAP2_OBIO_0_BASE
164 && mb->mb_iosize == OMAP2_OBIO_0_SIZE
165 && (obio_attached & 1) == 0)
166 return 1;
167 #endif
169 #ifdef OMAP2_OBIO_1_BASE
170 if (mb->mb_iobase == OMAP2_OBIO_1_BASE
171 && mb->mb_iosize == OMAP2_OBIO_1_SIZE
172 && (obio_attached & 2) == 0)
173 return 1;
174 #endif
176 #ifdef OMAP2_OBIO_2_BASE
177 if (mb->mb_iobase == OMAP2_OBIO_2_BASE
178 && mb->mb_iosize == OMAP2_OBIO_2_SIZE
179 && (obio_attached & 4) == 0)
180 return 1;
181 #endif
183 #ifdef OMAP2_OBIO_3_BASE
184 if (mb->mb_iobase == OMAP2_OBIO_3_BASE
185 && mb->mb_iosize == OMAP2_OBIO_3_SIZE
186 && (obio_attached & 8) == 0)
187 return 1;
188 #endif
190 return 0;
193 static void
194 obio_attach(device_t parent, device_t self, void *aux)
196 struct obio_softc *sc = device_private(self);
197 struct mainbus_attach_args *mb = (struct mainbus_attach_args *)aux;
199 sc->sc_dev = self;
200 sc->sc_iot = &omap_bs_tag;
202 aprint_normal(": On-Board IO\n");
204 sc->sc_ioh = 0;
205 #ifdef NOTYET
206 sc->sc_dmat = &omap_bus_dma_tag;
207 #endif
208 sc->sc_base = mb->mb_iobase;
209 sc->sc_size = mb->mb_iosize;
211 #ifdef OMAP2_OBIO_0_BASE
212 if (mb->mb_iobase == OMAP2_OBIO_0_BASE)
213 obio_attached |= 1;
214 #endif
215 #ifdef OMAP2_OBIO_1_BASE
216 else if (mb->mb_iobase == OMAP2_OBIO_1_BASE)
217 obio_attached |= 2;
218 #endif
219 #ifdef OMAP2_OBIO_2_BASE
220 else if (mb->mb_iobase == OMAP2_OBIO_2_BASE)
221 obio_attached |= 4;
222 #endif
223 #ifdef OMAP2_OBIO_3_BASE
224 else if (mb->mb_iobase == OMAP2_OBIO_3_BASE)
225 obio_attached |= 8;
226 #endif
229 * Attach critical devices first.
231 obio_attach_critical(sc);
233 * Then attach the rest of our devices
235 config_search_ia(obio_search, self, "obio", NULL);
238 static int
239 obio_search(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
241 struct obio_softc * const sc = device_private(parent);
242 struct obio_attach_args oa;
244 /* Set up the attach args. */
245 if (cf->cf_loc[OBIOCF_NOBYTEACC] == 1) {
246 if (cf->cf_loc[OBIOCF_MULT] == 1)
247 oa.obio_iot = &nobyteacc_bs_tag;
248 else
249 panic("nobyteacc specified for device with "
250 "non-byte multiplier\n");
251 } else {
252 switch (cf->cf_loc[OBIOCF_MULT]) {
253 case 1:
254 oa.obio_iot = &omap_bs_tag;
255 break;
256 case 2:
257 oa.obio_iot = &omap_a2x_bs_tag;
258 break;
259 case 4:
260 oa.obio_iot = &omap_a4x_bs_tag;
261 break;
262 default:
263 panic("Unsupported EMIFS multiplier.");
264 break;
268 oa.obio_dmat = sc->sc_dmat;
269 oa.obio_addr = cf->cf_loc[OBIOCF_ADDR];
270 oa.obio_size = cf->cf_loc[OBIOCF_SIZE];
271 oa.obio_intr = cf->cf_loc[OBIOCF_INTR];
272 oa.obio_intrbase = cf->cf_loc[OBIOCF_INTRBASE];
274 #if defined(OMAP2)
275 if ((oa.obio_addr >= sc->sc_base)
276 && (oa.obio_addr < (sc->sc_base + sc->sc_size))) {
277 /* XXX
278 * if size was specified, then check it too
279 * otherwise just assume it is OK
281 if ((oa.obio_size != OBIOCF_SIZE_DEFAULT)
282 && ((oa.obio_addr + oa.obio_size)
283 >= (sc->sc_base + sc->sc_size)))
284 return 1; /* NG */
285 if (config_match(parent, cf, &oa)) {
286 config_attach(parent, cf, &oa, obio_print);
287 return 0; /* love it */
290 #endif
292 return UNCONF; /* NG */
295 static int
296 obio_find(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
298 struct obio_attach_args * const oa = aux;
300 if (oa->obio_addr != OBIOCF_ADDR_DEFAULT
301 && oa->obio_addr != cf->cf_loc[OBIOCF_ADDR])
302 return 0;
303 if (oa->obio_size != OBIOCF_SIZE_DEFAULT
304 && oa->obio_size != cf->cf_loc[OBIOCF_SIZE])
305 return 0;
306 if (oa->obio_intr != OBIOCF_INTR_DEFAULT
307 && oa->obio_intr != cf->cf_loc[OBIOCF_INTR])
308 return 0;
309 if (oa->obio_intrbase != OBIOCF_INTRBASE_DEFAULT
310 && oa->obio_intrbase != cf->cf_loc[OBIOCF_INTRBASE])
311 return 0;
313 /* Set up the attach args. */
314 if (cf->cf_loc[OBIOCF_NOBYTEACC] == 1) {
315 if (cf->cf_loc[OBIOCF_MULT] == 1)
316 oa->obio_iot = &nobyteacc_bs_tag;
317 else
318 panic("nobyteacc specified for device with "
319 "non-byte multiplier\n");
320 } else {
321 switch (cf->cf_loc[OBIOCF_MULT]) {
322 case 1:
323 oa->obio_iot = &omap_bs_tag;
324 break;
325 case 2:
326 oa->obio_iot = &omap_a2x_bs_tag;
327 break;
328 case 4:
329 oa->obio_iot = &omap_a4x_bs_tag;
330 break;
331 default:
332 panic("Unsupported EMIFS multiplier.");
333 break;
336 oa->obio_addr = cf->cf_loc[OBIOCF_ADDR];
337 oa->obio_size = cf->cf_loc[OBIOCF_SIZE];
338 oa->obio_intr = cf->cf_loc[OBIOCF_INTR];
339 oa->obio_intrbase = cf->cf_loc[OBIOCF_INTRBASE];
341 return config_match(parent, cf, oa);
344 #if 0 && NOMAP2ICU == 0
345 #error no avic present in config file
346 #endif
348 static const struct {
349 const char *name;
350 bus_addr_t addr;
351 bool required;
352 } critical_devs[] = {
353 { .name = "avic", .addr = INTC_BASE, .required = true },
354 { .name = "gpio1", .addr = GPIO1_BASE, .required = false },
355 { .name = "gpio2", .addr = GPIO2_BASE, .required = false },
356 { .name = "gpio3", .addr = GPIO3_BASE, .required = false },
357 #if 0
358 { .name = "dmac", .addr = DMAC_BASE, .required = true },
359 #endif
362 static void
363 obio_attach_critical(struct obio_softc *sc)
365 struct obio_attach_args oa;
366 cfdata_t cf;
367 size_t i;
369 for (i = 0; i < __arraycount(critical_devs); i++) {
370 oa.obio_iot = sc->sc_iot;
371 #ifdef NOTYET
372 oa.obio_dmat = sc->sc_dmat;
373 #endif
375 oa.obio_addr = critical_devs[i].addr;
376 oa.obio_size = OBIOCF_SIZE_DEFAULT;
377 oa.obio_intr = OBIOCF_INTR_DEFAULT;
378 oa.obio_intrbase = OBIOCF_INTRBASE_DEFAULT;
380 if (oa.obio_addr != OBIOCF_ADDR_DEFAULT
381 && (oa.obio_addr < sc->sc_base
382 || oa.obio_addr >= sc->sc_base + sc->sc_size))
383 continue;
385 cf = config_search_ia(obio_find, sc->sc_dev, "obio", &oa);
386 if (cf == NULL) {
387 if (critical_devs[i].required)
388 panic("obio_attach_critical: failed to find %s!",
389 critical_devs[i].name);
390 continue;
393 oa.obio_addr = cf->cf_loc[OBIOCF_ADDR];
394 oa.obio_size = cf->cf_loc[OBIOCF_SIZE];
395 oa.obio_intr = cf->cf_loc[OBIOCF_INTR];
396 oa.obio_intrbase = cf->cf_loc[OBIOCF_INTRBASE];
397 config_attach(sc->sc_dev, cf, &oa, obio_print);
401 static int
402 obio_print(void *aux, const char *name)
404 struct obio_attach_args *oa = (struct obio_attach_args*)aux;
406 if (oa->obio_addr != OBIOCF_ADDR_DEFAULT) {
407 aprint_normal(" addr 0x%08lx", oa->obio_addr);
408 if (oa->obio_size != OBIOCF_SIZE_DEFAULT)
409 aprint_normal("-0x%08lx",
410 oa->obio_addr + oa->obio_size-1);
412 if (oa->obio_intr != OBIOCF_INTR_DEFAULT)
413 aprint_normal(" intr %d", oa->obio_intr);
414 if (oa->obio_intrbase != OBIOCF_INTRBASE_DEFAULT)
415 aprint_normal(" intrbase %d", oa->obio_intrbase);
417 return UNCONF;