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