gio.c revision 1.9.2.1 1 1.9.2.1 skrll /* $NetBSD: gio.c,v 1.9.2.1 2004/08/03 10:40:05 skrll Exp $ */
2 1.1 soren
3 1.1 soren /*
4 1.1 soren * Copyright (c) 2000 Soren S. Jorvang
5 1.1 soren * All rights reserved.
6 1.2 simonb *
7 1.1 soren * Redistribution and use in source and binary forms, with or without
8 1.1 soren * modification, are permitted provided that the following conditions
9 1.1 soren * are met:
10 1.1 soren * 1. Redistributions of source code must retain the above copyright
11 1.1 soren * notice, this list of conditions and the following disclaimer.
12 1.1 soren * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 soren * notice, this list of conditions and the following disclaimer in the
14 1.1 soren * documentation and/or other materials provided with the distribution.
15 1.1 soren * 3. All advertising materials mentioning features or use of this software
16 1.1 soren * must display the following acknowledgement:
17 1.1 soren * This product includes software developed for the
18 1.9.2.1 skrll * NetBSD Project. See http://www.NetBSD.org/ for
19 1.1 soren * information about NetBSD.
20 1.1 soren * 4. The name of the author may not be used to endorse or promote products
21 1.1 soren * derived from this software without specific prior written permission.
22 1.2 simonb *
23 1.1 soren * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24 1.1 soren * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25 1.1 soren * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 1.1 soren * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27 1.1 soren * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28 1.1 soren * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 1.1 soren * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 1.1 soren * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 1.1 soren * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32 1.1 soren * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 1.1 soren */
34 1.1 soren
35 1.9.2.1 skrll #include <sys/cdefs.h>
36 1.9.2.1 skrll __KERNEL_RCSID(0, "$NetBSD: gio.c,v 1.9.2.1 2004/08/03 10:40:05 skrll Exp $");
37 1.9.2.1 skrll
38 1.1 soren #include "opt_ddb.h"
39 1.1 soren
40 1.1 soren #include <sys/param.h>
41 1.1 soren #include <sys/systm.h>
42 1.1 soren #include <sys/device.h>
43 1.1 soren
44 1.9.2.1 skrll #include <machine/bus.h>
45 1.9.2.1 skrll
46 1.1 soren #include <sgimips/gio/gioreg.h>
47 1.1 soren #include <sgimips/gio/giovar.h>
48 1.9.2.1 skrll #include <sgimips/gio/giodevs_data.h>
49 1.1 soren
50 1.1 soren #include "locators.h"
51 1.9.2.1 skrll #include "newport.h"
52 1.9.2.1 skrll #include "grtwo.h"
53 1.9.2.1 skrll
54 1.9.2.1 skrll #if (NNEWPORT > 0)
55 1.9.2.1 skrll #include <sgimips/gio/newportvar.h>
56 1.9.2.1 skrll #endif
57 1.9.2.1 skrll
58 1.9.2.1 skrll #if (NGRTWO > 0)
59 1.9.2.1 skrll #include <sgimips/gio/grtwovar.h>
60 1.9.2.1 skrll #endif
61 1.1 soren
62 1.1 soren struct gio_softc {
63 1.1 soren struct device sc_dev;
64 1.1 soren };
65 1.1 soren
66 1.1 soren static int gio_match(struct device *, struct cfdata *, void *);
67 1.1 soren static void gio_attach(struct device *, struct device *, void *);
68 1.1 soren static int gio_print(void *, const char *);
69 1.1 soren static int gio_search(struct device *, struct cfdata *, void *);
70 1.9.2.1 skrll static int gio_submatch(struct device *, struct cfdata *, void *);
71 1.1 soren
72 1.6 thorpej CFATTACH_DECL(gio, sizeof(struct gio_softc),
73 1.7 thorpej gio_match, gio_attach, NULL, NULL);
74 1.1 soren
75 1.9.2.1 skrll static uint32_t gio_slot_addr[] = {
76 1.9.2.1 skrll 0x1f400000,
77 1.9.2.1 skrll 0x1f600000,
78 1.9.2.1 skrll 0x1f000000,
79 1.9.2.1 skrll 0
80 1.9.2.1 skrll };
81 1.9.2.1 skrll
82 1.1 soren static int
83 1.9.2.1 skrll gio_match(struct device *parent, struct cfdata *match, void *aux)
84 1.1 soren {
85 1.1 soren struct giobus_attach_args *gba = aux;
86 1.1 soren
87 1.3 thorpej if (strcmp(gba->gba_busname, match->cf_name) != 0)
88 1.1 soren return 0;
89 1.1 soren
90 1.2 simonb return 1;
91 1.1 soren }
92 1.1 soren
93 1.1 soren static void
94 1.9.2.1 skrll gio_attach(struct device *parent, struct device *self, void *aux)
95 1.1 soren {
96 1.1 soren struct gio_attach_args ga;
97 1.9.2.1 skrll int i;
98 1.1 soren
99 1.1 soren printf("\n");
100 1.1 soren
101 1.9.2.1 skrll for (i=0; gio_slot_addr[i] != 0; i++) {
102 1.9.2.1 skrll ga.ga_slot = i;
103 1.9.2.1 skrll ga.ga_addr = gio_slot_addr[i];
104 1.9.2.1 skrll ga.ga_iot = 0;
105 1.9.2.1 skrll ga.ga_ioh = MIPS_PHYS_TO_KSEG1(gio_slot_addr[i]);
106 1.9.2.1 skrll
107 1.9.2.1 skrll #if 0
108 1.9.2.1 skrll /* XXX */
109 1.9.2.1 skrll if (bus_space_peek_4(ga.ga_iot, ga.ga_ioh, 0, &ga.ga_product))
110 1.9.2.1 skrll continue;
111 1.9.2.1 skrll #else
112 1.9.2.1 skrll if (badaddr((void *)ga.ga_ioh,sizeof(uint32_t)))
113 1.9.2.1 skrll continue;
114 1.9.2.1 skrll
115 1.9.2.1 skrll ga.ga_product = bus_space_read_4(ga.ga_iot, ga.ga_ioh, 0);
116 1.9.2.1 skrll #endif
117 1.9.2.1 skrll
118 1.9.2.1 skrll config_found_sm(self, &ga, gio_print, gio_submatch);
119 1.9.2.1 skrll }
120 1.9.2.1 skrll
121 1.1 soren config_search(gio_search, self, &ga);
122 1.1 soren }
123 1.1 soren
124 1.1 soren static int
125 1.9.2.1 skrll gio_print(void *aux, const char *pnp)
126 1.1 soren {
127 1.1 soren struct gio_attach_args *ga = aux;
128 1.9.2.1 skrll int i = 0;
129 1.9.2.1 skrll
130 1.9.2.1 skrll if (pnp != NULL) {
131 1.9.2.1 skrll int product, revision;
132 1.1 soren
133 1.9.2.1 skrll product = GIO_PRODUCT_PRODUCTID(ga->ga_product);
134 1.9.2.1 skrll
135 1.9.2.1 skrll if (GIO_PRODUCT_32BIT_ID(ga->ga_product))
136 1.9.2.1 skrll revision = GIO_PRODUCT_REVISION(ga->ga_product);
137 1.9.2.1 skrll else
138 1.9.2.1 skrll revision = 0;
139 1.9.2.1 skrll
140 1.9.2.1 skrll while (gio_knowndevs[i].productid != 0) {
141 1.9.2.1 skrll if (gio_knowndevs[i].productid == product) {
142 1.9.2.1 skrll aprint_normal("%s", gio_knowndevs[i].product);
143 1.9.2.1 skrll break;
144 1.9.2.1 skrll }
145 1.9.2.1 skrll i++;
146 1.9.2.1 skrll }
147 1.9.2.1 skrll
148 1.9.2.1 skrll if (gio_knowndevs[i].productid == 0)
149 1.9.2.1 skrll aprint_normal("unknown GIO card");
150 1.9.2.1 skrll
151 1.9.2.1 skrll aprint_normal(" (product 0x%02x revision 0x%02x) at %s",
152 1.9.2.1 skrll product, revision, pnp);
153 1.9.2.1 skrll }
154 1.1 soren
155 1.1 soren if (ga->ga_slot != GIOCF_SLOT_DEFAULT)
156 1.9 thorpej aprint_normal(" slot %d", ga->ga_slot);
157 1.8 thorpej if (ga->ga_addr != (uint32_t) GIOCF_ADDR_DEFAULT)
158 1.9 thorpej aprint_normal(" addr 0x%x", ga->ga_addr);
159 1.1 soren
160 1.1 soren return UNCONF;
161 1.1 soren }
162 1.1 soren
163 1.1 soren static int
164 1.9.2.1 skrll gio_search(struct device *parent, struct cfdata *cf, void *aux)
165 1.2 simonb {
166 1.1 soren struct gio_attach_args *ga = aux;
167 1.1 soren
168 1.1 soren do {
169 1.9.2.1 skrll /* Handled by direct configuration, so skip here */
170 1.9.2.1 skrll if (cf->cf_loc[GIOCF_ADDR] == GIOCF_ADDR_DEFAULT)
171 1.9.2.1 skrll return 0;
172 1.9.2.1 skrll
173 1.1 soren ga->ga_slot = cf->cf_loc[GIOCF_SLOT];
174 1.1 soren ga->ga_addr = cf->cf_loc[GIOCF_ADDR];
175 1.1 soren ga->ga_iot = 0;
176 1.1 soren ga->ga_ioh = MIPS_PHYS_TO_KSEG1(ga->ga_addr);
177 1.9.2.1 skrll
178 1.4 thorpej if (config_match(parent, cf, ga) > 0)
179 1.1 soren config_attach(parent, cf, ga, gio_print);
180 1.1 soren } while (cf->cf_fstate == FSTATE_STAR);
181 1.1 soren
182 1.1 soren return 0;
183 1.1 soren }
184 1.9.2.1 skrll
185 1.9.2.1 skrll static int
186 1.9.2.1 skrll gio_submatch(struct device *parent, struct cfdata *cf, void *aux)
187 1.9.2.1 skrll {
188 1.9.2.1 skrll struct gio_attach_args *ga = aux;
189 1.9.2.1 skrll
190 1.9.2.1 skrll if (cf->cf_loc[GIOCF_SLOT] != GIOCF_SLOT_DEFAULT &&
191 1.9.2.1 skrll cf->cf_loc[GIOCF_SLOT] != ga->ga_slot)
192 1.9.2.1 skrll return 0;
193 1.9.2.1 skrll
194 1.9.2.1 skrll if (cf->cf_loc[GIOCF_ADDR] != GIOCF_ADDR_DEFAULT &&
195 1.9.2.1 skrll cf->cf_loc[GIOCF_ADDR] != ga->ga_addr)
196 1.9.2.1 skrll return 0;
197 1.9.2.1 skrll
198 1.9.2.1 skrll return config_match(parent, cf, aux);
199 1.9.2.1 skrll }
200 1.9.2.1 skrll
201 1.9.2.1 skrll int
202 1.9.2.1 skrll gio_cnattach()
203 1.9.2.1 skrll {
204 1.9.2.1 skrll struct gio_attach_args ga;
205 1.9.2.1 skrll int i;
206 1.9.2.1 skrll
207 1.9.2.1 skrll /* XXX Duplicate code XXX */
208 1.9.2.1 skrll for (i=0; gio_slot_addr[i] != 0; i++) {
209 1.9.2.1 skrll ga.ga_slot = i;
210 1.9.2.1 skrll ga.ga_addr = gio_slot_addr[i];
211 1.9.2.1 skrll ga.ga_iot = 0;
212 1.9.2.1 skrll ga.ga_ioh = MIPS_PHYS_TO_KSEG1(gio_slot_addr[i]);
213 1.9.2.1 skrll
214 1.9.2.1 skrll #if 0
215 1.9.2.1 skrll /* XXX */
216 1.9.2.1 skrll if (bus_space_peek_4(ga.ga_iot, ga.ga_ioh, 0, &ga.ga_product))
217 1.9.2.1 skrll continue;
218 1.9.2.1 skrll #else
219 1.9.2.1 skrll
220 1.9.2.1 skrll if (badaddr((void *)ga.ga_ioh,sizeof(uint32_t)))
221 1.9.2.1 skrll continue;
222 1.9.2.1 skrll
223 1.9.2.1 skrll ga.ga_product = bus_space_read_4(ga.ga_iot, ga.ga_ioh, 0);
224 1.9.2.1 skrll #endif
225 1.9.2.1 skrll
226 1.9.2.1 skrll #if (NGRTWO > 0)
227 1.9.2.1 skrll if (grtwo_cnattach(&ga) == 0)
228 1.9.2.1 skrll return 0;
229 1.9.2.1 skrll #endif
230 1.9.2.1 skrll
231 1.9.2.1 skrll /* XXX This probably attaches console to the wrong newport on
232 1.9.2.1 skrll * dualhead Indys, as GFX slot is tried last not first */
233 1.9.2.1 skrll #if (NNEWPORT > 0)
234 1.9.2.1 skrll if (newport_cnattach(&ga) == 0)
235 1.9.2.1 skrll return 0;
236 1.9.2.1 skrll #endif
237 1.9.2.1 skrll
238 1.9.2.1 skrll }
239 1.9.2.1 skrll
240 1.9.2.1 skrll return ENXIO;
241 1.9.2.1 skrll }
242