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