iomd.c revision 1.18
1/* $NetBSD: iomd.c,v 1.18 2012/05/10 09:56:27 skrll Exp $ */ 2 3/* 4 * Copyright (c) 1996-1997 Mark Brinicombe. 5 * Copyright (c) 1997 Causality Limited 6 * All rights reserved. 7 * 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. 22 * 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. 34 * 35 * RiscBSD kernel project 36 * 37 * iomd.c 38 * 39 * Probing and configuration for the IOMD 40 * 41 * Created : 10/10/95 42 * Updated : 18/03/01 for rpckbd as part of the wscons project 43 */ 44 45#include <sys/cdefs.h> 46__KERNEL_RCSID(0, "$NetBSD: iomd.c,v 1.18 2012/05/10 09:56:27 skrll Exp $"); 47 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 <sys/bus.h> 55#include <machine/cpu.h> 56#include <machine/intr.h> 57#include <arm/iomd/iomdreg.h> 58#include <arm/iomd/iomdvar.h> 59 60#include "iomd.h" 61 62/* 63 * IOMD device. 64 * 65 * This probes and attaches the top level IOMD device. 66 * It then configures any children of the IOMD device. 67 */ 68 69/* 70 * IOMD softc structure. 71 * 72 * Contains the device node, bus space tag, handle and address 73 * and the IOMD id. 74 */ 75 76struct 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 */ 81}; 82 83static int iomdmatch(struct device *parent, struct cfdata *cf, 84 void *aux); 85static void iomdattach(struct device *parent, struct device *self, 86 void *aux); 87static int iomdprint(void *aux, const char *iomdbus); 88 89CFATTACH_DECL(iomd, sizeof(struct iomd_softc), 90 iomdmatch, iomdattach, NULL, NULL); 91 92extern struct bus_space iomd_bs_tag; 93 94int iomd_found; 95uint32_t iomd_base = IOMD_BASE; 96 97/* following flag is used in iomd_irq.s ... has to be cleaned up one day ! */ 98uint32_t arm7500_ioc_found = 0; 99 100 101/* Declare prototypes */ 102 103/* 104 * int iomdprint(void *aux, const char *name) 105 * 106 * print configuration info for children 107 */ 108 109static int 110iomdprint(void *aux, const char *name) 111{ 112/* union iomd_attach_args *ia = aux;*/ 113 114 return QUIET; 115} 116 117/* 118 * int iomdmatch(struct device *parent, struct cfdata *cf, void *aux) 119 * 120 * Just return ok for this if it is device 0 121 */ 122 123static int 124iomdmatch(struct device *parent, struct cfdata *cf, void *aux) 125{ 126 127 if (iomd_found) 128 return 0; 129 return 1; 130} 131 132 133/* 134 * void iomdattach(struct device *parent, struct device *dev, void *aux) 135 * 136 * Map the IOMD and identify it. 137 * Then configure the child devices based on the IOMD ID. 138 */ 139 140static void 141iomdattach(struct device *parent, struct device *self, void *aux) 142{ 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; 152 153 /* There can be only 1 IOMD. */ 154 iomd_found = 1; 155 156 iot = sc->sc_iot = &iomd_bs_tag; 157 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); 161 162 sc->sc_ioh = ioh; 163 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(": "); 168 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; 191 } 192 printf("version %d\n", bus_space_read_1(iot, ioh, IOMD_VERSION)); 193 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; 216 } 217 218 printf("\n"); 219#if 0 220 /* 221 * No point in reporting this as it may get changed when devices are 222 * attached 223 */ 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 237 238 /* Set up the external DMA channels */ 239 /* XXX - this should be machine dependent not IOMD dependent */ 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; 248 } 249 250 /* Configure the child devices */ 251 252 /* Attach clock device */ 253 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); 258 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); 267 268 /* Attach iic device */ 269 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); 276 277 switch (sc->sc_id) { 278 case ARM7500_IOC_ID: 279 case ARM7500FE_IOC_ID: 280 /* Attach opms device */ 281 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 */ 292 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); 296 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; 304 } 305} 306 307/* End of iomd.c */ 308