gt.c revision 1.5 1 1.5 lukem /* $NetBSD: gt.c,v 1.5 2003/07/14 15:47:16 lukem Exp $ */
2 1.1 matt
3 1.1 matt /*
4 1.1 matt * Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
5 1.1 matt * All rights reserved.
6 1.1 matt *
7 1.1 matt * Redistribution and use in source and binary forms, with or without
8 1.1 matt * modification, are permitted provided that the following conditions
9 1.1 matt * are met:
10 1.1 matt * 1. Redistributions of source code must retain the above copyright
11 1.1 matt * notice, this list of conditions and the following disclaimer.
12 1.1 matt * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 matt * notice, this list of conditions and the following disclaimer in the
14 1.1 matt * documentation and/or other materials provided with the distribution.
15 1.1 matt * 3. All advertising materials mentioning features or use of this software
16 1.1 matt * must display the following acknowledgement:
17 1.1 matt * This product includes software developed for the NetBSD Project by
18 1.1 matt * Allegro Networks, Inc., and Wasabi Systems, Inc.
19 1.1 matt * 4. The name of Allegro Networks, Inc. may not be used to endorse
20 1.1 matt * or promote products derived from this software without specific prior
21 1.1 matt * written permission.
22 1.1 matt * 5. The name of Wasabi Systems, Inc. may not be used to endorse
23 1.1 matt * or promote products derived from this software without specific prior
24 1.1 matt * written permission.
25 1.1 matt *
26 1.1 matt * THIS SOFTWARE IS PROVIDED BY ALLEGRO NETWORKS, INC. AND
27 1.1 matt * WASABI SYSTEMS, INC. ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
28 1.1 matt * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
29 1.1 matt * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
30 1.1 matt * IN NO EVENT SHALL EITHER ALLEGRO NETWORKS, INC. OR WASABI SYSTEMS, INC.
31 1.1 matt * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 1.1 matt * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 1.1 matt * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 1.1 matt * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 1.1 matt * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 1.1 matt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 1.1 matt * POSSIBILITY OF SUCH DAMAGE.
38 1.1 matt */
39 1.1 matt
40 1.1 matt /*
41 1.1 matt * gt.c -- GT system controller driver
42 1.1 matt */
43 1.5 lukem
44 1.5 lukem #include <sys/cdefs.h>
45 1.5 lukem __KERNEL_RCSID(0, "$NetBSD: gt.c,v 1.5 2003/07/14 15:47:16 lukem Exp $");
46 1.1 matt
47 1.1 matt #include "opt_marvell.h"
48 1.1 matt
49 1.1 matt #include <sys/param.h>
50 1.1 matt #include <sys/types.h>
51 1.1 matt #include <sys/cdefs.h>
52 1.1 matt #include <sys/extent.h>
53 1.1 matt #include <sys/device.h>
54 1.1 matt #include <sys/kernel.h>
55 1.1 matt #include <sys/malloc.h>
56 1.1 matt
57 1.1 matt #define _BUS_SPACE_PRIVATE
58 1.1 matt #define _BUS_DMA_PRIVATE
59 1.1 matt #include <machine/bus.h>
60 1.1 matt
61 1.1 matt #include <powerpc/spr.h>
62 1.1 matt #include <powerpc/oea/hid.h>
63 1.1 matt
64 1.1 matt #include <dev/marvell/gtreg.h>
65 1.1 matt #include <dev/marvell/gtintrreg.h>
66 1.1 matt #include <dev/marvell/gtvar.h>
67 1.1 matt #include <dev/marvell/gtethreg.h>
68 1.1 matt
69 1.1 matt #ifdef DEBUG
70 1.1 matt #include <sys/systm.h> /* for Debugger() */
71 1.1 matt #endif
72 1.1 matt
73 1.1 matt #if ((GT_MPP_WATCHDOG & 0xf0f0f0f0) != 0)
74 1.1 matt # error /* unqualified: configuration botch! */
75 1.1 matt #endif
76 1.1 matt #if ((GT_MPP_WATCHDOG & GT_MPP_INTERRUPTS) != 0)
77 1.1 matt # error /* conflict: configuration botch! */
78 1.1 matt #endif
79 1.1 matt
80 1.3 matt static void gt_comm_intr_enb(struct gt_softc *);
81 1.3 matt static void gt_devbus_intr_enb(struct gt_softc *);
82 1.1 matt #ifdef GT_ECC
83 1.3 matt static void gt_ecc_intr_enb(struct gt_softc *);
84 1.1 matt #endif
85 1.1 matt
86 1.1 matt void gt_init_hostid (struct gt_softc *);
87 1.1 matt void gt_init_interrupt (struct gt_softc *);
88 1.1 matt static int gt_comm_intr (void *);
89 1.1 matt
90 1.3 matt void gt_watchdog_init(struct gt_softc *);
91 1.3 matt void gt_watchdog_enable(void);
92 1.3 matt void gt_watchdog_disable(void);
93 1.3 matt void gt_watchdog_reset(void);
94 1.1 matt
95 1.1 matt extern struct cfdriver gt_cd;
96 1.1 matt
97 1.1 matt static int gtfound = 0;
98 1.1 matt
99 1.1 matt static struct gt_softc *gt_watchdog_sc = 0;
100 1.1 matt static int gt_watchdog_state = 0;
101 1.1 matt
102 1.1 matt int
103 1.1 matt gt_cfprint (void *aux, const char *pnp)
104 1.1 matt {
105 1.1 matt struct gt_attach_args *ga = aux;
106 1.1 matt
107 1.1 matt if (pnp) {
108 1.3 matt aprint_normal("%s at %s", ga->ga_name, pnp);
109 1.1 matt }
110 1.1 matt
111 1.3 matt aprint_normal(" unit %d", ga->ga_unit);
112 1.1 matt return (UNCONF);
113 1.1 matt }
114 1.1 matt
115 1.1 matt
116 1.1 matt static int
117 1.3 matt gt_cfsearch(struct device *parent, struct cfdata *cf, void *aux)
118 1.1 matt {
119 1.3 matt struct gt_softc *gt = (struct gt_softc *) parent;
120 1.1 matt struct gt_attach_args ga;
121 1.1 matt
122 1.1 matt ga.ga_name = cf->cf_name;
123 1.1 matt ga.ga_dmat = gt->gt_dmat;
124 1.1 matt ga.ga_memt = gt->gt_memt;
125 1.3 matt ga.ga_memh = gt->gt_memh;
126 1.1 matt ga.ga_unit = cf->cf_loc[GTCF_UNIT];
127 1.1 matt
128 1.1 matt if (config_match(parent, cf, &ga) > 0)
129 1.1 matt config_attach(parent, cf, &ga, gt_cfprint);
130 1.1 matt
131 1.1 matt return (0);
132 1.1 matt }
133 1.1 matt
134 1.1 matt void
135 1.1 matt gt_attach_common(struct gt_softc *gt)
136 1.1 matt {
137 1.1 matt uint32_t cpucfg, cpumode, cpumstr;
138 1.1 matt #ifdef DEBUG
139 1.1 matt uint32_t loaddr, hiaddr;
140 1.1 matt #endif
141 1.1 matt
142 1.1 matt gtfound = 1;
143 1.1 matt
144 1.3 matt cpumode = gt_read(gt, GT_CPU_Mode);
145 1.3 matt aprint_normal(": id %d", GT_CPUMode_MultiGTID_GET(cpumode));
146 1.1 matt if (cpumode & GT_CPUMode_MultiGT)
147 1.3 matt aprint_normal (" (multi)");
148 1.1 matt switch (GT_CPUMode_CPUType_GET(cpumode)) {
149 1.3 matt case 4: aprint_normal(", 60x bus"); break;
150 1.3 matt case 5: aprint_normal(", MPX bus"); break;
151 1.3 matt default: aprint_normal(", %#x(?) bus", GT_CPUMode_CPUType_GET(cpumode)); break;
152 1.1 matt }
153 1.1 matt
154 1.3 matt cpumstr = gt_read(gt, GT_CPU_Master_Ctl);
155 1.1 matt cpumstr &= ~(GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock);
156 1.1 matt #if 0
157 1.1 matt cpumstr |= GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock;
158 1.1 matt #endif
159 1.3 matt gt_write(gt, GT_CPU_Master_Ctl, cpumstr);
160 1.1 matt
161 1.1 matt switch (cpumstr & (GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock)) {
162 1.1 matt case 0: break;
163 1.3 matt case GT_CPUMstrCtl_CleanBlock: aprint_normal(", snoop=clean"); break;
164 1.3 matt case GT_CPUMstrCtl_FlushBlock: aprint_normal(", snoop=flush"); break;
165 1.1 matt case GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock:
166 1.3 matt aprint_normal(", snoop=clean&flush"); break;
167 1.1 matt }
168 1.3 matt aprint_normal(" wdog=%#x,%#x\n",
169 1.3 matt gt_read(gt, GT_WDOG_Config),
170 1.3 matt gt_read(gt, GT_WDOG_Value));
171 1.1 matt
172 1.1 matt #if DEBUG
173 1.3 matt loaddr = GT_LowAddr_GET(gt_read(gt, GT_SCS0_Low_Decode));
174 1.3 matt hiaddr = GT_HighAddr_GET(gt_read(gt, GT_SCS0_High_Decode));
175 1.3 matt aprint_normal("%s: scs[0]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
176 1.3 matt
177 1.3 matt loaddr = GT_LowAddr_GET(gt_read(gt, GT_SCS1_Low_Decode));
178 1.3 matt hiaddr = GT_HighAddr_GET(gt_read(gt, GT_SCS1_High_Decode));
179 1.3 matt aprint_normal("%s: scs[1]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
180 1.3 matt
181 1.3 matt loaddr = GT_LowAddr_GET(gt_read(gt, GT_SCS2_Low_Decode));
182 1.3 matt hiaddr = GT_HighAddr_GET(gt_read(gt, GT_SCS2_High_Decode));
183 1.3 matt aprint_normal("%s: scs[2]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
184 1.3 matt
185 1.3 matt loaddr = GT_LowAddr_GET(gt_read(gt, GT_SCS3_Low_Decode));
186 1.3 matt hiaddr = GT_HighAddr_GET(gt_read(gt, GT_SCS3_High_Decode));
187 1.3 matt aprint_normal("%s: scs[3]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
188 1.3 matt
189 1.3 matt loaddr = GT_LowAddr_GET(gt_read(gt, GT_CS0_Low_Decode));
190 1.3 matt hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CS0_High_Decode));
191 1.3 matt aprint_normal("%s: cs[0]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
192 1.3 matt
193 1.3 matt loaddr = GT_LowAddr_GET(gt_read(gt, GT_CS1_Low_Decode));
194 1.3 matt hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CS1_High_Decode));
195 1.3 matt aprint_normal("%s: cs[1]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
196 1.3 matt
197 1.3 matt loaddr = GT_LowAddr_GET(gt_read(gt, GT_CS2_Low_Decode));
198 1.3 matt hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CS2_High_Decode));
199 1.3 matt aprint_normal("%s: cs[2]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
200 1.3 matt
201 1.3 matt loaddr = GT_LowAddr_GET(gt_read(gt, GT_CS3_Low_Decode));
202 1.3 matt hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CS3_High_Decode));
203 1.3 matt aprint_normal("%s: cs[3]=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
204 1.3 matt
205 1.3 matt loaddr = GT_LowAddr_GET(gt_read(gt, GT_BootCS_Low_Decode));
206 1.3 matt hiaddr = GT_HighAddr_GET(gt_read(gt, GT_BootCS_High_Decode));
207 1.3 matt aprint_normal("%s: bootcs=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
208 1.3 matt
209 1.3 matt loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI0_IO_Low_Decode));
210 1.3 matt hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI0_IO_High_Decode));
211 1.3 matt aprint_normal("%s: pci0io=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr);
212 1.3 matt
213 1.3 matt loaddr = gt_read(gt, GT_PCI0_IO_Remap);
214 1.3 matt aprint_normal("remap=%#010x\n", loaddr);
215 1.3 matt
216 1.3 matt loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI0_Mem0_Low_Decode));
217 1.3 matt hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI0_Mem0_High_Decode));
218 1.3 matt aprint_normal("%s: pci0mem[0]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr);
219 1.3 matt
220 1.3 matt loaddr = gt_read(gt, GT_PCI0_Mem0_Remap_Low);
221 1.3 matt hiaddr = gt_read(gt, GT_PCI0_Mem0_Remap_High);
222 1.3 matt aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
223 1.3 matt
224 1.3 matt loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI0_Mem1_Low_Decode));
225 1.3 matt hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI0_Mem1_High_Decode));
226 1.3 matt aprint_normal("%s: pci0mem[1]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr);
227 1.3 matt
228 1.3 matt loaddr = gt_read(gt, GT_PCI0_Mem1_Remap_Low);
229 1.3 matt hiaddr = gt_read(gt, GT_PCI0_Mem1_Remap_High);
230 1.3 matt aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
231 1.3 matt
232 1.3 matt loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI0_Mem2_Low_Decode));
233 1.3 matt hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI0_Mem2_High_Decode));
234 1.3 matt aprint_normal("%s: pci0mem[2]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr);
235 1.3 matt
236 1.3 matt loaddr = gt_read(gt, GT_PCI0_Mem2_Remap_Low);
237 1.3 matt hiaddr = gt_read(gt, GT_PCI0_Mem2_Remap_High);
238 1.3 matt aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
239 1.3 matt
240 1.3 matt loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI0_Mem3_Low_Decode));
241 1.3 matt hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI0_Mem3_High_Decode));
242 1.3 matt aprint_normal("%s: pci0mem[3]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr);
243 1.3 matt
244 1.3 matt loaddr = gt_read(gt, GT_PCI0_Mem3_Remap_Low);
245 1.3 matt hiaddr = gt_read(gt, GT_PCI0_Mem3_Remap_High);
246 1.3 matt aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
247 1.3 matt
248 1.3 matt loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI1_IO_Low_Decode));
249 1.3 matt hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI1_IO_High_Decode));
250 1.3 matt aprint_normal("%s: pci1io=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr);
251 1.3 matt
252 1.3 matt loaddr = gt_read(gt, GT_PCI1_IO_Remap);
253 1.3 matt aprint_normal("remap=%#010x\n", loaddr);
254 1.3 matt
255 1.3 matt loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI1_Mem0_Low_Decode));
256 1.3 matt hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI1_Mem0_High_Decode));
257 1.3 matt aprint_normal("%s: pci1mem[0]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr);
258 1.3 matt
259 1.3 matt loaddr = gt_read(gt, GT_PCI1_Mem0_Remap_Low);
260 1.3 matt hiaddr = gt_read(gt, GT_PCI1_Mem0_Remap_High);
261 1.3 matt aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
262 1.3 matt
263 1.3 matt loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI1_Mem1_Low_Decode));
264 1.3 matt hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI1_Mem1_High_Decode));
265 1.3 matt aprint_normal("%s: pci1mem[1]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr);
266 1.3 matt
267 1.3 matt loaddr = gt_read(gt, GT_PCI1_Mem1_Remap_Low);
268 1.3 matt hiaddr = gt_read(gt, GT_PCI1_Mem1_Remap_High);
269 1.3 matt aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
270 1.3 matt
271 1.3 matt loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI1_Mem2_Low_Decode));
272 1.3 matt hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI1_Mem2_High_Decode));
273 1.3 matt aprint_normal("%s: pci1mem[2]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr);
274 1.3 matt
275 1.3 matt loaddr = gt_read(gt, GT_PCI1_Mem2_Remap_Low);
276 1.3 matt hiaddr = gt_read(gt, GT_PCI1_Mem2_Remap_High);
277 1.3 matt aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
278 1.3 matt
279 1.3 matt loaddr = GT_LowAddr_GET(gt_read(gt, GT_PCI1_Mem3_Low_Decode));
280 1.3 matt hiaddr = GT_HighAddr_GET(gt_read(gt, GT_PCI1_Mem3_High_Decode));
281 1.3 matt aprint_normal("%s: pci1mem[3]=%#10x-%#10x ", gt->gt_dev.dv_xname, loaddr, hiaddr);
282 1.3 matt
283 1.3 matt loaddr = gt_read(gt, GT_PCI1_Mem3_Remap_Low);
284 1.3 matt hiaddr = gt_read(gt, GT_PCI1_Mem3_Remap_High);
285 1.3 matt aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
286 1.1 matt
287 1.3 matt loaddr = GT_LowAddr_GET(gt_read(gt, GT_Internal_Decode));
288 1.3 matt aprint_normal("%s: internal=%#10x-%#10x\n", gt->gt_dev.dv_xname,
289 1.1 matt loaddr, loaddr+256*1024);
290 1.1 matt
291 1.3 matt loaddr = GT_LowAddr_GET(gt_read(gt, GT_CPU0_Low_Decode));
292 1.3 matt hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CPU0_High_Decode));
293 1.3 matt aprint_normal("%s: cpu0=%#10x-%#10x\n", gt->gt_dev.dv_xname, loaddr, hiaddr);
294 1.1 matt
295 1.3 matt loaddr = GT_LowAddr_GET(gt_read(gt, GT_CPU1_Low_Decode));
296 1.3 matt hiaddr = GT_HighAddr_GET(gt_read(gt, GT_CPU1_High_Decode));
297 1.3 matt aprint_normal("%s: cpu1=%#10x-%#10x", gt->gt_dev.dv_xname, loaddr, hiaddr);
298 1.1 matt #endif
299 1.1 matt
300 1.3 matt aprint_normal("%s:", gt->gt_dev.dv_xname);
301 1.1 matt
302 1.3 matt cpucfg = gt_read(gt, GT_CPU_Cfg);
303 1.1 matt cpucfg |= GT_CPUCfg_ConfSBDis; /* per errata #46 */
304 1.1 matt cpucfg |= GT_CPUCfg_AACKDelay; /* per restriction #18 */
305 1.3 matt gt_write(gt, GT_CPU_Cfg, cpucfg);
306 1.1 matt if (cpucfg & GT_CPUCfg_Pipeline)
307 1.3 matt aprint_normal(" pipeline");
308 1.1 matt if (cpucfg & GT_CPUCfg_AACKDelay)
309 1.3 matt aprint_normal(" aack-delay");
310 1.1 matt if (cpucfg & GT_CPUCfg_RdOOO)
311 1.3 matt aprint_normal(" read-ooo");
312 1.1 matt if (cpucfg & GT_CPUCfg_IOSBDis)
313 1.3 matt aprint_normal(" io-sb-dis");
314 1.1 matt if (cpucfg & GT_CPUCfg_ConfSBDis)
315 1.3 matt aprint_normal(" conf-sb-dis");
316 1.1 matt if (cpucfg & GT_CPUCfg_ClkSync)
317 1.3 matt aprint_normal(" clk-sync");
318 1.3 matt aprint_normal("\n");
319 1.1 matt
320 1.1 matt gt_init_hostid(gt);
321 1.1 matt
322 1.1 matt gt_watchdog_init(gt);
323 1.1 matt
324 1.1 matt gt_init_interrupt(gt);
325 1.1 matt
326 1.1 matt #ifdef GT_ECC
327 1.1 matt gt_ecc_intr_enb(gt);
328 1.1 matt #endif
329 1.1 matt
330 1.1 matt gt_comm_intr_enb(gt);
331 1.1 matt gt_devbus_intr_enb(gt);
332 1.1 matt
333 1.4 scw gt_watchdog_disable();
334 1.3 matt config_search(gt_cfsearch, >->gt_dev, NULL);
335 1.1 matt gt_watchdog_service();
336 1.4 scw gt_watchdog_enable();
337 1.1 matt }
338 1.1 matt
339 1.1 matt void
340 1.1 matt gt_init_hostid(struct gt_softc *gt)
341 1.1 matt {
342 1.1 matt
343 1.1 matt hostid = 1; /* XXX: Used by i2c; needs work -- AKB */
344 1.1 matt }
345 1.1 matt
346 1.1 matt void
347 1.1 matt gt_init_interrupt(struct gt_softc *gt)
348 1.1 matt {
349 1.1 matt u_int32_t mppirpts = GT_MPP_INTERRUPTS; /* from config */
350 1.1 matt u_int32_t r;
351 1.1 matt u_int32_t mppbit;
352 1.1 matt u_int32_t mask;
353 1.1 matt u_int32_t mppsel;
354 1.1 matt u_int32_t regoff;
355 1.1 matt
356 1.3 matt gt_write(gt, ICR_CIM_LO, 0);
357 1.3 matt gt_write(gt, ICR_CIM_HI, 0);
358 1.1 matt
359 1.1 matt /*
360 1.1 matt * configure the GPP interrupts:
361 1.1 matt * - set the configured MPP pins in GPP mode
362 1.1 matt * - set the configured GPP pins to input, active low, interrupt enbl
363 1.1 matt */
364 1.1 matt #ifdef DEBUG
365 1.1 matt printf("%s: mpp cfg ", gt->gt_dev.dv_xname);
366 1.1 matt for (regoff = GT_MPP_Control0; regoff <= GT_MPP_Control3; regoff += 4)
367 1.3 matt printf("%#x ", gt_read(gt, regoff));
368 1.1 matt printf(", mppirpts 0x%x\n", mppirpts);
369 1.1 matt #endif
370 1.1 matt mppbit = 0x1;
371 1.1 matt for (regoff = GT_MPP_Control0; regoff <= GT_MPP_Control3; regoff += 4) {
372 1.1 matt mask = 0;
373 1.1 matt for (mppsel = 0xf; mppsel; mppsel <<= 4) {
374 1.1 matt if (mppirpts & mppbit)
375 1.1 matt mask |= mppsel;
376 1.1 matt mppbit <<= 1;
377 1.1 matt }
378 1.1 matt if (mask) {
379 1.3 matt r = gt_read(gt, regoff);
380 1.1 matt r &= ~mask;
381 1.3 matt gt_write(gt, regoff, r);
382 1.1 matt }
383 1.1 matt }
384 1.1 matt
385 1.3 matt r = gt_read(gt, GT_GPP_IO_Control);
386 1.1 matt r &= ~mppirpts;
387 1.3 matt gt_write(gt, GT_GPP_IO_Control, r);
388 1.1 matt
389 1.3 matt r = gt_read(gt, GT_GPP_Level_Control);
390 1.1 matt r |= mppirpts;
391 1.3 matt gt_write(gt, GT_GPP_Level_Control, r);
392 1.1 matt
393 1.3 matt r = gt_read(gt, GT_GPP_Interrupt_Mask);
394 1.1 matt r |= mppirpts;
395 1.3 matt gt_write(gt, GT_GPP_Interrupt_Mask, r);
396 1.1 matt }
397 1.1 matt
398 1.1 matt uint32_t
399 1.1 matt gt_read_mpp (void)
400 1.1 matt {
401 1.3 matt return gt_read((struct gt_softc *)gt_cd.cd_devs[0], GT_GPP_Value);
402 1.1 matt }
403 1.1 matt
404 1.1 matt #if 0
405 1.1 matt int
406 1.1 matt gt_bs_extent_init(struct discovery_bus_space *bs, char *name)
407 1.1 matt {
408 1.1 matt u_long start, end;
409 1.1 matt int i, j, error;
410 1.1 matt
411 1.1 matt if (bs->bs_nregion == 0) {
412 1.1 matt bs->bs_extent = extent_create(name, 0xffffffffUL, 0xffffffffUL,
413 1.1 matt M_DEVBUF, NULL, 0, EX_NOCOALESCE|EX_WAITOK);
414 1.1 matt KASSERT(bs->bs_extent != NULL);
415 1.1 matt return 0;
416 1.1 matt }
417 1.1 matt /*
418 1.1 matt * Find the top and bottoms of this bus space.
419 1.1 matt */
420 1.1 matt start = bs->bs_regions[0].br_start;
421 1.1 matt end = bs->bs_regions[0].br_end;
422 1.1 matt #ifdef DEBUG
423 1.1 matt if (gtpci_debug > 1)
424 1.1 matt printf("gtpci_bs_extent_init: %s: region %d: %#lx-%#lx\n",
425 1.1 matt name, 0, bs->bs_regions[0].br_start,
426 1.1 matt bs->bs_regions[0].br_end);
427 1.1 matt #endif
428 1.1 matt for (i = 1; i < bs->bs_nregion; i++) {
429 1.1 matt if (bs->bs_regions[i].br_start < start)
430 1.1 matt start = bs->bs_regions[i].br_start;
431 1.1 matt if (bs->bs_regions[i].br_end > end)
432 1.1 matt end = bs->bs_regions[i].br_end;
433 1.1 matt #ifdef DEBUG
434 1.1 matt if (gtpci_debug > 1)
435 1.1 matt printf("gtpci_bs_extent_init: %s: region %d:"
436 1.1 matt " %#lx-%#lx\n",
437 1.1 matt name, i, bs->bs_regions[i].br_start,
438 1.1 matt bs->bs_regions[i].br_end);
439 1.1 matt #endif
440 1.1 matt }
441 1.1 matt /*
442 1.1 matt * Now that we have the top and bottom limits of this
443 1.1 matt * bus space, create the extent map that will manage this
444 1.1 matt * space for us.
445 1.1 matt */
446 1.1 matt #ifdef DEBUG
447 1.1 matt if (gtpci_debug > 1)
448 1.1 matt printf("gtpci_bs_extent_init: %s: create: %#lx-%#lx\n",
449 1.1 matt name, start, end);
450 1.1 matt #endif
451 1.1 matt bs->bs_extent = extent_create(name, start, end, M_DEVBUF,
452 1.1 matt NULL, 0, EX_NOCOALESCE|EX_WAITOK);
453 1.1 matt KASSERT(bs->bs_extent != NULL);
454 1.1 matt
455 1.1 matt /* If there was more than one bus space region, then there
456 1.1 matt * might gaps in between them. Allocate the gap so that
457 1.1 matt * they will not be legal addresses in the extent.
458 1.1 matt */
459 1.1 matt for (i = 0; i < bs->bs_nregion && bs->bs_nregion > 1; i++) {
460 1.1 matt /* Initial start is "infinity" and the inital end is
461 1.1 matt * is the end of this bus region.
462 1.1 matt */
463 1.1 matt start = ~0UL;
464 1.1 matt end = bs->bs_regions[i].br_end;
465 1.1 matt /* For each region, if it starts after this region but less
466 1.1 matt * than the saved start, use its start address. If the start
467 1.1 matt * address is one past the end address, then we're done
468 1.1 matt */
469 1.1 matt for (j = 0; j < bs->bs_nregion && start > end + 1; j++) {
470 1.1 matt if (i == j)
471 1.1 matt continue;
472 1.1 matt if (bs->bs_regions[j].br_start > end &&
473 1.1 matt bs->bs_regions[j].br_start < start)
474 1.1 matt start = bs->bs_regions[j].br_start;
475 1.1 matt }
476 1.1 matt /*
477 1.1 matt * If we found a gap, allocate it away.
478 1.1 matt */
479 1.1 matt if (start != ~0UL && start != end + 1) {
480 1.1 matt #ifdef DEBUG
481 1.1 matt if (gtpci_debug > 1)
482 1.1 matt printf("gtpci_bs_extent_init: %s: alloc(hole): %#lx-%#lx\n",
483 1.1 matt name, end + 1, start - 1);
484 1.1 matt #endif
485 1.1 matt error = extent_alloc_region(bs->bs_extent, end + 1,
486 1.1 matt start - (end + 1), EX_NOWAIT);
487 1.1 matt KASSERT(error == 0);
488 1.1 matt }
489 1.1 matt }
490 1.1 matt return 1;
491 1.1 matt }
492 1.1 matt #endif
493 1.1 matt
494 1.1 matt /*
495 1.1 matt * unknown board, enable everything
496 1.1 matt */
497 1.1 matt # define GT_CommUnitIntr_DFLT GT_CommUnitIntr_S0|GT_CommUnitIntr_S1 \
498 1.1 matt |GT_CommUnitIntr_E0|GT_CommUnitIntr_E1 \
499 1.1 matt |GT_CommUnitIntr_E2
500 1.1 matt
501 1.1 matt static const char * const gt_comm_subunit_name[8] = {
502 1.1 matt "ethernet 0",
503 1.1 matt "ethernet 1",
504 1.1 matt "ethernet 2",
505 1.1 matt "(reserved)",
506 1.1 matt "MPSC 0",
507 1.1 matt "MPSC 1",
508 1.1 matt "(reserved)",
509 1.1 matt "(sel)",
510 1.1 matt };
511 1.1 matt
512 1.1 matt static int
513 1.1 matt gt_comm_intr(void *arg)
514 1.1 matt {
515 1.1 matt struct gt_softc *gt = (struct gt_softc *)arg;
516 1.1 matt u_int32_t cause;
517 1.1 matt u_int32_t addr;
518 1.1 matt unsigned int mask;
519 1.1 matt int i;
520 1.1 matt
521 1.3 matt cause = gt_read(gt, GT_CommUnitIntr_Cause);
522 1.3 matt gt_write(gt, GT_CommUnitIntr_Cause, ~cause);
523 1.3 matt addr = gt_read(gt, GT_CommUnitIntr_ErrAddr);
524 1.1 matt
525 1.1 matt printf("%s: Comm Unit irpt, cause %#x addr %#x\n",
526 1.1 matt gt->gt_dev.dv_xname, cause, addr);
527 1.1 matt
528 1.1 matt cause &= GT_CommUnitIntr_DFLT;
529 1.1 matt if (cause == 0)
530 1.1 matt return 0;
531 1.3 matt
532 1.1 matt mask = 0x7;
533 1.1 matt for (i=0; i<7; i++) {
534 1.1 matt if (cause & mask) {
535 1.1 matt printf("%s: Comm Unit %s:", gt->gt_dev.dv_xname,
536 1.1 matt gt_comm_subunit_name[i]);
537 1.1 matt if (cause & 1)
538 1.1 matt printf(" AddrMiss");
539 1.1 matt if (cause & 2)
540 1.1 matt printf(" AccProt");
541 1.1 matt if (cause & 4)
542 1.1 matt printf(" WrProt");
543 1.1 matt printf("\n");
544 1.1 matt }
545 1.1 matt cause >>= 4;
546 1.1 matt }
547 1.1 matt return 1;
548 1.1 matt }
549 1.1 matt
550 1.1 matt /*
551 1.1 matt * gt_comm_intr_init - enable GT-64260 Comm Unit interrupts
552 1.1 matt */
553 1.1 matt static void
554 1.1 matt gt_comm_intr_enb(struct gt_softc *gt)
555 1.1 matt {
556 1.1 matt u_int32_t cause;
557 1.1 matt
558 1.3 matt cause = gt_read(gt, GT_CommUnitIntr_Cause);
559 1.1 matt if (cause)
560 1.3 matt gt_write(gt, GT_CommUnitIntr_Cause, ~cause);
561 1.3 matt gt_write(gt, GT_CommUnitIntr_Mask, GT_CommUnitIntr_DFLT);
562 1.3 matt (void)gt_read(gt, GT_CommUnitIntr_ErrAddr);
563 1.1 matt
564 1.1 matt intr_establish(IRQ_COMM, IST_LEVEL, IPL_GTERR, gt_comm_intr, gt);
565 1.1 matt printf("%s: Comm Unit irpt at %d\n", gt->gt_dev.dv_xname, IRQ_COMM);
566 1.1 matt }
567 1.1 matt
568 1.1 matt #ifdef GT_ECC
569 1.1 matt static char *gt_ecc_intr_str[4] = {
570 1.1 matt "(none)",
571 1.1 matt "single bit",
572 1.1 matt "double bit",
573 1.1 matt "(reserved)"
574 1.1 matt };
575 1.1 matt
576 1.1 matt static int
577 1.1 matt gt_ecc_intr(void *arg)
578 1.1 matt {
579 1.1 matt struct gt_softc *gt = (struct gt_softc *)arg;
580 1.1 matt u_int32_t addr;
581 1.1 matt u_int32_t dlo;
582 1.1 matt u_int32_t dhi;
583 1.1 matt u_int32_t rec;
584 1.1 matt u_int32_t calc;
585 1.1 matt u_int32_t count;
586 1.1 matt int err;
587 1.1 matt
588 1.3 matt count = gt_read(gt, GT_ECC_Count);
589 1.3 matt dlo = gt_read(gt, GT_ECC_Data_Lo);
590 1.3 matt dhi = gt_read(gt, GT_ECC_Data_Hi);
591 1.3 matt rec = gt_read(gt, GT_ECC_Rec);
592 1.3 matt calc = gt_read(gt, GT_ECC_Calc);
593 1.3 matt addr = gt_read(gt, GT_ECC_Addr); /* read last! */
594 1.3 matt gt_write(gt, GT_ECC_Addr, 0); /* clear irpt */
595 1.1 matt
596 1.1 matt err = addr & 0x3;
597 1.1 matt
598 1.1 matt printf("%s: ECC error: %s: "
599 1.1 matt "addr %#x data %#x.%#x rec %#x calc %#x cnt %#x\n",
600 1.1 matt gt->gt_dev.dv_xname, gt_ecc_intr_str[err],
601 1.1 matt addr, dhi, dlo, rec, calc, count);
602 1.1 matt
603 1.1 matt if (err == 2)
604 1.1 matt panic("ecc");
605 1.1 matt
606 1.1 matt return (err == 1);
607 1.1 matt }
608 1.1 matt
609 1.1 matt /*
610 1.1 matt * gt_ecc_intr_enb - enable GT-64260 ECC interrupts
611 1.1 matt */
612 1.1 matt static void
613 1.1 matt gt_ecc_intr_enb(struct gt_softc *gt)
614 1.1 matt {
615 1.1 matt u_int32_t ctl;
616 1.1 matt
617 1.3 matt ctl = gt_read(gt, GT_ECC_Ctl);
618 1.1 matt ctl |= 1 << 16; /* XXX 1-bit threshold == 1 */
619 1.3 matt gt_write(gt, GT_ECC_Ctl, ctl);
620 1.3 matt (void)gt_read(gt, GT_ECC_Data_Lo);
621 1.3 matt (void)gt_read(gt, GT_ECC_Data_Hi);
622 1.3 matt (void)gt_read(gt, GT_ECC_Rec);
623 1.3 matt (void)gt_read(gt, GT_ECC_Calc);
624 1.3 matt (void)gt_read(gt, GT_ECC_Addr); /* read last! */
625 1.3 matt gt_write(gt, GT_ECC_Addr, 0); /* clear irpt */
626 1.1 matt
627 1.1 matt intr_establish(IRQ_ECC, IST_LEVEL, IPL_GTERR, gt_ecc_intr, gt);
628 1.1 matt printf("%s: ECC irpt at %d\n", gt->gt_dev.dv_xname, IRQ_ECC);
629 1.1 matt }
630 1.1 matt #endif /* GT_ECC */
631 1.1 matt
632 1.1 matt
633 1.1 matt #ifndef GT_MPP_WATCHDOG
634 1.1 matt void
635 1.3 matt gt_watchdog_init(struct gt_softc *gt)
636 1.1 matt {
637 1.1 matt u_int32_t r;
638 1.1 matt unsigned int omsr;
639 1.1 matt
640 1.1 matt omsr = extintr_disable();
641 1.1 matt
642 1.3 matt printf("%s: watchdog", gt->gt_dev.dv_xname);
643 1.1 matt
644 1.1 matt /*
645 1.1 matt * handle case where firmware started watchdog
646 1.1 matt */
647 1.3 matt r = gt_read(gt, GT_WDOG_Config);
648 1.1 matt printf(" status %#x,%#x:",
649 1.3 matt r, gt_read(gt, GT_WDOG_Value));
650 1.1 matt if ((r & 0x80000000) != 0) {
651 1.3 matt gt_watchdog_sc = gt; /* enabled */
652 1.1 matt gt_watchdog_state = 1;
653 1.1 matt printf(" firmware-enabled\n");
654 1.1 matt gt_watchdog_service();
655 1.1 matt return;
656 1.1 matt } else {
657 1.1 matt printf(" firmware-disabled\n");
658 1.1 matt }
659 1.1 matt
660 1.1 matt extintr_restore(omsr);
661 1.1 matt }
662 1.1 matt
663 1.1 matt #else /* GT_MPP_WATCHDOG */
664 1.1 matt
665 1.1 matt void
666 1.3 matt gt_watchdog_init(struct gt_softc *gt)
667 1.1 matt {
668 1.1 matt u_int32_t mpp_watchdog = GT_MPP_WATCHDOG; /* from config */
669 1.1 matt u_int32_t r;
670 1.1 matt u_int32_t cfgbits;
671 1.1 matt u_int32_t mppbits;
672 1.1 matt u_int32_t mppmask=0;
673 1.1 matt u_int32_t regoff;
674 1.1 matt unsigned int omsr;
675 1.1 matt
676 1.3 matt printf("%s: watchdog", gt->gt_dev.dv_xname);
677 1.1 matt
678 1.1 matt if (mpp_watchdog == 0) {
679 1.1 matt printf(" not configured\n");
680 1.1 matt return;
681 1.1 matt }
682 1.1 matt
683 1.1 matt #if 0
684 1.1 matt if (afw_wdog_ctl == 1) {
685 1.1 matt printf(" admin disabled\n");
686 1.1 matt return;
687 1.1 matt }
688 1.1 matt #endif
689 1.1 matt
690 1.1 matt omsr = extintr_disable();
691 1.1 matt
692 1.1 matt /*
693 1.1 matt * if firmware started watchdog, we disable and start
694 1.1 matt * from scratch to get it in a known state.
695 1.1 matt *
696 1.1 matt * on GT-64260A we always see 0xffffffff
697 1.1 matt * in both the GT_WDOG_Config_Enb and GT_WDOG_Value regsiters.
698 1.1 matt * Use AFW-supplied flag to determine run state.
699 1.1 matt */
700 1.3 matt r = gt_read(gt, GT_WDOG_Config);
701 1.1 matt if (r != ~0) {
702 1.1 matt if ((r & GT_WDOG_Config_Enb) != 0) {
703 1.3 matt gt_write(gt, GT_WDOG_Config,
704 1.1 matt (GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT));
705 1.3 matt gt_write(gt, GT_WDOG_Config,
706 1.1 matt (GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT));
707 1.1 matt }
708 1.1 matt } else {
709 1.1 matt #if 0
710 1.1 matt if (afw_wdog_state == 1) {
711 1.3 matt gt_write(gt, GT_WDOG_Config,
712 1.1 matt (GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT));
713 1.3 matt gt_write(gt, GT_WDOG_Config,
714 1.1 matt (GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT));
715 1.1 matt }
716 1.1 matt #endif
717 1.1 matt }
718 1.1 matt
719 1.1 matt /*
720 1.1 matt * "the watchdog timer can be activated only after
721 1.1 matt * configuring two MPP pins to act as WDE and WDNMI"
722 1.1 matt */
723 1.1 matt mppbits = 0;
724 1.1 matt cfgbits = 0x3;
725 1.1 matt for (regoff = GT_MPP_Control0; regoff <= GT_MPP_Control3; regoff += 4) {
726 1.1 matt if ((mpp_watchdog & cfgbits) == cfgbits) {
727 1.1 matt mppbits = 0x99;
728 1.1 matt mppmask = 0xff;
729 1.1 matt break;
730 1.1 matt }
731 1.1 matt cfgbits <<= 2;
732 1.1 matt if ((mpp_watchdog & cfgbits) == cfgbits) {
733 1.1 matt mppbits = 0x9900;
734 1.1 matt mppmask = 0xff00;
735 1.1 matt break;
736 1.1 matt }
737 1.1 matt cfgbits <<= 6; /* skip unqualified bits */
738 1.1 matt }
739 1.1 matt if (mppbits == 0) {
740 1.1 matt printf(" config error\n");
741 1.1 matt extintr_restore(omsr);
742 1.1 matt return;
743 1.1 matt }
744 1.1 matt
745 1.3 matt r = gt_read(gt, regoff);
746 1.1 matt r &= ~mppmask;
747 1.1 matt r |= mppbits;
748 1.3 matt gt_write(gt, regoff, r);
749 1.1 matt printf(" mpp %#x %#x", regoff, mppbits);
750 1.1 matt
751 1.3 matt gt_write(gt, GT_WDOG_Value, GT_WDOG_NMI_DFLT);
752 1.1 matt
753 1.3 matt gt_write(gt, GT_WDOG_Config,
754 1.1 matt (GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT));
755 1.3 matt gt_write(gt, GT_WDOG_Config,
756 1.1 matt (GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT));
757 1.1 matt
758 1.1 matt
759 1.3 matt r = gt_read(gt, GT_WDOG_Config),
760 1.1 matt printf(" status %#x,%#x: %s",
761 1.3 matt r, gt_read(gt, GT_WDOG_Value),
762 1.1 matt ((r & GT_WDOG_Config_Enb) != 0) ? "enabled" : "botch");
763 1.1 matt
764 1.1 matt if ((r & GT_WDOG_Config_Enb) != 0) {
765 1.1 matt register_t hid0;
766 1.1 matt
767 1.3 matt gt_watchdog_sc = gt; /* enabled */
768 1.1 matt gt_watchdog_state = 1;
769 1.1 matt
770 1.1 matt /*
771 1.1 matt * configure EMCP in HID0 in case it's not already set
772 1.1 matt */
773 1.1 matt __asm __volatile("sync");
774 1.1 matt hid0 = mfspr(SPR_HID0);
775 1.1 matt if ((hid0 & HID0_EMCP) == 0) {
776 1.1 matt hid0 |= HID0_EMCP;
777 1.1 matt __asm __volatile("sync"); mtspr(SPR_HID0, hid0);
778 1.1 matt __asm __volatile("sync"); hid0 = mfspr(SPR_HID0);
779 1.1 matt printf(", EMCP set");
780 1.1 matt }
781 1.1 matt }
782 1.1 matt printf("\n");
783 1.1 matt
784 1.1 matt extintr_restore(omsr);
785 1.1 matt }
786 1.1 matt #endif /* GT_MPP_WATCHDOG */
787 1.1 matt
788 1.1 matt #ifdef DEBUG
789 1.1 matt u_int32_t hid0_print(void);
790 1.1 matt u_int32_t
791 1.1 matt hid0_print()
792 1.1 matt {
793 1.1 matt u_int32_t hid0;
794 1.1 matt __asm __volatile("sync; mfspr %0,1008;" : "=r"(hid0));
795 1.1 matt printf("hid0: %#x\n", hid0);
796 1.1 matt return hid0;
797 1.1 matt }
798 1.1 matt #endif
799 1.1 matt
800 1.1 matt void
801 1.1 matt gt_watchdog_enable(void)
802 1.1 matt {
803 1.3 matt struct gt_softc *gt;
804 1.1 matt unsigned int omsr;
805 1.1 matt
806 1.1 matt omsr = extintr_disable();
807 1.3 matt gt = gt_watchdog_sc;
808 1.3 matt if ((gt != NULL) && (gt_watchdog_state == 0)) {
809 1.1 matt gt_watchdog_state = 1;
810 1.1 matt
811 1.3 matt gt_write(gt, GT_WDOG_Config,
812 1.1 matt (GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT));
813 1.3 matt gt_write(gt, GT_WDOG_Config,
814 1.1 matt (GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT));
815 1.1 matt }
816 1.1 matt extintr_restore(omsr);
817 1.1 matt }
818 1.1 matt
819 1.1 matt void
820 1.1 matt gt_watchdog_disable(void)
821 1.1 matt {
822 1.3 matt struct gt_softc *gt;
823 1.1 matt unsigned int omsr;
824 1.1 matt
825 1.1 matt omsr = extintr_disable();
826 1.3 matt gt = gt_watchdog_sc;
827 1.3 matt if ((gt != NULL) && (gt_watchdog_state != 0)) {
828 1.1 matt gt_watchdog_state = 0;
829 1.1 matt
830 1.3 matt gt_write(gt, GT_WDOG_Config,
831 1.1 matt (GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT));
832 1.3 matt gt_write(gt, GT_WDOG_Config,
833 1.1 matt (GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT));
834 1.1 matt }
835 1.1 matt extintr_restore(omsr);
836 1.1 matt }
837 1.1 matt
838 1.1 matt #ifdef DEBUG
839 1.1 matt int inhibit_watchdog_service = 0;
840 1.1 matt #endif
841 1.1 matt void
842 1.1 matt gt_watchdog_service(void)
843 1.1 matt {
844 1.3 matt struct gt_softc *gt = gt_watchdog_sc;
845 1.1 matt
846 1.3 matt if ((gt == NULL) || (gt_watchdog_state == 0))
847 1.1 matt return; /* not enabled */
848 1.1 matt #ifdef DEBUG
849 1.1 matt if (inhibit_watchdog_service)
850 1.1 matt return;
851 1.1 matt #endif
852 1.1 matt
853 1.3 matt gt_write(gt, GT_WDOG_Config,
854 1.1 matt (GT_WDOG_Config_Ctl2a | GT_WDOG_Preset_DFLT));
855 1.3 matt gt_write(gt, GT_WDOG_Config,
856 1.1 matt (GT_WDOG_Config_Ctl2b | GT_WDOG_Preset_DFLT));
857 1.1 matt }
858 1.1 matt
859 1.1 matt /*
860 1.1 matt * gt_watchdog_reset - force a watchdog reset using Preset_VAL=0
861 1.1 matt */
862 1.1 matt void
863 1.1 matt gt_watchdog_reset()
864 1.1 matt {
865 1.3 matt struct gt_softc *gt = gt_watchdog_sc;
866 1.1 matt u_int32_t r;
867 1.1 matt
868 1.1 matt (void)extintr_disable();
869 1.3 matt r = gt_read(gt, GT_WDOG_Config);
870 1.3 matt gt_write(gt, GT_WDOG_Config, (GT_WDOG_Config_Ctl1a | 0));
871 1.3 matt gt_write(gt, GT_WDOG_Config, (GT_WDOG_Config_Ctl1b | 0));
872 1.1 matt if ((r & GT_WDOG_Config_Enb) != 0) {
873 1.1 matt /*
874 1.1 matt * was enabled, we just toggled it off, toggle on again
875 1.1 matt */
876 1.3 matt gt_write(gt, GT_WDOG_Config,
877 1.1 matt (GT_WDOG_Config_Ctl1a | 0));
878 1.3 matt gt_write(gt, GT_WDOG_Config,
879 1.1 matt (GT_WDOG_Config_Ctl1b | 0));
880 1.1 matt }
881 1.1 matt for(;;);
882 1.1 matt }
883 1.1 matt
884 1.1 matt static int
885 1.1 matt gt_devbus_intr(void *arg)
886 1.1 matt {
887 1.1 matt struct gt_softc *gt = (struct gt_softc *)arg;
888 1.1 matt u_int32_t cause;
889 1.1 matt u_int32_t addr;
890 1.1 matt
891 1.3 matt cause = gt_read(gt, GT_DEVBUS_ICAUSE);
892 1.3 matt addr = gt_read(gt, GT_DEVBUS_ERR_ADDR);
893 1.3 matt gt_write(gt, GT_DEVBUS_ICAUSE, 0); /* clear irpt */
894 1.1 matt
895 1.1 matt if (cause & GT_DEVBUS_DBurstErr) {
896 1.1 matt printf("%s: Device Bus error: burst violation",
897 1.1 matt gt->gt_dev.dv_xname);
898 1.1 matt if ((cause & GT_DEVBUS_Sel) == 0)
899 1.1 matt printf(", addr %#x", addr);
900 1.1 matt printf("\n");
901 1.1 matt }
902 1.1 matt if (cause & GT_DEVBUS_DRdyErr) {
903 1.1 matt printf("%s: Device Bus error: ready timer expired",
904 1.1 matt gt->gt_dev.dv_xname);
905 1.1 matt if ((cause & GT_DEVBUS_Sel) != 0)
906 1.1 matt printf(", addr %#x\n", addr);
907 1.1 matt printf("\n");
908 1.1 matt }
909 1.1 matt
910 1.1 matt return (cause != 0);
911 1.1 matt }
912 1.1 matt
913 1.1 matt /*
914 1.1 matt * gt_ecc_intr_enb - enable GT-64260 ECC interrupts
915 1.1 matt */
916 1.1 matt static void
917 1.1 matt gt_devbus_intr_enb(struct gt_softc *gt)
918 1.1 matt {
919 1.3 matt gt_write(gt, GT_DEVBUS_IMASK,
920 1.1 matt GT_DEVBUS_DBurstErr|GT_DEVBUS_DRdyErr);
921 1.3 matt (void)gt_read(gt, GT_DEVBUS_ERR_ADDR); /* clear addr */
922 1.3 matt gt_write(gt, GT_ECC_Addr, 0); /* clear irpt */
923 1.1 matt
924 1.1 matt intr_establish(IRQ_DEV, IST_LEVEL, IPL_GTERR, gt_devbus_intr, gt);
925 1.1 matt printf("%s: Device Bus Error irpt at %d\n",
926 1.1 matt gt->gt_dev.dv_xname, IRQ_DEV);
927 1.1 matt }
928 1.1 matt
929 1.1 matt
930 1.1 matt int
931 1.1 matt gt_mii_read(
932 1.1 matt struct device *child,
933 1.1 matt struct device *parent,
934 1.1 matt int phy,
935 1.1 matt int reg)
936 1.1 matt {
937 1.3 matt struct gt_softc * const gt = (struct gt_softc *) parent;
938 1.1 matt uint32_t data;
939 1.1 matt int count = 10000;
940 1.1 matt
941 1.1 matt do {
942 1.1 matt DELAY(10);
943 1.3 matt data = gt_read(gt, ETH_ESMIR);
944 1.1 matt } while ((data & ETH_ESMIR_Busy) && count-- > 0);
945 1.1 matt
946 1.1 matt if (count == 0) {
947 1.1 matt printf("%s: mii read for phy %d reg %d busied out\n",
948 1.1 matt child->dv_xname, phy, reg);
949 1.1 matt return ETH_ESMIR_Value_GET(data);
950 1.1 matt }
951 1.1 matt
952 1.3 matt gt_write(gt, ETH_ESMIR, ETH_ESMIR_READ(phy, reg));
953 1.1 matt
954 1.1 matt count = 10000;
955 1.1 matt do {
956 1.1 matt DELAY(10);
957 1.3 matt data = gt_read(gt, ETH_ESMIR);
958 1.1 matt } while ((data & ETH_ESMIR_ReadValid) == 0 && count-- > 0);
959 1.1 matt
960 1.1 matt if (count == 0)
961 1.1 matt printf("%s: mii read for phy %d reg %d timed out\n",
962 1.1 matt child->dv_xname, phy, reg);
963 1.1 matt #if defined(GTMIIDEBUG)
964 1.1 matt printf("%s: mii_read(%d, %d): %#x data %#x\n",
965 1.1 matt child->dv_xname, phy, reg,
966 1.1 matt data, ETH_ESMIR_Value_GET(data));
967 1.1 matt #endif
968 1.1 matt return ETH_ESMIR_Value_GET(data);
969 1.1 matt }
970 1.1 matt
971 1.1 matt void
972 1.1 matt gt_mii_write (
973 1.1 matt struct device *child,
974 1.1 matt struct device *parent,
975 1.1 matt int phy, int reg,
976 1.1 matt int value)
977 1.1 matt {
978 1.3 matt struct gt_softc * const gt = (struct gt_softc *) parent;
979 1.1 matt uint32_t data;
980 1.1 matt int count = 10000;
981 1.1 matt
982 1.1 matt do {
983 1.1 matt DELAY(10);
984 1.3 matt data = gt_read(gt, ETH_ESMIR);
985 1.1 matt } while ((data & ETH_ESMIR_Busy) && count-- > 0);
986 1.1 matt
987 1.1 matt if (count == 0) {
988 1.1 matt printf("%s: mii write for phy %d reg %d busied out (busy)\n",
989 1.1 matt child->dv_xname, phy, reg);
990 1.1 matt return;
991 1.1 matt }
992 1.1 matt
993 1.3 matt gt_write(gt, ETH_ESMIR,
994 1.1 matt ETH_ESMIR_WRITE(phy, reg, value));
995 1.1 matt
996 1.1 matt count = 10000;
997 1.1 matt do {
998 1.1 matt DELAY(10);
999 1.3 matt data = gt_read(gt, ETH_ESMIR);
1000 1.1 matt } while ((data & ETH_ESMIR_Busy) && count-- > 0);
1001 1.1 matt
1002 1.1 matt if (count == 0)
1003 1.1 matt printf("%s: mii write for phy %d reg %d timed out\n",
1004 1.1 matt child->dv_xname, phy, reg);
1005 1.1 matt #if defined(GTMIIDEBUG)
1006 1.1 matt printf("%s: mii_write(%d, %d, %#x)\n",
1007 1.1 matt child->dv_xname, phy, reg, value);
1008 1.1 matt #endif
1009 1.1 matt }
1010 1.1 matt
1011