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