/*
 * arch/sh/kernel/cpu/sh4/clock-sh4-202.c
 *
 * Additional SH4-202 support for the clock framework
 *
 *  Copyright (C) 2005  Paul Mundt
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 */
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/err.h>
#include <asm/clock.h>
#include <asm/freq.h>
#include <asm/io.h>

#define CPG2_FRQCR3	0xfe0a0018

static int frqcr3_divisors[] = { 1, 2, 3, 4, 6, 8, 16 };
static int frqcr3_values[]   = { 0, 1, 2, 3, 4, 5, 6  };

static unsigned long emi_clk_recalc(struct clk *clk)
{
	int idx = ctrl_inl(CPG2_FRQCR3) & 0x0007;
	return clk->parent->rate / frqcr3_divisors[idx];
}

static inline int frqcr3_lookup(struct clk *clk, unsigned long rate)
{
	int divisor = clk->parent->rate / rate;
	int i;

	for (i = 0; i < ARRAY_SIZE(frqcr3_divisors); i++)
		if (frqcr3_divisors[i] == divisor)
			return frqcr3_values[i];

	/* Safe fallback */
	return 5;
}

static struct clk_ops sh4202_emi_clk_ops = {
	.recalc		= emi_clk_recalc,
};

static struct clk sh4202_emi_clk = {
	.name		= "emi_clk",
	.flags		= CLK_ENABLE_ON_INIT,
	.ops		= &sh4202_emi_clk_ops,
};

static unsigned long femi_clk_recalc(struct clk *clk)
{
	int idx = (ctrl_inl(CPG2_FRQCR3) >> 3) & 0x0007;
	return clk->parent->rate / frqcr3_divisors[idx];
}

static struct clk_ops sh4202_femi_clk_ops = {
	.recalc		= femi_clk_recalc,
};

static struct clk sh4202_femi_clk = {
	.name		= "femi_clk",
	.flags		= CLK_ENABLE_ON_INIT,
	.ops		= &sh4202_femi_clk_ops,
};

static void shoc_clk_init(struct clk *clk)
{
	int i;

	/*
	 * For some reason, the shoc_clk seems to be set to some really
	 * insane value at boot (values outside of the allowable frequency
	 * range for instance). We deal with this by scaling it back down
	 * to something sensible just in case.
	 *
	 * Start scaling from the high end down until we find something
	 * that passes rate verification..
	 */
	for (i = 0; i < ARRAY_SIZE(frqcr3_divisors); i++) {
		int divisor = frqcr3_divisors[i];

		if (clk->ops->set_rate(clk, clk->parent->rate /
						divisor, 0) == 0)
			break;
	}

	WARN_ON(i == ARRAY_SIZE(frqcr3_divisors));	/* Undefined clock */
}

static unsigned long shoc_clk_recalc(struct clk *clk)
{
	int idx = (ctrl_inl(CPG2_FRQCR3) >> 6) & 0x0007;
	return clk->parent->rate / frqcr3_divisors[idx];
}

static int shoc_clk_verify_rate(struct clk *clk, unsigned long rate)
{
	struct clk *bclk = clk_get(NULL, "bus_clk");
	unsigned long bclk_rate = clk_get_rate(bclk);

	clk_put(bclk);

	if (rate > bclk_rate)
		return 1;
	if (rate > 66000000)
		return 1;

	return 0;
}

static int shoc_clk_set_rate(struct clk *clk, unsigned long rate, int algo_id)
{
	unsigned long frqcr3;
	unsigned int tmp;

	/* Make sure we have something sensible to switch to */
	if (shoc_clk_verify_rate(clk, rate) != 0)
		return -EINVAL;

	tmp = frqcr3_lookup(clk, rate);

	frqcr3 = ctrl_inl(CPG2_FRQCR3);
	frqcr3 &= ~(0x0007 << 6);
	frqcr3 |= tmp << 6;
	ctrl_outl(frqcr3, CPG2_FRQCR3);

	clk->rate = clk->parent->rate / frqcr3_divisors[tmp];

	return 0;
}

static struct clk_ops sh4202_shoc_clk_ops = {
	.init		= shoc_clk_init,
	.recalc		= shoc_clk_recalc,
	.set_rate	= shoc_clk_set_rate,
};

static struct clk sh4202_shoc_clk = {
	.name		= "shoc_clk",
	.flags		= CLK_ENABLE_ON_INIT,
	.ops		= &sh4202_shoc_clk_ops,
};

static struct clk *sh4202_onchip_clocks[] = {
	&sh4202_emi_clk,
	&sh4202_femi_clk,
	&sh4202_shoc_clk,
};

int __init arch_clk_init(void)
{
	struct clk *clk;
	int i, ret = 0;

	cpg_clk_init();

	clk = clk_get(NULL, "master_clk");
	for (i = 0; i < ARRAY_SIZE(sh4202_onchip_clocks); i++) {
		struct clk *clkp = sh4202_onchip_clocks[i];

		clkp->parent = clk;
		ret |= clk_register(clkp);
	}

	clk_put(clk);

	return ret;
}
