/*
 * 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 <linux/io.h>
#include <asm/clkdev.h>
#include <asm/clock.h>
#include <asm/freq.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 = __raw_readl(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 = {
	.flags		= CLK_ENABLE_ON_INIT,
	.ops		= &sh4202_emi_clk_ops,
};

static unsigned long femi_clk_recalc(struct clk *clk)
{
	int idx = (__raw_readl(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 = {
	.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 = (__raw_readl(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 = __raw_readl(CPG2_FRQCR3);
	frqcr3 &= ~(0x0007 << 6);
	frqcr3 |= tmp << 6;
	__raw_writel(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 = {
	.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,
};

#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk }

static struct clk_lookup lookups[] = {
	/* main clocks */
	CLKDEV_CON_ID("emi_clk", &sh4202_emi_clk),
	CLKDEV_CON_ID("femi_clk", &sh4202_femi_clk),
	CLKDEV_CON_ID("shoc_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);

	clkdev_add_table(lookups, ARRAY_SIZE(lookups));

	return ret;
}
