Home | History | Annotate | Line # | Download | only in vr
bcu_vrip.c revision 1.12.4.2
      1  1.12.4.2  nathanw /*	$NetBSD: bcu_vrip.c,v 1.12.4.2 2002/02/28 04:10:03 nathanw Exp $	*/
      2  1.12.4.2  nathanw 
      3  1.12.4.2  nathanw /*-
      4  1.12.4.2  nathanw  * Copyright (c) 1999-2001 SATO Kazumi. All rights reserved.
      5  1.12.4.2  nathanw  * Copyright (c) 1999, 2002 PocketBSD Project. All rights reserved.
      6  1.12.4.2  nathanw  *
      7  1.12.4.2  nathanw  * Redistribution and use in source and binary forms, with or without
      8  1.12.4.2  nathanw  * modification, are permitted provided that the following conditions
      9  1.12.4.2  nathanw  * are met:
     10  1.12.4.2  nathanw  * 1. Redistributions of source code must retain the above copyright
     11  1.12.4.2  nathanw  *    notice, this list of conditions and the following disclaimer.
     12  1.12.4.2  nathanw  * 2. Redistributions in binary form must reproduce the above copyright
     13  1.12.4.2  nathanw  *    notice, this list of conditions and the following disclaimer in the
     14  1.12.4.2  nathanw  *    documentation and/or other materials provided with the distribution.
     15  1.12.4.2  nathanw  * 3. All advertising materials mentioning features or use of this software
     16  1.12.4.2  nathanw  *    must display the following acknowledgement:
     17  1.12.4.2  nathanw  *	This product includes software developed by the PocketBSD project
     18  1.12.4.2  nathanw  *	and its contributors.
     19  1.12.4.2  nathanw  * 4. Neither the name of the project nor the names of its contributors
     20  1.12.4.2  nathanw  *    may be used to endorse or promote products derived from this software
     21  1.12.4.2  nathanw  *    without specific prior written permission.
     22  1.12.4.2  nathanw  *
     23  1.12.4.2  nathanw  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     24  1.12.4.2  nathanw  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25  1.12.4.2  nathanw  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26  1.12.4.2  nathanw  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     27  1.12.4.2  nathanw  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28  1.12.4.2  nathanw  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29  1.12.4.2  nathanw  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30  1.12.4.2  nathanw  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31  1.12.4.2  nathanw  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32  1.12.4.2  nathanw  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33  1.12.4.2  nathanw  * SUCH DAMAGE.
     34  1.12.4.2  nathanw  *
     35  1.12.4.2  nathanw  */
     36  1.12.4.2  nathanw 
     37  1.12.4.2  nathanw #include <sys/param.h>
     38  1.12.4.2  nathanw #include <sys/systm.h>
     39  1.12.4.2  nathanw #include <sys/device.h>
     40  1.12.4.2  nathanw #include <sys/reboot.h>
     41  1.12.4.2  nathanw 
     42  1.12.4.2  nathanw #include <machine/bus.h>
     43  1.12.4.2  nathanw #include <machine/debug.h>
     44  1.12.4.2  nathanw #include <machine/platid.h>
     45  1.12.4.2  nathanw #include <machine/platid_mask.h>
     46  1.12.4.2  nathanw 
     47  1.12.4.2  nathanw #include <mips/cpuregs.h>
     48  1.12.4.2  nathanw 
     49  1.12.4.2  nathanw #include "opt_vr41xx.h"
     50  1.12.4.2  nathanw #include <hpcmips/vr/vr.h>
     51  1.12.4.2  nathanw #include <hpcmips/vr/vrcpudef.h>
     52  1.12.4.2  nathanw #include <hpcmips/vr/vripif.h>
     53  1.12.4.2  nathanw #include <hpcmips/vr/vripvar.h>
     54  1.12.4.2  nathanw #include <hpcmips/vr/vripreg.h>
     55  1.12.4.2  nathanw #include <hpcmips/vr/bcureg.h>
     56  1.12.4.2  nathanw #include <hpcmips/vr/bcuvar.h>
     57  1.12.4.2  nathanw 
     58  1.12.4.2  nathanw static int vrbcu_match(struct device *, struct cfdata *, void *);
     59  1.12.4.2  nathanw static void vrbcu_attach(struct device *, struct device *, void *);
     60  1.12.4.2  nathanw 
     61  1.12.4.2  nathanw static void vrbcu_write(struct vrbcu_softc *, int, unsigned short);
     62  1.12.4.2  nathanw static unsigned short vrbcu_read(struct vrbcu_softc *, int);
     63  1.12.4.2  nathanw 
     64  1.12.4.2  nathanw static void vrbcu_dump_regs(void);
     65  1.12.4.2  nathanw 
     66  1.12.4.2  nathanw char	*vr_cpuname=NULL;
     67  1.12.4.2  nathanw int	vr_major=-1;
     68  1.12.4.2  nathanw int	vr_minor=-1;
     69  1.12.4.2  nathanw int	vr_cpuid=-1;
     70  1.12.4.2  nathanw 
     71  1.12.4.2  nathanw struct cfattach vrbcu_ca = {
     72  1.12.4.2  nathanw 	sizeof(struct vrbcu_softc), vrbcu_match, vrbcu_attach
     73  1.12.4.2  nathanw };
     74  1.12.4.2  nathanw 
     75  1.12.4.2  nathanw struct vrbcu_softc *the_bcu_sc = NULL;
     76  1.12.4.2  nathanw 
     77  1.12.4.2  nathanw #ifdef SINGLE_VRIP_BASE
     78  1.12.4.2  nathanw #define vrbcu_addr()	VRIP_BCU_ADDR
     79  1.12.4.2  nathanw #else
     80  1.12.4.2  nathanw static bus_addr_t vrbcu_addr(void);
     81  1.12.4.2  nathanw static bus_addr_t
     82  1.12.4.2  nathanw vrbcu_addr()
     83  1.12.4.2  nathanw {
     84  1.12.4.2  nathanw 	static bus_addr_t addr = NULL;
     85  1.12.4.2  nathanw 	static struct platid_data addrs[] = {
     86  1.12.4.2  nathanw 		{ &platid_mask_CPU_MIPS_VR_4102, (void *)VR4102_BCU_ADDR },
     87  1.12.4.2  nathanw 		{ &platid_mask_CPU_MIPS_VR_4111, (void *)VR4102_BCU_ADDR },
     88  1.12.4.2  nathanw 		{ &platid_mask_CPU_MIPS_VR_4121, (void *)VR4102_BCU_ADDR },
     89  1.12.4.2  nathanw 		{ &platid_mask_CPU_MIPS_VR_4122, (void *)VR4122_BCU_ADDR },
     90  1.12.4.2  nathanw 		{ &platid_mask_CPU_MIPS_VR_4131, (void *)VR4122_BCU_ADDR },
     91  1.12.4.2  nathanw 		{ &platid_mask_CPU_MIPS_VR_4181, (void *)VR4181_BCU_ADDR },
     92  1.12.4.2  nathanw 		{ NULL, NULL }	/* terminator, don't delete */
     93  1.12.4.2  nathanw 	};
     94  1.12.4.2  nathanw 	struct platid_data *p;
     95  1.12.4.2  nathanw 
     96  1.12.4.2  nathanw 	if (addr == NULL) {
     97  1.12.4.2  nathanw 		if ((p = platid_search_data(&platid, addrs)) == NULL)
     98  1.12.4.2  nathanw 			panic("%s: can't find VR BCU address\n", __FUNCTION__);
     99  1.12.4.2  nathanw 		addr = (bus_addr_t)p->data;
    100  1.12.4.2  nathanw 	}
    101  1.12.4.2  nathanw 
    102  1.12.4.2  nathanw 	return (addr);
    103  1.12.4.2  nathanw }
    104  1.12.4.2  nathanw #endif /* SINGLE_VRIP_BASE */
    105  1.12.4.2  nathanw 
    106  1.12.4.2  nathanw static inline void
    107  1.12.4.2  nathanw vrbcu_write(struct vrbcu_softc *sc, int port, unsigned short val)
    108  1.12.4.2  nathanw {
    109  1.12.4.2  nathanw 
    110  1.12.4.2  nathanw 	bus_space_write_2(sc->sc_iot, sc->sc_ioh, port, val);
    111  1.12.4.2  nathanw }
    112  1.12.4.2  nathanw 
    113  1.12.4.2  nathanw static inline unsigned short
    114  1.12.4.2  nathanw vrbcu_read(struct vrbcu_softc *sc, int port)
    115  1.12.4.2  nathanw {
    116  1.12.4.2  nathanw 
    117  1.12.4.2  nathanw 	return (bus_space_read_2(sc->sc_iot, sc->sc_ioh, port));
    118  1.12.4.2  nathanw }
    119  1.12.4.2  nathanw 
    120  1.12.4.2  nathanw static int
    121  1.12.4.2  nathanw vrbcu_match(struct device *parent, struct cfdata *cf, void *aux)
    122  1.12.4.2  nathanw {
    123  1.12.4.2  nathanw 
    124  1.12.4.2  nathanw 	return (2);
    125  1.12.4.2  nathanw }
    126  1.12.4.2  nathanw 
    127  1.12.4.2  nathanw static void
    128  1.12.4.2  nathanw vrbcu_attach(struct device *parent, struct device *self, void *aux)
    129  1.12.4.2  nathanw {
    130  1.12.4.2  nathanw 	struct vrip_attach_args *va = aux;
    131  1.12.4.2  nathanw 	struct vrbcu_softc *sc = (struct vrbcu_softc *)self;
    132  1.12.4.2  nathanw 
    133  1.12.4.2  nathanw 	sc->sc_iot = va->va_iot;
    134  1.12.4.2  nathanw 	bus_space_map(sc->sc_iot, va->va_addr, va->va_size,
    135  1.12.4.2  nathanw 	    0, /* no flags */
    136  1.12.4.2  nathanw 	    &sc->sc_ioh);
    137  1.12.4.2  nathanw 
    138  1.12.4.2  nathanw 	printf("\n");
    139  1.12.4.2  nathanw 	the_bcu_sc = sc;
    140  1.12.4.2  nathanw 	vrbcu_dump_regs();
    141  1.12.4.2  nathanw }
    142  1.12.4.2  nathanw 
    143  1.12.4.2  nathanw static void
    144  1.12.4.2  nathanw vrbcu_dump_regs()
    145  1.12.4.2  nathanw {
    146  1.12.4.2  nathanw 	struct vrbcu_softc *sc = the_bcu_sc;
    147  1.12.4.2  nathanw 	int cpuclock = 0, tclock = 0, vtclock = 0, cpuid;
    148  1.12.4.2  nathanw #if !defined(ONLY_VR4102)
    149  1.12.4.2  nathanw 	int spdreg;
    150  1.12.4.2  nathanw #endif
    151  1.12.4.2  nathanw #ifdef VRBCUDEBUG
    152  1.12.4.2  nathanw 	int reg;
    153  1.12.4.2  nathanw #endif /* VRBCUDEBUG */
    154  1.12.4.2  nathanw 
    155  1.12.4.2  nathanw 	cpuid = vrbcu_vrip_getcpuid();
    156  1.12.4.2  nathanw #if !defined(ONLY_VR4181) && !defined(ONLY_VR4102)
    157  1.12.4.2  nathanw 	if (cpuid != BCUREVID_FIXRID_4181
    158  1.12.4.2  nathanw 	    && cpuid <= BCUREVID_RID_4131
    159  1.12.4.2  nathanw 	    && cpuid >= BCUREVID_RID_4111) {
    160  1.12.4.2  nathanw 		spdreg = vrbcu_read(sc, BCUCLKSPEED_REG_W);
    161  1.12.4.2  nathanw #ifdef VRBCUDEBUG
    162  1.12.4.2  nathanw 		printf("vrbcu: CLKSPEED %x: \n",  spdreg);
    163  1.12.4.2  nathanw #endif /* VRBCUDEBUG */
    164  1.12.4.2  nathanw 	}
    165  1.12.4.2  nathanw #endif
    166  1.12.4.2  nathanw #if defined VR4181
    167  1.12.4.2  nathanw 	if (cpuid == BCUREVID_FIXRID_4181){
    168  1.12.4.2  nathanw 		spdreg = vrbcu_read(sc, BCU81CLKSPEED_REG_W);
    169  1.12.4.2  nathanw #ifdef VRBCUDEBUG
    170  1.12.4.2  nathanw 		printf("vrbcu: CLKSPEED %x: \n",  spdreg);
    171  1.12.4.2  nathanw #endif /* VRBCUDEBUG */
    172  1.12.4.2  nathanw 	}
    173  1.12.4.2  nathanw #endif
    174  1.12.4.2  nathanw 
    175  1.12.4.2  nathanw 	cpuclock = vrbcu_vrip_getcpuclock();
    176  1.12.4.2  nathanw 
    177  1.12.4.2  nathanw 	switch (cpuid) {
    178  1.12.4.2  nathanw #if defined VR4181
    179  1.12.4.2  nathanw 	case BCUREVID_FIXRID_4181:
    180  1.12.4.2  nathanw 		switch ((spdreg & BCU81CLKSPEED_DIVTMASK) >>
    181  1.12.4.2  nathanw 		    BCU81CLKSPEED_DIVTSHFT){
    182  1.12.4.2  nathanw 		case BCU81CLKSPEED_DIVT1:
    183  1.12.4.2  nathanw 			vtclock = tclock = cpuclock;
    184  1.12.4.2  nathanw 			break;
    185  1.12.4.2  nathanw 		case BCU81CLKSPEED_DIVT2:
    186  1.12.4.2  nathanw 			vtclock = tclock = cpuclock/2;
    187  1.12.4.2  nathanw 			break;
    188  1.12.4.2  nathanw 		case BCU81CLKSPEED_DIVT3:
    189  1.12.4.2  nathanw 			vtclock = tclock = cpuclock/3;
    190  1.12.4.2  nathanw 			break;
    191  1.12.4.2  nathanw 		case BCU81CLKSPEED_DIVT4:
    192  1.12.4.2  nathanw 			vtclock = tclock = cpuclock/4;
    193  1.12.4.2  nathanw 			break;
    194  1.12.4.2  nathanw 		default:
    195  1.12.4.2  nathanw 			vtclock = tclock = 0;
    196  1.12.4.2  nathanw 		}
    197  1.12.4.2  nathanw 		break;
    198  1.12.4.2  nathanw #endif /* VR4181 */
    199  1.12.4.2  nathanw 	case BCUREVID_RID_4101:
    200  1.12.4.2  nathanw 	case BCUREVID_RID_4102:
    201  1.12.4.2  nathanw 		vtclock = tclock = cpuclock/2;
    202  1.12.4.2  nathanw 		break;
    203  1.12.4.2  nathanw #if defined VR4111
    204  1.12.4.2  nathanw 	case BCUREVID_RID_4111:
    205  1.12.4.2  nathanw 		if ((spdreg&BCUCLKSPEED_DIVT2B) == 0)
    206  1.12.4.2  nathanw 			vtclock = tclock = cpuclock/2;
    207  1.12.4.2  nathanw 		else if ((spdreg&BCUCLKSPEED_DIVT3B) == 0)
    208  1.12.4.2  nathanw 			vtclock = tclock = cpuclock/3;
    209  1.12.4.2  nathanw 		else if ((spdreg&BCUCLKSPEED_DIVT4B) == 0)
    210  1.12.4.2  nathanw 			vtclock = tclock = cpuclock/4;
    211  1.12.4.2  nathanw 		else
    212  1.12.4.2  nathanw 			vtclock = tclock = 0; /* XXX */
    213  1.12.4.2  nathanw 		break;
    214  1.12.4.2  nathanw #endif /* VR4111 */
    215  1.12.4.2  nathanw #if defined VR4121
    216  1.12.4.2  nathanw 	case BCUREVID_RID_4121:
    217  1.12.4.2  nathanw 	{
    218  1.12.4.2  nathanw 		int vt;
    219  1.12.4.2  nathanw 		tclock = cpuclock / ((spdreg & BCUCLKSPEED_DIVTMASK) >>
    220  1.12.4.2  nathanw 		    BCUCLKSPEED_DIVTSHFT);
    221  1.12.4.2  nathanw 		vt = ((spdreg & BCUCLKSPEED_DIVVTMASK) >>
    222  1.12.4.2  nathanw 		    BCUCLKSPEED_DIVVTSHFT);
    223  1.12.4.2  nathanw 		if (vt == 0)
    224  1.12.4.2  nathanw 			vtclock = 0; /* XXX */
    225  1.12.4.2  nathanw 		else if (vt < 0x9)
    226  1.12.4.2  nathanw 			vtclock = cpuclock / vt;
    227  1.12.4.2  nathanw 		else
    228  1.12.4.2  nathanw 			vtclock = cpuclock / ((vt - 8)*2+1) * 2;
    229  1.12.4.2  nathanw 	}
    230  1.12.4.2  nathanw 	break;
    231  1.12.4.2  nathanw #endif /* VR4121 */
    232  1.12.4.2  nathanw #if defined VR4122 || defined VR4131
    233  1.12.4.2  nathanw 	case BCUREVID_RID_4122:
    234  1.12.4.2  nathanw 	case BCUREVID_RID_4131:
    235  1.12.4.2  nathanw 	{
    236  1.12.4.2  nathanw 		int vtdiv;
    237  1.12.4.2  nathanw 
    238  1.12.4.2  nathanw 		vtdiv = ((spdreg & BCUCLKSPEED_VTDIVMODE) >>
    239  1.12.4.2  nathanw 		    BCUCLKSPEED_VTDIVSHFT);
    240  1.12.4.2  nathanw 		if (vtdiv == 0 || vtdiv > BCUCLKSPEED_VTDIV6)
    241  1.12.4.2  nathanw 			vtclock = 0; /* XXX */
    242  1.12.4.2  nathanw 		else
    243  1.12.4.2  nathanw 			vtclock = cpuclock / vtdiv;
    244  1.12.4.2  nathanw 		tclock = vtclock /
    245  1.12.4.2  nathanw 		    (((spdreg & BCUCLKSPEED_TDIVMODE) >>
    246  1.12.4.2  nathanw 			BCUCLKSPEED_TDIVSHFT) ? 4 : 2);
    247  1.12.4.2  nathanw 	}
    248  1.12.4.2  nathanw 	break;
    249  1.12.4.2  nathanw #endif /* VR4122 || VR4131 */
    250  1.12.4.2  nathanw 	default:
    251  1.12.4.2  nathanw 		break;
    252  1.12.4.2  nathanw 	}
    253  1.12.4.2  nathanw 	if (tclock)
    254  1.12.4.2  nathanw 		printf("%s: cpu %d.%03dMHz, bus %d.%03dMHz, ram %d.%03dMHz\n",
    255  1.12.4.2  nathanw 		    sc->sc_dev.dv_xname,
    256  1.12.4.2  nathanw 		    cpuclock/1000000, (cpuclock%1000000)/1000,
    257  1.12.4.2  nathanw 		    tclock/1000000, (tclock%1000000)/1000,
    258  1.12.4.2  nathanw 		    vtclock/1000000, (vtclock%1000000)/1000);
    259  1.12.4.2  nathanw 	else {
    260  1.12.4.2  nathanw 		printf("%s: cpu %d.%03dMHz\n",
    261  1.12.4.2  nathanw 		    sc->sc_dev.dv_xname,
    262  1.12.4.2  nathanw 		    cpuclock/1000000, (cpuclock%1000000)/1000);
    263  1.12.4.2  nathanw 		printf("%s: UNKNOWN BUS CLOCK SPEED:"
    264  1.12.4.2  nathanw 		    " CPU is UNKNOWN or NOT CONFIGURED\n",
    265  1.12.4.2  nathanw 		    sc->sc_dev.dv_xname);
    266  1.12.4.2  nathanw 	}
    267  1.12.4.2  nathanw #ifdef VRBCUDEBUG
    268  1.12.4.2  nathanw 	reg = vrbcu_read(sc, BCUCNT1_REG_W);
    269  1.12.4.2  nathanw 	printf("vrbcu: CNT1 %x: ",  reg);
    270  1.12.4.2  nathanw 	dbg_bit_print(reg);
    271  1.12.4.2  nathanw #if !defined(ONLY_VR4181)
    272  1.12.4.2  nathanw 	if (cpuid != BCUREVID_FIXRID_4181
    273  1.12.4.2  nathanw 	    && cpuid <= BCUREVID_RID_4121
    274  1.12.4.2  nathanw 	    && cpuid >= BCUREVID_RID_4102) {
    275  1.12.4.2  nathanw 		reg = vrbcu_read(sc, BCUCNT2_REG_W);
    276  1.12.4.2  nathanw 		printf("vrbcu: CNT2 %x: ",  reg);
    277  1.12.4.2  nathanw 		dbg_bit_print(reg);
    278  1.12.4.2  nathanw 	}
    279  1.12.4.2  nathanw #endif /* !defined ONLY_VR4181 */
    280  1.12.4.2  nathanw #if !defined(ONLY_VR4181) || !defined(ONLY_VR4122_4131)
    281  1.12.4.2  nathanw 	if (cpuid != BCUREVID_FIXRID_4181
    282  1.12.4.2  nathanw 	    && cpuid <= BCUREVID_RID_4121
    283  1.12.4.2  nathanw 	    && cpuid >= BCUREVID_RID_4102) {
    284  1.12.4.2  nathanw 		reg = vrbcu_read(sc, BCUSPEED_REG_W);
    285  1.12.4.2  nathanw 		printf("vrbcu: SPEED %x: ",  reg);
    286  1.12.4.2  nathanw 		dbg_bit_print(reg);
    287  1.12.4.2  nathanw 		reg = vrbcu_read(sc, BCUERRST_REG_W);
    288  1.12.4.2  nathanw 		printf("vrbcu: ERRST %x: ",  reg);
    289  1.12.4.2  nathanw 		dbg_bit_print(reg);
    290  1.12.4.2  nathanw 		reg = vrbcu_read(sc, BCURFCNT_REG_W);
    291  1.12.4.2  nathanw 		printf("vrbcu: RFCNT %x\n",  reg);
    292  1.12.4.2  nathanw 		reg = vrbcu_read(sc, BCUREFCOUNT_REG_W);
    293  1.12.4.2  nathanw 		printf("vrbcu: RFCOUNT %x\n",  reg);
    294  1.12.4.2  nathanw 	}
    295  1.12.4.2  nathanw #endif /* !defined(ONLY_VR4181) || !defined(ONLY_VR4122_4131) */
    296  1.12.4.2  nathanw #if !defined(ONLY_VR4181)
    297  1.12.4.2  nathanw 	if (cpuid != BCUREVID_FIXRID_4181
    298  1.12.4.2  nathanw 	    && cpuid <= BCUREVID_RID_4131
    299  1.12.4.2  nathanw 	    && cpuid >= BCUREVID_RID_4111)
    300  1.12.4.2  nathanw 	{
    301  1.12.4.2  nathanw 		reg = vrbcu_read(sc, BCUCNT3_REG_W);
    302  1.12.4.2  nathanw 		printf("vrbcu: CNT3 %x: ",  reg);
    303  1.12.4.2  nathanw 		dbg_bit_print(reg);
    304  1.12.4.2  nathanw 	}
    305  1.12.4.2  nathanw #endif /* !defined ONLY_VR4181 */
    306  1.12.4.2  nathanw #endif /* VRBCUDEBUG */
    307  1.12.4.2  nathanw 
    308  1.12.4.2  nathanw }
    309  1.12.4.2  nathanw 
    310  1.12.4.2  nathanw static char *cpuname[] = {
    311  1.12.4.2  nathanw 	"VR4101",	/* 0 */
    312  1.12.4.2  nathanw 	"VR4102",	/* 1 */
    313  1.12.4.2  nathanw 	"VR4111",	/* 2 */
    314  1.12.4.2  nathanw 	"VR4121",	/* 3 */
    315  1.12.4.2  nathanw 	"VR4122",	/* 4 */
    316  1.12.4.2  nathanw 	"VR4131",	/* 5 */
    317  1.12.4.2  nathanw 	"UNKNOWN",
    318  1.12.4.2  nathanw 	"UNKNOWN",
    319  1.12.4.2  nathanw 	"UNKNOWN",
    320  1.12.4.2  nathanw 	"UNKNOWN",
    321  1.12.4.2  nathanw 	"UNKNOWN",
    322  1.12.4.2  nathanw 	"UNKNOWN",
    323  1.12.4.2  nathanw 	"UNKNOWN",
    324  1.12.4.2  nathanw 	"UNKNOWN",
    325  1.12.4.2  nathanw 	"UNKNOWN",
    326  1.12.4.2  nathanw 	"UNKNOWN",
    327  1.12.4.2  nathanw 	"VR4181",	/* 0x10 + 0 */
    328  1.12.4.2  nathanw };
    329  1.12.4.2  nathanw 
    330  1.12.4.2  nathanw int
    331  1.12.4.2  nathanw vrbcu_vrip_getcpuid(void)
    332  1.12.4.2  nathanw {
    333  1.12.4.2  nathanw 	volatile u_int16_t *revreg;
    334  1.12.4.2  nathanw 
    335  1.12.4.2  nathanw 	if (vr_cpuid != -1)
    336  1.12.4.2  nathanw 		return (vr_cpuid);
    337  1.12.4.2  nathanw 
    338  1.12.4.2  nathanw 	if (vr_cpuid == -1) {
    339  1.12.4.2  nathanw 		if (vrbcu_addr() == VR4181_BCU_ADDR)
    340  1.12.4.2  nathanw 			revreg = (u_int16_t *)MIPS_PHYS_TO_KSEG1
    341  1.12.4.2  nathanw 			    ((vrbcu_addr() + BCU81REVID_REG_W));
    342  1.12.4.2  nathanw 		else
    343  1.12.4.2  nathanw 			revreg = (u_int16_t *)MIPS_PHYS_TO_KSEG1
    344  1.12.4.2  nathanw 			    ((vrbcu_addr() + BCUREVID_REG_W));
    345  1.12.4.2  nathanw 
    346  1.12.4.2  nathanw 		vr_cpuid = *revreg;
    347  1.12.4.2  nathanw 		vr_cpuid = (vr_cpuid&BCUREVID_RIDMASK)>>BCUREVID_RIDSHFT;
    348  1.12.4.2  nathanw 		if (vrbcu_addr() == VR4181_BCU_ADDR
    349  1.12.4.2  nathanw 		    && vr_cpuid == BCUREVID_RID_4181) /* conflict vr4101 */
    350  1.12.4.2  nathanw 			vr_cpuid = BCUREVID_FIXRID_4181;
    351  1.12.4.2  nathanw 	}
    352  1.12.4.2  nathanw 	return (vr_cpuid);
    353  1.12.4.2  nathanw }
    354  1.12.4.2  nathanw 
    355  1.12.4.2  nathanw char *
    356  1.12.4.2  nathanw vrbcu_vrip_getcpuname(void)
    357  1.12.4.2  nathanw {
    358  1.12.4.2  nathanw 	int cpuid;
    359  1.12.4.2  nathanw 
    360  1.12.4.2  nathanw 	if (vr_cpuname != NULL)
    361  1.12.4.2  nathanw 		return (vr_cpuname);
    362  1.12.4.2  nathanw 
    363  1.12.4.2  nathanw 	cpuid = vrbcu_vrip_getcpuid();
    364  1.12.4.2  nathanw 	vr_cpuname = cpuname[cpuid];
    365  1.12.4.2  nathanw 
    366  1.12.4.2  nathanw 	return (vr_cpuname);
    367  1.12.4.2  nathanw }
    368  1.12.4.2  nathanw 
    369  1.12.4.2  nathanw 
    370  1.12.4.2  nathanw int
    371  1.12.4.2  nathanw vrbcu_vrip_getcpumajor(void)
    372  1.12.4.2  nathanw {
    373  1.12.4.2  nathanw 	volatile u_int16_t *revreg;
    374  1.12.4.2  nathanw 
    375  1.12.4.2  nathanw 	if (vr_major != -1)
    376  1.12.4.2  nathanw 		return (vr_major);
    377  1.12.4.2  nathanw 
    378  1.12.4.2  nathanw 	revreg = (u_int16_t *)MIPS_PHYS_TO_KSEG1
    379  1.12.4.2  nathanw 	    ((vrbcu_addr() + BCUREVID_REG_W));
    380  1.12.4.2  nathanw 
    381  1.12.4.2  nathanw 	vr_major = *revreg;
    382  1.12.4.2  nathanw 	vr_major = (vr_major&BCUREVID_MJREVMASK)>>BCUREVID_MJREVSHFT;
    383  1.12.4.2  nathanw 
    384  1.12.4.2  nathanw 	return (vr_major);
    385  1.12.4.2  nathanw }
    386  1.12.4.2  nathanw 
    387  1.12.4.2  nathanw int
    388  1.12.4.2  nathanw vrbcu_vrip_getcpuminor(void)
    389  1.12.4.2  nathanw {
    390  1.12.4.2  nathanw 	volatile u_int16_t *revreg;
    391  1.12.4.2  nathanw 
    392  1.12.4.2  nathanw 	if (vr_minor != -1)
    393  1.12.4.2  nathanw 		return (vr_minor);
    394  1.12.4.2  nathanw 
    395  1.12.4.2  nathanw 	revreg = (u_int16_t *)MIPS_PHYS_TO_KSEG1
    396  1.12.4.2  nathanw 	    ((vrbcu_addr() + BCUREVID_REG_W));
    397  1.12.4.2  nathanw 
    398  1.12.4.2  nathanw 	vr_minor = *revreg;
    399  1.12.4.2  nathanw 	vr_minor = (vr_minor&BCUREVID_MNREVMASK)>>BCUREVID_MNREVSHFT;
    400  1.12.4.2  nathanw 
    401  1.12.4.2  nathanw 	return (vr_minor);
    402  1.12.4.2  nathanw }
    403  1.12.4.2  nathanw 
    404  1.12.4.2  nathanw #define CLKX	18432000	/* CLKX1,CLKX2: 18.432MHz */
    405  1.12.4.2  nathanw #define MHZ	1000000
    406  1.12.4.2  nathanw 
    407  1.12.4.2  nathanw int
    408  1.12.4.2  nathanw vrbcu_vrip_getcpuclock(void)
    409  1.12.4.2  nathanw {
    410  1.12.4.2  nathanw 	u_int16_t clksp;
    411  1.12.4.2  nathanw 	int cpuid, cpuclock;
    412  1.12.4.2  nathanw 
    413  1.12.4.2  nathanw 	cpuid = vrbcu_vrip_getcpuid();
    414  1.12.4.2  nathanw 	if (cpuid != BCUREVID_FIXRID_4181 && cpuid >= BCUREVID_RID_4111) {
    415  1.12.4.2  nathanw 		clksp = *(u_int16_t *)MIPS_PHYS_TO_KSEG1
    416  1.12.4.2  nathanw 		    ((vrbcu_addr() + BCUCLKSPEED_REG_W)) &
    417  1.12.4.2  nathanw 		    BCUCLKSPEED_CLKSPMASK;
    418  1.12.4.2  nathanw 	} else if (cpuid == BCUREVID_FIXRID_4181) {
    419  1.12.4.2  nathanw 		clksp = *(u_int16_t *)MIPS_PHYS_TO_KSEG1
    420  1.12.4.2  nathanw 		    ((vrbcu_addr() + BCU81CLKSPEED_REG_W)) &
    421  1.12.4.2  nathanw 		    BCUCLKSPEED_CLKSPMASK;
    422  1.12.4.2  nathanw 	}
    423  1.12.4.2  nathanw 
    424  1.12.4.2  nathanw 	switch (cpuid) {
    425  1.12.4.2  nathanw 	case BCUREVID_FIXRID_4181:
    426  1.12.4.2  nathanw 		cpuclock = CLKX / clksp * 64;
    427  1.12.4.2  nathanw 		/* branch delay is 1 clock; 2 clock/loop */
    428  1.12.4.2  nathanw 		cpuspeed = (cpuclock / 2 + MHZ / 2) / MHZ;
    429  1.12.4.2  nathanw 		break;
    430  1.12.4.2  nathanw 	case BCUREVID_RID_4101:
    431  1.12.4.2  nathanw 		/* assume 33MHz */
    432  1.12.4.2  nathanw 		cpuclock = 33000000;
    433  1.12.4.2  nathanw 		/* branch delay is 1 clock; 2 clock/loop */
    434  1.12.4.2  nathanw 		cpuspeed = (cpuclock / 2 + MHZ / 2) / MHZ;
    435  1.12.4.2  nathanw 		break;
    436  1.12.4.2  nathanw 	case BCUREVID_RID_4102:
    437  1.12.4.2  nathanw 		cpuclock = CLKX / clksp * 32;
    438  1.12.4.2  nathanw 		/* branch delay is 1 clock; 2 clock/loop */
    439  1.12.4.2  nathanw 		cpuspeed = (cpuclock / 2 + MHZ / 2) / MHZ;
    440  1.12.4.2  nathanw 		break;
    441  1.12.4.2  nathanw 	case BCUREVID_RID_4111:
    442  1.12.4.2  nathanw 		cpuclock = CLKX / clksp * 64;
    443  1.12.4.2  nathanw 		/* branch delay is 1 clock; 2 clock/loop */
    444  1.12.4.2  nathanw 		cpuspeed = (cpuclock / 2 + MHZ / 2) / MHZ;
    445  1.12.4.2  nathanw 		break;
    446  1.12.4.2  nathanw 	case BCUREVID_RID_4121:
    447  1.12.4.2  nathanw 		cpuclock = CLKX / clksp * 64;
    448  1.12.4.2  nathanw 		/* branch delay is 2 clock; 3 clock/loop */
    449  1.12.4.2  nathanw 		cpuspeed = (cpuclock / 3 + MHZ / 2) / MHZ;
    450  1.12.4.2  nathanw 		break;
    451  1.12.4.2  nathanw 	case BCUREVID_RID_4122:
    452  1.12.4.2  nathanw 		cpuclock = CLKX / clksp * 98;
    453  1.12.4.2  nathanw 		/* branch delay is 2 clock; 3 clock/loop */
    454  1.12.4.2  nathanw 		cpuspeed = (cpuclock / 3 + MHZ / 2) / MHZ;
    455  1.12.4.2  nathanw 		break;
    456  1.12.4.2  nathanw 	case BCUREVID_RID_4131:
    457  1.12.4.2  nathanw 		cpuclock = CLKX / clksp * 98;
    458  1.12.4.2  nathanw 		/* branch delay is 2 clock; 3 clock/loop */
    459  1.12.4.2  nathanw 		cpuspeed = (cpuclock / 3 + MHZ / 2) / MHZ;
    460  1.12.4.2  nathanw 		break;
    461  1.12.4.2  nathanw 	default:
    462  1.12.4.2  nathanw 		panic("unknown CPU type %d\n", cpuid);
    463  1.12.4.2  nathanw 		break;
    464  1.12.4.2  nathanw 	}
    465  1.12.4.2  nathanw 
    466  1.12.4.2  nathanw 	return (cpuclock);
    467  1.12.4.2  nathanw }
    468