1194140Simp/*	$NetBSD: obio.c,v 1.11 2003/07/15 00:25:05 lukem Exp $	*/
2194140Simp
3194140Simp/*-
4194140Simp * Copyright (c) 2001, 2002, 2003 Wasabi Systems, Inc.
5194140Simp * All rights reserved.
6194140Simp *
7194140Simp * Written by Jason R. Thorpe for Wasabi Systems, Inc.
8194140Simp *
9194140Simp * Redistribution and use in source and binary forms, with or without
10194140Simp * modification, are permitted provided that the following conditions
11194140Simp * are met:
12194140Simp * 1. Redistributions of source code must retain the above copyright
13194140Simp *    notice, this list of conditions and the following disclaimer.
14194140Simp * 2. Redistributions in binary form must reproduce the above copyright
15194140Simp *    notice, this list of conditions and the following disclaimer in the
16194140Simp *    documentation and/or other materials provided with the distribution.
17194140Simp * 3. All advertising materials mentioning features or use of this software
18194140Simp *    must display the following acknowledgement:
19194140Simp *	This product includes software developed for the NetBSD Project by
20194140Simp *	Wasabi Systems, Inc.
21194140Simp * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22194140Simp *    or promote products derived from this software without specific prior
23194140Simp *    written permission.
24194140Simp *
25194140Simp * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26194140Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27194140Simp * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28194140Simp * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
29194140Simp * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30194140Simp * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31194140Simp * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32194140Simp * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33194140Simp * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34194140Simp * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35194140Simp * POSSIBILITY OF SUCH DAMAGE.
36194140Simp */
37194140Simp
38194140Simp/*
39202985Simp * On-board device autoconfiguration support for Cavium OCTEON 1 family of
40202985Simp * SoC devices.
41194140Simp */
42194140Simp
43194140Simp#include <sys/cdefs.h>
44194140Simp__FBSDID("$FreeBSD$");
45194140Simp
46194140Simp#include <sys/param.h>
47194140Simp#include <sys/systm.h>
48194140Simp#include <sys/bus.h>
49194140Simp#include <sys/kernel.h>
50194140Simp#include <sys/module.h>
51194140Simp#include <sys/rman.h>
52194140Simp#include <sys/malloc.h>
53194140Simp
54194140Simp#include <machine/bus.h>
55194140Simp
56202867Simp#include <mips/cavium/octeon_pcmap_regs.h>
57202063Simp#include <mips/cavium/obiovar.h>
58194140Simp
59210311Sjmallett#include <contrib/octeon-sdk/cvmx.h>
60232812Sjmallett#include <mips/cavium/octeon_irq.h>
61210311Sjmallett
62202985Simpextern struct bus_space octeon_uart_tag;
63202985Simp
64210311Sjmallettstatic void	obio_identify(driver_t *, device_t);
65210311Sjmallettstatic int	obio_probe(device_t);
66210311Sjmallettstatic int	obio_attach(device_t);
67194140Simp
68210311Sjmallettstatic void
69210311Sjmallettobio_identify(driver_t *drv, device_t parent)
70210311Sjmallett{
71210311Sjmallett	BUS_ADD_CHILD(parent, 0, "obio", 0);
72210311Sjmallett}
73194140Simp
74210311Sjmallettstatic int
75194140Simpobio_probe(device_t dev)
76194140Simp{
77210311Sjmallett	if (device_get_unit(dev) != 0)
78210311Sjmallett		return (ENXIO);
79210311Sjmallett	return (0);
80194140Simp}
81194140Simp
82210311Sjmallettstatic int
83194140Simpobio_attach(device_t dev)
84194140Simp{
85194140Simp	struct obio_softc *sc = device_get_softc(dev);
86194140Simp
87196236Simp	sc->oba_st = mips_bus_space_generic;
88210311Sjmallett	/*
89210311Sjmallett	 * XXX
90210311Sjmallett	 * Here and elsewhere using RBR as a base address because it kind of
91210311Sjmallett	 * is, but that feels pretty sloppy.  Should consider adding a define
92210311Sjmallett	 * that's more semantic, at least.
93210311Sjmallett	 */
94210311Sjmallett	sc->oba_addr = CVMX_MIO_UARTX_RBR(0);
95194140Simp	sc->oba_size = 0x10000;
96194140Simp	sc->oba_rman.rm_type = RMAN_ARRAY;
97194140Simp	sc->oba_rman.rm_descr = "OBIO I/O";
98194140Simp	if (rman_init(&sc->oba_rman) != 0 ||
99194140Simp	    rman_manage_region(&sc->oba_rman,
100194140Simp	    sc->oba_addr, sc->oba_addr + sc->oba_size) != 0)
101194140Simp		panic("obio_attach: failed to set up I/O rman");
102194140Simp	sc->oba_irq_rman.rm_type = RMAN_ARRAY;
103194140Simp	sc->oba_irq_rman.rm_descr = "OBIO IRQ";
104194140Simp
105194140Simp	/*
106194140Simp	 * This module is intended for UART purposes only and
107210311Sjmallett	 * manages IRQs for UART0 and UART1.
108194140Simp	 */
109194140Simp	if (rman_init(&sc->oba_irq_rman) != 0 ||
110232812Sjmallett	    rman_manage_region(&sc->oba_irq_rman, OCTEON_IRQ_UART0, OCTEON_IRQ_UART1) != 0)
111194140Simp		panic("obio_attach: failed to set up IRQ rman");
112194140Simp
113194140Simp	device_add_child(dev, "uart", 1);  /* Setup Uart-1 first. */
114194140Simp	device_add_child(dev, "uart", 0);  /* Uart-0 next. So it is first in console list */
115194140Simp	bus_generic_probe(dev);
116194140Simp	bus_generic_attach(dev);
117194140Simp	return (0);
118194140Simp}
119194140Simp
120194140Simpstatic struct resource *
121194140Simpobio_alloc_resource(device_t bus, device_t child, int type, int *rid,
122194140Simp    u_long start, u_long end, u_long count, u_int flags)
123194140Simp{
124194140Simp	struct resource *rv;
125194140Simp	struct rman *rm;
126194140Simp	bus_space_tag_t bt = 0;
127194140Simp	bus_space_handle_t bh = 0;
128194140Simp	struct obio_softc *sc = device_get_softc(bus);
129194140Simp
130194140Simp	switch (type) {
131194140Simp	case SYS_RES_IRQ:
132210311Sjmallett		switch (device_get_unit(child)) {
133210311Sjmallett		case 0:
134232812Sjmallett			start = end = OCTEON_IRQ_UART0;
135210311Sjmallett			break;
136210311Sjmallett		case 1:
137232812Sjmallett			start = end = OCTEON_IRQ_UART1;
138210311Sjmallett			break;
139210311Sjmallett		default:
140210311Sjmallett			return (NULL);
141210311Sjmallett		}
142194140Simp		rm = &sc->oba_irq_rman;
143194140Simp		break;
144194140Simp	case SYS_RES_MEMORY:
145194140Simp		return (NULL);
146194140Simp	case SYS_RES_IOPORT:
147194140Simp		rm = &sc->oba_rman;
148202985Simp		bt = &octeon_uart_tag;
149210311Sjmallett		bh = CVMX_MIO_UARTX_RBR(device_get_unit(child));
150194140Simp		start = bh;
151194140Simp		break;
152194140Simp	default:
153194140Simp		return (NULL);
154194140Simp	}
155194140Simp
156194140Simp	rv = rman_reserve_resource(rm, start, end, count, flags, child);
157194140Simp	if (rv == NULL)  {
158194140Simp		return (NULL);
159194140Simp        }
160194140Simp	if (type == SYS_RES_IRQ) {
161194140Simp		return (rv);
162194140Simp        }
163194140Simp	rman_set_rid(rv, *rid);
164194140Simp	rman_set_bustag(rv, bt);
165194140Simp	rman_set_bushandle(rv, bh);
166194140Simp
167194140Simp	if (0) {
168194140Simp		if (bus_activate_resource(child, type, *rid, rv)) {
169194140Simp			rman_release_resource(rv);
170194140Simp			return (NULL);
171194140Simp		}
172194140Simp	}
173194140Simp	return (rv);
174194140Simp
175194140Simp}
176194140Simp
177194140Simpstatic int
178194140Simpobio_activate_resource(device_t bus, device_t child, int type, int rid,
179194140Simp    struct resource *r)
180194140Simp{
181194140Simp	return (0);
182194140Simp}
183194140Simpstatic device_method_t obio_methods[] = {
184210311Sjmallett	/* Device methods */
185210311Sjmallett	DEVMETHOD(device_identify,	obio_identify),
186210311Sjmallett	DEVMETHOD(device_probe,		obio_probe),
187210311Sjmallett	DEVMETHOD(device_attach,	obio_attach),
188194140Simp
189210311Sjmallett	/* Bus methods */
190210311Sjmallett	DEVMETHOD(bus_alloc_resource,	obio_alloc_resource),
191210311Sjmallett	DEVMETHOD(bus_activate_resource,obio_activate_resource),
192194140Simp	DEVMETHOD(bus_setup_intr,	bus_generic_setup_intr),
193194140Simp	DEVMETHOD(bus_teardown_intr,	bus_generic_teardown_intr),
194194140Simp
195212843Sjmallett	DEVMETHOD(bus_add_child,	bus_generic_add_child),
196212843Sjmallett
197194140Simp	{0, 0},
198194140Simp};
199194140Simp
200194140Simpstatic driver_t obio_driver = {
201194140Simp	"obio",
202194140Simp	obio_methods,
203194140Simp	sizeof(struct obio_softc),
204194140Simp};
205194140Simpstatic devclass_t obio_devclass;
206194140Simp
207210311SjmallettDRIVER_MODULE(obio, ciu, obio_driver, obio_devclass, 0, 0);
208