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