1 /* $NetBSD: iomd.c,v 1.14 2005/12/11 12:16:47 christos Exp $ */
4 * Copyright (c) 1996-1997 Mark Brinicombe.
5 * Copyright (c) 1997 Causality Limited
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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
35 * RiscBSD kernel project
39 * Probing and configuration for the IOMD
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>
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>
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
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
,
85 static void iomdattach(struct device
*parent
, struct device
*self
,
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
;
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
110 iomdprint(void *aux
, const char *name
)
112 /* union iomd_attach_args *ia = aux;*/
118 * int iomdmatch(struct device *parent, struct cfdata *cf, void *aux)
120 * Just return ok for this if it is device 0
124 iomdmatch(struct device
*parent
, struct cfdata
*cf
, void *aux
)
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.
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;*/
149 union iomd_attach_args ia
;
151 bus_space_handle_t ioh
;
153 /* There can be only 1 IOMD. */
156 iot
= sc
->sc_iot
= &iomd_bs_tag
;
159 if (bus_space_map(iot
, (int) iomd_base
, IOMD_SIZE
, 0, &ioh
))
160 panic("%s: Cannot map registers", self
->dv_xname
);
165 sc
->sc_id
= bus_space_read_1(iot
, ioh
, IOMD_ID0
)
166 | (bus_space_read_1(iot
, ioh
, IOMD_ID1
) << 8);
169 /* Identify it and get the DRAM refresh rate */
172 printf("ARM7500 IOMD ");
173 refresh
= bus_space_read_1(iot
, ioh
, IOMD_REFCR
) & 0x0f;
174 arm7500_ioc_found
= 1;
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;
183 refresh
= bus_space_read_1(iot
, ioh
, IOMD_VREFCR
) & 0x09;
184 arm7500_ioc_found
= 0;
187 printf("Unknown IOMD ID=%04x ", sc
->sc_id
);
189 arm7500_ioc_found
= 0; /* just in case */
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=");
214 printf("unknown [%02x]", refresh
);
221 * No point in reporting this as it may get changed when devices are
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
);
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
);
233 for (i
= 0; i
< 4; i
++, tmp
>>= 2)
234 printf("%c", 'A' + (tmp
& 3));
238 /* Set up the external DMA channels */
239 /* XXX - this should be machine dependant not IOMD dependant */
242 case ARM7500FE_IOC_ID
:
245 /* DMA channels 2 & 3 are external */
246 bus_space_write_1(iot
, ioh
, IOMD_DMAEXT
, 0x0c);
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
);
279 case ARM7500FE_IOC_ID
:
280 /* Attach opms device */
282 if (bus_space_subregion(iot
, ioh
, IOMD_MSDATA
, 8,
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
);
291 /* Attach (ws)qms device */
293 if (bus_space_subregion(iot
, ioh
, IOMD_MOUSEX
, 8,
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
);