2 * Copyright (c) 2003-2009 RMI Corporation
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of RMI Corporation, nor the names of its contributors,
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
35 #define __RMAN_RESOURCE_VISIBLE
36 #include <sys/param.h>
37 #include <sys/systm.h>
39 #include <sys/kernel.h>
41 #include <sys/mutex.h>
42 #include <sys/reboot.h>
44 #include <sys/types.h>
45 #include <sys/malloc.h>
46 #include <sys/interrupt.h>
47 #include <sys/module.h>
49 #include <machine/cpu.h>
50 #include <machine/bus.h>
51 #include <machine/param.h>
52 #include <machine/intr_machdep.h>
53 #include <machine/clock.h> /* for DELAY */
54 #include <machine/resource.h>
56 #include <mips/rmi/board.h>
57 #include <mips/rmi/pic.h>
58 #include <mips/rmi/interrupt.h>
59 #include <mips/rmi/msgring.h>
60 #include <mips/rmi/iomap.h>
61 #include <mips/rmi/rmi_mips_exts.h>
63 #include <mips/rmi/dev/xlr/atx_cpld.h>
64 #include <mips/rmi/dev/xlr/xgmac_mdio.h>
66 extern bus_space_tag_t uart_bus_space_mem;
68 static struct resource *
69 iodi_alloc_resource(device_t, device_t, int, int *,
70 u_long, u_long, u_long, u_int);
73 iodi_activate_resource(device_t, device_t, int, int,
76 iodi_setup_intr(device_t, device_t, struct resource *, int,
77 driver_filter_t *, driver_intr_t *, void *, void **);
79 struct iodi_softc *iodi_softc; /* There can be only one. */
82 * We will manage the Flash/PCMCIA devices in IODI for now.
83 * The NOR flash, Compact flash etc. which can be connected on
84 * various chip selects on the peripheral IO, should have a
88 bridge_pcmcia_ack(int irq)
90 xlr_reg_t *mmio = xlr_io_mmio(XLR_IO_FLASH_OFFSET);
92 xlr_write_reg(mmio, 0x60, 0xffffffff);
96 iodi_setup_intr(device_t dev, device_t child,
97 struct resource *ires, int flags, driver_filter_t *filt,
98 driver_intr_t *intr, void *arg, void **cookiep)
100 const char *name = device_get_name(child);
102 if (strcmp(name, "uart") == 0) {
104 cpu_establish_hardintr("uart", filt, intr, arg,
105 PIC_UART_0_IRQ, flags, cookiep);
106 pic_setup_intr(PIC_IRT_UART_0_INDEX, PIC_UART_0_IRQ, 0x1, 1);
107 } else if (strcmp(name, "nlge") == 0) {
110 /* This is a hack to pass in the irq */
111 irq = (intptr_t)ires->__r_i;
112 cpu_establish_hardintr("nlge", filt, intr, arg, irq, flags,
114 pic_setup_intr(irq - PIC_IRQ_BASE, irq, 0x1, 1);
115 } else if (strcmp(name, "ehci") == 0) {
116 cpu_establish_hardintr("ehci", filt, intr, arg, PIC_USB_IRQ, flags,
118 pic_setup_intr(PIC_USB_IRQ - PIC_IRQ_BASE, PIC_USB_IRQ, 0x1, 1);
119 } else if (strcmp(name, "ata") == 0) {
120 xlr_establish_intr("ata", filt, intr, arg, PIC_PCMCIA_IRQ, flags,
121 cookiep, bridge_pcmcia_ack);
122 pic_setup_intr(PIC_PCMCIA_IRQ - PIC_IRQ_BASE, PIC_PCMCIA_IRQ, 0x1, 1);
127 static struct resource *
128 iodi_alloc_resource(device_t bus, device_t child, int type, int *rid,
129 u_long start, u_long end, u_long count, u_int flags)
131 struct resource *res = malloc(sizeof(*res), M_DEVBUF, M_WAITOK);
132 const char *name = device_get_name(child);
138 device_printf(bus, "IRQ resource - for %s %lx-%lx\n",
139 device_get_nameunit(child), start, end);
143 device_printf(bus, "IOPORT resource - for %s %lx-%lx\n",
144 device_get_nameunit(child), start, end);
148 device_printf(bus, "MEMORY resource - for %s %lx-%lx\n",
149 device_get_nameunit(child), start, end);
154 if (strcmp(name, "uart") == 0) {
155 if ((unit = device_get_unit(child)) == 0) { /* uart 0 */
156 res->r_bushandle = (xlr_io_base + XLR_IO_UART_0_OFFSET);
157 } else if (unit == 1) {
158 res->r_bushandle = (xlr_io_base + XLR_IO_UART_1_OFFSET);
160 printf("%s: Unknown uart unit\n", __FUNCTION__);
162 res->r_bustag = uart_bus_space_mem;
163 } else if (strcmp(name, "ehci") == 0) {
164 res->r_bushandle = MIPS_PHYS_TO_KSEG1(0x1ef24000);
165 res->r_bustag = rmi_pci_bus_space;
166 } else if (strcmp(name, "cfi") == 0) {
167 res->r_bushandle = MIPS_PHYS_TO_KSEG1(0x1c000000);
169 } else if (strcmp(name, "ata") == 0) {
170 res->r_bushandle = MIPS_PHYS_TO_KSEG1(0x1d000000);
171 res->r_bustag = rmi_pci_bus_space; /* byte swapping (not really PCI) */
173 /* res->r_start = *rid; */
178 iodi_activate_resource(device_t bus, device_t child, int type, int rid,
185 static int iodi_probe(device_t);
186 static int iodi_attach(device_t);
187 static int iodi_detach(device_t);
188 static void iodi_identify(driver_t *, device_t);
191 iodi_probe(device_t dev)
193 return (BUS_PROBE_NOWILDCARD);
197 iodi_identify(driver_t * driver, device_t parent)
200 BUS_ADD_CHILD(parent, 0, "iodi", 0);
204 iodi_attach(device_t dev)
210 * Attach each devices
212 device_add_child(dev, "uart", 0);
213 device_add_child(dev, "xlr_i2c", 0);
214 device_add_child(dev, "xlr_i2c", 1);
215 device_add_child(dev, "pcib", 0);
216 device_add_child(dev, "rmisec", -1);
218 if (xlr_board_info.usb)
219 device_add_child(dev, "ehci", 0);
221 if (xlr_board_info.cfi)
222 device_add_child(dev, "cfi", 0);
224 if (xlr_board_info.ata)
225 device_add_child(dev, "ata", 0);
227 for (i = 0; i < 3; i++) {
228 if (xlr_board_info.gmac_block[i].enabled == 0)
230 tmpd = device_add_child(dev, "nlna", i);
231 device_set_ivars(tmpd, &xlr_board_info.gmac_block[i]);
234 bus_generic_probe(dev);
235 bus_generic_attach(dev);
240 iodi_detach(device_t dev)
247 for (i = 0; i < 3; i++) {
248 nlna_dev = device_find_child(dev, "nlna", i);
249 if (nlna_dev != NULL)
250 error = bus_generic_detach(nlna_dev);
257 static device_method_t iodi_methods[] = {
258 DEVMETHOD(device_probe, iodi_probe),
259 DEVMETHOD(device_attach, iodi_attach),
260 DEVMETHOD(device_detach, iodi_detach),
261 DEVMETHOD(device_identify, iodi_identify),
262 DEVMETHOD(bus_alloc_resource, iodi_alloc_resource),
263 DEVMETHOD(bus_activate_resource, iodi_activate_resource),
264 DEVMETHOD(bus_add_child, bus_generic_add_child),
265 DEVMETHOD(bus_setup_intr, iodi_setup_intr),
269 static driver_t iodi_driver = {
274 static devclass_t iodi_devclass;
276 DRIVER_MODULE(iodi, nexus, iodi_driver, iodi_devclass, 0, 0);