1/* $NetBSD: obio.c,v 1.11 2003/07/15 00:25:05 lukem Exp $ */ 2 3/*- 4 * Copyright (c) 2001, 2002, 2003 Wasabi Systems, Inc. 5 * All rights reserved. 6 * 7 * Written by Jason R. Thorpe for Wasabi Systems, Inc. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. All advertising materials mentioning features or use of this software 18 * must display the following acknowledgement: 19 * This product includes software developed for the NetBSD Project by 20 * Wasabi Systems, Inc. 21 * 4. The name of Wasabi Systems, Inc. may not be used to endorse 22 * or promote products derived from this software without specific prior 23 * written permission. 24 * 25 * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND 26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC 29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 35 * POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38/* 39 * On-board device autoconfiguration support for Cavium OCTEON 1 family of 40 * SoC devices. 41 */ 42 43#include <sys/cdefs.h> 44__FBSDID("$FreeBSD$"); 45 46#include <sys/param.h> 47#include <sys/systm.h> 48#include <sys/bus.h> 49#include <sys/kernel.h> 50#include <sys/module.h> 51#include <sys/rman.h> 52#include <sys/malloc.h> 53 54#include <machine/bus.h> 55 56#include <mips/cavium/octeon_pcmap_regs.h> 57#include <mips/cavium/obiovar.h> 58 59#include <contrib/octeon-sdk/cvmx.h> 60#include <mips/cavium/octeon_irq.h> 61 62extern struct bus_space octeon_uart_tag; 63 64static void obio_identify(driver_t *, device_t); 65static int obio_probe(device_t); 66static int obio_attach(device_t); 67 68static void 69obio_identify(driver_t *drv, device_t parent) 70{ 71 BUS_ADD_CHILD(parent, 0, "obio", 0); 72} 73 74static int 75obio_probe(device_t dev) 76{ 77 if (device_get_unit(dev) != 0) 78 return (ENXIO); 79 return (0); 80} 81 82static int 83obio_attach(device_t dev) 84{ 85 struct obio_softc *sc = device_get_softc(dev); 86 87 sc->oba_st = mips_bus_space_generic; 88 /* 89 * XXX 90 * Here and elsewhere using RBR as a base address because it kind of 91 * is, but that feels pretty sloppy. Should consider adding a define 92 * that's more semantic, at least. 93 */ 94 sc->oba_addr = CVMX_MIO_UARTX_RBR(0); 95 sc->oba_size = 0x10000; 96 sc->oba_rman.rm_type = RMAN_ARRAY; 97 sc->oba_rman.rm_descr = "OBIO I/O"; 98 if (rman_init(&sc->oba_rman) != 0 || 99 rman_manage_region(&sc->oba_rman, 100 sc->oba_addr, sc->oba_addr + sc->oba_size) != 0) 101 panic("obio_attach: failed to set up I/O rman"); 102 sc->oba_irq_rman.rm_type = RMAN_ARRAY; 103 sc->oba_irq_rman.rm_descr = "OBIO IRQ"; 104 105 /* 106 * This module is intended for UART purposes only and 107 * manages IRQs for UART0 and UART1. 108 */ 109 if (rman_init(&sc->oba_irq_rman) != 0 || 110 rman_manage_region(&sc->oba_irq_rman, OCTEON_IRQ_UART0, OCTEON_IRQ_UART1) != 0) 111 panic("obio_attach: failed to set up IRQ rman"); 112 113 device_add_child(dev, "uart", 1); /* Setup Uart-1 first. */ 114 device_add_child(dev, "uart", 0); /* Uart-0 next. So it is first in console list */ 115 bus_generic_probe(dev); 116 bus_generic_attach(dev); 117 return (0); 118} 119 120static struct resource * 121obio_alloc_resource(device_t bus, device_t child, int type, int *rid, 122 u_long start, u_long end, u_long count, u_int flags) 123{ 124 struct resource *rv; 125 struct rman *rm; 126 bus_space_tag_t bt = 0; 127 bus_space_handle_t bh = 0; 128 struct obio_softc *sc = device_get_softc(bus); 129 130 switch (type) { 131 case SYS_RES_IRQ: 132 switch (device_get_unit(child)) { 133 case 0: 134 start = end = OCTEON_IRQ_UART0; 135 break; 136 case 1: 137 start = end = OCTEON_IRQ_UART1; 138 break; 139 default: 140 return (NULL); 141 } 142 rm = &sc->oba_irq_rman; 143 break; 144 case SYS_RES_MEMORY: 145 return (NULL); 146 case SYS_RES_IOPORT: 147 rm = &sc->oba_rman; 148 bt = &octeon_uart_tag; 149 bh = CVMX_MIO_UARTX_RBR(device_get_unit(child)); 150 start = bh; 151 break; 152 default: 153 return (NULL); 154 } 155 156 rv = rman_reserve_resource(rm, start, end, count, flags, child); 157 if (rv == NULL) { 158 return (NULL); 159 } 160 if (type == SYS_RES_IRQ) { 161 return (rv); 162 } 163 rman_set_rid(rv, *rid); 164 rman_set_bustag(rv, bt); 165 rman_set_bushandle(rv, bh); 166 167 if (0) { 168 if (bus_activate_resource(child, type, *rid, rv)) { 169 rman_release_resource(rv); 170 return (NULL); 171 } 172 } 173 return (rv); 174 175} 176 177static int 178obio_activate_resource(device_t bus, device_t child, int type, int rid, 179 struct resource *r) 180{ 181 return (0); 182} 183static device_method_t obio_methods[] = { 184 /* Device methods */ 185 DEVMETHOD(device_identify, obio_identify), 186 DEVMETHOD(device_probe, obio_probe), 187 DEVMETHOD(device_attach, obio_attach), 188 189 /* Bus methods */ 190 DEVMETHOD(bus_alloc_resource, obio_alloc_resource), 191 DEVMETHOD(bus_activate_resource,obio_activate_resource), 192 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 193 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 194 195 DEVMETHOD(bus_add_child, bus_generic_add_child), 196 197 {0, 0}, 198}; 199 200static driver_t obio_driver = { 201 "obio", 202 obio_methods, 203 sizeof(struct obio_softc), 204}; 205static devclass_t obio_devclass; 206 207DRIVER_MODULE(obio, ciu, obio_driver, obio_devclass, 0, 0); 208