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