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