plumiobus.c revision 1.2 1 /* $NetBSD: plumiobus.c,v 1.2 1999/12/07 17:37:21 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 plum_power_establish(sc->sc_pc, PLUM_PWR_IO5);
106
107 /* Address space <-> IRQ mapping */
108 pr = &sc->sc_isa[IO5CS0];
109 pr->pr_irq = PLUM_INT_EXT5IO0;
110 pr->pr_iot = __plumiobus_subregion(
111 sc->sc_iot,
112 PLUM_IOBUS_IOBASE + PLUM_IOBUS_IO5CS0BASE,
113 PLUM_IOBUS_IO5SIZE);
114
115 pr = &sc->sc_isa[IO5CS1];
116 pr->pr_irq = PLUM_INT_EXT5IO1;
117 pr->pr_iot = __plumiobus_subregion(
118 sc->sc_iot,
119 PLUM_IOBUS_IOBASE + PLUM_IOBUS_IO5CS1BASE,
120 PLUM_IOBUS_IO5SIZE);
121
122 pr = &sc->sc_isa[IO5CS2];
123 pr->pr_irq = PLUM_INT_EXT5IO2;
124 pr->pr_iot = __plumiobus_subregion(
125 sc->sc_iot,
126 PLUM_IOBUS_IOBASE + PLUM_IOBUS_IO5CS2BASE,
127 PLUM_IOBUS_IO5SIZE);
128
129 pr = &sc->sc_isa[IO5CS3];
130 pr->pr_irq = PLUM_INT_EXT5IO3;
131 pr->pr_iot = __plumiobus_subregion(
132 sc->sc_iot,
133 PLUM_IOBUS_IOBASE + PLUM_IOBUS_IO5CS3BASE,
134 PLUM_IOBUS_IO5SIZE);
135
136 pr = &sc->sc_isa[IO5CS4];
137 pr->pr_irq = PLUM_INT_EXT3IO0; /* XXX */
138 pr->pr_iot = __plumiobus_subregion(
139 sc->sc_iot,
140 PLUM_IOBUS_IOBASE + PLUM_IOBUS_IO5CS4BASE,
141 PLUM_IOBUS_IO5SIZE);
142
143
144 pr = &sc->sc_isa[IO5NCS];
145 pr->pr_irq = PLUM_INT_EXT3IO1;
146 pr->pr_iot = __plumiobus_subregion(
147 sc->sc_iot,
148 PLUM_IOBUS_IOBASE + PLUM_IOBUS_IO5CS5BASE,
149 PLUM_IOBUS_IO5SIZE);
150
151
152 plumiobus_dump(sc);
153
154 config_search(plumiobus_search, self, plumiobus_print);
155 }
156
157 /* XXX something kludge */
158 bus_space_tag_t
159 __plumiobus_subregion(t, ofs, size)
160 bus_space_tag_t t;
161 bus_addr_t ofs;
162 bus_size_t size;
163 {
164 struct hpcmips_bus_space *hbs;
165
166 if (!(hbs = malloc(sizeof(struct hpcmips_bus_space),
167 M_DEVBUF, M_NOWAIT))) {
168 panic ("__plumiobus_subregion: no memory.");
169 }
170 *hbs = *t;
171 hbs->t_base += ofs;
172 hbs->t_size = size;
173
174 return hbs;
175 }
176
177 int
178 plumiobus_search(parent, cf, aux)
179 struct device *parent;
180 struct cfdata *cf;
181 void *aux;
182 {
183 struct plumiobus_softc *sc = (void*)parent;
184 struct plumiobus_attach_args pba;
185 int slot;
186
187 /* Disallow wildcarded IO5CS slot */
188 if (cf->cf_loc[PLUMIOBUSIFCF_SLOT] == PLUMIOBUSIFCF_SLOT_DEFAULT) {
189 printf("plumiobus_search: wildcarded slot, skipping\n");
190 return 0;
191 }
192 slot = pba.pba_slot = cf->cf_loc[PLUMIOBUSIFCF_SLOT];
193
194 pba.pba_pc = sc->sc_pc;
195 pba.pba_iot = sc->sc_isa[slot].pr_iot;
196 pba.pba_irq = sc->sc_isa[slot].pr_irq;
197 pba.pba_busname = "plumisab";
198
199 if (!(sc->sc_isa[slot].pr_enabled) && /* not attached slot */
200 (*cf->cf_attach->ca_match)(parent, cf, &pba)) {
201 config_attach(parent, cf, &pba, plumiobus_print);
202 sc->sc_isa[slot].pr_enabled = 1;
203 }
204
205 return 0;
206 }
207
208 int
209 plumiobus_print(aux, pnp)
210 void *aux;
211 const char *pnp;
212 {
213 return pnp ? QUIET : UNCONF;
214 }
215
216 void
217 plumiobus_dump(sc)
218 struct plumiobus_softc *sc;
219 {
220 bus_space_tag_t regt = sc->sc_regt;
221 bus_space_handle_t regh = sc->sc_regh;
222 plumreg_t reg;
223 int i, wait;
224
225 reg = plum_conf_read(regt, regh, PLUM_IOBUS_IOXBSZ_REG);
226 printf("8bit port:");
227 for (i = 0; i < 6; i++) {
228 if (reg & (1 << i)) {
229 printf(" IO5CS%d", i);
230 }
231 }
232 printf("\n");
233
234 reg = PLUM_IOBUS_IOXCCNT_MASK &
235 plum_conf_read(regt, regh, PLUM_IOBUS_IOXCCNT_REG);
236 printf(" # of wait to become from the access begining: %d clock\n",
237 reg + 1);
238 reg = plum_conf_read(regt, regh, PLUM_IOBUS_IOXACNT_REG);
239 printf(" # of wait in access clock: ");
240 for (i = 0; i < 5; i++) {
241 wait = (reg >> (i * PLUM_IOBUS_IOXACNT_SHIFT))
242 & PLUM_IOBUS_IOXACNT_MASK;
243 printf("[CS%d:%d] ", i, wait + 1);
244 }
245 printf("\n");
246
247 reg = PLUM_IOBUS_IOXSCNT_MASK &
248 plum_conf_read(regt, regh, PLUM_IOBUS_IOXSCNT_REG);
249 printf(" # of wait during access by I/O bus : %d clock\n", reg + 1);
250
251 reg = plum_conf_read(regt, regh, PLUM_IOBUS_IDEMODE_REG);
252 if (reg & PLUM_IOBUS_IDEMODE) {
253 printf("IO5CS3,4 IDE mode\n");
254 }
255
256 }
257
258