plumiobus.c revision 1.3
1/*	$NetBSD: plumiobus.c,v 1.3 2000/02/27 16:28:13 uch Exp $ */
2
3/*
4 * Copyright (c) 1999, 2000 by UCHIYAMA Yasushi
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. The name of the developer may NOT be used to endorse or promote products
13 *    derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 */
28#define PLUMIOBUSDEBUG
29#include "opt_tx39_debug.h"
30
31#include <sys/param.h>
32#include <sys/systm.h>
33#include <sys/device.h>
34#include <sys/malloc.h>
35
36#include <machine/bus.h>
37#include <machine/intr.h>
38
39#include <hpcmips/tx/tx39var.h>
40#include <hpcmips/dev/plumvar.h>
41#include <hpcmips/dev/plumicuvar.h>
42#include <hpcmips/dev/plumpowervar.h>
43#include <hpcmips/dev/plumiobusreg.h>
44#include <hpcmips/dev/plumiobusvar.h>
45
46#include "locators.h"
47
48#ifdef PLUMIOBUSDEBUG
49int	plumiobus_debug = 0;
50#define	DPRINTF(arg) if (plumiobus_debug) printf arg;
51#define	DPRINTFN(n, arg) if (plumiobus_debug > (n)) printf arg;
52#else
53#define	DPRINTF(arg)
54#define DPRINTFN(n, arg)
55#endif
56
57int	plumiobus_match __P((struct device*, struct cfdata*, void*));
58void	plumiobus_attach __P((struct device*, struct device*, void*));
59int	plumiobus_print __P((void*, const char*));
60int	plumiobus_search __P((struct device*, struct cfdata*, void*));
61
62struct plumisa_resource {
63	int		pr_irq;
64	bus_space_tag_t	pr_iot;
65	int		pr_enabled;
66};
67
68struct plumiobus_softc {
69	struct	device		sc_dev;
70	plum_chipset_tag_t	sc_pc;
71	bus_space_tag_t		sc_regt;
72	bus_space_handle_t	sc_regh;
73	bus_space_tag_t		sc_iot;
74	bus_space_handle_t	sc_ioh;
75	struct plumisa_resource	sc_isa[PLUM_IOBUS_IO5CSMAX];
76};
77
78struct cfattach plumiobus_ca = {
79	sizeof(struct plumiobus_softc), plumiobus_match, plumiobus_attach
80};
81
82bus_space_tag_t __plumiobus_subregion __P((bus_space_tag_t, bus_addr_t,
83					   bus_size_t));
84#ifdef PLUMIOBUSDEBUG
85void	plumiobus_dump __P((struct plumiobus_softc*));
86#endif
87
88int
89plumiobus_match(parent, cf, aux)
90	struct device *parent;
91	struct cfdata *cf;
92	void *aux;
93{
94	return (1);
95}
96
97void
98plumiobus_attach(parent, self, aux)
99	struct device *parent;
100	struct device *self;
101	void *aux;
102{
103	struct plum_attach_args *pa = aux;
104	struct plumiobus_softc *sc = (void*)self;
105	struct plumisa_resource *pr;
106
107	sc->sc_pc	= pa->pa_pc;
108	sc->sc_regt	= pa->pa_regt;
109	sc->sc_iot	= pa->pa_iot;
110
111	if (bus_space_map(sc->sc_regt, PLUM_IOBUS_REGBASE,
112			  PLUM_IOBUS_REGSIZE, 0, &sc->sc_regh)) {
113		printf(": register map failed.\n");
114		return;
115	}
116	printf("\n");
117	plum_power_establish(sc->sc_pc, PLUM_PWR_IO5);
118
119	/* Address space <-> IRQ mapping */
120	pr = &sc->sc_isa[IO5CS0];
121	pr->pr_irq = PLUM_INT_EXT5IO0;
122	pr->pr_iot = __plumiobus_subregion(
123		sc->sc_iot,
124		PLUM_IOBUS_IOBASE + PLUM_IOBUS_IO5CS0BASE,
125		PLUM_IOBUS_IO5SIZE);
126
127	pr = &sc->sc_isa[IO5CS1];
128	pr->pr_irq = PLUM_INT_EXT5IO1;
129	pr->pr_iot = __plumiobus_subregion(
130		sc->sc_iot,
131		PLUM_IOBUS_IOBASE + PLUM_IOBUS_IO5CS1BASE,
132		PLUM_IOBUS_IO5SIZE);
133
134	pr = &sc->sc_isa[IO5CS2];
135	pr->pr_irq = PLUM_INT_EXT5IO2;
136	pr->pr_iot = __plumiobus_subregion(
137		sc->sc_iot,
138		PLUM_IOBUS_IOBASE + PLUM_IOBUS_IO5CS2BASE,
139		PLUM_IOBUS_IO5SIZE);
140
141	pr = &sc->sc_isa[IO5CS3];
142	pr->pr_irq = PLUM_INT_EXT5IO3;
143	pr->pr_iot = __plumiobus_subregion(
144		sc->sc_iot,
145		PLUM_IOBUS_IOBASE + PLUM_IOBUS_IO5CS3BASE,
146		PLUM_IOBUS_IO5SIZE);
147
148	pr = &sc->sc_isa[IO5CS4];
149	pr->pr_irq = PLUM_INT_EXT3IO0; /* XXX */
150	pr->pr_iot = __plumiobus_subregion(
151		sc->sc_iot,
152		PLUM_IOBUS_IOBASE + PLUM_IOBUS_IO5CS4BASE,
153		PLUM_IOBUS_IO5SIZE);
154
155
156	pr = &sc->sc_isa[IO5NCS];
157	pr->pr_irq = PLUM_INT_EXT3IO1;
158	pr->pr_iot = __plumiobus_subregion(
159		sc->sc_iot,
160		PLUM_IOBUS_IOBASE + PLUM_IOBUS_IO5CS5BASE,
161		PLUM_IOBUS_IO5SIZE);
162
163#ifdef PLUMIOBUSDEBUG
164	plumiobus_dump(sc);
165#endif
166
167	config_search(plumiobus_search, self, plumiobus_print);
168}
169
170/* XXX something kludge */
171bus_space_tag_t
172__plumiobus_subregion(t, ofs, size)
173	bus_space_tag_t t;
174	bus_addr_t ofs;
175	bus_size_t size;
176{
177	struct hpcmips_bus_space *hbs;
178
179	if (!(hbs = malloc(sizeof(struct hpcmips_bus_space),
180			   M_DEVBUF, M_NOWAIT))) {
181		panic ("__plumiobus_subregion: no memory.");
182	}
183	*hbs = *t;
184	hbs->t_base += ofs;
185	hbs->t_size = size;
186
187	return (hbs);
188}
189
190int
191plumiobus_search(parent, cf, aux)
192	struct device *parent;
193	struct cfdata *cf;
194	void *aux;
195{
196	struct plumiobus_softc *sc = (void*)parent;
197	struct plumiobus_attach_args pba;
198	int slot;
199
200	/* Disallow wildcarded IO5CS slot */
201	if (cf->cf_loc[PLUMIOBUSIFCF_SLOT] == PLUMIOBUSIFCF_SLOT_DEFAULT) {
202		printf("plumiobus_search: wildcarded slot, skipping\n");
203		return (0);
204	}
205	slot = pba.pba_slot = cf->cf_loc[PLUMIOBUSIFCF_SLOT];
206
207	pba.pba_pc	= sc->sc_pc;
208	pba.pba_iot	= sc->sc_isa[slot].pr_iot;
209	pba.pba_irq	= sc->sc_isa[slot].pr_irq;
210	pba.pba_busname	= "plumisab";
211
212	if (!(sc->sc_isa[slot].pr_enabled) && /* not attached slot */
213	    (*cf->cf_attach->ca_match)(parent, cf, &pba)) {
214		config_attach(parent, cf, &pba, plumiobus_print);
215		sc->sc_isa[slot].pr_enabled = 1;
216	}
217
218	return (0);
219}
220
221int
222plumiobus_print(aux, pnp)
223	void *aux;
224	const char *pnp;
225{
226	return (pnp ? QUIET : UNCONF);
227}
228
229#ifdef PLUMIOBUSDEBUG
230void
231plumiobus_dump(sc)
232	struct plumiobus_softc *sc;
233{
234	bus_space_tag_t regt = sc->sc_regt;
235	bus_space_handle_t regh = sc->sc_regh;
236	plumreg_t reg;
237	int i, wait;
238
239	reg = plum_conf_read(regt, regh, PLUM_IOBUS_IOXBSZ_REG);
240	printf("8bit port:");
241	for (i = 0; i < 6; i++) {
242		if (reg & (1 << i)) {
243			printf(" IO5CS%d", i);
244		}
245	}
246	printf("\n");
247
248	reg = PLUM_IOBUS_IOXCCNT_MASK &
249		plum_conf_read(regt, regh, PLUM_IOBUS_IOXCCNT_REG);
250	printf(" # of wait to become from the access begining: %d clock\n",
251	       reg + 1);
252	reg = plum_conf_read(regt, regh, PLUM_IOBUS_IOXACNT_REG);
253	printf(" # of wait in access clock: ");
254	for (i = 0; i < 5; i++) {
255		wait = (reg >> (i * PLUM_IOBUS_IOXACNT_SHIFT))
256			& PLUM_IOBUS_IOXACNT_MASK;
257		printf("[CS%d:%d] ", i, wait + 1);
258	}
259	printf("\n");
260
261	reg = PLUM_IOBUS_IOXSCNT_MASK &
262		plum_conf_read(regt, regh, PLUM_IOBUS_IOXSCNT_REG);
263	printf(" # of wait during access by I/O bus : %d clock\n", reg + 1);
264
265	reg = plum_conf_read(regt, regh, PLUM_IOBUS_IDEMODE_REG);
266	if (reg & PLUM_IOBUS_IDEMODE) {
267		printf("IO5CS3,4 IDE mode\n");
268	}
269}
270#endif /* PLUMIOBUSDEBUG */
271