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