1 /* $Id: omap2_obio.c,v 1.7 2008/12/12 17:36:14 matt Exp $ */
4 /* $NetBSD: omap2_obio.c,v 1.6 2008/11/21 17:13:07 matt Exp $ */
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
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
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
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.
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
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
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"
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>
135 bus_dma_tag_t sc_dmat
;
136 bus_space_tag_t sc_iot
;
137 bus_space_handle_t sc_ioh
;
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
;
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)
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)
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)
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)
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
;
200 sc
->sc_iot
= &omap_bs_tag
;
202 aprint_normal(": On-Board IO\n");
206 sc
->sc_dmat
= &omap_bus_dma_tag
;
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
)
215 #ifdef OMAP2_OBIO_1_BASE
216 else if (mb
->mb_iobase
== OMAP2_OBIO_1_BASE
)
219 #ifdef OMAP2_OBIO_2_BASE
220 else if (mb
->mb_iobase
== OMAP2_OBIO_2_BASE
)
223 #ifdef OMAP2_OBIO_3_BASE
224 else if (mb
->mb_iobase
== OMAP2_OBIO_3_BASE
)
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
);
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
;
249 panic("nobyteacc specified for device with "
250 "non-byte multiplier\n");
252 switch (cf
->cf_loc
[OBIOCF_MULT
]) {
254 oa
.obio_iot
= &omap_bs_tag
;
257 oa
.obio_iot
= &omap_a2x_bs_tag
;
260 oa
.obio_iot
= &omap_a4x_bs_tag
;
263 panic("Unsupported EMIFS multiplier.");
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
];
275 if ((oa
.obio_addr
>= sc
->sc_base
)
276 && (oa
.obio_addr
< (sc
->sc_base
+ sc
->sc_size
))) {
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
)))
285 if (config_match(parent
, cf
, &oa
)) {
286 config_attach(parent
, cf
, &oa
, obio_print
);
287 return 0; /* love it */
292 return UNCONF
; /* NG */
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
])
303 if (oa
->obio_size
!= OBIOCF_SIZE_DEFAULT
304 && oa
->obio_size
!= cf
->cf_loc
[OBIOCF_SIZE
])
306 if (oa
->obio_intr
!= OBIOCF_INTR_DEFAULT
307 && oa
->obio_intr
!= cf
->cf_loc
[OBIOCF_INTR
])
309 if (oa
->obio_intrbase
!= OBIOCF_INTRBASE_DEFAULT
310 && oa
->obio_intrbase
!= cf
->cf_loc
[OBIOCF_INTRBASE
])
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
;
318 panic("nobyteacc specified for device with "
319 "non-byte multiplier\n");
321 switch (cf
->cf_loc
[OBIOCF_MULT
]) {
323 oa
->obio_iot
= &omap_bs_tag
;
326 oa
->obio_iot
= &omap_a2x_bs_tag
;
329 oa
->obio_iot
= &omap_a4x_bs_tag
;
332 panic("Unsupported EMIFS multiplier.");
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
348 static const struct {
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 },
358 { .name
= "dmac", .addr
= DMAC_BASE
, .required
= true },
363 obio_attach_critical(struct obio_softc
*sc
)
365 struct obio_attach_args oa
;
369 for (i
= 0; i
< __arraycount(critical_devs
); i
++) {
370 oa
.obio_iot
= sc
->sc_iot
;
372 oa
.obio_dmat
= sc
->sc_dmat
;
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
))
385 cf
= config_search_ia(obio_find
, sc
->sc_dev
, "obio", &oa
);
387 if (critical_devs
[i
].required
)
388 panic("obio_attach_critical: failed to find %s!",
389 critical_devs
[i
].name
);
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
);
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
);