imc.c revision 1.4 1 /* $NetBSD: imc.c,v 1.4 2002/03/13 13:12:26 simonb Exp $ */
2
3 /*
4 * Copyright (c) 2001 Rafal K. Boni
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. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include <sys/param.h>
31 #include <sys/device.h>
32 #include <sys/systm.h>
33
34 #include <machine/cpu.h>
35 #include <machine/locore.h>
36 #include <machine/autoconf.h>
37 #include <machine/bus.h>
38 #include <machine/machtype.h>
39
40 #include <sgimips/dev/imcreg.h>
41
42 #include "locators.h"
43
44 struct imc_softc {
45 struct device sc_dev;
46
47 int eisa_present : 1;
48 };
49
50 static int imc_match(struct device *, struct cfdata *, void *);
51 static void imc_attach(struct device *, struct device *, void *);
52 static int imc_print(void *, const char *);
53
54 struct cfattach imc_ca = {
55 sizeof(struct imc_softc), imc_match, imc_attach
56 };
57
58 struct imc_attach_args {
59 const char* iaa_name;
60
61 bus_space_tag_t iaa_st;
62 bus_space_handle_t iaa_sh;
63
64 /* ? */
65 long iaa_offset;
66 int iaa_intr;
67 #if 0
68 int iaa_stride;
69 #endif
70 };
71
72 static int
73 imc_match(parent, match, aux)
74 struct device *parent;
75 struct cfdata *match;
76 void *aux;
77 {
78
79 /*
80 * The IMC is an INDY/INDIGO2 thing.
81 */
82 if (mach_type != MACH_SGI_IP22)
83 return (0);
84
85 /* Make sure it's actually there and readable */
86 if (badaddr((void*)MIPS_PHYS_TO_KSEG1(IMC_SYSID), sizeof(u_int32_t)))
87 return (0);
88
89 return (1);
90 }
91
92 static void
93 imc_attach(parent, self, aux)
94 struct device *parent;
95 struct device *self;
96 void *aux;
97 {
98 u_int32_t reg;
99 struct imc_attach_args iaa;
100 struct imc_softc *isc = (void *) self;
101 u_int32_t sysid = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(IMC_SYSID);
102
103 /* EISA present bit is on even on Indys, so don't trust it! */
104 if (mach_subtype == MACH_SGI_IP22_FULLHOUSE)
105 isc->eisa_present = (sysid & IMC_SYSID_HAVEISA);
106 else
107 isc->eisa_present = 0;
108
109 printf("\nimc0: Revision %d", (sysid & IMC_SYSID_REVMASK));
110
111 if (isc->eisa_present)
112 printf(", EISA bus present");
113
114 printf("\n");
115
116 /* Clear CPU/GIO error status registers to clear any leftover bits. */
117 *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(IMC_CPU_ERRSTAT) = 0;
118 *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(IMC_GIO_ERRSTAT) = 0;
119
120 /*
121 * Enable parity reporting on GIO/main memory transactions.
122 * Disable parity checking on CPU bus transactions (as turning
123 * it on seems to cause spurious bus errors), but enable parity
124 * checking on CPU reads from main memory (note that this bit
125 * has the opposite sense... Turning it on turns the checks off!).
126 * Finally, turn on interrupt writes to the CPU from the MC.
127 */
128 reg = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(IMC_CPUCTRL0);
129 reg &= ~IMC_CPUCTRL0_NCHKMEMPAR;
130 reg |= (IMC_CPUCTRL0_GPR | IMC_CPUCTRL0_MPR | IMC_CPUCTRL0_INTENA);
131 *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(IMC_CPUCTRL0) = reg;
132
133 /* Setup the MC write buffer depth */
134 reg = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(IMC_CPUCTRL1);
135 reg = (reg & ~IMC_CPUCTRL1_MCHWMSK) | 13;
136 *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(IMC_CPUCTRL1) = reg;
137
138 /*
139 * Set GIO64 arbitrator configuration register:
140 *
141 * Preserve PROM-set graphics-related bits, as they seem to depend
142 * on the graphics variant present and I'm not sure how to figure
143 * that out or 100% sure what the correct settings are for each.
144 */
145 reg = *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(IMC_GIO64ARB);
146 reg &= (IMC_GIO64ARB_GRX64 | IMC_GIO64ARB_GRXRT | IMC_GIO64ARB_GRXMST);
147
148 /* GIO64 invariant for all IP22 platforms: one GIO bus, HPC1 @ 64 */
149 reg |= IMC_GIO64ARB_ONEGIO | IMC_GIO64ARB_HPC64;
150
151 /* Rest of settings are machine/board dependant */
152 switch (mach_subtype) {
153 case MACH_SGI_IP22_GUINESS:
154 /* EISA can bus-master, is 64-bit */
155 reg |= (IMC_GIO64ARB_EISAMST | IMC_GIO64ARB_EISA64);
156 break;
157
158 case MACH_SGI_IP22_FULLHOUSE:
159 /*
160 * All Fullhouse boards have a 64-bit HPC2 and pipelined
161 * EXP0 slot.
162 */
163 reg |= (IMC_GIO64ARB_HPCEXP64 | IMC_GIO64ARB_EXP0PIPE);
164
165 if (mach_boardrev < 2) {
166 /* EXP0 realtime, EXP1 can master */
167 reg |= (IMC_GIO64ARB_EXP0RT | IMC_GIO64ARB_EXP1MST);
168 } else {
169 /* EXP1 pipelined as well, EISA masters */
170 reg |= (IMC_GIO64ARB_EXP1PIPE | IMC_GIO64ARB_EISAMST);
171 }
172 break;
173 }
174
175 *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(IMC_GIO64ARB) = reg;
176
177 if (isc->eisa_present) {
178 #if notyet
179 memset(&iaa, 0, sizeof(iaa));
180
181 iaa.iaa_name = "eisa";
182 (void)config_found(self, (void*)&iaa, imc_print);
183 #endif
184 }
185
186 memset(&iaa, 0, sizeof(iaa));
187
188 iaa.iaa_name = "gio";
189 (void)config_found(self, (void*)&iaa, imc_print);
190 }
191
192
193 static int
194 imc_print(aux, name)
195 void *aux;
196 const char *name;
197 {
198 struct imc_attach_args* iaa = aux;
199
200 if (name)
201 printf("%s at %s", iaa->iaa_name, name);
202
203 return UNCONF;
204 }
205
206