1 /* $NetBSD: gemini_obio.c,v 1.7 2008/11/20 20:23:05 cliff Exp $ */
4 * NetBSD: omap2_obio.c,v 1.5 2008/10/21 18:50:25 matt Exp
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
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
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
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.
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
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
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"
111 #include "geminiicu.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>
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
);
150 obio_match(device_t parent
, cfdata_t match
, void *aux
)
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
;
161 struct pcibus_attach_args pba
;
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;
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
);
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",
199 * initialize the PCI chipset tag
201 gemini_pci_init(&sc
->sc_pci_chipset
, sc
);
205 * attach the rest of our devices
207 config_search_ia(obio_search
, self
, "obio", NULL
);
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
;
219 pba
.pba_bridgetag
= NULL
;
220 pba
.pba_intrswiz
= 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
);
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) {
239 if (cf
->cf_loc
[OBIOCF_MULT
] == 1)
240 oa
.obio_iot
= &nobyteacc_bs_tag
;
243 panic("nobyteacc specified for device with "
244 "non-byte multiplier\n");
246 switch (cf
->cf_loc
[OBIOCF_MULT
]) {
248 oa
.obio_iot
= &gemini_bs_tag
;
252 oa
.obio_iot
= &gemini_a2x_bs_tag
;
256 oa
.obio_iot
= &gemini_a4x_bs_tag
;
259 panic("Unsupported obio bus multiplier.");
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 */
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
])
286 if (oa
->obio_size
!= OBIOCF_SIZE_DEFAULT
287 && oa
->obio_size
!= cf
->cf_loc
[OBIOCF_SIZE
])
289 if (oa
->obio_intr
!= OBIOCF_INTR_DEFAULT
290 && oa
->obio_intr
!= cf
->cf_loc
[OBIOCF_INTR
])
292 if (oa
->obio_intrbase
!= OBIOCF_INTRBASE_DEFAULT
293 && oa
->obio_intrbase
!= cf
->cf_loc
[OBIOCF_INTRBASE
])
296 /* Set up the attach args. */
297 if (cf
->cf_loc
[OBIOCF_NOBYTEACC
] == 1) {
299 if (cf
->cf_loc
[OBIOCF_MULT
] == 1)
300 oa
->obio_iot
= &nobyteacc_bs_tag
;
303 panic("nobyteacc specified for device with "
304 "non-byte multiplier\n");
306 switch (cf
->cf_loc
[OBIOCF_MULT
]) {
308 oa
->obio_iot
= &gemini_bs_tag
;
312 oa
->obio_iot
= &gemini_a2x_bs_tag
;
316 oa
->obio_iot
= &gemini_a4x_bs_tag
;
319 panic("Unsupported obio bus multiplier.");
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
);
332 #error no geminiicu present in config file
335 static const struct {
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 },
355 obio_attach_critical(struct obio_softc
*sc
)
357 struct obio_attach_args oa
;
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
;
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
))
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
);
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
);