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