gt.c revision 1.30
1/*	$NetBSD: gt.c,v 1.30 2021/08/07 16:19:13 thorpej 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.30 2021/08/07 16:19:13 thorpej Exp $");
46
47#include "opt_marvell.h"
48#include "gtmpsc.h"
49#include "opt_multiprocessor.h"
50#include "locators.h"
51
52#include <sys/param.h>
53#include <sys/bus.h>
54#include <sys/device.h>
55#include <sys/kernel.h>
56#include <sys/types.h>
57
58#include <dev/marvell/gtintrreg.h>
59#include <dev/marvell/gtsdmareg.h>
60#if NGTMPSC > 0
61#include <dev/marvell/gtmpscreg.h>
62#include <dev/marvell/gtmpscvar.h>
63#endif
64#include <dev/marvell/gtpcireg.h>
65#include <dev/marvell/gtreg.h>
66#include <dev/marvell/gtvar.h>
67#include <dev/marvell/marvellreg.h>
68#include <dev/marvell/marvellvar.h>
69
70#include <dev/pci/pcireg.h>
71
72#if ((GT_MPP_WATCHDOG & 0xf0f0f0f0) != 0)
73# error		/* unqualified: configuration botch! */
74#endif
75
76#define gt_read(sc,r)	 bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (r))
77#define gt_write(sc,r,v) bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (r), (v))
78
79
80static int	gt_cfprint(void *, const char *);
81static int	gt_cfsearch(device_t, cfdata_t, const int *, void *);
82static void	gt_attach_peripherals(struct gt_softc *);
83
84#ifdef GT_DEVBUS
85static int	gt_devbus_intr(void *);
86static void	gt_devbus_intr_enb(struct gt_softc *);
87#endif
88#ifdef GT_ECC
89static int	gt_ecc_intr(void *);
90static void	gt_ecc_intr_enb(struct gt_softc *);
91#endif
92#if NGTMPSC > 0
93static void	gt_sdma_intr_enb(struct gt_softc *);
94#endif
95#ifdef GT_COMM
96static int	gt_comm_intr(void *);
97static void	gt_comm_intr_enb(struct gt_softc *);
98#endif
99
100
101#ifdef GT_WATCHDOG
102static void gt_watchdog_init(struct gt_softc *);
103static void gt_watchdog_enable(struct gt_softc *);
104#ifndef GT_MPP_WATCHDOG
105static void gt_watchdog_disable(struct gt_softc *);
106#endif
107
108static struct gt_softc *gt_watchdog_sc = NULL;
109static int gt_watchdog_state = 0;
110#endif
111
112
113#define OFFSET_DEFAULT	MVA_OFFSET_DEFAULT
114#define IRQ_DEFAULT	MVA_IRQ_DEFAULT
115static const struct gt_dev {
116	int model;
117	const char *name;
118	int unit;
119	bus_size_t offset;
120	int irq;
121} gt_devs[] = {
122	{ MARVELL_DISCOVERY,	"gfec",    0,	0x0000,		IRQ_DEFAULT },
123	{ MARVELL_DISCOVERY,	"gtidmac", 0,	0x0000,		4 /*...7 */ },
124	{ MARVELL_DISCOVERY,	"gtmpsc",  0,	0x8000,		40 },
125	{ MARVELL_DISCOVERY,	"gtmpsc",  1,	0x9000,		42 },
126	{ MARVELL_DISCOVERY,	"gtpci",   0,	OFFSET_DEFAULT,	IRQ_DEFAULT },
127	{ MARVELL_DISCOVERY,	"gtpci",   1,	OFFSET_DEFAULT,	IRQ_DEFAULT },
128	{ MARVELL_DISCOVERY,	"gttwsi",  0,	0xc000,		37 },
129	{ MARVELL_DISCOVERY,	"obio",    0,	OFFSET_DEFAULT,	IRQ_DEFAULT },
130	{ MARVELL_DISCOVERY,	"obio",    1,	OFFSET_DEFAULT,	IRQ_DEFAULT },
131	{ MARVELL_DISCOVERY,	"obio",    2,	OFFSET_DEFAULT,	IRQ_DEFAULT },
132	{ MARVELL_DISCOVERY,	"obio",    3,	OFFSET_DEFAULT,	IRQ_DEFAULT },
133	{ MARVELL_DISCOVERY,	"obio",    4,	OFFSET_DEFAULT,	IRQ_DEFAULT },
134
135	{ MARVELL_DISCOVERY_II,	"gtidmac", 0,	0x0000,		4 /*...7 */ },
136	{ MARVELL_DISCOVERY_II,	"gtmpsc",  0,	0x8000,		40 },
137	{ MARVELL_DISCOVERY_II,	"gtmpsc",  1,	0x9000,		42 },
138	{ MARVELL_DISCOVERY_II,	"gtpci",   0,	OFFSET_DEFAULT,	IRQ_DEFAULT },
139	{ MARVELL_DISCOVERY_II,	"gtpci",   1,	OFFSET_DEFAULT,	IRQ_DEFAULT },
140	{ MARVELL_DISCOVERY_II,	"gttwsi",  0,	0xc000,		37 },
141	{ MARVELL_DISCOVERY_II,	"mvgbec",  0,	0x0000,		IRQ_DEFAULT },
142
143	{ MARVELL_DISCOVERY_III,"gtidmac", 0,	0x0000,		4 /*...7 */ },
144	{ MARVELL_DISCOVERY_III,"gtmpsc",  0,	0x8000,		40 },
145	{ MARVELL_DISCOVERY_III,"gtmpsc",  1,	0x9000,		42 },
146	{ MARVELL_DISCOVERY_III,"gtpci",   0,	OFFSET_DEFAULT,	IRQ_DEFAULT },
147	{ MARVELL_DISCOVERY_III,"gtpci",   1,	OFFSET_DEFAULT,	IRQ_DEFAULT },
148	{ MARVELL_DISCOVERY_III,"gttwsi",  0,	0xc000,		37 },
149	{ MARVELL_DISCOVERY_III,"mvgbec",  0,	0x0000,		IRQ_DEFAULT },
150
151#if 0	/* XXXXXX: from www.marvell.com */
152	/* Discovery LT (Discovery Light) MV644[23]0 */
153	{ MARVELL_DISCOVERY_LT,	"gtidmac", 0,	0x?000,		? /*...? */ },
154	{ MARVELL_DISCOVERY_LT,	"gtmpsc",  0,	0x?000,		? },
155	{ MARVELL_DISCOVERY_LT,	"gtmpsc",  1,	0x?000,		? },
156	{ MARVELL_DISCOVERY_LT,	"gtpci",   0,	OFFSET_DEFAULT,	IRQ_DEFAULT },
157	{ MARVELL_DISCOVERY_LT,	"gtpci",   1,	OFFSET_DEFAULT,	IRQ_DEFAULT },
158	{ MARVELL_DISCOVERY_LT,	"gttwsi",  0,	0x?000,		? },
159	{ MARVELL_DISCOVERY_LT,	"mvgbec",  0,	0x?000,		IRQ_DEFAULT },
160
161	/* Discovery V MV64560 */
162	{ MARVELL_DISCOVERY_V,	"com",     ?,	0x?0000,	? },
163	{ MARVELL_DISCOVERY_V,	"ehci",    0,	0x?0000,	? },
164	{ MARVELL_DISCOVERY_V,	"ehci",    1,	0x?0000,	? },
165	{ MARVELL_DISCOVERY_V,	"gtidmac", 0,	0x?0000,	? /*...? */ },
166	{ MARVELL_DISCOVERY_V,	"gtpci",   0,	0x?0000,	IRQ_DEFAULT },
167	{ MARVELL_DISCOVERY_V,	"gttwsi",  0,	0x?0000,	? },
168	{ MARVELL_DISCOVERY_V,	"mvgbec",  0,	0x?0000,	IRQ_DEFAULT },
169	{ MARVELL_DISCOVERY_V,	"mvpex or gtpci?", 0, 0x?0000,	IRQ_DEFAULT },
170	{ MARVELL_DISCOVERY_V,	"obio",    0,	OFFSET_DEFAULT,	IRQ_DEFAULT },
171
172	/* Discovery VI MV64660 */
173	/* MV64560 + SATA? */
174	{ MARVELL_DISCOVERY_VI, "mvsata",  0,	0x?0000,	? },
175#endif
176};
177
178
179static int
180gt_cfprint(void *aux, const char *pnp)
181{
182	struct marvell_attach_args *mva = aux;
183
184	if (pnp)
185		aprint_normal("%s at %s unit %d",
186		    mva->mva_name, pnp, mva->mva_unit);
187	else {
188		if (mva->mva_unit != MVA_UNIT_DEFAULT)
189			aprint_normal(" unit %d", mva->mva_unit);
190		if (mva->mva_offset != MVA_OFFSET_DEFAULT) {
191			aprint_normal(" offset 0x%04x", mva->mva_offset);
192			if (mva->mva_size > 0)
193				aprint_normal("-0x%04x",
194				    mva->mva_offset + mva->mva_size - 1);
195		}
196		if (mva->mva_irq != MVA_IRQ_DEFAULT)
197			aprint_normal(" irq %d", mva->mva_irq);
198	}
199
200	return UNCONF;
201}
202
203
204/* ARGSUSED */
205static int
206gt_cfsearch(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
207{
208	struct marvell_attach_args *mva = aux;
209
210	if (cf->cf_loc[GTCF_IRQ] != MVA_IRQ_DEFAULT)
211		mva->mva_irq = cf->cf_loc[GTCF_IRQ];
212
213	return config_match(parent, cf, aux);
214}
215
216static void
217gt_attach_peripherals(struct gt_softc *sc)
218{
219	struct marvell_attach_args mva;
220	int i;
221
222	for (i = 0; i < __arraycount(gt_devs); i++) {
223		if (gt_devs[i].model != sc->sc_model)
224			continue;
225
226		mva.mva_name = gt_devs[i].name;
227		mva.mva_model = sc->sc_model;
228		mva.mva_revision = sc->sc_rev;
229		mva.mva_iot = sc->sc_iot;
230		mva.mva_ioh = sc->sc_ioh;
231		mva.mva_unit = gt_devs[i].unit;
232		mva.mva_addr = sc->sc_addr;
233		mva.mva_offset = gt_devs[i].offset;
234		mva.mva_size = 0;
235		mva.mva_dmat = sc->sc_dmat;
236		mva.mva_irq = gt_devs[i].irq;
237
238		config_found(sc->sc_dev, &mva, gt_cfprint,
239		    CFARGS(.submatch = gt_cfsearch));
240	}
241}
242
243void
244gt_attach_common(struct gt_softc *gt)
245{
246	uint32_t cpucfg, cpumode, cpumstr;
247#ifdef GT_DEBUG
248	uint32_t loaddr, hiaddr;
249#endif
250
251	gt_write(gt, GTPCI_CA(0), PCI_ID_REG);
252	gt->sc_model = PCI_PRODUCT(gt_read(gt, GTPCI_CD(0)));
253	gt_write(gt, GTPCI_CA(0), PCI_CLASS_REG);
254	gt->sc_rev = PCI_REVISION(gt_read(gt, GTPCI_CD(0)));
255
256	aprint_naive("\n");
257	switch (gt->sc_model) {
258	case MARVELL_DISCOVERY:
259		aprint_normal(": GT-6426x%c Discovery\n",
260		    (gt->sc_rev == MARVELL_DISCOVERY_REVA) ? 'A' : 'B');
261		break;
262	case MARVELL_DISCOVERY_II:
263		aprint_normal(": MV6436x Discovery II\n");
264		break;
265
266	case MARVELL_DISCOVERY_III:
267		aprint_normal(": MV6446x Discovery III\n");
268		break;
269#if 0
270	case MARVELL_DISCOVERY_LT:
271	case MARVELL_DISCOVERY_V:
272	case MARVELL_DISCOVERY_VI:
273#endif
274
275	default:
276		aprint_normal(": type unknown\n"); break;
277	}
278
279	cpumode = gt_read(gt, GT_CPU_Mode);
280	aprint_normal_dev(gt->sc_dev,
281	    "id %d", GT_CPUMode_MultiGTID_GET(cpumode));
282	if (cpumode & GT_CPUMode_MultiGT)
283		aprint_normal (" (multi)");
284	switch (GT_CPUMode_CPUType_GET(cpumode)) {
285	case 4: aprint_normal(", 60x bus"); break;
286	case 5: aprint_normal(", MPX bus"); break;
287
288	default:
289		aprint_normal(", %#x(?) bus", GT_CPUMode_CPUType_GET(cpumode));
290		break;
291	}
292
293	cpumstr = gt_read(gt, GT_CPU_Master_Ctl);
294	switch (cpumstr & (GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock)) {
295	case 0: break;
296	case GT_CPUMstrCtl_CleanBlock: aprint_normal(", snoop=clean"); break;
297	case GT_CPUMstrCtl_FlushBlock: aprint_normal(", snoop=flush"); break;
298	case GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock:
299		aprint_normal(", snoop=clean&flush"); break;
300	}
301	aprint_normal(" wdog=%#x,%#x\n",
302	    gt_read(gt, GT_WDOG_Config), gt_read(gt, GT_WDOG_Value));
303
304#ifdef GT_DEBUG
305	loaddr = GT_LADDR_GET(gt_read(gt, GT_SCS0_Low_Decode), gt->sc_model);
306	hiaddr = GT_HADDR_GET(gt_read(gt, GT_SCS0_High_Decode), gt->sc_model);
307	aprint_normal_dev(gt->sc_dev, "     scs[0]=%#10x-%#10x\n",
308	    loaddr, hiaddr);
309
310	loaddr = GT_LADDR_GET(gt_read(gt, GT_SCS1_Low_Decode), gt->sc_model);
311	hiaddr = GT_HADDR_GET(gt_read(gt, GT_SCS1_High_Decode), gt->sc_model);
312	aprint_normal_dev(gt->sc_dev, "     scs[1]=%#10x-%#10x\n",
313	    loaddr, hiaddr);
314
315	loaddr = GT_LADDR_GET(gt_read(gt, GT_SCS2_Low_Decode), gt->sc_model);
316	hiaddr = GT_HADDR_GET(gt_read(gt, GT_SCS2_High_Decode), gt->sc_model);
317	aprint_normal_dev(gt->sc_dev, "     scs[2]=%#10x-%#10x\n",
318	    loaddr, hiaddr);
319
320	loaddr = GT_LADDR_GET(gt_read(gt, GT_SCS3_Low_Decode), gt->sc_model);
321	hiaddr = GT_HADDR_GET(gt_read(gt, GT_SCS3_High_Decode), gt->sc_model);
322	aprint_normal_dev(gt->sc_dev, "     scs[3]=%#10x-%#10x\n",
323	    loaddr, hiaddr);
324
325	loaddr = GT_LADDR_GET(gt_read(gt, GT_CS0_Low_Decode), gt->sc_model);
326	hiaddr = GT_HADDR_GET(gt_read(gt, GT_CS0_High_Decode), gt->sc_model);
327	aprint_normal_dev(gt->sc_dev, "      cs[0]=%#10x-%#10x\n",
328	    loaddr, hiaddr);
329
330	loaddr = GT_LADDR_GET(gt_read(gt, GT_CS1_Low_Decode), gt->sc_model);
331	hiaddr = GT_HADDR_GET(gt_read(gt, GT_CS1_High_Decode), gt->sc_model);
332	aprint_normal_dev(gt->sc_dev, "      cs[1]=%#10x-%#10x\n",
333	    loaddr, hiaddr);
334
335	loaddr = GT_LADDR_GET(gt_read(gt, GT_CS2_Low_Decode), gt->sc_model);
336	hiaddr = GT_HADDR_GET(gt_read(gt, GT_CS2_High_Decode), gt->sc_model);
337	aprint_normal_dev(gt->sc_dev, "      cs[2]=%#10x-%#10x\n",
338	    loaddr, hiaddr);
339
340	loaddr = GT_LADDR_GET(gt_read(gt, GT_CS3_Low_Decode), gt->sc_model);
341	hiaddr = GT_HADDR_GET(gt_read(gt, GT_CS3_High_Decode), gt->sc_model);
342	aprint_normal_dev(gt->sc_dev, "      cs[3]=%#10x-%#10x\n",
343	    loaddr, hiaddr);
344
345	loaddr = GT_LADDR_GET(gt_read(gt, GT_BootCS_Low_Decode), gt->sc_model);
346	hiaddr = GT_HADDR_GET(gt_read(gt, GT_BootCS_High_Decode), gt->sc_model);
347	aprint_normal_dev(gt->sc_dev, "     bootcs=%#10x-%#10x\n",
348	    loaddr, hiaddr);
349
350	loaddr = GT_LADDR_GET(gt_read(gt, GT_PCI0_IO_Low_Decode), gt->sc_model);
351	hiaddr =
352	    GT_HADDR_GET(gt_read(gt, GT_PCI0_IO_High_Decode), gt->sc_model);
353	aprint_normal_dev(gt->sc_dev, "     pci0io=%#10x-%#10x  ",
354	    loaddr, hiaddr);
355
356	loaddr = gt_read(gt, GT_PCI0_IO_Remap);
357	aprint_normal("remap=%#010x\n", loaddr);
358
359	loaddr =
360	    GT_LADDR_GET(gt_read(gt, GT_PCI0_Mem0_Low_Decode), gt->sc_model);
361	hiaddr =
362	    GT_HADDR_GET(gt_read(gt, GT_PCI0_Mem0_High_Decode), gt->sc_model);
363	aprint_normal_dev(gt->sc_dev, " pci0mem[0]=%#10x-%#10x  ",
364	    loaddr, hiaddr);
365
366	loaddr = gt_read(gt, GT_PCI0_Mem0_Remap_Low);
367	hiaddr = gt_read(gt, GT_PCI0_Mem0_Remap_High);
368	aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
369
370	loaddr =
371	    GT_LADDR_GET(gt_read(gt, GT_PCI0_Mem1_Low_Decode), gt->sc_model);
372	hiaddr =
373	    GT_HADDR_GET(gt_read(gt, GT_PCI0_Mem1_High_Decode), gt->sc_model);
374	aprint_normal_dev(gt->sc_dev, " pci0mem[1]=%#10x-%#10x  ",
375	    loaddr, hiaddr);
376
377	loaddr = gt_read(gt, GT_PCI0_Mem1_Remap_Low);
378	hiaddr = gt_read(gt, GT_PCI0_Mem1_Remap_High);
379	aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
380
381	loaddr =
382	    GT_LADDR_GET(gt_read(gt, GT_PCI0_Mem2_Low_Decode), gt->sc_model);
383	hiaddr =
384	    GT_HADDR_GET(gt_read(gt, GT_PCI0_Mem2_High_Decode), gt->sc_model);
385	aprint_normal_dev(gt->sc_dev, " pci0mem[2]=%#10x-%#10x  ",
386	    loaddr, hiaddr);
387
388	loaddr = gt_read(gt, GT_PCI0_Mem2_Remap_Low);
389	hiaddr = gt_read(gt, GT_PCI0_Mem2_Remap_High);
390	aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
391
392	loaddr =
393	    GT_LADDR_GET(gt_read(gt, GT_PCI0_Mem3_Low_Decode), gt->sc_model);
394	hiaddr =
395	    GT_HADDR_GET(gt_read(gt, GT_PCI0_Mem3_High_Decode), gt->sc_model);
396	aprint_normal_dev(gt->sc_dev, " pci0mem[3]=%#10x-%#10x  ",
397	    loaddr, hiaddr);
398
399	loaddr = gt_read(gt, GT_PCI0_Mem3_Remap_Low);
400	hiaddr = gt_read(gt, GT_PCI0_Mem3_Remap_High);
401	aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
402
403	loaddr = GT_LADDR_GET(gt_read(gt, GT_PCI1_IO_Low_Decode), gt->sc_model);
404	hiaddr =
405	    GT_HADDR_GET(gt_read(gt, GT_PCI1_IO_High_Decode), gt->sc_model);
406	aprint_normal_dev(gt->sc_dev, "     pci1io=%#10x-%#10x  ",
407	    loaddr, hiaddr);
408
409	loaddr = gt_read(gt, GT_PCI1_IO_Remap);
410	aprint_normal("remap=%#010x\n", loaddr);
411
412	loaddr =
413	    GT_LADDR_GET(gt_read(gt, GT_PCI1_Mem0_Low_Decode), gt->sc_model);
414	hiaddr =
415	    GT_HADDR_GET(gt_read(gt, GT_PCI1_Mem0_High_Decode), gt->sc_model);
416	aprint_normal_dev(gt->sc_dev, " pci1mem[0]=%#10x-%#10x  ",
417	    loaddr, hiaddr);
418
419	loaddr = gt_read(gt, GT_PCI1_Mem0_Remap_Low);
420	hiaddr = gt_read(gt, GT_PCI1_Mem0_Remap_High);
421	aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
422
423	loaddr =
424	    GT_LADDR_GET(gt_read(gt, GT_PCI1_Mem1_Low_Decode), gt->sc_model);
425	hiaddr =
426	    GT_HADDR_GET(gt_read(gt, GT_PCI1_Mem1_High_Decode), gt->sc_model);
427	aprint_normal_dev(gt->sc_dev, " pci1mem[1]=%#10x-%#10x  ",
428	    loaddr, hiaddr);
429
430	loaddr = gt_read(gt, GT_PCI1_Mem1_Remap_Low);
431	hiaddr = gt_read(gt, GT_PCI1_Mem1_Remap_High);
432	aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
433
434	loaddr =
435	    GT_LADDR_GET(gt_read(gt, GT_PCI1_Mem2_Low_Decode), gt->sc_model);
436	hiaddr =
437	    GT_HADDR_GET(gt_read(gt, GT_PCI1_Mem2_High_Decode), gt->sc_model);
438	aprint_normal_dev(gt->sc_dev, " pci1mem[2]=%#10x-%#10x  ",
439	    loaddr, hiaddr);
440
441	loaddr = gt_read(gt, GT_PCI1_Mem2_Remap_Low);
442	hiaddr = gt_read(gt, GT_PCI1_Mem2_Remap_High);
443	aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
444
445	loaddr =
446	    GT_LADDR_GET(gt_read(gt, GT_PCI1_Mem3_Low_Decode), gt->sc_model);
447	hiaddr =
448	    GT_HADDR_GET(gt_read(gt, GT_PCI1_Mem3_High_Decode), gt->sc_model);
449	aprint_normal_dev(gt->sc_dev, " pci1mem[3]=%#10x-%#10x  ",
450	    loaddr, hiaddr);
451
452	loaddr = gt_read(gt, GT_PCI1_Mem3_Remap_Low);
453	hiaddr = gt_read(gt, GT_PCI1_Mem3_Remap_High);
454	aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
455
456	loaddr = GT_LADDR_GET(gt_read(gt, GT_Internal_Decode), gt->sc_model);
457	aprint_normal_dev(gt->sc_dev, "   internal=%#10x-%#10x\n",
458	    loaddr, loaddr + 256 * 1024);
459
460	loaddr = GT_LADDR_GET(gt_read(gt, GT_CPU0_Low_Decode), gt->sc_model);
461	hiaddr = GT_HADDR_GET(gt_read(gt, GT_CPU0_High_Decode), gt->sc_model);
462	aprint_normal_dev(gt->sc_dev, "       cpu0=%#10x-%#10x\n",
463	    loaddr, hiaddr);
464
465#ifdef MULTIPROCESSOR
466	loaddr = GT_LADDR_GET(gt_read(gt, GT_CPU1_Low_Decode), gt->sc_model);
467	hiaddr = GT_HADDR_GET(gt_read(gt, GT_CPU1_High_Decode), gt->sc_model);
468	aprint_normal_dev(gt->sc_dev, "       cpu1=%#10x-%#10x",
469	    loaddr, hiaddr);
470#endif
471#endif
472
473	aprint_normal("%s:", device_xname(gt->sc_dev));
474
475	cpucfg = gt_read(gt, GT_CPU_Cfg);
476	cpucfg |= GT_CPUCfg_ConfSBDis;		/* per errata #46 */
477	cpucfg |= GT_CPUCfg_AACKDelay;		/* per restriction #18 */
478	gt_write(gt, GT_CPU_Cfg, cpucfg);
479	if (cpucfg & GT_CPUCfg_Pipeline)
480		aprint_normal(" pipeline");
481	if (cpucfg & GT_CPUCfg_AACKDelay)
482		aprint_normal(" aack-delay");
483	if (cpucfg & GT_CPUCfg_RdOOO)
484		aprint_normal(" read-ooo");
485	if (cpucfg & GT_CPUCfg_IOSBDis)
486		aprint_normal(" io-sb-dis");
487	if (cpucfg & GT_CPUCfg_ConfSBDis)
488		aprint_normal(" conf-sb-dis");
489	if (cpucfg & GT_CPUCfg_ClkSync)
490		aprint_normal(" clk-sync");
491	aprint_normal("\n");
492
493#ifdef GT_WATCHDOG
494	gt_watchdog_init(gt);
495#endif
496
497#ifdef GT_DEVBUS
498	gt_devbus_intr_enb(gt);
499#endif
500#ifdef GT_ECC
501	gt_ecc_intr_enb(gt);
502#endif
503#if NGTMPSC > 0
504	gt_sdma_intr_enb(gt);
505#endif
506#ifdef GT_COMM
507	gt_comm_intr_enb(gt);
508#endif
509
510	gt_attach_peripherals(gt);
511
512#ifdef GT_WATCHDOG
513	gt_watchdog_service();
514	gt_watchdog_enable(gt);
515#endif
516}
517
518
519#ifdef GT_DEVBUS
520static int
521gt_devbus_intr(void *arg)
522{
523	struct gt_softc *gt = (struct gt_softc *)arg;
524	u_int32_t cause;
525	u_int32_t addr;
526
527	cause = gt_read(gt, GT_DEVBUS_ICAUSE);
528	addr = gt_read(gt, GT_DEVBUS_ERR_ADDR);
529	gt_write(gt, GT_DEVBUS_ICAUSE, 0);	/* clear intr */
530
531	if (cause & GT_DEVBUS_DBurstErr) {
532		aprint_error_dev(gt->sc_dev,
533		    "Device Bus error: burst violation");
534		if ((cause & GT_DEVBUS_Sel) == 0)
535			aprint_error(", addr %#x", addr);
536		aprint_error("\n");
537	}
538	if (cause & GT_DEVBUS_DRdyErr) {
539		aprint_error_dev(gt->sc_dev,
540		    "Device Bus error: ready timer expired");
541		if ((cause & GT_DEVBUS_Sel) != 0)
542			aprint_error(", addr %#x\n", addr);
543		aprint_error("\n");
544	}
545
546	return cause != 0;
547}
548
549/*
550 * gt_devbus_intr_enb - enable GT-64260 Device Bus interrupts
551 */
552static void
553gt_devbus_intr_enb(struct gt_softc *gt)
554{
555	gt_write(gt, GT_DEVBUS_IMASK,
556		GT_DEVBUS_DBurstErr|GT_DEVBUS_DRdyErr);
557	(void)gt_read(gt, GT_DEVBUS_ERR_ADDR);	/* clear addr */
558	gt_write(gt, GT_DEVBUS_ICAUSE, 0);	/* clear intr */
559
560	(void)marvell_intr_establish(IRQ_DEV, IPL_VM, gt_devbus_intr, gt);
561}
562#endif	/* GT_DEVBUS */
563
564#ifdef GT_ECC
565const static char *gt_ecc_intr_str[4] = {
566	"(none)",
567	"single bit",
568	"double bit",
569	"(reserved)"
570};
571
572static int
573gt_ecc_intr(void *arg)
574{
575	struct gt_softc *gt = (struct gt_softc *)arg;
576	uint32_t addr, dlo, dhi, rec, calc, count;
577	int err;
578
579	count = gt_read(gt, GT_ECC_Count);
580	dlo   = gt_read(gt, GT_ECC_Data_Lo);
581	dhi   = gt_read(gt, GT_ECC_Data_Hi);
582	rec   = gt_read(gt, GT_ECC_Rec);
583	calc  = gt_read(gt, GT_ECC_Calc);
584	addr  = gt_read(gt, GT_ECC_Addr);	/* read last! */
585	gt_write(gt, GT_ECC_Addr, 0);		/* clear intr */
586
587	err = addr & 0x3;
588
589	aprint_error_dev(gt->sc_dev,
590	    "ECC error: %s: addr %#x data %#x.%#x rec %#x calc %#x cnt %#x\n",
591	    gt_ecc_intr_str[err], addr, dhi, dlo, rec, calc, count);
592
593	if (err == 2)
594		panic("ecc");
595
596	return err == 1;
597}
598
599/*
600 * gt_ecc_intr_enb - enable GT-64260 ECC interrupts
601 */
602static void
603gt_ecc_intr_enb(struct gt_softc *gt)
604{
605	uint32_t ctl;
606
607	ctl = gt_read(gt, GT_ECC_Ctl);
608	ctl |= 1 << 16;		/* XXX 1-bit threshold == 1 */
609	gt_write(gt, GT_ECC_Ctl, ctl);
610	(void)gt_read(gt, GT_ECC_Data_Lo);
611	(void)gt_read(gt, GT_ECC_Data_Hi);
612	(void)gt_read(gt, GT_ECC_Rec);
613	(void)gt_read(gt, GT_ECC_Calc);
614	(void)gt_read(gt, GT_ECC_Addr);		/* read last! */
615	gt_write(gt, GT_ECC_Addr, 0);		/* clear intr */
616
617	(void)marvell_intr_establish(IRQ_ECC, IPL_VM, gt_ecc_intr, gt);
618}
619#endif	/* GT_ECC */
620
621#if NGTMPSC > 0
622/*
623 * gt_sdma_intr_enb - enable GT-64260 SDMA interrupts
624 */
625static void
626gt_sdma_intr_enb(struct gt_softc *gt)
627{
628
629	(void)marvell_intr_establish(IRQ_SDMA, IPL_SERIAL, gtmpsc_intr, gt);
630}
631#endif
632
633#ifdef GT_COMM
634/*
635 * unknown board, enable everything
636 */
637# define GT_CommUnitIntr_DFLT	\
638	    GT_CommUnitIntr_S0 |\
639	    GT_CommUnitIntr_S1 |\
640	    GT_CommUnitIntr_E0 |\
641	    GT_CommUnitIntr_E1 |\
642	    GT_CommUnitIntr_E2
643
644static const char * const gt_comm_subunit_name[8] = {
645	"ethernet 0",
646	"ethernet 1",
647	"ethernet 2",
648	"(reserved)",
649	"MPSC 0",
650	"MPSC 1",
651	"(reserved)",
652	"(sel)",
653};
654
655static int
656gt_comm_intr(void *arg)
657{
658	struct gt_softc *gt = (struct gt_softc *)arg;
659	uint32_t cause, addr;
660	unsigned int mask;
661	int i;
662
663	cause = gt_read(gt, GT_CommUnitIntr_Cause);
664	gt_write(gt, GT_CommUnitIntr_Cause, ~cause);
665	addr = gt_read(gt, GT_CommUnitIntr_ErrAddr);
666
667	aprint_error_dev(gt->sc_dev,
668	    "Communications Unit Controller interrupt, cause %#x addr %#x\n",
669	    cause, addr);
670
671	cause &= GT_CommUnitIntr_DFLT;
672	if (cause == 0)
673		return 0;
674
675	mask = 0x7;
676	for (i=0; i<7; i++) {
677		if (cause & mask) {
678			printf("%s: Comm Unit %s:", device_xname(gt->sc_dev),
679				gt_comm_subunit_name[i]);
680			if (cause & 1)
681				printf(" AddrMiss");
682			if (cause & 2)
683				printf(" AccProt");
684			if (cause & 4)
685				printf(" WrProt");
686			printf("\n");
687		}
688		cause >>= 4;
689	}
690	return 1;
691}
692
693/*
694 * gt_comm_intr_init - enable GT-64260 Comm Unit interrupts
695 */
696static void
697gt_comm_intr_enb(struct gt_softc *gt)
698{
699	uint32_t cause;
700
701	cause = gt_read(gt, GT_CommUnitIntr_Cause);
702	if (cause)
703		gt_write(gt, GT_CommUnitIntr_Cause, ~cause);
704	gt_write(gt, GT_CommUnitIntr_Mask, GT_CommUnitIntr_DFLT);
705	(void)gt_read(gt, GT_CommUnitIntr_ErrAddr);
706
707	(void)marvell_intr_establish(IRQ_COMM, IPL_VM, gt_comm_intr, gt);
708}
709#endif	/* GT_COMM */
710
711
712#ifdef GT_WATCHDOG
713#ifndef GT_MPP_WATCHDOG
714static void
715gt_watchdog_init(struct gt_softc *gt)
716{
717	u_int32_t r;
718
719	aprint_normal_dev(gt->sc_dev, "watchdog");
720
721	/*
722	 * handle case where firmware started watchdog
723	 */
724	r = gt_read(gt, GT_WDOG_Config);
725	aprint_normal(" status %#x,%#x:", r, gt_read(gt, GT_WDOG_Value));
726	if ((r & 0x80000000) != 0) {
727		gt_watchdog_sc = gt;		/* enabled */
728		gt_watchdog_state = 1;
729		aprint_normal(" firmware-enabled\n");
730		gt_watchdog_disable(gt);
731	} else
732		aprint_normal(" firmware-disabled\n");
733}
734
735#elif	GT_MPP_WATCHDOG == 0
736
737static void
738gt_watchdog_init(struct gt_softc *gt)
739{
740
741	aprint_normal_dev(gt->sc_dev, "watchdog not configured\n");
742	return;
743}
744
745#else	/* GT_MPP_WATCHDOG > 0 */
746
747static void
748gt_watchdog_init(struct gt_softc *gt)
749{
750	u_int32_t mpp_watchdog = GT_MPP_WATCHDOG;	/* from config */
751	u_int32_t cfgbits, mppbits, mppmask, regoff, r;
752
753	mppmask = 0;
754
755	aprint_normal_dev(gt->sc_dev, "watchdog");
756
757	/*
758	 * if firmware started watchdog, we disable and start
759	 * from scratch to get it in a known state.
760	 *
761	 * on GT-64260A we always see 0xffffffff
762	 * in both the GT_WDOG_Config_Enb and GT_WDOG_Value registers.
763	 */
764	r = gt_read(gt, GT_WDOG_Config);
765	if (r != ~0) {
766		if ((r & GT_WDOG_Config_Enb) != 0) {
767			gt_write(gt, GT_WDOG_Config,
768			    GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT);
769			gt_write(gt, GT_WDOG_Config,
770			    GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT);
771		}
772	}
773
774	/*
775	 * "the watchdog timer can be activated only after
776	 * configuring two MPP pins to act as WDE and WDNMI"
777	 */
778	mppbits = 0;
779	cfgbits = 0x3;
780	for (regoff = GT_MPP_Control0; regoff <= GT_MPP_Control3; regoff += 4) {
781		if ((mpp_watchdog & cfgbits) == cfgbits) {
782			mppbits = 0x99;
783			mppmask = 0xff;
784			break;
785		}
786		cfgbits <<= 2;
787		if ((mpp_watchdog & cfgbits) == cfgbits) {
788			mppbits = 0x9900;
789			mppmask = 0xff00;
790			break;
791		}
792		cfgbits <<= 6;	/* skip unqualified bits */
793	}
794	if (mppbits == 0) {
795		aprint_error(" config error\n");
796		return;
797	}
798
799	r = gt_read(gt, regoff);
800	r &= ~mppmask;
801	r |= mppbits;
802	gt_write(gt, regoff, r);
803	aprint_normal(" mpp %#x %#x", regoff, mppbits);
804
805	gt_write(gt, GT_WDOG_Value, GT_WDOG_NMI_DFLT);
806
807	gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1a|GT_WDOG_Preset_DFLT);
808	gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1b|GT_WDOG_Preset_DFLT);
809
810	r = gt_read(gt, GT_WDOG_Config);
811	aprint_normal(" status %#x,%#x: %s\n",
812	    r, gt_read(gt, GT_WDOG_Value),
813	    ((r & GT_WDOG_Config_Enb) != 0) ? "enabled" : "botch");
814}
815#endif	/* GT_MPP_WATCHDOG */
816
817static void
818gt_watchdog_enable(struct gt_softc *gt)
819{
820
821	if (gt_watchdog_state == 0) {
822		gt_watchdog_state = 1;
823
824		gt_write(gt, GT_WDOG_Config,
825		    GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT);
826		gt_write(gt, GT_WDOG_Config,
827		    GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT);
828	}
829}
830
831#ifndef GT_MPP_WATCHDOG
832static void
833gt_watchdog_disable(struct gt_softc *gt)
834{
835
836	if (gt_watchdog_state != 0) {
837		gt_watchdog_state = 0;
838
839		gt_write(gt, GT_WDOG_Config,
840		    GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT);
841		gt_write(gt, GT_WDOG_Config,
842		    GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT);
843	}
844}
845#endif
846
847/*
848 * XXXX: gt_watchdog_service/reset functions need mutex lock...
849 */
850
851#ifdef GT_DEBUG
852int inhibit_watchdog_service = 0;
853#endif
854void
855gt_watchdog_service(void)
856{
857	struct gt_softc *gt = gt_watchdog_sc;
858
859	if ((gt == NULL) || (gt_watchdog_state == 0))
860		return;		/* not enabled */
861#ifdef GT_DEBUG
862	if (inhibit_watchdog_service)
863		return;
864#endif
865
866	gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl2a|GT_WDOG_Preset_DFLT);
867	gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl2b|GT_WDOG_Preset_DFLT);
868}
869
870/*
871 * gt_watchdog_reset - force a watchdog reset using Preset_VAL=0
872 */
873void
874gt_watchdog_reset(void)
875{
876	struct gt_softc *gt = gt_watchdog_sc;
877	u_int32_t r;
878
879	r = gt_read(gt, GT_WDOG_Config);
880	gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1a);
881	gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1b);
882	if ((r & GT_WDOG_Config_Enb) != 0) {
883		/*
884		 * was enabled, we just toggled it off, toggle on again
885		 */
886		gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1a);
887		gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1b);
888	}
889	for(;;);
890}
891#endif
892
893
894int
895marvell_winparams_by_tag(device_t dev, int tag, int *target, int *attr,
896			 uint64_t *base, uint32_t *size)
897{
898	static const struct {
899		int tag;
900		uint32_t attribute;
901		uint32_t basereg;
902		uint32_t sizereg;
903	} tagtbl[] = {
904		{ MARVELL_TAG_SDRAM_CS0,	MARVELL_ATTR_SDRAM_CS0,
905		  GT_SCS0_Low_Decode,		GT_SCS0_High_Decode },
906		{ MARVELL_TAG_SDRAM_CS1,	MARVELL_ATTR_SDRAM_CS1,
907		  GT_SCS1_Low_Decode,		GT_SCS1_High_Decode },
908		{ MARVELL_TAG_SDRAM_CS2,	MARVELL_ATTR_SDRAM_CS2,
909		  GT_SCS2_Low_Decode,		GT_SCS2_High_Decode },
910		{ MARVELL_TAG_SDRAM_CS3,	MARVELL_ATTR_SDRAM_CS3,
911		  GT_SCS3_Low_Decode,		GT_SCS3_High_Decode },
912
913		{ MARVELL_TAG_UNDEFINED, 0, 0 }
914	};
915	struct gt_softc *sc = device_private(dev);
916	int i;
917
918	for (i = 0; tagtbl[i].tag != MARVELL_TAG_UNDEFINED; i++)
919		if (tag == tagtbl[i].tag)
920			break;
921	if (tagtbl[i].tag == MARVELL_TAG_UNDEFINED)
922		return -1;
923
924	if (target != NULL)
925		*target = 0;
926	if (attr != NULL)
927		*attr = tagtbl[i].attribute;
928	if (base != NULL)
929		*base = gt_read(sc, tagtbl[i].basereg) <<
930		    (sc->sc_model == MARVELL_DISCOVERY ? 20 : 16);
931	if (size != NULL) {
932		const uint32_t s = gt_read(sc, tagtbl[i].sizereg);
933
934		if (s != 0)
935			*size = (s + 1) <<
936			    (sc->sc_model == MARVELL_DISCOVERY ? 20 : 16);
937		else
938			*size = 0;
939	}
940
941	return 0;
942}
943