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