1*c7fb772bSthorpej /* $NetBSD: gio.c,v 1.38 2021/08/07 16:19:04 thorpej Exp $ */
2f12e2b4dSsoren
3f12e2b4dSsoren /*
4f12e2b4dSsoren * Copyright (c) 2000 Soren S. Jorvang
5f12e2b4dSsoren * All rights reserved.
6f12e2b4dSsoren *
7f12e2b4dSsoren * Redistribution and use in source and binary forms, with or without
8f12e2b4dSsoren * modification, are permitted provided that the following conditions
9f12e2b4dSsoren * are met:
10f12e2b4dSsoren * 1. Redistributions of source code must retain the above copyright
11f12e2b4dSsoren * notice, this list of conditions and the following disclaimer.
12f12e2b4dSsoren * 2. Redistributions in binary form must reproduce the above copyright
13f12e2b4dSsoren * notice, this list of conditions and the following disclaimer in the
14f12e2b4dSsoren * documentation and/or other materials provided with the distribution.
15f12e2b4dSsoren * 3. All advertising materials mentioning features or use of this software
16f12e2b4dSsoren * must display the following acknowledgement:
17f12e2b4dSsoren * This product includes software developed for the
1807147999Skeihan * NetBSD Project. See http://www.NetBSD.org/ for
19f12e2b4dSsoren * information about NetBSD.
20f12e2b4dSsoren * 4. The name of the author may not be used to endorse or promote products
21f12e2b4dSsoren * derived from this software without specific prior written permission.
22f12e2b4dSsoren *
23f12e2b4dSsoren * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
24f12e2b4dSsoren * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
25f12e2b4dSsoren * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26f12e2b4dSsoren * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
27f12e2b4dSsoren * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
28f12e2b4dSsoren * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29f12e2b4dSsoren * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30f12e2b4dSsoren * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31f12e2b4dSsoren * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
32f12e2b4dSsoren * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33f12e2b4dSsoren */
34f12e2b4dSsoren
35ed517291Slukem #include <sys/cdefs.h>
36*c7fb772bSthorpej __KERNEL_RCSID(0, "$NetBSD: gio.c,v 1.38 2021/08/07 16:19:04 thorpej Exp $");
37ed517291Slukem
38f12e2b4dSsoren #include "opt_ddb.h"
39f12e2b4dSsoren
40f12e2b4dSsoren #include <sys/param.h>
41f12e2b4dSsoren #include <sys/systm.h>
42f12e2b4dSsoren #include <sys/device.h>
43f12e2b4dSsoren
44cf10107dSdyoung #include <sys/bus.h>
452d1cbf72Srumble #include <machine/machtype.h>
461426ceedSrumble #include <machine/sysconf.h>
4761349135Slonewolf
48f12e2b4dSsoren #include <sgimips/gio/gioreg.h>
49f12e2b4dSsoren #include <sgimips/gio/giovar.h>
5069911c67Ssekiya #include <sgimips/gio/giodevs_data.h>
51f12e2b4dSsoren
52f12e2b4dSsoren #include "locators.h"
5361349135Slonewolf #include "newport.h"
549c873da2Ssekiya #include "grtwo.h"
55163b9bb1Srumble #include "light.h"
562d1cbf72Srumble #include "imc.h"
572d1cbf72Srumble #include "pic.h"
5861349135Slonewolf
5961349135Slonewolf #if (NNEWPORT > 0)
6061349135Slonewolf #include <sgimips/gio/newportvar.h>
6161349135Slonewolf #endif
62f12e2b4dSsoren
639c873da2Ssekiya #if (NGRTWO > 0)
649c873da2Ssekiya #include <sgimips/gio/grtwovar.h>
659c873da2Ssekiya #endif
669c873da2Ssekiya
67eb755ecbSrumble #if (NLIGHT > 0)
68eb755ecbSrumble #include <sgimips/gio/lightvar.h>
69eb755ecbSrumble #endif
70eb755ecbSrumble
712d1cbf72Srumble #if (NIMC > 0)
722d1cbf72Srumble extern int imc_gio64_arb_config(int, uint32_t);
732d1cbf72Srumble #endif
742d1cbf72Srumble
752d1cbf72Srumble #if (NPIC > 0)
762d1cbf72Srumble extern int pic_gio32_arb_config(int, uint32_t);
772d1cbf72Srumble #endif
782d1cbf72Srumble
792d1cbf72Srumble
80cbab9cadSchs static int gio_match(device_t, cfdata_t, void *);
81cbab9cadSchs static void gio_attach(device_t, device_t, void *);
82f12e2b4dSsoren static int gio_print(void *, const char *);
83cbab9cadSchs static int gio_search(device_t, cfdata_t, const int *, void *);
84cbab9cadSchs static int gio_submatch(device_t, cfdata_t, const int *, void *);
85f12e2b4dSsoren
86cbab9cadSchs CFATTACH_DECL_NEW(gio, 0,
8789bf5a8fSthorpej gio_match, gio_attach, NULL, NULL);
88f12e2b4dSsoren
89163b9bb1Srumble struct gio_probe {
90163b9bb1Srumble uint32_t slot;
91163b9bb1Srumble uint32_t base;
92163b9bb1Srumble uint32_t mach_type;
93163b9bb1Srumble uint32_t mach_subtype;
9461349135Slonewolf };
9561349135Slonewolf
96163b9bb1Srumble /*
97163b9bb1Srumble * Expansion Slot Base Addresses
98163b9bb1Srumble *
99163b9bb1Srumble * IP12, IP20 and IP24 have two GIO connectors: GIO_SLOT_EXP0 and
100163b9bb1Srumble * GIO_SLOT_EXP1.
101163b9bb1Srumble *
102163b9bb1Srumble * On IP24 these slots exist on the graphics board or the IOPLUS
103163b9bb1Srumble * "mezzanine" on Indy and Challenge S, respectively. The IOPLUS or
104163b9bb1Srumble * graphics board connects to the mainboard via a single GIO64 connector.
105163b9bb1Srumble *
106163b9bb1Srumble * IP22 has either three or four physical connectors, but only two
107163b9bb1Srumble * electrically distinct slots: GIO_SLOT_GFX and GIO_SLOT_EXP0.
108163b9bb1Srumble *
109163b9bb1Srumble * It should also be noted that DMA is (mostly) not supported in Challenge
110163b9bb1Srumble * S's GIO_SLOT_EXP1. See gio(4) for the story.
111163b9bb1Srumble */
112163b9bb1Srumble static const struct gio_probe slot_bases[] = {
113163b9bb1Srumble { GIO_SLOT_GFX, 0x1f000000, MACH_SGI_IP22, MACH_SGI_IP22_FULLHOUSE },
114163b9bb1Srumble
115163b9bb1Srumble { GIO_SLOT_EXP0, 0x1f400000, MACH_SGI_IP12, -1 },
116163b9bb1Srumble { GIO_SLOT_EXP0, 0x1f400000, MACH_SGI_IP20, -1 },
117163b9bb1Srumble { GIO_SLOT_EXP0, 0x1f400000, MACH_SGI_IP22, -1 },
118163b9bb1Srumble
119163b9bb1Srumble { GIO_SLOT_EXP1, 0x1f600000, MACH_SGI_IP12, -1 },
120163b9bb1Srumble { GIO_SLOT_EXP1, 0x1f600000, MACH_SGI_IP20, -1 },
121163b9bb1Srumble { GIO_SLOT_EXP1, 0x1f600000, MACH_SGI_IP22, MACH_SGI_IP22_GUINNESS },
122163b9bb1Srumble
123163b9bb1Srumble { 0, 0, 0, 0 }
124163b9bb1Srumble };
125163b9bb1Srumble
126163b9bb1Srumble /*
127163b9bb1Srumble * Graphic Board Base Addresses
128163b9bb1Srumble *
129163b9bb1Srumble * Graphics boards are not treated like expansion slot cards. Their base
130163b9bb1Srumble * addresses do not necessarily correspond to GIO slot addresses and they
131163b9bb1Srumble * do not contain product identification words.
132163b9bb1Srumble */
133163b9bb1Srumble static const struct gio_probe gfx_bases[] = {
134163b9bb1Srumble /* grtwo, and newport on IP22 */
135163b9bb1Srumble { -1, 0x1f000000, MACH_SGI_IP12, -1 },
136163b9bb1Srumble { -1, 0x1f000000, MACH_SGI_IP20, -1 },
137163b9bb1Srumble { -1, 0x1f000000, MACH_SGI_IP22, -1 },
138163b9bb1Srumble
139163b9bb1Srumble /* light */
140163b9bb1Srumble { -1, 0x1f3f0000, MACH_SGI_IP12, -1 },
141163b9bb1Srumble { -1, 0x1f3f0000, MACH_SGI_IP20, -1 },
142163b9bb1Srumble
143163b9bb1Srumble /* light (dual headed) */
144163b9bb1Srumble { -1, 0x1f3f8000, MACH_SGI_IP12, -1 },
145163b9bb1Srumble { -1, 0x1f3f8000, MACH_SGI_IP20, -1 },
146163b9bb1Srumble
147163b9bb1Srumble /* grtwo, and newport on IP22 */
148163b9bb1Srumble { -1, 0x1f400000, MACH_SGI_IP12, -1 },
149163b9bb1Srumble { -1, 0x1f400000, MACH_SGI_IP20, -1 },
150163b9bb1Srumble { -1, 0x1f400000, MACH_SGI_IP22, -1 },
151163b9bb1Srumble
152163b9bb1Srumble /* grtwo */
153163b9bb1Srumble { -1, 0x1f600000, MACH_SGI_IP12, -1 },
154163b9bb1Srumble { -1, 0x1f600000, MACH_SGI_IP20, -1 },
155163b9bb1Srumble { -1, 0x1f600000, MACH_SGI_IP22, -1 },
156163b9bb1Srumble
157163b9bb1Srumble /* newport */
158163b9bb1Srumble { -1, 0x1f800000, MACH_SGI_IP22, MACH_SGI_IP22_FULLHOUSE },
159163b9bb1Srumble
160163b9bb1Srumble /* newport */
161163b9bb1Srumble { -1, 0x1fc00000, MACH_SGI_IP22, MACH_SGI_IP22_FULLHOUSE },
162163b9bb1Srumble
163163b9bb1Srumble { 0, 0, 0, 0 }
164163b9bb1Srumble };
165163b9bb1Srumble
166163b9bb1Srumble /* maximum number of graphics boards possible (arbitrarily large estimate) */
167163b9bb1Srumble #define MAXGFX 8
168163b9bb1Srumble
169f12e2b4dSsoren static int
gio_match(device_t parent,cfdata_t match,void * aux)170cbab9cadSchs gio_match(device_t parent, cfdata_t match, void *aux)
171f12e2b4dSsoren {
172439e902aSrumble if (mach_type == MACH_SGI_IP12 || mach_type == MACH_SGI_IP20 ||
173439e902aSrumble mach_type == MACH_SGI_IP22)
174f12e2b4dSsoren return 1;
175439e902aSrumble
176439e902aSrumble return 0;
177f12e2b4dSsoren }
178f12e2b4dSsoren
179f12e2b4dSsoren static void
gio_attach(device_t parent,device_t self,void * aux)180cbab9cadSchs gio_attach(device_t parent, device_t self, void *aux)
181f12e2b4dSsoren {
182f12e2b4dSsoren struct gio_attach_args ga;
183163b9bb1Srumble uint32_t gfx[MAXGFX];
184163b9bb1Srumble int i, j, ngfx;
185f12e2b4dSsoren
186f12e2b4dSsoren printf("\n");
187f12e2b4dSsoren
188163b9bb1Srumble ngfx = 0;
189163b9bb1Srumble memset(gfx, 0, sizeof(gfx));
190163b9bb1Srumble
191163b9bb1Srumble /*
192163b9bb1Srumble * Attach graphics devices first. They do not contain a Product
193163b9bb1Srumble * Identification Word and have no slot number.
194163b9bb1Srumble *
195163b9bb1Srumble * Record addresses to which graphics devices attach so that
196163b9bb1Srumble * we do not confuse them with expansion slots, should the
197163b9bb1Srumble * addresses coincide.
198163b9bb1Srumble */
199163b9bb1Srumble for (i = 0; gfx_bases[i].base != 0; i++) {
200163b9bb1Srumble /* skip slots that don't apply to us */
201163b9bb1Srumble if (gfx_bases[i].mach_type != mach_type)
202163b9bb1Srumble continue;
203163b9bb1Srumble
204163b9bb1Srumble if (gfx_bases[i].mach_subtype != -1 &&
205163b9bb1Srumble gfx_bases[i].mach_subtype != mach_subtype)
206163b9bb1Srumble continue;
207163b9bb1Srumble
208163b9bb1Srumble ga.ga_slot = -1;
209163b9bb1Srumble ga.ga_addr = gfx_bases[i].base;
2106f0091eeSmacallan /* XXX */
2116f0091eeSmacallan if (platform.badaddr((void *)MIPS_PHYS_TO_KSEG1(ga.ga_addr),
2126f0091eeSmacallan sizeof(uint32_t)))
2136f0091eeSmacallan continue;
214eb488f67Smacallan ga.ga_iot = normal_memt;
2156f0091eeSmacallan if (bus_space_map(normal_memt, ga.ga_addr, 0,
2166f0091eeSmacallan BUS_SPACE_MAP_LINEAR, &ga.ga_ioh) != 0)
2176f0091eeSmacallan continue;
218163b9bb1Srumble ga.ga_dmat = &sgimips_default_bus_dma_tag;
219163b9bb1Srumble ga.ga_product = -1;
220163b9bb1Srumble
221163b9bb1Srumble
2222685996bSthorpej if (config_found(self, &ga, gio_print,
223*c7fb772bSthorpej CFARGS(.submatch = gio_submatch)) != NULL) {
224163b9bb1Srumble if (ngfx == MAXGFX)
225163b9bb1Srumble panic("gio_attach: MAXGFX");
226163b9bb1Srumble gfx[ngfx++] = gfx_bases[i].base;
227163b9bb1Srumble }
228163b9bb1Srumble }
229163b9bb1Srumble
230163b9bb1Srumble /*
231163b9bb1Srumble * Now attach any GIO expansion cards.
232163b9bb1Srumble *
233163b9bb1Srumble * Be sure to skip any addresses to which a graphics device has
234163b9bb1Srumble * already been attached.
235163b9bb1Srumble */
236163b9bb1Srumble for (i = 0; slot_bases[i].base != 0; i++) {
237f6d76ae2Sthorpej bool skip = false;
238163b9bb1Srumble
239163b9bb1Srumble /* skip slots that don't apply to us */
240163b9bb1Srumble if (slot_bases[i].mach_type != mach_type)
241163b9bb1Srumble continue;
242163b9bb1Srumble
243163b9bb1Srumble if (slot_bases[i].mach_subtype != -1 &&
244163b9bb1Srumble slot_bases[i].mach_subtype != mach_subtype)
245163b9bb1Srumble continue;
246163b9bb1Srumble
247163b9bb1Srumble for (j = 0; j < ngfx; j++) {
248163b9bb1Srumble if (slot_bases[i].base == gfx[j]) {
249f6d76ae2Sthorpej skip = true;
250163b9bb1Srumble break;
251163b9bb1Srumble }
252163b9bb1Srumble }
253163b9bb1Srumble if (skip)
254163b9bb1Srumble continue;
255163b9bb1Srumble
256163b9bb1Srumble ga.ga_slot = slot_bases[i].slot;
257163b9bb1Srumble ga.ga_addr = slot_bases[i].base;
2586f0091eeSmacallan /* XXX */
2596f0091eeSmacallan if (platform.badaddr((void *)MIPS_PHYS_TO_KSEG1(ga.ga_addr),
2606f0091eeSmacallan sizeof(uint32_t)))
26161349135Slonewolf continue;
2626f0091eeSmacallan ga.ga_iot = normal_memt;
2636f0091eeSmacallan if (bus_space_map(normal_memt, ga.ga_addr, 0,
2646f0091eeSmacallan BUS_SPACE_MAP_LINEAR, &ga.ga_ioh) != 0)
2656f0091eeSmacallan continue;
2666f0091eeSmacallan ga.ga_dmat = &sgimips_default_bus_dma_tag;
26761349135Slonewolf
26861349135Slonewolf ga.ga_product = bus_space_read_4(ga.ga_iot, ga.ga_ioh, 0);
26961349135Slonewolf
2702685996bSthorpej config_found(self, &ga, gio_print,
271*c7fb772bSthorpej CFARGS(.submatch = gio_submatch));
27261349135Slonewolf }
27361349135Slonewolf
2742685996bSthorpej config_search(self, &ga,
275*c7fb772bSthorpej CFARGS(.search = gio_search));
276f12e2b4dSsoren }
277f12e2b4dSsoren
278f12e2b4dSsoren static int
gio_print(void * aux,const char * pnp)27961349135Slonewolf gio_print(void *aux, const char *pnp)
280f12e2b4dSsoren {
281f12e2b4dSsoren struct gio_attach_args *ga = aux;
282c370623aSsekiya int i = 0;
283f12e2b4dSsoren
284163b9bb1Srumble /* gfx probe */
285163b9bb1Srumble if (ga->ga_product == -1)
286163b9bb1Srumble return (QUIET);
287163b9bb1Srumble
28861349135Slonewolf if (pnp != NULL) {
28961349135Slonewolf int product, revision;
29061349135Slonewolf
29161349135Slonewolf product = GIO_PRODUCT_PRODUCTID(ga->ga_product);
29261349135Slonewolf
29361349135Slonewolf if (GIO_PRODUCT_32BIT_ID(ga->ga_product))
29461349135Slonewolf revision = GIO_PRODUCT_REVISION(ga->ga_product);
29561349135Slonewolf else
29661349135Slonewolf revision = 0;
29761349135Slonewolf
298c370623aSsekiya while (gio_knowndevs[i].productid != 0) {
299c370623aSsekiya if (gio_knowndevs[i].productid == product) {
300c370623aSsekiya aprint_normal("%s", gio_knowndevs[i].product);
301c370623aSsekiya break;
302c370623aSsekiya }
303c370623aSsekiya i++;
304c370623aSsekiya }
305c370623aSsekiya
306c370623aSsekiya if (gio_knowndevs[i].productid == 0)
307c370623aSsekiya aprint_normal("unknown GIO card");
308c370623aSsekiya
309c370623aSsekiya aprint_normal(" (product 0x%02x revision 0x%02x) at %s",
31061349135Slonewolf product, revision, pnp);
31161349135Slonewolf }
312f12e2b4dSsoren
313f12e2b4dSsoren if (ga->ga_slot != GIOCF_SLOT_DEFAULT)
314dca15fc8Sthorpej aprint_normal(" slot %d", ga->ga_slot);
31573f78d5eSthorpej if (ga->ga_addr != (uint32_t) GIOCF_ADDR_DEFAULT)
316dca15fc8Sthorpej aprint_normal(" addr 0x%x", ga->ga_addr);
317f12e2b4dSsoren
318f12e2b4dSsoren return UNCONF;
319f12e2b4dSsoren }
320f12e2b4dSsoren
321f12e2b4dSsoren static int
gio_search(device_t parent,cfdata_t cf,const int * ldesc,void * aux)322cbab9cadSchs gio_search(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
323f12e2b4dSsoren {
324f12e2b4dSsoren struct gio_attach_args *ga = aux;
325f12e2b4dSsoren
326f12e2b4dSsoren do {
32761349135Slonewolf /* Handled by direct configuration, so skip here */
32861349135Slonewolf if (cf->cf_loc[GIOCF_ADDR] == GIOCF_ADDR_DEFAULT)
32961349135Slonewolf return 0;
33061349135Slonewolf
331f12e2b4dSsoren ga->ga_slot = cf->cf_loc[GIOCF_SLOT];
332f12e2b4dSsoren ga->ga_addr = cf->cf_loc[GIOCF_ADDR];
333ac797d23Smacallan ga->ga_iot = normal_memt;
334f12e2b4dSsoren ga->ga_ioh = MIPS_PHYS_TO_KSEG1(ga->ga_addr);
33561349135Slonewolf
3362685996bSthorpej if (config_probe(parent, cf, ga))
337*c7fb772bSthorpej config_attach(parent, cf, ga, gio_print, CFARGS_NONE);
338f12e2b4dSsoren } while (cf->cf_fstate == FSTATE_STAR);
339f12e2b4dSsoren
340f12e2b4dSsoren return 0;
341f12e2b4dSsoren }
34261349135Slonewolf
34361349135Slonewolf static int
gio_submatch(device_t parent,cfdata_t cf,const int * ldesc,void * aux)344cbab9cadSchs gio_submatch(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
34561349135Slonewolf {
34661349135Slonewolf struct gio_attach_args *ga = aux;
34761349135Slonewolf
34861349135Slonewolf if (cf->cf_loc[GIOCF_SLOT] != GIOCF_SLOT_DEFAULT &&
34961349135Slonewolf cf->cf_loc[GIOCF_SLOT] != ga->ga_slot)
35061349135Slonewolf return 0;
35161349135Slonewolf
35261349135Slonewolf if (cf->cf_loc[GIOCF_ADDR] != GIOCF_ADDR_DEFAULT &&
35361349135Slonewolf cf->cf_loc[GIOCF_ADDR] != ga->ga_addr)
35461349135Slonewolf return 0;
35561349135Slonewolf
35661349135Slonewolf return config_match(parent, cf, aux);
35761349135Slonewolf }
35861349135Slonewolf
35961349135Slonewolf int
gio_cnattach(void)360df7f595eScegger gio_cnattach(void)
36161349135Slonewolf {
36261349135Slonewolf struct gio_attach_args ga;
36361349135Slonewolf int i;
36461349135Slonewolf
365163b9bb1Srumble for (i = 0; gfx_bases[i].base != 0; i++) {
366163b9bb1Srumble /* skip bases that don't apply to us */
367163b9bb1Srumble if (gfx_bases[i].mach_type != mach_type)
36861349135Slonewolf continue;
369163b9bb1Srumble
370163b9bb1Srumble if (gfx_bases[i].mach_subtype != -1 &&
371163b9bb1Srumble gfx_bases[i].mach_subtype != mach_subtype)
372163b9bb1Srumble continue;
373163b9bb1Srumble
374163b9bb1Srumble ga.ga_slot = -1;
375163b9bb1Srumble ga.ga_addr = gfx_bases[i].base;
3766f0091eeSmacallan /* XXX */
3776f0091eeSmacallan if (platform.badaddr((void *)MIPS_PHYS_TO_KSEG1(ga.ga_addr),
3786f0091eeSmacallan sizeof(uint32_t)))
3796f0091eeSmacallan continue;
380eb488f67Smacallan ga.ga_iot = normal_memt;
3816f0091eeSmacallan if (bus_space_map(normal_memt, ga.ga_addr, 0,
3826f0091eeSmacallan BUS_SPACE_MAP_LINEAR, &ga.ga_ioh) != 0)
3836f0091eeSmacallan continue;
384163b9bb1Srumble ga.ga_dmat = &sgimips_default_bus_dma_tag;
385163b9bb1Srumble ga.ga_product = -1;
38661349135Slonewolf
387bf7ef66fSsekiya #if (NGRTWO > 0)
388bf7ef66fSsekiya if (grtwo_cnattach(&ga) == 0)
389bf7ef66fSsekiya return 0;
390bf7ef66fSsekiya #endif
391bf7ef66fSsekiya
392eb755ecbSrumble #if (NLIGHT > 0)
393eb755ecbSrumble if (light_cnattach(&ga) == 0)
394eb755ecbSrumble return 0;
395eb755ecbSrumble #endif
396eb755ecbSrumble
39761349135Slonewolf #if (NNEWPORT > 0)
39861349135Slonewolf if (newport_cnattach(&ga) == 0)
39961349135Slonewolf return 0;
40061349135Slonewolf #endif
401bf7ef66fSsekiya
40261349135Slonewolf }
40361349135Slonewolf
40461349135Slonewolf return ENXIO;
40561349135Slonewolf }
4062d1cbf72Srumble
4072d1cbf72Srumble /*
4082d1cbf72Srumble * Devices living in the expansion slots must enable or disable some
4092d1cbf72Srumble * GIO arbiter settings. This is accomplished via imc(4) or pic(4)
4102d1cbf72Srumble * registers, depending on the machine in question.
4112d1cbf72Srumble */
4122d1cbf72Srumble int
gio_arb_config(int slot,uint32_t flags)4132d1cbf72Srumble gio_arb_config(int slot, uint32_t flags)
4142d1cbf72Srumble {
4152d1cbf72Srumble
4162d1cbf72Srumble if (flags == 0)
4172d1cbf72Srumble return (EINVAL);
4182d1cbf72Srumble
4192d1cbf72Srumble if (flags & ~(GIO_ARB_RT | GIO_ARB_LB | GIO_ARB_MST | GIO_ARB_SLV |
4202c7e4582Srumble GIO_ARB_PIPE | GIO_ARB_NOPIPE | GIO_ARB_32BIT | GIO_ARB_64BIT |
4212c7e4582Srumble GIO_ARB_HPC2_32BIT | GIO_ARB_HPC2_64BIT))
4222d1cbf72Srumble return (EINVAL);
4232d1cbf72Srumble
4242d1cbf72Srumble if (((flags & GIO_ARB_RT) && (flags & GIO_ARB_LB)) ||
4252d1cbf72Srumble ((flags & GIO_ARB_MST) && (flags & GIO_ARB_SLV)) ||
4262c7e4582Srumble ((flags & GIO_ARB_PIPE) && (flags & GIO_ARB_NOPIPE)) ||
4272c7e4582Srumble ((flags & GIO_ARB_32BIT) && (flags & GIO_ARB_64BIT)) ||
4282c7e4582Srumble ((flags & GIO_ARB_HPC2_32BIT) && (flags & GIO_ARB_HPC2_64BIT)))
4292d1cbf72Srumble return (EINVAL);
4302d1cbf72Srumble
4312d1cbf72Srumble #if (NPIC > 0)
4322d1cbf72Srumble if (mach_type == MACH_SGI_IP12)
4332d1cbf72Srumble return (pic_gio32_arb_config(slot, flags));
4342d1cbf72Srumble #endif
4352d1cbf72Srumble
4362d1cbf72Srumble #if (NIMC > 0)
4372d1cbf72Srumble if (mach_type == MACH_SGI_IP20 || mach_type == MACH_SGI_IP22)
4382d1cbf72Srumble return (imc_gio64_arb_config(slot, flags));
4392d1cbf72Srumble #endif
4402d1cbf72Srumble
4412d1cbf72Srumble return (EINVAL);
4422d1cbf72Srumble }
4432d1cbf72Srumble
4442d1cbf72Srumble /*
4452d1cbf72Srumble * Establish an interrupt handler for the specified slot.
44679cd03d3Srumble *
44779cd03d3Srumble * Indy and Challenge S have an interrupt per GIO slot. Indigo and Indigo2
44879cd03d3Srumble * share a single interrupt, however.
4492d1cbf72Srumble */
4502d1cbf72Srumble void *
gio_intr_establish(int slot,int level,int (* func)(void *),void * arg)4512d1cbf72Srumble gio_intr_establish(int slot, int level, int (*func)(void *), void *arg)
4522d1cbf72Srumble {
4532d1cbf72Srumble int intr;
4542d1cbf72Srumble
4552d1cbf72Srumble switch (mach_type) {
4562d1cbf72Srumble case MACH_SGI_IP12:
4572d1cbf72Srumble case MACH_SGI_IP20:
4582d1cbf72Srumble if (slot == GIO_SLOT_GFX)
4592d1cbf72Srumble panic("gio_intr_establish: slot %d", slot);
46079cd03d3Srumble intr = 6;
4612d1cbf72Srumble break;
4622d1cbf72Srumble
4632d1cbf72Srumble case MACH_SGI_IP22:
4642d1cbf72Srumble if (mach_subtype == MACH_SGI_IP22_FULLHOUSE) {
4652d1cbf72Srumble if (slot == GIO_SLOT_EXP1)
4662d1cbf72Srumble panic("gio_intr_establish: slot %d", slot);
46779cd03d3Srumble intr = 6;
4682d1cbf72Srumble } else {
4692d1cbf72Srumble if (slot == GIO_SLOT_GFX)
4702d1cbf72Srumble panic("gio_intr_establish: slot %d", slot);
4712d1cbf72Srumble intr = (slot == GIO_SLOT_EXP0) ? 22 : 23;
4722d1cbf72Srumble }
4732d1cbf72Srumble break;
4742d1cbf72Srumble
4752d1cbf72Srumble default:
4762d1cbf72Srumble panic("gio_intr_establish: mach_type");
4772d1cbf72Srumble }
4782d1cbf72Srumble
4792d1cbf72Srumble return (cpu_intr_establish(intr, level, func, arg));
4802d1cbf72Srumble }
4812d1cbf72Srumble
4822d1cbf72Srumble const char *
gio_product_string(int prid)4832d1cbf72Srumble gio_product_string(int prid)
4842d1cbf72Srumble {
4852d1cbf72Srumble int i;
4862d1cbf72Srumble
4872d1cbf72Srumble for (i = 0; gio_knowndevs[i].product != NULL; i++)
4882d1cbf72Srumble if (gio_knowndevs[i].productid == prid)
4892d1cbf72Srumble return (gio_knowndevs[i].product);
4902d1cbf72Srumble
4912d1cbf72Srumble return (NULL);
4922d1cbf72Srumble }
493