/*
 *  bcu.c, Bus Control Unit routines for the NEC VR4100 series.
 *
 *  Copyright (C) 2002	MontaVista Software Inc.
 *    Author: Yoichi Yuasa <source@mvista.com>
 *  Copyright (C) 2003-2005  Yoichi Yuasa <yuasa@linux-mips.org>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
/*
 * Changes:
 *  MontaVista Software Inc. <source@mvista.com>
 *  - New creation, NEC VR4122 and VR4131 are supported.
 *  - Added support for NEC VR4111 and VR4121.
 *
 *  Yoichi Yuasa <yuasa@linux-mips.org>
 *  - Added support for NEC VR4133.
 */
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/smp.h>
#include <linux/types.h>

#include <asm/cpu.h>
#include <asm/io.h>

#define CLKSPEEDREG_TYPE1	(void __iomem *)KSEG1ADDR(0x0b000014)
#define CLKSPEEDREG_TYPE2	(void __iomem *)KSEG1ADDR(0x0f000014)
 #define CLKSP(x)		((x) & 0x001f)
 #define CLKSP_VR4133(x)	((x) & 0x0007)

 #define DIV2B			0x8000
 #define DIV3B			0x4000
 #define DIV4B			0x2000

 #define DIVT(x)		(((x) & 0xf000) >> 12)
 #define DIVVT(x)		(((x) & 0x0f00) >> 8)

 #define TDIVMODE(x)		(2 << (((x) & 0x1000) >> 12))
 #define VTDIVMODE(x)		(((x) & 0x0700) >> 8)

static unsigned long vr41xx_vtclock;
static unsigned long vr41xx_tclock;

unsigned long vr41xx_get_vtclock_frequency(void)
{
	return vr41xx_vtclock;
}

EXPORT_SYMBOL_GPL(vr41xx_get_vtclock_frequency);

unsigned long vr41xx_get_tclock_frequency(void)
{
	return vr41xx_tclock;
}

EXPORT_SYMBOL_GPL(vr41xx_get_tclock_frequency);

static inline uint16_t read_clkspeed(void)
{
	switch (current_cpu_type()) {
	case CPU_VR4111:
	case CPU_VR4121: return readw(CLKSPEEDREG_TYPE1);
	case CPU_VR4122:
	case CPU_VR4131:
	case CPU_VR4133: return readw(CLKSPEEDREG_TYPE2);
	default:
		printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
		break;
	}

	return 0;
}

static inline unsigned long calculate_pclock(uint16_t clkspeed)
{
	unsigned long pclock = 0;

	switch (current_cpu_type()) {
	case CPU_VR4111:
	case CPU_VR4121:
		pclock = 18432000 * 64;
		pclock /= CLKSP(clkspeed);
		break;
	case CPU_VR4122:
		pclock = 18432000 * 98;
		pclock /= CLKSP(clkspeed);
		break;
	case CPU_VR4131:
		pclock = 18432000 * 108;
		pclock /= CLKSP(clkspeed);
		break;
	case CPU_VR4133:
		switch (CLKSP_VR4133(clkspeed)) {
		case 0:
			pclock = 133000000;
			break;
		case 1:
			pclock = 149000000;
			break;
		case 2:
			pclock = 165900000;
			break;
		case 3:
			pclock = 199100000;
			break;
		case 4:
			pclock = 265900000;
			break;
		default:
			printk(KERN_INFO "Unknown PClock speed for NEC VR4133\n");
			break;
		}
		break;
	default:
		printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
		break;
	}

	printk(KERN_INFO "PClock: %ldHz\n", pclock);

	return pclock;
}

static inline unsigned long calculate_vtclock(uint16_t clkspeed, unsigned long pclock)
{
	unsigned long vtclock = 0;

	switch (current_cpu_type()) {
	case CPU_VR4111:
		/* The NEC VR4111 doesn't have the VTClock. */
		break;
	case CPU_VR4121:
		vtclock = pclock;
		/* DIVVT == 9 Divide by 1.5 . VTClock = (PClock * 6) / 9 */
		if (DIVVT(clkspeed) == 9)
			vtclock = pclock * 6;
		/* DIVVT == 10 Divide by 2.5 . VTClock = (PClock * 4) / 10 */
		else if (DIVVT(clkspeed) == 10)
			vtclock = pclock * 4;
		vtclock /= DIVVT(clkspeed);
		printk(KERN_INFO "VTClock: %ldHz\n", vtclock);
		break;
	case CPU_VR4122:
		if(VTDIVMODE(clkspeed) == 7)
			vtclock = pclock / 1;
		else if(VTDIVMODE(clkspeed) == 1)
			vtclock = pclock / 2;
		else
			vtclock = pclock / VTDIVMODE(clkspeed);
		printk(KERN_INFO "VTClock: %ldHz\n", vtclock);
		break;
	case CPU_VR4131:
	case CPU_VR4133:
		vtclock = pclock / VTDIVMODE(clkspeed);
		printk(KERN_INFO "VTClock: %ldHz\n", vtclock);
		break;
	default:
		printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
		break;
	}

	return vtclock;
}

static inline unsigned long calculate_tclock(uint16_t clkspeed, unsigned long pclock,
					     unsigned long vtclock)
{
	unsigned long tclock = 0;

	switch (current_cpu_type()) {
	case CPU_VR4111:
		if (!(clkspeed & DIV2B))
			tclock = pclock / 2;
		else if (!(clkspeed & DIV3B))
			tclock = pclock / 3;
		else if (!(clkspeed & DIV4B))
			tclock = pclock / 4;
		break;
	case CPU_VR4121:
		tclock = pclock / DIVT(clkspeed);
		break;
	case CPU_VR4122:
	case CPU_VR4131:
	case CPU_VR4133:
		tclock = vtclock / TDIVMODE(clkspeed);
		break;
	default:
		printk(KERN_INFO "Unexpected CPU of NEC VR4100 series\n");
		break;
	}

	printk(KERN_INFO "TClock: %ldHz\n", tclock);

	return tclock;
}

void vr41xx_calculate_clock_frequency(void)
{
	unsigned long pclock;
	uint16_t clkspeed;

	clkspeed = read_clkspeed();

	pclock = calculate_pclock(clkspeed);
	vr41xx_vtclock = calculate_vtclock(clkspeed, pclock);
	vr41xx_tclock = calculate_tclock(clkspeed, pclock, vr41xx_vtclock);
}

EXPORT_SYMBOL_GPL(vr41xx_calculate_clock_frequency);
