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