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