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