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