Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / arch / arm / iomd / iomd.c
blob00c14a4ad7ea47f3cb0efd75ce2e998be597fb43
1 /* $NetBSD: iomd.c,v 1.14 2005/12/11 12:16:47 christos Exp $ */
3 /*
4 * Copyright (c) 1996-1997 Mark Brinicombe.
5 * Copyright (c) 1997 Causality Limited
6 * All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. All advertising materials mentioning features or use of this software
17 * must display the following acknowledgement:
18 * This product includes software developed by Mark Brinicombe.
19 * 4. The name of the company nor the name of the author may be used to
20 * endorse or promote products derived from this software without specific
21 * prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
24 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
25 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
35 * RiscBSD kernel project
37 * iomd.c
39 * Probing and configuration for the IOMD
41 * Created : 10/10/95
42 * Updated : 18/03/01 for rpckbd as part of the wscons project
45 #include <sys/cdefs.h>
46 __KERNEL_RCSID(0, "$NetBSD: iomd.c,v 1.14 2005/12/11 12:16:47 christos Exp $");
48 #include <sys/param.h>
49 #include <sys/systm.h>
50 #include <sys/kernel.h>
51 #include <sys/conf.h>
52 #include <sys/malloc.h>
53 #include <sys/device.h>
54 #include <machine/bus.h>
55 #include <machine/cpu.h>
56 #include <machine/intr.h>
57 #include <arm/iomd/iomdreg.h>
58 #include <arm/iomd/iomdvar.h>
60 #include "iomd.h"
63 * IOMD device.
65 * This probes and attaches the top level IOMD device.
66 * It then configures any children of the IOMD device.
70 * IOMD softc structure.
72 * Contains the device node, bus space tag, handle and address
73 * and the IOMD id.
76 struct iomd_softc {
77 struct device sc_dev; /* device node */
78 bus_space_tag_t sc_iot; /* bus tag */
79 bus_space_handle_t sc_ioh; /* bus handle */
80 int sc_id; /* IOMD id */
83 static int iomdmatch(struct device *parent, struct cfdata *cf,
84 void *aux);
85 static void iomdattach(struct device *parent, struct device *self,
86 void *aux);
87 static int iomdprint(void *aux, const char *iomdbus);
89 CFATTACH_DECL(iomd, sizeof(struct iomd_softc),
90 iomdmatch, iomdattach, NULL, NULL);
92 extern struct bus_space iomd_bs_tag;
94 int iomd_found;
95 u_int32_t iomd_base = IOMD_BASE;
97 /* following flag is used in iomd_irq.s ... has to be cleaned up one day ! */
98 u_int32_t arm7500_ioc_found = 0;
101 /* Declare prototypes */
104 * int iomdprint(void *aux, const char *name)
106 * print configuration info for children
109 static int
110 iomdprint(void *aux, const char *name)
112 /* union iomd_attach_args *ia = aux;*/
114 return QUIET;
118 * int iomdmatch(struct device *parent, struct cfdata *cf, void *aux)
120 * Just return ok for this if it is device 0
123 static int
124 iomdmatch(struct device *parent, struct cfdata *cf, void *aux)
127 if (iomd_found)
128 return 0;
129 return 1;
134 * void iomdattach(struct device *parent, struct device *dev, void *aux)
136 * Map the IOMD and identify it.
137 * Then configure the child devices based on the IOMD ID.
140 static void
141 iomdattach(struct device *parent, struct device *self, void *aux)
143 struct iomd_softc *sc = (struct iomd_softc *)self;
144 /* struct mainbus_attach_args *mb = aux;*/
145 int refresh;
146 #if 0
147 int i, tmp;
148 #endif
149 union iomd_attach_args ia;
150 bus_space_tag_t iot;
151 bus_space_handle_t ioh;
153 /* There can be only 1 IOMD. */
154 iomd_found = 1;
156 iot = sc->sc_iot = &iomd_bs_tag;
158 /* Map the IOMD */
159 if (bus_space_map(iot, (int) iomd_base, IOMD_SIZE, 0, &ioh))
160 panic("%s: Cannot map registers", self->dv_xname);
162 sc->sc_ioh = ioh;
164 /* Get the ID */
165 sc->sc_id = bus_space_read_1(iot, ioh, IOMD_ID0)
166 | (bus_space_read_1(iot, ioh, IOMD_ID1) << 8);
167 printf(": ");
169 /* Identify it and get the DRAM refresh rate */
170 switch (sc->sc_id) {
171 case ARM7500_IOC_ID:
172 printf("ARM7500 IOMD ");
173 refresh = bus_space_read_1(iot, ioh, IOMD_REFCR) & 0x0f;
174 arm7500_ioc_found = 1;
175 break;
176 case ARM7500FE_IOC_ID:
177 printf("ARM7500FE IOMD ");
178 refresh = bus_space_read_1(iot, ioh, IOMD_REFCR) & 0x0f;
179 arm7500_ioc_found = 1;
180 break;
181 case RPC600_IOMD_ID:
182 printf("IOMD20 ");
183 refresh = bus_space_read_1(iot, ioh, IOMD_VREFCR) & 0x09;
184 arm7500_ioc_found = 0;
185 break;
186 default:
187 printf("Unknown IOMD ID=%04x ", sc->sc_id);
188 refresh = -1;
189 arm7500_ioc_found = 0; /* just in case */
190 break;
192 printf("version %d\n", bus_space_read_1(iot, ioh, IOMD_VERSION));
194 /* Report the DRAM refresh rate */
195 printf("%s: ", self->dv_xname);
196 printf("DRAM refresh=");
197 switch (refresh) {
198 case 0x0:
199 printf("off");
200 break;
201 case 0x1:
202 printf("16us");
203 break;
204 case 0x2:
205 printf("32us");
206 break;
207 case 0x4:
208 printf("64us");
209 break;
210 case 0x8:
211 printf("128us");
212 break;
213 default:
214 printf("unknown [%02x]", refresh);
215 break;
218 printf("\n");
219 #if 0
221 * No point in reporting this as it may get changed when devices are
222 * attached
224 tmp = bus_space_read_1(iot, ioh, IOMD_IOTCR);
225 printf("%s: I/O timings: combo %c, NPCCS1/2 %c", self->dv_xname,
226 'A' + ((tmp >>2) & 3), 'A' + (tmp & 3));
227 tmp = bus_space_read_1(iot, ioh, IOMD_ECTCR);
228 printf(", EASI ");
229 for (i = 0; i < 8; i++, tmp >>= 1)
230 printf("%c", 'A' + ((tmp & 1) << 2));
231 tmp = bus_space_read_1(iot, ioh, IOMD_DMATCR);
232 printf(", DMA ");
233 for (i = 0; i < 4; i++, tmp >>= 2)
234 printf("%c", 'A' + (tmp & 3));
235 printf("\n");
236 #endif
238 /* Set up the external DMA channels */
239 /* XXX - this should be machine dependant not IOMD dependant */
240 switch (sc->sc_id) {
241 case ARM7500_IOC_ID:
242 case ARM7500FE_IOC_ID:
243 break;
244 case RPC600_IOMD_ID:
245 /* DMA channels 2 & 3 are external */
246 bus_space_write_1(iot, ioh, IOMD_DMAEXT, 0x0c);
247 break;
250 /* Configure the child devices */
252 /* Attach clock device */
254 ia.ia_clk.ca_name = "clk";
255 ia.ia_clk.ca_iot = iot;
256 ia.ia_clk.ca_ioh = ioh;
257 config_found(self, &ia, iomdprint);
259 /* Attach kbd device when configured */
260 if (bus_space_subregion(iot, ioh, IOMD_KBDDAT, 8, &ia.ia_kbd.ka_ioh))
261 panic("%s: Cannot map kbd registers", self->dv_xname);
262 ia.ia_kbd.ka_name = "kbd";
263 ia.ia_kbd.ka_iot = iot;
264 ia.ia_kbd.ka_rxirq = IRQ_KBDRX;
265 ia.ia_kbd.ka_txirq = IRQ_KBDTX;
266 config_found(self, &ia, iomdprint);
268 /* Attach iic device */
270 if (bus_space_subregion(iot, ioh, IOMD_IOCR, 4, &ia.ia_iic.ia_ioh))
271 panic("%s: Cannot map iic registers", self->dv_xname);
272 ia.ia_iic.ia_name = "iic";
273 ia.ia_iic.ia_iot = iot;
274 ia.ia_iic.ia_irq = -1;
275 config_found(self, &ia, iomdprint);
277 switch (sc->sc_id) {
278 case ARM7500_IOC_ID:
279 case ARM7500FE_IOC_ID:
280 /* Attach opms device */
282 if (bus_space_subregion(iot, ioh, IOMD_MSDATA, 8,
283 &ia.ia_opms.pa_ioh))
284 panic("%s: Cannot map opms registers", self->dv_xname);
285 ia.ia_opms.pa_name = "opms";
286 ia.ia_opms.pa_iot = iot;
287 ia.ia_opms.pa_irq = IRQ_MSDRX;
288 config_found(self, &ia, iomdprint);
289 break;
290 case RPC600_IOMD_ID:
291 /* Attach (ws)qms device */
293 if (bus_space_subregion(iot, ioh, IOMD_MOUSEX, 8,
294 &ia.ia_qms.qa_ioh))
295 panic("%s: Cannot map qms registers", self->dv_xname);
297 if (bus_space_map(iot, IO_MOUSE_BUTTONS, 4, 0, &ia.ia_qms.qa_ioh_but))
298 panic("%s: Cannot map registers", self->dv_xname);
299 ia.ia_qms.qa_name = "qms";
300 ia.ia_qms.qa_iot = iot;
301 ia.ia_qms.qa_irq = IRQ_VSYNC;
302 config_found(self, &ia, iomdprint);
303 break;
307 /* End of iomd.c */