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