gt.c revision 1.3 1 1.3 matt /* $NetBSD: gt.c,v 1.3 2003/03/16 07:05:33 matt 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.3 matt config_search(gt_cfsearch, >->gt_dev, NULL);
331 1.1 matt gt_watchdog_service();
332 1.1 matt }
333 1.1 matt
334 1.1 matt void
335 1.1 matt gt_init_hostid(struct gt_softc *gt)
336 1.1 matt {
337 1.1 matt
338 1.1 matt hostid = 1; /* XXX: Used by i2c; needs work -- AKB */
339 1.1 matt }
340 1.1 matt
341 1.1 matt void
342 1.1 matt gt_init_interrupt(struct gt_softc *gt)
343 1.1 matt {
344 1.1 matt u_int32_t mppirpts = GT_MPP_INTERRUPTS; /* from config */
345 1.1 matt u_int32_t r;
346 1.1 matt u_int32_t mppbit;
347 1.1 matt u_int32_t mask;
348 1.1 matt u_int32_t mppsel;
349 1.1 matt u_int32_t regoff;
350 1.1 matt
351 1.3 matt gt_write(gt, ICR_CIM_LO, 0);
352 1.3 matt gt_write(gt, ICR_CIM_HI, 0);
353 1.1 matt
354 1.1 matt /*
355 1.1 matt * configure the GPP interrupts:
356 1.1 matt * - set the configured MPP pins in GPP mode
357 1.1 matt * - set the configured GPP pins to input, active low, interrupt enbl
358 1.1 matt */
359 1.1 matt #ifdef DEBUG
360 1.1 matt printf("%s: mpp cfg ", gt->gt_dev.dv_xname);
361 1.1 matt for (regoff = GT_MPP_Control0; regoff <= GT_MPP_Control3; regoff += 4)
362 1.3 matt printf("%#x ", gt_read(gt, regoff));
363 1.1 matt printf(", mppirpts 0x%x\n", mppirpts);
364 1.1 matt #endif
365 1.1 matt mppbit = 0x1;
366 1.1 matt for (regoff = GT_MPP_Control0; regoff <= GT_MPP_Control3; regoff += 4) {
367 1.1 matt mask = 0;
368 1.1 matt for (mppsel = 0xf; mppsel; mppsel <<= 4) {
369 1.1 matt if (mppirpts & mppbit)
370 1.1 matt mask |= mppsel;
371 1.1 matt mppbit <<= 1;
372 1.1 matt }
373 1.1 matt if (mask) {
374 1.3 matt r = gt_read(gt, regoff);
375 1.1 matt r &= ~mask;
376 1.3 matt gt_write(gt, regoff, r);
377 1.1 matt }
378 1.1 matt }
379 1.1 matt
380 1.3 matt r = gt_read(gt, GT_GPP_IO_Control);
381 1.1 matt r &= ~mppirpts;
382 1.3 matt gt_write(gt, GT_GPP_IO_Control, r);
383 1.1 matt
384 1.3 matt r = gt_read(gt, GT_GPP_Level_Control);
385 1.1 matt r |= mppirpts;
386 1.3 matt gt_write(gt, GT_GPP_Level_Control, r);
387 1.1 matt
388 1.3 matt r = gt_read(gt, GT_GPP_Interrupt_Mask);
389 1.1 matt r |= mppirpts;
390 1.3 matt gt_write(gt, GT_GPP_Interrupt_Mask, r);
391 1.1 matt }
392 1.1 matt
393 1.1 matt uint32_t
394 1.1 matt gt_read_mpp (void)
395 1.1 matt {
396 1.3 matt return gt_read((struct gt_softc *)gt_cd.cd_devs[0], GT_GPP_Value);
397 1.1 matt }
398 1.1 matt
399 1.1 matt #if 0
400 1.1 matt int
401 1.1 matt gt_bs_extent_init(struct discovery_bus_space *bs, char *name)
402 1.1 matt {
403 1.1 matt u_long start, end;
404 1.1 matt int i, j, error;
405 1.1 matt
406 1.1 matt if (bs->bs_nregion == 0) {
407 1.1 matt bs->bs_extent = extent_create(name, 0xffffffffUL, 0xffffffffUL,
408 1.1 matt M_DEVBUF, NULL, 0, EX_NOCOALESCE|EX_WAITOK);
409 1.1 matt KASSERT(bs->bs_extent != NULL);
410 1.1 matt return 0;
411 1.1 matt }
412 1.1 matt /*
413 1.1 matt * Find the top and bottoms of this bus space.
414 1.1 matt */
415 1.1 matt start = bs->bs_regions[0].br_start;
416 1.1 matt end = bs->bs_regions[0].br_end;
417 1.1 matt #ifdef DEBUG
418 1.1 matt if (gtpci_debug > 1)
419 1.1 matt printf("gtpci_bs_extent_init: %s: region %d: %#lx-%#lx\n",
420 1.1 matt name, 0, bs->bs_regions[0].br_start,
421 1.1 matt bs->bs_regions[0].br_end);
422 1.1 matt #endif
423 1.1 matt for (i = 1; i < bs->bs_nregion; i++) {
424 1.1 matt if (bs->bs_regions[i].br_start < start)
425 1.1 matt start = bs->bs_regions[i].br_start;
426 1.1 matt if (bs->bs_regions[i].br_end > end)
427 1.1 matt end = bs->bs_regions[i].br_end;
428 1.1 matt #ifdef DEBUG
429 1.1 matt if (gtpci_debug > 1)
430 1.1 matt printf("gtpci_bs_extent_init: %s: region %d:"
431 1.1 matt " %#lx-%#lx\n",
432 1.1 matt name, i, bs->bs_regions[i].br_start,
433 1.1 matt bs->bs_regions[i].br_end);
434 1.1 matt #endif
435 1.1 matt }
436 1.1 matt /*
437 1.1 matt * Now that we have the top and bottom limits of this
438 1.1 matt * bus space, create the extent map that will manage this
439 1.1 matt * space for us.
440 1.1 matt */
441 1.1 matt #ifdef DEBUG
442 1.1 matt if (gtpci_debug > 1)
443 1.1 matt printf("gtpci_bs_extent_init: %s: create: %#lx-%#lx\n",
444 1.1 matt name, start, end);
445 1.1 matt #endif
446 1.1 matt bs->bs_extent = extent_create(name, start, end, M_DEVBUF,
447 1.1 matt NULL, 0, EX_NOCOALESCE|EX_WAITOK);
448 1.1 matt KASSERT(bs->bs_extent != NULL);
449 1.1 matt
450 1.1 matt /* If there was more than one bus space region, then there
451 1.1 matt * might gaps in between them. Allocate the gap so that
452 1.1 matt * they will not be legal addresses in the extent.
453 1.1 matt */
454 1.1 matt for (i = 0; i < bs->bs_nregion && bs->bs_nregion > 1; i++) {
455 1.1 matt /* Initial start is "infinity" and the inital end is
456 1.1 matt * is the end of this bus region.
457 1.1 matt */
458 1.1 matt start = ~0UL;
459 1.1 matt end = bs->bs_regions[i].br_end;
460 1.1 matt /* For each region, if it starts after this region but less
461 1.1 matt * than the saved start, use its start address. If the start
462 1.1 matt * address is one past the end address, then we're done
463 1.1 matt */
464 1.1 matt for (j = 0; j < bs->bs_nregion && start > end + 1; j++) {
465 1.1 matt if (i == j)
466 1.1 matt continue;
467 1.1 matt if (bs->bs_regions[j].br_start > end &&
468 1.1 matt bs->bs_regions[j].br_start < start)
469 1.1 matt start = bs->bs_regions[j].br_start;
470 1.1 matt }
471 1.1 matt /*
472 1.1 matt * If we found a gap, allocate it away.
473 1.1 matt */
474 1.1 matt if (start != ~0UL && start != end + 1) {
475 1.1 matt #ifdef DEBUG
476 1.1 matt if (gtpci_debug > 1)
477 1.1 matt printf("gtpci_bs_extent_init: %s: alloc(hole): %#lx-%#lx\n",
478 1.1 matt name, end + 1, start - 1);
479 1.1 matt #endif
480 1.1 matt error = extent_alloc_region(bs->bs_extent, end + 1,
481 1.1 matt start - (end + 1), EX_NOWAIT);
482 1.1 matt KASSERT(error == 0);
483 1.1 matt }
484 1.1 matt }
485 1.1 matt return 1;
486 1.1 matt }
487 1.1 matt #endif
488 1.1 matt
489 1.1 matt /*
490 1.1 matt * unknown board, enable everything
491 1.1 matt */
492 1.1 matt # define GT_CommUnitIntr_DFLT GT_CommUnitIntr_S0|GT_CommUnitIntr_S1 \
493 1.1 matt |GT_CommUnitIntr_E0|GT_CommUnitIntr_E1 \
494 1.1 matt |GT_CommUnitIntr_E2
495 1.1 matt
496 1.1 matt static const char * const gt_comm_subunit_name[8] = {
497 1.1 matt "ethernet 0",
498 1.1 matt "ethernet 1",
499 1.1 matt "ethernet 2",
500 1.1 matt "(reserved)",
501 1.1 matt "MPSC 0",
502 1.1 matt "MPSC 1",
503 1.1 matt "(reserved)",
504 1.1 matt "(sel)",
505 1.1 matt };
506 1.1 matt
507 1.1 matt static int
508 1.1 matt gt_comm_intr(void *arg)
509 1.1 matt {
510 1.1 matt struct gt_softc *gt = (struct gt_softc *)arg;
511 1.1 matt u_int32_t cause;
512 1.1 matt u_int32_t addr;
513 1.1 matt unsigned int mask;
514 1.1 matt int i;
515 1.1 matt
516 1.3 matt cause = gt_read(gt, GT_CommUnitIntr_Cause);
517 1.3 matt gt_write(gt, GT_CommUnitIntr_Cause, ~cause);
518 1.3 matt addr = gt_read(gt, GT_CommUnitIntr_ErrAddr);
519 1.1 matt
520 1.1 matt printf("%s: Comm Unit irpt, cause %#x addr %#x\n",
521 1.1 matt gt->gt_dev.dv_xname, cause, addr);
522 1.1 matt
523 1.1 matt cause &= GT_CommUnitIntr_DFLT;
524 1.1 matt if (cause == 0)
525 1.1 matt return 0;
526 1.3 matt
527 1.1 matt mask = 0x7;
528 1.1 matt for (i=0; i<7; i++) {
529 1.1 matt if (cause & mask) {
530 1.1 matt printf("%s: Comm Unit %s:", gt->gt_dev.dv_xname,
531 1.1 matt gt_comm_subunit_name[i]);
532 1.1 matt if (cause & 1)
533 1.1 matt printf(" AddrMiss");
534 1.1 matt if (cause & 2)
535 1.1 matt printf(" AccProt");
536 1.1 matt if (cause & 4)
537 1.1 matt printf(" WrProt");
538 1.1 matt printf("\n");
539 1.1 matt }
540 1.1 matt cause >>= 4;
541 1.1 matt }
542 1.1 matt return 1;
543 1.1 matt }
544 1.1 matt
545 1.1 matt /*
546 1.1 matt * gt_comm_intr_init - enable GT-64260 Comm Unit interrupts
547 1.1 matt */
548 1.1 matt static void
549 1.1 matt gt_comm_intr_enb(struct gt_softc *gt)
550 1.1 matt {
551 1.1 matt u_int32_t cause;
552 1.1 matt
553 1.3 matt cause = gt_read(gt, GT_CommUnitIntr_Cause);
554 1.1 matt if (cause)
555 1.3 matt gt_write(gt, GT_CommUnitIntr_Cause, ~cause);
556 1.3 matt gt_write(gt, GT_CommUnitIntr_Mask, GT_CommUnitIntr_DFLT);
557 1.3 matt (void)gt_read(gt, GT_CommUnitIntr_ErrAddr);
558 1.1 matt
559 1.1 matt intr_establish(IRQ_COMM, IST_LEVEL, IPL_GTERR, gt_comm_intr, gt);
560 1.1 matt printf("%s: Comm Unit irpt at %d\n", gt->gt_dev.dv_xname, IRQ_COMM);
561 1.1 matt }
562 1.1 matt
563 1.1 matt #ifdef GT_ECC
564 1.1 matt static char *gt_ecc_intr_str[4] = {
565 1.1 matt "(none)",
566 1.1 matt "single bit",
567 1.1 matt "double bit",
568 1.1 matt "(reserved)"
569 1.1 matt };
570 1.1 matt
571 1.1 matt static int
572 1.1 matt gt_ecc_intr(void *arg)
573 1.1 matt {
574 1.1 matt struct gt_softc *gt = (struct gt_softc *)arg;
575 1.1 matt u_int32_t addr;
576 1.1 matt u_int32_t dlo;
577 1.1 matt u_int32_t dhi;
578 1.1 matt u_int32_t rec;
579 1.1 matt u_int32_t calc;
580 1.1 matt u_int32_t count;
581 1.1 matt int err;
582 1.1 matt
583 1.3 matt count = gt_read(gt, GT_ECC_Count);
584 1.3 matt dlo = gt_read(gt, GT_ECC_Data_Lo);
585 1.3 matt dhi = gt_read(gt, GT_ECC_Data_Hi);
586 1.3 matt rec = gt_read(gt, GT_ECC_Rec);
587 1.3 matt calc = gt_read(gt, GT_ECC_Calc);
588 1.3 matt addr = gt_read(gt, GT_ECC_Addr); /* read last! */
589 1.3 matt gt_write(gt, GT_ECC_Addr, 0); /* clear irpt */
590 1.1 matt
591 1.1 matt err = addr & 0x3;
592 1.1 matt
593 1.1 matt printf("%s: ECC error: %s: "
594 1.1 matt "addr %#x data %#x.%#x rec %#x calc %#x cnt %#x\n",
595 1.1 matt gt->gt_dev.dv_xname, gt_ecc_intr_str[err],
596 1.1 matt addr, dhi, dlo, rec, calc, count);
597 1.1 matt
598 1.1 matt if (err == 2)
599 1.1 matt panic("ecc");
600 1.1 matt
601 1.1 matt return (err == 1);
602 1.1 matt }
603 1.1 matt
604 1.1 matt /*
605 1.1 matt * gt_ecc_intr_enb - enable GT-64260 ECC interrupts
606 1.1 matt */
607 1.1 matt static void
608 1.1 matt gt_ecc_intr_enb(struct gt_softc *gt)
609 1.1 matt {
610 1.1 matt u_int32_t ctl;
611 1.1 matt
612 1.3 matt ctl = gt_read(gt, GT_ECC_Ctl);
613 1.1 matt ctl |= 1 << 16; /* XXX 1-bit threshold == 1 */
614 1.3 matt gt_write(gt, GT_ECC_Ctl, ctl);
615 1.3 matt (void)gt_read(gt, GT_ECC_Data_Lo);
616 1.3 matt (void)gt_read(gt, GT_ECC_Data_Hi);
617 1.3 matt (void)gt_read(gt, GT_ECC_Rec);
618 1.3 matt (void)gt_read(gt, GT_ECC_Calc);
619 1.3 matt (void)gt_read(gt, GT_ECC_Addr); /* read last! */
620 1.3 matt gt_write(gt, GT_ECC_Addr, 0); /* clear irpt */
621 1.1 matt
622 1.1 matt intr_establish(IRQ_ECC, IST_LEVEL, IPL_GTERR, gt_ecc_intr, gt);
623 1.1 matt printf("%s: ECC irpt at %d\n", gt->gt_dev.dv_xname, IRQ_ECC);
624 1.1 matt }
625 1.1 matt #endif /* GT_ECC */
626 1.1 matt
627 1.1 matt
628 1.1 matt #ifndef GT_MPP_WATCHDOG
629 1.1 matt void
630 1.3 matt gt_watchdog_init(struct gt_softc *gt)
631 1.1 matt {
632 1.1 matt u_int32_t r;
633 1.1 matt unsigned int omsr;
634 1.1 matt
635 1.1 matt omsr = extintr_disable();
636 1.1 matt
637 1.3 matt printf("%s: watchdog", gt->gt_dev.dv_xname);
638 1.1 matt
639 1.1 matt /*
640 1.1 matt * handle case where firmware started watchdog
641 1.1 matt */
642 1.3 matt r = gt_read(gt, GT_WDOG_Config);
643 1.1 matt printf(" status %#x,%#x:",
644 1.3 matt r, gt_read(gt, GT_WDOG_Value));
645 1.1 matt if ((r & 0x80000000) != 0) {
646 1.3 matt gt_watchdog_sc = gt; /* enabled */
647 1.1 matt gt_watchdog_state = 1;
648 1.1 matt printf(" firmware-enabled\n");
649 1.1 matt gt_watchdog_service();
650 1.1 matt return;
651 1.1 matt } else {
652 1.1 matt printf(" firmware-disabled\n");
653 1.1 matt }
654 1.1 matt
655 1.1 matt extintr_restore(omsr);
656 1.1 matt }
657 1.1 matt
658 1.1 matt #else /* GT_MPP_WATCHDOG */
659 1.1 matt
660 1.1 matt void
661 1.3 matt gt_watchdog_init(struct gt_softc *gt)
662 1.1 matt {
663 1.1 matt u_int32_t mpp_watchdog = GT_MPP_WATCHDOG; /* from config */
664 1.1 matt u_int32_t r;
665 1.1 matt u_int32_t cfgbits;
666 1.1 matt u_int32_t mppbits;
667 1.1 matt u_int32_t mppmask=0;
668 1.1 matt u_int32_t regoff;
669 1.1 matt unsigned int omsr;
670 1.1 matt
671 1.3 matt printf("%s: watchdog", gt->gt_dev.dv_xname);
672 1.1 matt
673 1.1 matt if (mpp_watchdog == 0) {
674 1.1 matt printf(" not configured\n");
675 1.1 matt return;
676 1.1 matt }
677 1.1 matt
678 1.1 matt #if 0
679 1.1 matt if (afw_wdog_ctl == 1) {
680 1.1 matt printf(" admin disabled\n");
681 1.1 matt return;
682 1.1 matt }
683 1.1 matt #endif
684 1.1 matt
685 1.1 matt omsr = extintr_disable();
686 1.1 matt
687 1.1 matt /*
688 1.1 matt * if firmware started watchdog, we disable and start
689 1.1 matt * from scratch to get it in a known state.
690 1.1 matt *
691 1.1 matt * on GT-64260A we always see 0xffffffff
692 1.1 matt * in both the GT_WDOG_Config_Enb and GT_WDOG_Value regsiters.
693 1.1 matt * Use AFW-supplied flag to determine run state.
694 1.1 matt */
695 1.3 matt r = gt_read(gt, GT_WDOG_Config);
696 1.1 matt if (r != ~0) {
697 1.1 matt if ((r & GT_WDOG_Config_Enb) != 0) {
698 1.3 matt gt_write(gt, GT_WDOG_Config,
699 1.1 matt (GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT));
700 1.3 matt gt_write(gt, GT_WDOG_Config,
701 1.1 matt (GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT));
702 1.1 matt }
703 1.1 matt } else {
704 1.1 matt #if 0
705 1.1 matt if (afw_wdog_state == 1) {
706 1.3 matt gt_write(gt, GT_WDOG_Config,
707 1.1 matt (GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT));
708 1.3 matt gt_write(gt, GT_WDOG_Config,
709 1.1 matt (GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT));
710 1.1 matt }
711 1.1 matt #endif
712 1.1 matt }
713 1.1 matt
714 1.1 matt /*
715 1.1 matt * "the watchdog timer can be activated only after
716 1.1 matt * configuring two MPP pins to act as WDE and WDNMI"
717 1.1 matt */
718 1.1 matt mppbits = 0;
719 1.1 matt cfgbits = 0x3;
720 1.1 matt for (regoff = GT_MPP_Control0; regoff <= GT_MPP_Control3; regoff += 4) {
721 1.1 matt if ((mpp_watchdog & cfgbits) == cfgbits) {
722 1.1 matt mppbits = 0x99;
723 1.1 matt mppmask = 0xff;
724 1.1 matt break;
725 1.1 matt }
726 1.1 matt cfgbits <<= 2;
727 1.1 matt if ((mpp_watchdog & cfgbits) == cfgbits) {
728 1.1 matt mppbits = 0x9900;
729 1.1 matt mppmask = 0xff00;
730 1.1 matt break;
731 1.1 matt }
732 1.1 matt cfgbits <<= 6; /* skip unqualified bits */
733 1.1 matt }
734 1.1 matt if (mppbits == 0) {
735 1.1 matt printf(" config error\n");
736 1.1 matt extintr_restore(omsr);
737 1.1 matt return;
738 1.1 matt }
739 1.1 matt
740 1.3 matt r = gt_read(gt, regoff);
741 1.1 matt r &= ~mppmask;
742 1.1 matt r |= mppbits;
743 1.3 matt gt_write(gt, regoff, r);
744 1.1 matt printf(" mpp %#x %#x", regoff, mppbits);
745 1.1 matt
746 1.3 matt gt_write(gt, GT_WDOG_Value, GT_WDOG_NMI_DFLT);
747 1.1 matt
748 1.3 matt gt_write(gt, GT_WDOG_Config,
749 1.1 matt (GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT));
750 1.3 matt gt_write(gt, GT_WDOG_Config,
751 1.1 matt (GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT));
752 1.1 matt
753 1.1 matt
754 1.3 matt r = gt_read(gt, GT_WDOG_Config),
755 1.1 matt printf(" status %#x,%#x: %s",
756 1.3 matt r, gt_read(gt, GT_WDOG_Value),
757 1.1 matt ((r & GT_WDOG_Config_Enb) != 0) ? "enabled" : "botch");
758 1.1 matt
759 1.1 matt if ((r & GT_WDOG_Config_Enb) != 0) {
760 1.1 matt register_t hid0;
761 1.1 matt
762 1.3 matt gt_watchdog_sc = gt; /* enabled */
763 1.1 matt gt_watchdog_state = 1;
764 1.1 matt
765 1.1 matt /*
766 1.1 matt * configure EMCP in HID0 in case it's not already set
767 1.1 matt */
768 1.1 matt __asm __volatile("sync");
769 1.1 matt hid0 = mfspr(SPR_HID0);
770 1.1 matt if ((hid0 & HID0_EMCP) == 0) {
771 1.1 matt hid0 |= HID0_EMCP;
772 1.1 matt __asm __volatile("sync"); mtspr(SPR_HID0, hid0);
773 1.1 matt __asm __volatile("sync"); hid0 = mfspr(SPR_HID0);
774 1.1 matt printf(", EMCP set");
775 1.1 matt }
776 1.1 matt }
777 1.1 matt printf("\n");
778 1.1 matt
779 1.1 matt extintr_restore(omsr);
780 1.1 matt }
781 1.1 matt #endif /* GT_MPP_WATCHDOG */
782 1.1 matt
783 1.1 matt #ifdef DEBUG
784 1.1 matt u_int32_t hid0_print(void);
785 1.1 matt u_int32_t
786 1.1 matt hid0_print()
787 1.1 matt {
788 1.1 matt u_int32_t hid0;
789 1.1 matt __asm __volatile("sync; mfspr %0,1008;" : "=r"(hid0));
790 1.1 matt printf("hid0: %#x\n", hid0);
791 1.1 matt return hid0;
792 1.1 matt }
793 1.1 matt #endif
794 1.1 matt
795 1.1 matt void
796 1.1 matt gt_watchdog_enable(void)
797 1.1 matt {
798 1.3 matt struct gt_softc *gt;
799 1.1 matt unsigned int omsr;
800 1.1 matt
801 1.1 matt omsr = extintr_disable();
802 1.3 matt gt = gt_watchdog_sc;
803 1.3 matt if ((gt != NULL) && (gt_watchdog_state == 0)) {
804 1.1 matt gt_watchdog_state = 1;
805 1.1 matt
806 1.3 matt gt_write(gt, GT_WDOG_Config,
807 1.1 matt (GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT));
808 1.3 matt gt_write(gt, GT_WDOG_Config,
809 1.1 matt (GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT));
810 1.1 matt }
811 1.1 matt extintr_restore(omsr);
812 1.1 matt }
813 1.1 matt
814 1.1 matt void
815 1.1 matt gt_watchdog_disable(void)
816 1.1 matt {
817 1.3 matt struct gt_softc *gt;
818 1.1 matt unsigned int omsr;
819 1.1 matt
820 1.1 matt omsr = extintr_disable();
821 1.3 matt gt = gt_watchdog_sc;
822 1.3 matt if ((gt != NULL) && (gt_watchdog_state != 0)) {
823 1.1 matt gt_watchdog_state = 0;
824 1.1 matt
825 1.3 matt gt_write(gt, GT_WDOG_Config,
826 1.1 matt (GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT));
827 1.3 matt gt_write(gt, GT_WDOG_Config,
828 1.1 matt (GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT));
829 1.1 matt }
830 1.1 matt extintr_restore(omsr);
831 1.1 matt }
832 1.1 matt
833 1.1 matt #ifdef DEBUG
834 1.1 matt int inhibit_watchdog_service = 0;
835 1.1 matt #endif
836 1.1 matt void
837 1.1 matt gt_watchdog_service(void)
838 1.1 matt {
839 1.3 matt struct gt_softc *gt = gt_watchdog_sc;
840 1.1 matt
841 1.3 matt if ((gt == NULL) || (gt_watchdog_state == 0))
842 1.1 matt return; /* not enabled */
843 1.1 matt #ifdef DEBUG
844 1.1 matt if (inhibit_watchdog_service)
845 1.1 matt return;
846 1.1 matt #endif
847 1.1 matt
848 1.3 matt gt_write(gt, GT_WDOG_Config,
849 1.1 matt (GT_WDOG_Config_Ctl2a | GT_WDOG_Preset_DFLT));
850 1.3 matt gt_write(gt, GT_WDOG_Config,
851 1.1 matt (GT_WDOG_Config_Ctl2b | GT_WDOG_Preset_DFLT));
852 1.1 matt }
853 1.1 matt
854 1.1 matt /*
855 1.1 matt * gt_watchdog_reset - force a watchdog reset using Preset_VAL=0
856 1.1 matt */
857 1.1 matt void
858 1.1 matt gt_watchdog_reset()
859 1.1 matt {
860 1.3 matt struct gt_softc *gt = gt_watchdog_sc;
861 1.1 matt u_int32_t r;
862 1.1 matt
863 1.1 matt (void)extintr_disable();
864 1.3 matt r = gt_read(gt, GT_WDOG_Config);
865 1.3 matt gt_write(gt, GT_WDOG_Config, (GT_WDOG_Config_Ctl1a | 0));
866 1.3 matt gt_write(gt, GT_WDOG_Config, (GT_WDOG_Config_Ctl1b | 0));
867 1.1 matt if ((r & GT_WDOG_Config_Enb) != 0) {
868 1.1 matt /*
869 1.1 matt * was enabled, we just toggled it off, toggle on again
870 1.1 matt */
871 1.3 matt gt_write(gt, GT_WDOG_Config,
872 1.1 matt (GT_WDOG_Config_Ctl1a | 0));
873 1.3 matt gt_write(gt, GT_WDOG_Config,
874 1.1 matt (GT_WDOG_Config_Ctl1b | 0));
875 1.1 matt }
876 1.1 matt for(;;);
877 1.1 matt }
878 1.1 matt
879 1.1 matt static int
880 1.1 matt gt_devbus_intr(void *arg)
881 1.1 matt {
882 1.1 matt struct gt_softc *gt = (struct gt_softc *)arg;
883 1.1 matt u_int32_t cause;
884 1.1 matt u_int32_t addr;
885 1.1 matt
886 1.3 matt cause = gt_read(gt, GT_DEVBUS_ICAUSE);
887 1.3 matt addr = gt_read(gt, GT_DEVBUS_ERR_ADDR);
888 1.3 matt gt_write(gt, GT_DEVBUS_ICAUSE, 0); /* clear irpt */
889 1.1 matt
890 1.1 matt if (cause & GT_DEVBUS_DBurstErr) {
891 1.1 matt printf("%s: Device Bus error: burst violation",
892 1.1 matt gt->gt_dev.dv_xname);
893 1.1 matt if ((cause & GT_DEVBUS_Sel) == 0)
894 1.1 matt printf(", addr %#x", addr);
895 1.1 matt printf("\n");
896 1.1 matt }
897 1.1 matt if (cause & GT_DEVBUS_DRdyErr) {
898 1.1 matt printf("%s: Device Bus error: ready timer expired",
899 1.1 matt gt->gt_dev.dv_xname);
900 1.1 matt if ((cause & GT_DEVBUS_Sel) != 0)
901 1.1 matt printf(", addr %#x\n", addr);
902 1.1 matt printf("\n");
903 1.1 matt }
904 1.1 matt
905 1.1 matt return (cause != 0);
906 1.1 matt }
907 1.1 matt
908 1.1 matt /*
909 1.1 matt * gt_ecc_intr_enb - enable GT-64260 ECC interrupts
910 1.1 matt */
911 1.1 matt static void
912 1.1 matt gt_devbus_intr_enb(struct gt_softc *gt)
913 1.1 matt {
914 1.3 matt gt_write(gt, GT_DEVBUS_IMASK,
915 1.1 matt GT_DEVBUS_DBurstErr|GT_DEVBUS_DRdyErr);
916 1.3 matt (void)gt_read(gt, GT_DEVBUS_ERR_ADDR); /* clear addr */
917 1.3 matt gt_write(gt, GT_ECC_Addr, 0); /* clear irpt */
918 1.1 matt
919 1.1 matt intr_establish(IRQ_DEV, IST_LEVEL, IPL_GTERR, gt_devbus_intr, gt);
920 1.1 matt printf("%s: Device Bus Error irpt at %d\n",
921 1.1 matt gt->gt_dev.dv_xname, IRQ_DEV);
922 1.1 matt }
923 1.1 matt
924 1.1 matt
925 1.1 matt int
926 1.1 matt gt_mii_read(
927 1.1 matt struct device *child,
928 1.1 matt struct device *parent,
929 1.1 matt int phy,
930 1.1 matt int reg)
931 1.1 matt {
932 1.3 matt struct gt_softc * const gt = (struct gt_softc *) parent;
933 1.1 matt uint32_t data;
934 1.1 matt int count = 10000;
935 1.1 matt
936 1.1 matt do {
937 1.1 matt DELAY(10);
938 1.3 matt data = gt_read(gt, ETH_ESMIR);
939 1.1 matt } while ((data & ETH_ESMIR_Busy) && count-- > 0);
940 1.1 matt
941 1.1 matt if (count == 0) {
942 1.1 matt printf("%s: mii read for phy %d reg %d busied out\n",
943 1.1 matt child->dv_xname, phy, reg);
944 1.1 matt return ETH_ESMIR_Value_GET(data);
945 1.1 matt }
946 1.1 matt
947 1.3 matt gt_write(gt, ETH_ESMIR, ETH_ESMIR_READ(phy, reg));
948 1.1 matt
949 1.1 matt count = 10000;
950 1.1 matt do {
951 1.1 matt DELAY(10);
952 1.3 matt data = gt_read(gt, ETH_ESMIR);
953 1.1 matt } while ((data & ETH_ESMIR_ReadValid) == 0 && count-- > 0);
954 1.1 matt
955 1.1 matt if (count == 0)
956 1.1 matt printf("%s: mii read for phy %d reg %d timed out\n",
957 1.1 matt child->dv_xname, phy, reg);
958 1.1 matt #if defined(GTMIIDEBUG)
959 1.1 matt printf("%s: mii_read(%d, %d): %#x data %#x\n",
960 1.1 matt child->dv_xname, phy, reg,
961 1.1 matt data, ETH_ESMIR_Value_GET(data));
962 1.1 matt #endif
963 1.1 matt return ETH_ESMIR_Value_GET(data);
964 1.1 matt }
965 1.1 matt
966 1.1 matt void
967 1.1 matt gt_mii_write (
968 1.1 matt struct device *child,
969 1.1 matt struct device *parent,
970 1.1 matt int phy, int reg,
971 1.1 matt int value)
972 1.1 matt {
973 1.3 matt struct gt_softc * const gt = (struct gt_softc *) parent;
974 1.1 matt uint32_t data;
975 1.1 matt int count = 10000;
976 1.1 matt
977 1.1 matt do {
978 1.1 matt DELAY(10);
979 1.3 matt data = gt_read(gt, ETH_ESMIR);
980 1.1 matt } while ((data & ETH_ESMIR_Busy) && count-- > 0);
981 1.1 matt
982 1.1 matt if (count == 0) {
983 1.1 matt printf("%s: mii write for phy %d reg %d busied out (busy)\n",
984 1.1 matt child->dv_xname, phy, reg);
985 1.1 matt return;
986 1.1 matt }
987 1.1 matt
988 1.3 matt gt_write(gt, ETH_ESMIR,
989 1.1 matt ETH_ESMIR_WRITE(phy, reg, value));
990 1.1 matt
991 1.1 matt count = 10000;
992 1.1 matt do {
993 1.1 matt DELAY(10);
994 1.3 matt data = gt_read(gt, ETH_ESMIR);
995 1.1 matt } while ((data & ETH_ESMIR_Busy) && count-- > 0);
996 1.1 matt
997 1.1 matt if (count == 0)
998 1.1 matt printf("%s: mii write for phy %d reg %d timed out\n",
999 1.1 matt child->dv_xname, phy, reg);
1000 1.1 matt #if defined(GTMIIDEBUG)
1001 1.1 matt printf("%s: mii_write(%d, %d, %#x)\n",
1002 1.1 matt child->dv_xname, phy, reg, value);
1003 1.1 matt #endif
1004 1.1 matt }
1005 1.1 matt
1006