Home | History | Annotate | Line # | Download | only in vr
bcu_vrip.c revision 1.12.4.3
      1  1.12.4.3  nathanw /*	$NetBSD: bcu_vrip.c,v 1.12.4.3 2002/10/18 02:37:15 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.3  nathanw CFATTACH_DECL(vrbcu, sizeof(struct vrbcu_softc),
     72  1.12.4.3  nathanw     vrbcu_match, vrbcu_attach, NULL, NULL);
     73  1.12.4.2  nathanw 
     74  1.12.4.2  nathanw struct vrbcu_softc *the_bcu_sc = NULL;
     75  1.12.4.2  nathanw 
     76  1.12.4.2  nathanw #ifdef SINGLE_VRIP_BASE
     77  1.12.4.2  nathanw #define vrbcu_addr()	VRIP_BCU_ADDR
     78  1.12.4.2  nathanw #else
     79  1.12.4.2  nathanw static bus_addr_t vrbcu_addr(void);
     80  1.12.4.2  nathanw static bus_addr_t
     81  1.12.4.2  nathanw vrbcu_addr()
     82  1.12.4.2  nathanw {
     83  1.12.4.2  nathanw 	static bus_addr_t addr = NULL;
     84  1.12.4.2  nathanw 	static struct platid_data addrs[] = {
     85  1.12.4.2  nathanw 		{ &platid_mask_CPU_MIPS_VR_4102, (void *)VR4102_BCU_ADDR },
     86  1.12.4.2  nathanw 		{ &platid_mask_CPU_MIPS_VR_4111, (void *)VR4102_BCU_ADDR },
     87  1.12.4.2  nathanw 		{ &platid_mask_CPU_MIPS_VR_4121, (void *)VR4102_BCU_ADDR },
     88  1.12.4.2  nathanw 		{ &platid_mask_CPU_MIPS_VR_4122, (void *)VR4122_BCU_ADDR },
     89  1.12.4.2  nathanw 		{ &platid_mask_CPU_MIPS_VR_4131, (void *)VR4122_BCU_ADDR },
     90  1.12.4.2  nathanw 		{ &platid_mask_CPU_MIPS_VR_4181, (void *)VR4181_BCU_ADDR },
     91  1.12.4.2  nathanw 		{ NULL, NULL }	/* terminator, don't delete */
     92  1.12.4.2  nathanw 	};
     93  1.12.4.2  nathanw 	struct platid_data *p;
     94  1.12.4.2  nathanw 
     95  1.12.4.2  nathanw 	if (addr == NULL) {
     96  1.12.4.2  nathanw 		if ((p = platid_search_data(&platid, addrs)) == NULL)
     97  1.12.4.3  nathanw 			panic("%s: can't find VR BCU address", __FUNCTION__);
     98  1.12.4.2  nathanw 		addr = (bus_addr_t)p->data;
     99  1.12.4.2  nathanw 	}
    100  1.12.4.2  nathanw 
    101  1.12.4.2  nathanw 	return (addr);
    102  1.12.4.2  nathanw }
    103  1.12.4.2  nathanw #endif /* SINGLE_VRIP_BASE */
    104  1.12.4.2  nathanw 
    105  1.12.4.2  nathanw static inline void
    106  1.12.4.2  nathanw vrbcu_write(struct vrbcu_softc *sc, int port, unsigned short val)
    107  1.12.4.2  nathanw {
    108  1.12.4.2  nathanw 
    109  1.12.4.2  nathanw 	bus_space_write_2(sc->sc_iot, sc->sc_ioh, port, val);
    110  1.12.4.2  nathanw }
    111  1.12.4.2  nathanw 
    112  1.12.4.2  nathanw static inline unsigned short
    113  1.12.4.2  nathanw vrbcu_read(struct vrbcu_softc *sc, int port)
    114  1.12.4.2  nathanw {
    115  1.12.4.2  nathanw 
    116  1.12.4.2  nathanw 	return (bus_space_read_2(sc->sc_iot, sc->sc_ioh, port));
    117  1.12.4.2  nathanw }
    118  1.12.4.2  nathanw 
    119  1.12.4.2  nathanw static int
    120  1.12.4.2  nathanw vrbcu_match(struct device *parent, struct cfdata *cf, void *aux)
    121  1.12.4.2  nathanw {
    122  1.12.4.2  nathanw 
    123  1.12.4.2  nathanw 	return (2);
    124  1.12.4.2  nathanw }
    125  1.12.4.2  nathanw 
    126  1.12.4.2  nathanw static void
    127  1.12.4.2  nathanw vrbcu_attach(struct device *parent, struct device *self, void *aux)
    128  1.12.4.2  nathanw {
    129  1.12.4.2  nathanw 	struct vrip_attach_args *va = aux;
    130  1.12.4.2  nathanw 	struct vrbcu_softc *sc = (struct vrbcu_softc *)self;
    131  1.12.4.2  nathanw 
    132  1.12.4.2  nathanw 	sc->sc_iot = va->va_iot;
    133  1.12.4.2  nathanw 	bus_space_map(sc->sc_iot, va->va_addr, va->va_size,
    134  1.12.4.2  nathanw 	    0, /* no flags */
    135  1.12.4.2  nathanw 	    &sc->sc_ioh);
    136  1.12.4.2  nathanw 
    137  1.12.4.2  nathanw 	printf("\n");
    138  1.12.4.2  nathanw 	the_bcu_sc = sc;
    139  1.12.4.2  nathanw 	vrbcu_dump_regs();
    140  1.12.4.2  nathanw }
    141  1.12.4.2  nathanw 
    142  1.12.4.2  nathanw static void
    143  1.12.4.2  nathanw vrbcu_dump_regs()
    144  1.12.4.2  nathanw {
    145  1.12.4.2  nathanw 	struct vrbcu_softc *sc = the_bcu_sc;
    146  1.12.4.2  nathanw 	int cpuclock = 0, tclock = 0, vtclock = 0, cpuid;
    147  1.12.4.2  nathanw #if !defined(ONLY_VR4102)
    148  1.12.4.2  nathanw 	int spdreg;
    149  1.12.4.2  nathanw #endif
    150  1.12.4.2  nathanw #ifdef VRBCUDEBUG
    151  1.12.4.2  nathanw 	int reg;
    152  1.12.4.2  nathanw #endif /* VRBCUDEBUG */
    153  1.12.4.2  nathanw 
    154  1.12.4.2  nathanw 	cpuid = vrbcu_vrip_getcpuid();
    155  1.12.4.2  nathanw #if !defined(ONLY_VR4181) && !defined(ONLY_VR4102)
    156  1.12.4.2  nathanw 	if (cpuid != BCUREVID_FIXRID_4181
    157  1.12.4.2  nathanw 	    && cpuid <= BCUREVID_RID_4131
    158  1.12.4.2  nathanw 	    && cpuid >= BCUREVID_RID_4111) {
    159  1.12.4.2  nathanw 		spdreg = vrbcu_read(sc, BCUCLKSPEED_REG_W);
    160  1.12.4.2  nathanw #ifdef VRBCUDEBUG
    161  1.12.4.2  nathanw 		printf("vrbcu: CLKSPEED %x: \n",  spdreg);
    162  1.12.4.2  nathanw #endif /* VRBCUDEBUG */
    163  1.12.4.2  nathanw 	}
    164  1.12.4.2  nathanw #endif
    165  1.12.4.2  nathanw #if defined VR4181
    166  1.12.4.2  nathanw 	if (cpuid == BCUREVID_FIXRID_4181){
    167  1.12.4.2  nathanw 		spdreg = vrbcu_read(sc, BCU81CLKSPEED_REG_W);
    168  1.12.4.2  nathanw #ifdef VRBCUDEBUG
    169  1.12.4.2  nathanw 		printf("vrbcu: CLKSPEED %x: \n",  spdreg);
    170  1.12.4.2  nathanw #endif /* VRBCUDEBUG */
    171  1.12.4.2  nathanw 	}
    172  1.12.4.2  nathanw #endif
    173  1.12.4.2  nathanw 
    174  1.12.4.2  nathanw 	cpuclock = vrbcu_vrip_getcpuclock();
    175  1.12.4.2  nathanw 
    176  1.12.4.2  nathanw 	switch (cpuid) {
    177  1.12.4.2  nathanw #if defined VR4181
    178  1.12.4.2  nathanw 	case BCUREVID_FIXRID_4181:
    179  1.12.4.2  nathanw 		switch ((spdreg & BCU81CLKSPEED_DIVTMASK) >>
    180  1.12.4.2  nathanw 		    BCU81CLKSPEED_DIVTSHFT){
    181  1.12.4.2  nathanw 		case BCU81CLKSPEED_DIVT1:
    182  1.12.4.2  nathanw 			vtclock = tclock = cpuclock;
    183  1.12.4.2  nathanw 			break;
    184  1.12.4.2  nathanw 		case BCU81CLKSPEED_DIVT2:
    185  1.12.4.2  nathanw 			vtclock = tclock = cpuclock/2;
    186  1.12.4.2  nathanw 			break;
    187  1.12.4.2  nathanw 		case BCU81CLKSPEED_DIVT3:
    188  1.12.4.2  nathanw 			vtclock = tclock = cpuclock/3;
    189  1.12.4.2  nathanw 			break;
    190  1.12.4.2  nathanw 		case BCU81CLKSPEED_DIVT4:
    191  1.12.4.2  nathanw 			vtclock = tclock = cpuclock/4;
    192  1.12.4.2  nathanw 			break;
    193  1.12.4.2  nathanw 		default:
    194  1.12.4.2  nathanw 			vtclock = tclock = 0;
    195  1.12.4.2  nathanw 		}
    196  1.12.4.2  nathanw 		break;
    197  1.12.4.2  nathanw #endif /* VR4181 */
    198  1.12.4.2  nathanw 	case BCUREVID_RID_4101:
    199  1.12.4.2  nathanw 	case BCUREVID_RID_4102:
    200  1.12.4.2  nathanw 		vtclock = tclock = cpuclock/2;
    201  1.12.4.2  nathanw 		break;
    202  1.12.4.2  nathanw #if defined VR4111
    203  1.12.4.2  nathanw 	case BCUREVID_RID_4111:
    204  1.12.4.2  nathanw 		if ((spdreg&BCUCLKSPEED_DIVT2B) == 0)
    205  1.12.4.2  nathanw 			vtclock = tclock = cpuclock/2;
    206  1.12.4.2  nathanw 		else if ((spdreg&BCUCLKSPEED_DIVT3B) == 0)
    207  1.12.4.2  nathanw 			vtclock = tclock = cpuclock/3;
    208  1.12.4.2  nathanw 		else if ((spdreg&BCUCLKSPEED_DIVT4B) == 0)
    209  1.12.4.2  nathanw 			vtclock = tclock = cpuclock/4;
    210  1.12.4.2  nathanw 		else
    211  1.12.4.2  nathanw 			vtclock = tclock = 0; /* XXX */
    212  1.12.4.2  nathanw 		break;
    213  1.12.4.2  nathanw #endif /* VR4111 */
    214  1.12.4.2  nathanw #if defined VR4121
    215  1.12.4.2  nathanw 	case BCUREVID_RID_4121:
    216  1.12.4.2  nathanw 	{
    217  1.12.4.2  nathanw 		int vt;
    218  1.12.4.2  nathanw 		tclock = cpuclock / ((spdreg & BCUCLKSPEED_DIVTMASK) >>
    219  1.12.4.2  nathanw 		    BCUCLKSPEED_DIVTSHFT);
    220  1.12.4.2  nathanw 		vt = ((spdreg & BCUCLKSPEED_DIVVTMASK) >>
    221  1.12.4.2  nathanw 		    BCUCLKSPEED_DIVVTSHFT);
    222  1.12.4.2  nathanw 		if (vt == 0)
    223  1.12.4.2  nathanw 			vtclock = 0; /* XXX */
    224  1.12.4.2  nathanw 		else if (vt < 0x9)
    225  1.12.4.2  nathanw 			vtclock = cpuclock / vt;
    226  1.12.4.2  nathanw 		else
    227  1.12.4.2  nathanw 			vtclock = cpuclock / ((vt - 8)*2+1) * 2;
    228  1.12.4.2  nathanw 	}
    229  1.12.4.2  nathanw 	break;
    230  1.12.4.2  nathanw #endif /* VR4121 */
    231  1.12.4.2  nathanw #if defined VR4122 || defined VR4131
    232  1.12.4.2  nathanw 	case BCUREVID_RID_4122:
    233  1.12.4.2  nathanw 	case BCUREVID_RID_4131:
    234  1.12.4.2  nathanw 	{
    235  1.12.4.2  nathanw 		int vtdiv;
    236  1.12.4.2  nathanw 
    237  1.12.4.2  nathanw 		vtdiv = ((spdreg & BCUCLKSPEED_VTDIVMODE) >>
    238  1.12.4.2  nathanw 		    BCUCLKSPEED_VTDIVSHFT);
    239  1.12.4.2  nathanw 		if (vtdiv == 0 || vtdiv > BCUCLKSPEED_VTDIV6)
    240  1.12.4.2  nathanw 			vtclock = 0; /* XXX */
    241  1.12.4.2  nathanw 		else
    242  1.12.4.2  nathanw 			vtclock = cpuclock / vtdiv;
    243  1.12.4.2  nathanw 		tclock = vtclock /
    244  1.12.4.2  nathanw 		    (((spdreg & BCUCLKSPEED_TDIVMODE) >>
    245  1.12.4.2  nathanw 			BCUCLKSPEED_TDIVSHFT) ? 4 : 2);
    246  1.12.4.2  nathanw 	}
    247  1.12.4.2  nathanw 	break;
    248  1.12.4.2  nathanw #endif /* VR4122 || VR4131 */
    249  1.12.4.2  nathanw 	default:
    250  1.12.4.2  nathanw 		break;
    251  1.12.4.2  nathanw 	}
    252  1.12.4.2  nathanw 	if (tclock)
    253  1.12.4.2  nathanw 		printf("%s: cpu %d.%03dMHz, bus %d.%03dMHz, ram %d.%03dMHz\n",
    254  1.12.4.2  nathanw 		    sc->sc_dev.dv_xname,
    255  1.12.4.2  nathanw 		    cpuclock/1000000, (cpuclock%1000000)/1000,
    256  1.12.4.2  nathanw 		    tclock/1000000, (tclock%1000000)/1000,
    257  1.12.4.2  nathanw 		    vtclock/1000000, (vtclock%1000000)/1000);
    258  1.12.4.2  nathanw 	else {
    259  1.12.4.2  nathanw 		printf("%s: cpu %d.%03dMHz\n",
    260  1.12.4.2  nathanw 		    sc->sc_dev.dv_xname,
    261  1.12.4.2  nathanw 		    cpuclock/1000000, (cpuclock%1000000)/1000);
    262  1.12.4.2  nathanw 		printf("%s: UNKNOWN BUS CLOCK SPEED:"
    263  1.12.4.2  nathanw 		    " CPU is UNKNOWN or NOT CONFIGURED\n",
    264  1.12.4.2  nathanw 		    sc->sc_dev.dv_xname);
    265  1.12.4.2  nathanw 	}
    266  1.12.4.2  nathanw #ifdef VRBCUDEBUG
    267  1.12.4.2  nathanw 	reg = vrbcu_read(sc, BCUCNT1_REG_W);
    268  1.12.4.2  nathanw 	printf("vrbcu: CNT1 %x: ",  reg);
    269  1.12.4.2  nathanw 	dbg_bit_print(reg);
    270  1.12.4.2  nathanw #if !defined(ONLY_VR4181)
    271  1.12.4.2  nathanw 	if (cpuid != BCUREVID_FIXRID_4181
    272  1.12.4.2  nathanw 	    && cpuid <= BCUREVID_RID_4121
    273  1.12.4.2  nathanw 	    && cpuid >= BCUREVID_RID_4102) {
    274  1.12.4.2  nathanw 		reg = vrbcu_read(sc, BCUCNT2_REG_W);
    275  1.12.4.2  nathanw 		printf("vrbcu: CNT2 %x: ",  reg);
    276  1.12.4.2  nathanw 		dbg_bit_print(reg);
    277  1.12.4.2  nathanw 	}
    278  1.12.4.2  nathanw #endif /* !defined ONLY_VR4181 */
    279  1.12.4.2  nathanw #if !defined(ONLY_VR4181) || !defined(ONLY_VR4122_4131)
    280  1.12.4.2  nathanw 	if (cpuid != BCUREVID_FIXRID_4181
    281  1.12.4.2  nathanw 	    && cpuid <= BCUREVID_RID_4121
    282  1.12.4.2  nathanw 	    && cpuid >= BCUREVID_RID_4102) {
    283  1.12.4.2  nathanw 		reg = vrbcu_read(sc, BCUSPEED_REG_W);
    284  1.12.4.2  nathanw 		printf("vrbcu: SPEED %x: ",  reg);
    285  1.12.4.2  nathanw 		dbg_bit_print(reg);
    286  1.12.4.2  nathanw 		reg = vrbcu_read(sc, BCUERRST_REG_W);
    287  1.12.4.2  nathanw 		printf("vrbcu: ERRST %x: ",  reg);
    288  1.12.4.2  nathanw 		dbg_bit_print(reg);
    289  1.12.4.2  nathanw 		reg = vrbcu_read(sc, BCURFCNT_REG_W);
    290  1.12.4.2  nathanw 		printf("vrbcu: RFCNT %x\n",  reg);
    291  1.12.4.2  nathanw 		reg = vrbcu_read(sc, BCUREFCOUNT_REG_W);
    292  1.12.4.2  nathanw 		printf("vrbcu: RFCOUNT %x\n",  reg);
    293  1.12.4.2  nathanw 	}
    294  1.12.4.2  nathanw #endif /* !defined(ONLY_VR4181) || !defined(ONLY_VR4122_4131) */
    295  1.12.4.2  nathanw #if !defined(ONLY_VR4181)
    296  1.12.4.2  nathanw 	if (cpuid != BCUREVID_FIXRID_4181
    297  1.12.4.2  nathanw 	    && cpuid <= BCUREVID_RID_4131
    298  1.12.4.2  nathanw 	    && cpuid >= BCUREVID_RID_4111)
    299  1.12.4.2  nathanw 	{
    300  1.12.4.2  nathanw 		reg = vrbcu_read(sc, BCUCNT3_REG_W);
    301  1.12.4.2  nathanw 		printf("vrbcu: CNT3 %x: ",  reg);
    302  1.12.4.2  nathanw 		dbg_bit_print(reg);
    303  1.12.4.2  nathanw 	}
    304  1.12.4.2  nathanw #endif /* !defined ONLY_VR4181 */
    305  1.12.4.2  nathanw #endif /* VRBCUDEBUG */
    306  1.12.4.2  nathanw 
    307  1.12.4.2  nathanw }
    308  1.12.4.2  nathanw 
    309  1.12.4.2  nathanw static char *cpuname[] = {
    310  1.12.4.2  nathanw 	"VR4101",	/* 0 */
    311  1.12.4.2  nathanw 	"VR4102",	/* 1 */
    312  1.12.4.2  nathanw 	"VR4111",	/* 2 */
    313  1.12.4.2  nathanw 	"VR4121",	/* 3 */
    314  1.12.4.2  nathanw 	"VR4122",	/* 4 */
    315  1.12.4.2  nathanw 	"VR4131",	/* 5 */
    316  1.12.4.2  nathanw 	"UNKNOWN",
    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 	"VR4181",	/* 0x10 + 0 */
    327  1.12.4.2  nathanw };
    328  1.12.4.2  nathanw 
    329  1.12.4.2  nathanw int
    330  1.12.4.2  nathanw vrbcu_vrip_getcpuid(void)
    331  1.12.4.2  nathanw {
    332  1.12.4.2  nathanw 	volatile u_int16_t *revreg;
    333  1.12.4.2  nathanw 
    334  1.12.4.2  nathanw 	if (vr_cpuid != -1)
    335  1.12.4.2  nathanw 		return (vr_cpuid);
    336  1.12.4.2  nathanw 
    337  1.12.4.2  nathanw 	if (vr_cpuid == -1) {
    338  1.12.4.2  nathanw 		if (vrbcu_addr() == VR4181_BCU_ADDR)
    339  1.12.4.2  nathanw 			revreg = (u_int16_t *)MIPS_PHYS_TO_KSEG1
    340  1.12.4.2  nathanw 			    ((vrbcu_addr() + BCU81REVID_REG_W));
    341  1.12.4.2  nathanw 		else
    342  1.12.4.2  nathanw 			revreg = (u_int16_t *)MIPS_PHYS_TO_KSEG1
    343  1.12.4.2  nathanw 			    ((vrbcu_addr() + BCUREVID_REG_W));
    344  1.12.4.2  nathanw 
    345  1.12.4.2  nathanw 		vr_cpuid = *revreg;
    346  1.12.4.2  nathanw 		vr_cpuid = (vr_cpuid&BCUREVID_RIDMASK)>>BCUREVID_RIDSHFT;
    347  1.12.4.2  nathanw 		if (vrbcu_addr() == VR4181_BCU_ADDR
    348  1.12.4.2  nathanw 		    && vr_cpuid == BCUREVID_RID_4181) /* conflict vr4101 */
    349  1.12.4.2  nathanw 			vr_cpuid = BCUREVID_FIXRID_4181;
    350  1.12.4.2  nathanw 	}
    351  1.12.4.2  nathanw 	return (vr_cpuid);
    352  1.12.4.2  nathanw }
    353  1.12.4.2  nathanw 
    354  1.12.4.2  nathanw char *
    355  1.12.4.2  nathanw vrbcu_vrip_getcpuname(void)
    356  1.12.4.2  nathanw {
    357  1.12.4.2  nathanw 	int cpuid;
    358  1.12.4.2  nathanw 
    359  1.12.4.2  nathanw 	if (vr_cpuname != NULL)
    360  1.12.4.2  nathanw 		return (vr_cpuname);
    361  1.12.4.2  nathanw 
    362  1.12.4.2  nathanw 	cpuid = vrbcu_vrip_getcpuid();
    363  1.12.4.2  nathanw 	vr_cpuname = cpuname[cpuid];
    364  1.12.4.2  nathanw 
    365  1.12.4.2  nathanw 	return (vr_cpuname);
    366  1.12.4.2  nathanw }
    367  1.12.4.2  nathanw 
    368  1.12.4.2  nathanw 
    369  1.12.4.2  nathanw int
    370  1.12.4.2  nathanw vrbcu_vrip_getcpumajor(void)
    371  1.12.4.2  nathanw {
    372  1.12.4.2  nathanw 	volatile u_int16_t *revreg;
    373  1.12.4.2  nathanw 
    374  1.12.4.2  nathanw 	if (vr_major != -1)
    375  1.12.4.2  nathanw 		return (vr_major);
    376  1.12.4.2  nathanw 
    377  1.12.4.2  nathanw 	revreg = (u_int16_t *)MIPS_PHYS_TO_KSEG1
    378  1.12.4.2  nathanw 	    ((vrbcu_addr() + BCUREVID_REG_W));
    379  1.12.4.2  nathanw 
    380  1.12.4.2  nathanw 	vr_major = *revreg;
    381  1.12.4.2  nathanw 	vr_major = (vr_major&BCUREVID_MJREVMASK)>>BCUREVID_MJREVSHFT;
    382  1.12.4.2  nathanw 
    383  1.12.4.2  nathanw 	return (vr_major);
    384  1.12.4.2  nathanw }
    385  1.12.4.2  nathanw 
    386  1.12.4.2  nathanw int
    387  1.12.4.2  nathanw vrbcu_vrip_getcpuminor(void)
    388  1.12.4.2  nathanw {
    389  1.12.4.2  nathanw 	volatile u_int16_t *revreg;
    390  1.12.4.2  nathanw 
    391  1.12.4.2  nathanw 	if (vr_minor != -1)
    392  1.12.4.2  nathanw 		return (vr_minor);
    393  1.12.4.2  nathanw 
    394  1.12.4.2  nathanw 	revreg = (u_int16_t *)MIPS_PHYS_TO_KSEG1
    395  1.12.4.2  nathanw 	    ((vrbcu_addr() + BCUREVID_REG_W));
    396  1.12.4.2  nathanw 
    397  1.12.4.2  nathanw 	vr_minor = *revreg;
    398  1.12.4.2  nathanw 	vr_minor = (vr_minor&BCUREVID_MNREVMASK)>>BCUREVID_MNREVSHFT;
    399  1.12.4.2  nathanw 
    400  1.12.4.2  nathanw 	return (vr_minor);
    401  1.12.4.2  nathanw }
    402  1.12.4.2  nathanw 
    403  1.12.4.2  nathanw #define CLKX	18432000	/* CLKX1,CLKX2: 18.432MHz */
    404  1.12.4.2  nathanw #define MHZ	1000000
    405  1.12.4.2  nathanw 
    406  1.12.4.2  nathanw int
    407  1.12.4.2  nathanw vrbcu_vrip_getcpuclock(void)
    408  1.12.4.2  nathanw {
    409  1.12.4.2  nathanw 	u_int16_t clksp;
    410  1.12.4.2  nathanw 	int cpuid, cpuclock;
    411  1.12.4.2  nathanw 
    412  1.12.4.2  nathanw 	cpuid = vrbcu_vrip_getcpuid();
    413  1.12.4.2  nathanw 	if (cpuid != BCUREVID_FIXRID_4181 && cpuid >= BCUREVID_RID_4111) {
    414  1.12.4.2  nathanw 		clksp = *(u_int16_t *)MIPS_PHYS_TO_KSEG1
    415  1.12.4.2  nathanw 		    ((vrbcu_addr() + BCUCLKSPEED_REG_W)) &
    416  1.12.4.2  nathanw 		    BCUCLKSPEED_CLKSPMASK;
    417  1.12.4.2  nathanw 	} else if (cpuid == BCUREVID_FIXRID_4181) {
    418  1.12.4.2  nathanw 		clksp = *(u_int16_t *)MIPS_PHYS_TO_KSEG1
    419  1.12.4.2  nathanw 		    ((vrbcu_addr() + BCU81CLKSPEED_REG_W)) &
    420  1.12.4.2  nathanw 		    BCUCLKSPEED_CLKSPMASK;
    421  1.12.4.2  nathanw 	}
    422  1.12.4.2  nathanw 
    423  1.12.4.2  nathanw 	switch (cpuid) {
    424  1.12.4.2  nathanw 	case BCUREVID_FIXRID_4181:
    425  1.12.4.2  nathanw 		cpuclock = CLKX / clksp * 64;
    426  1.12.4.2  nathanw 		/* branch delay is 1 clock; 2 clock/loop */
    427  1.12.4.2  nathanw 		cpuspeed = (cpuclock / 2 + MHZ / 2) / MHZ;
    428  1.12.4.2  nathanw 		break;
    429  1.12.4.2  nathanw 	case BCUREVID_RID_4101:
    430  1.12.4.2  nathanw 		/* assume 33MHz */
    431  1.12.4.2  nathanw 		cpuclock = 33000000;
    432  1.12.4.2  nathanw 		/* branch delay is 1 clock; 2 clock/loop */
    433  1.12.4.2  nathanw 		cpuspeed = (cpuclock / 2 + MHZ / 2) / MHZ;
    434  1.12.4.2  nathanw 		break;
    435  1.12.4.2  nathanw 	case BCUREVID_RID_4102:
    436  1.12.4.2  nathanw 		cpuclock = CLKX / clksp * 32;
    437  1.12.4.2  nathanw 		/* branch delay is 1 clock; 2 clock/loop */
    438  1.12.4.2  nathanw 		cpuspeed = (cpuclock / 2 + MHZ / 2) / MHZ;
    439  1.12.4.2  nathanw 		break;
    440  1.12.4.2  nathanw 	case BCUREVID_RID_4111:
    441  1.12.4.2  nathanw 		cpuclock = CLKX / clksp * 64;
    442  1.12.4.2  nathanw 		/* branch delay is 1 clock; 2 clock/loop */
    443  1.12.4.2  nathanw 		cpuspeed = (cpuclock / 2 + MHZ / 2) / MHZ;
    444  1.12.4.2  nathanw 		break;
    445  1.12.4.2  nathanw 	case BCUREVID_RID_4121:
    446  1.12.4.2  nathanw 		cpuclock = CLKX / clksp * 64;
    447  1.12.4.2  nathanw 		/* branch delay is 2 clock; 3 clock/loop */
    448  1.12.4.2  nathanw 		cpuspeed = (cpuclock / 3 + MHZ / 2) / MHZ;
    449  1.12.4.2  nathanw 		break;
    450  1.12.4.2  nathanw 	case BCUREVID_RID_4122:
    451  1.12.4.2  nathanw 		cpuclock = CLKX / clksp * 98;
    452  1.12.4.2  nathanw 		/* branch delay is 2 clock; 3 clock/loop */
    453  1.12.4.2  nathanw 		cpuspeed = (cpuclock / 3 + MHZ / 2) / MHZ;
    454  1.12.4.2  nathanw 		break;
    455  1.12.4.2  nathanw 	case BCUREVID_RID_4131:
    456  1.12.4.2  nathanw 		cpuclock = CLKX / clksp * 98;
    457  1.12.4.2  nathanw 		/* branch delay is 2 clock; 3 clock/loop */
    458  1.12.4.2  nathanw 		cpuspeed = (cpuclock / 3 + MHZ / 2) / MHZ;
    459  1.12.4.2  nathanw 		break;
    460  1.12.4.2  nathanw 	default:
    461  1.12.4.3  nathanw 		panic("unknown CPU type %d", cpuid);
    462  1.12.4.2  nathanw 		break;
    463  1.12.4.2  nathanw 	}
    464  1.12.4.2  nathanw 
    465  1.12.4.2  nathanw 	return (cpuclock);
    466  1.12.4.2  nathanw }
    467