plumiobus.c revision 1.1 1 /* $NetBSD: plumiobus.c,v 1.1 1999/11/21 06:50:26 uch Exp $ */
2
3 /*
4 * Copyright (c) 1999, 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
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 int plumiobus_match __P((struct device*, struct cfdata*, void*));
49 void plumiobus_attach __P((struct device*, struct device*, void*));
50 int plumiobus_print __P((void*, const char*));
51 int plumiobus_search __P((struct device*, struct cfdata*, void*));
52
53 struct plumisa_resource {
54 int pr_irq;
55 bus_space_tag_t pr_iot;
56 int pr_enabled;
57 };
58
59 struct plumiobus_softc {
60 struct device sc_dev;
61 plum_chipset_tag_t sc_pc;
62 bus_space_tag_t sc_regt;
63 bus_space_handle_t sc_regh;
64 bus_space_tag_t sc_iot;
65 bus_space_handle_t sc_ioh;
66 struct plumisa_resource sc_isa[PLUM_IOBUS_IO5CSMAX];
67 };
68
69 struct cfattach plumiobus_ca = {
70 sizeof(struct plumiobus_softc), plumiobus_match, plumiobus_attach
71 };
72
73 void plumiobus_dump __P((struct plumiobus_softc*));
74 bus_space_tag_t __plumiobus_subregion __P((bus_space_tag_t, bus_addr_t, bus_size_t));
75
76 int
77 plumiobus_match(parent, cf, aux)
78 struct device *parent;
79 struct cfdata *cf;
80 void *aux;
81 {
82 return 1;
83 }
84
85 void
86 plumiobus_attach(parent, self, aux)
87 struct device *parent;
88 struct device *self;
89 void *aux;
90 {
91 struct plum_attach_args *pa = aux;
92 struct plumiobus_softc *sc = (void*)self;
93 struct plumisa_resource *pr;
94
95 sc->sc_pc = pa->pa_pc;
96 sc->sc_regt = pa->pa_regt;
97 sc->sc_iot = pa->pa_iot;
98
99 if (bus_space_map(sc->sc_regt, PLUM_IOBUS_REGBASE,
100 PLUM_IOBUS_REGSIZE, 0, &sc->sc_regh)) {
101 printf(": register map failed.\n");
102 return;
103 }
104 printf("\n");
105
106 /* Address space <-> IRQ mapping */
107 pr = &sc->sc_isa[IO5CS0];
108 pr->pr_irq = PLUM_INT_EXT5IO0;
109 pr->pr_iot = __plumiobus_subregion(
110 sc->sc_iot,
111 PLUM_IOBUS_IOBASE + PLUM_IOBUS_IO5CS0BASE,
112 PLUM_IOBUS_IO5SIZE);
113
114 pr = &sc->sc_isa[IO5CS1];
115 pr->pr_irq = PLUM_INT_EXT5IO1;
116 pr->pr_iot = __plumiobus_subregion(
117 sc->sc_iot,
118 PLUM_IOBUS_IOBASE + PLUM_IOBUS_IO5CS1BASE,
119 PLUM_IOBUS_IO5SIZE);
120
121 pr = &sc->sc_isa[IO5CS2];
122 pr->pr_irq = PLUM_INT_EXT5IO2;
123 pr->pr_iot = __plumiobus_subregion(
124 sc->sc_iot,
125 PLUM_IOBUS_IOBASE + PLUM_IOBUS_IO5CS2BASE,
126 PLUM_IOBUS_IO5SIZE);
127
128 pr = &sc->sc_isa[IO5CS3];
129 pr->pr_irq = PLUM_INT_EXT5IO3;
130 pr->pr_iot = __plumiobus_subregion(
131 sc->sc_iot,
132 PLUM_IOBUS_IOBASE + PLUM_IOBUS_IO5CS3BASE,
133 PLUM_IOBUS_IO5SIZE);
134
135 pr = &sc->sc_isa[IO5CS4];
136 pr->pr_irq = PLUM_INT_EXT3IO0; /* XXX */
137 pr->pr_iot = __plumiobus_subregion(
138 sc->sc_iot,
139 PLUM_IOBUS_IOBASE + PLUM_IOBUS_IO5CS4BASE,
140 PLUM_IOBUS_IO5SIZE);
141
142
143 pr = &sc->sc_isa[IO5NCS];
144 pr->pr_irq = PLUM_INT_EXT3IO1;
145 pr->pr_iot = __plumiobus_subregion(
146 sc->sc_iot,
147 PLUM_IOBUS_IOBASE + PLUM_IOBUS_IO5CS5BASE,
148 PLUM_IOBUS_IO5SIZE);
149
150
151 plumiobus_dump(sc);
152
153 config_search(plumiobus_search, self, plumiobus_print);
154 }
155
156 /* XXX something kludge */
157 bus_space_tag_t
158 __plumiobus_subregion(t, ofs, size)
159 bus_space_tag_t t;
160 bus_addr_t ofs;
161 bus_size_t size;
162 {
163 struct hpcmips_bus_space *hbs;
164
165 if (!(hbs = malloc(sizeof(struct hpcmips_bus_space),
166 M_DEVBUF, M_NOWAIT))) {
167 panic ("__plumiobus_subregion: no memory.");
168 }
169 *hbs = *t;
170 hbs->t_base += ofs;
171 hbs->t_size = size;
172
173 return hbs;
174 }
175
176 int
177 plumiobus_search(parent, cf, aux)
178 struct device *parent;
179 struct cfdata *cf;
180 void *aux;
181 {
182 struct plumiobus_softc *sc = (void*)parent;
183 struct plumiobus_attach_args pba;
184 int slot;
185
186 /* Disallow wildcarded IO5CS slot */
187 if (cf->cf_loc[PLUMIOBUSIFCF_SLOT] == PLUMIOBUSIFCF_SLOT_DEFAULT) {
188 printf("plumiobus_search: wildcarded slot, skipping\n");
189 return 0;
190 }
191 slot = pba.pba_slot = cf->cf_loc[PLUMIOBUSIFCF_SLOT];
192
193 pba.pba_pc = sc->sc_pc;
194 pba.pba_iot = sc->sc_isa[slot].pr_iot;
195 pba.pba_irq = sc->sc_isa[slot].pr_irq;
196 pba.pba_busname = "plumisab";
197
198 if (!(sc->sc_isa[slot].pr_enabled) && /* not attached slot */
199 (*cf->cf_attach->ca_match)(parent, cf, &pba)) {
200 config_attach(parent, cf, &pba, plumiobus_print);
201 sc->sc_isa[slot].pr_enabled = 1;
202 }
203
204 return 0;
205 }
206
207 int
208 plumiobus_print(aux, pnp)
209 void *aux;
210 const char *pnp;
211 {
212 return pnp ? QUIET : UNCONF;
213 }
214
215 void
216 plumiobus_dump(sc)
217 struct plumiobus_softc *sc;
218 {
219 bus_space_tag_t regt = sc->sc_regt;
220 bus_space_handle_t regh = sc->sc_regh;
221 plumreg_t reg;
222 int i, wait;
223
224 reg = plum_conf_read(regt, regh, PLUM_IOBUS_IOXBSZ_REG);
225 printf("8bit port:");
226 for (i = 0; i < 6; i++) {
227 if (reg & (1 << i)) {
228 printf(" IO5CS%d", i);
229 }
230 }
231 printf("\n");
232
233 reg = PLUM_IOBUS_IOXCCNT_MASK &
234 plum_conf_read(regt, regh, PLUM_IOBUS_IOXCCNT_REG);
235 printf(" # of wait to become from the access begining: %d clock\n",
236 reg + 1);
237 reg = plum_conf_read(regt, regh, PLUM_IOBUS_IOXACNT_REG);
238 printf(" # of wait in access clock: ");
239 for (i = 0; i < 5; i++) {
240 wait = (reg >> (i * PLUM_IOBUS_IOXACNT_SHIFT))
241 & PLUM_IOBUS_IOXACNT_MASK;
242 printf("[CS%d:%d] ", i, wait + 1);
243 }
244 printf("\n");
245
246 reg = PLUM_IOBUS_IOXSCNT_MASK &
247 plum_conf_read(regt, regh, PLUM_IOBUS_IOXSCNT_REG);
248 printf(" # of wait during access by I/O bus : %d clock\n", reg + 1);
249
250 reg = plum_conf_read(regt, regh, PLUM_IOBUS_IDEMODE_REG);
251 if (reg & PLUM_IOBUS_IDEMODE) {
252 printf("IO5CS3,4 IDE mode\n");
253 }
254
255 }
256
257