/*
 * arch/sh/kernel/cpu/sh4a/clock-sh7722.c
 *
 * SH7722 & SH7366 support for the clock framework
 *
 * Copyright (c) 2006-2007 Nomad Global Solutions Inc
 * Based on code for sh7343 by 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/io.h>
#include <linux/errno.h>
#include <asm/clock.h>
#include <asm/freq.h>

#define N  (-1)
#define NM (-2)
#define ROUND_NEAREST 0
#define ROUND_DOWN -1
#define ROUND_UP   +1

static int adjust_algos[][3] = {
	{},	/* NO_CHANGE */
	{ NM, N, 1 },   /* N:1, N:1 */
	{ 3, 2, 2 },	/* 3:2:2 */
	{ 5, 2, 2 },    /* 5:2:2 */
	{ N, 1, 1 },	/* N:1:1 */

	{ N, 1 },	/* N:1 */

	{ N, 1 },	/* N:1 */
	{ 3, 2 },
	{ 4, 3 },
	{ 5, 4 },

	{ N, 1 }
};

static unsigned long adjust_pair_of_clocks(unsigned long r1, unsigned long r2,
			int m1, int m2, int round_flag)
{
	unsigned long rem, div;
	int the_one = 0;

	pr_debug( "Actual values: r1 = %ld\n", r1);
	pr_debug( "...............r2 = %ld\n", r2);

	if (m1 == m2) {
		r2 = r1;
		pr_debug( "setting equal rates: r2 now %ld\n", r2);
	} else if ((m2 == N  && m1 == 1) ||
		   (m2 == NM && m1 == N)) { /* N:1 or NM:N */
		pr_debug( "Setting rates as 1:N (N:N*M)\n");
		rem = r2 % r1;
		pr_debug( "...remainder = %ld\n", rem);
		if (rem) {
			div = r2 / r1;
			pr_debug( "...div = %ld\n", div);
			switch (round_flag) {
			case ROUND_NEAREST:
				the_one = rem >= r1/2 ? 1 : 0; break;
			case ROUND_UP:
				the_one = 1; break;
			case ROUND_DOWN:
				the_one = 0; break;
			}

			r2 = r1 * (div + the_one);
			pr_debug( "...setting r2 to %ld\n", r2);
		}
	} else if ((m2 == 1  && m1 == N) ||
		   (m2 == N && m1 == NM)) { /* 1:N or N:NM */
		pr_debug( "Setting rates as N:1 (N*M:N)\n");
		rem = r1 % r2;
		pr_debug( "...remainder = %ld\n", rem);
		if (rem) {
			div = r1 / r2;
			pr_debug( "...div = %ld\n", div);
			switch (round_flag) {
			case ROUND_NEAREST:
				the_one = rem > r2/2 ? 1 : 0; break;
			case ROUND_UP:
				the_one = 0; break;
			case ROUND_DOWN:
				the_one = 1; break;
			}

			r2 = r1 / (div + the_one);
			pr_debug( "...setting r2 to %ld\n", r2);
		}
	} else { /* value:value */
		pr_debug( "Setting rates as %d:%d\n", m1, m2);
		div = r1 / m1;
		r2 = div * m2;
		pr_debug( "...div = %ld\n", div);
		pr_debug( "...setting r2 to %ld\n", r2);
	}

	return r2;
}

static void adjust_clocks(int originate, int *l, unsigned long v[],
			  int n_in_line)
{
	int x;

	pr_debug( "Go down from %d...\n", originate);
	/* go up recalculation clocks */
	for (x = originate; x>0; x -- )
		v[x-1] = adjust_pair_of_clocks(v[x], v[x-1],
					l[x], l[x-1],
					ROUND_UP);

	pr_debug( "Go up from %d...\n", originate);
	/* go down recalculation clocks */
	for (x = originate; x<n_in_line - 1; x ++ )
		v[x+1] = adjust_pair_of_clocks(v[x], v[x+1],
					l[x], l[x+1],
					ROUND_UP);
}


/*
 * SH7722 uses a common set of multipliers and divisors, so this
 * is quite simple..
 */

/*
 * Instead of having two separate multipliers/divisors set, like this:
 *
 * static int multipliers[] = { 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
 * static int divisors[] = { 1, 3, 2, 5, 3, 4, 5, 6, 8, 10, 12, 16, 20 };
 *
 * I created the divisors2 array, which is used to calculate rate like
 *   rate = parent * 2 / divisors2[ divisor ];
*/
static int divisors2[] = { 2, 3, 4, 5, 6, 8, 10, 12, 16, 20, 24, 32, 40 };

static void master_clk_recalc(struct clk *clk)
{
	unsigned frqcr = ctrl_inl(FRQCR);

	clk->rate = CONFIG_SH_PCLK_FREQ * (((frqcr >> 24) & 0x1f) + 1);
}

static void master_clk_init(struct clk *clk)
{
	clk->parent = NULL;
	clk->flags |= CLK_RATE_PROPAGATES;
	clk->rate = CONFIG_SH_PCLK_FREQ;
	master_clk_recalc(clk);
}


static void module_clk_recalc(struct clk *clk)
{
	unsigned long frqcr = ctrl_inl(FRQCR);

	clk->rate = clk->parent->rate / (((frqcr >> 24) & 0x1f) + 1);
}

static int master_clk_setrate(struct clk *clk, unsigned long rate, int id)
{
	int div = rate / clk->rate;
	int master_divs[] = { 2, 3, 4, 6, 8, 16 };
	int index;
	unsigned long frqcr;

	for (index = 1; index < ARRAY_SIZE(master_divs); index++)
		if (div >= master_divs[index - 1] && div < master_divs[index])
			break;

	if (index >= ARRAY_SIZE(master_divs))
		index = ARRAY_SIZE(master_divs);
	div = master_divs[index - 1];

	frqcr = ctrl_inl(FRQCR);
	frqcr &= ~(0xF << 24);
	frqcr |= ( (div-1) << 24);
	ctrl_outl(frqcr, FRQCR);

	return 0;
}

static struct clk_ops sh7722_master_clk_ops = {
	.init = master_clk_init,
	.recalc = master_clk_recalc,
	.set_rate = master_clk_setrate,
};

static struct clk_ops sh7722_module_clk_ops = {
       .recalc = module_clk_recalc,
};

struct frqcr_context {
	unsigned mask;
	unsigned shift;
};

struct frqcr_context sh7722_get_clk_context(const char *name)
{
	struct frqcr_context ctx = { 0, };

	if (!strcmp(name, "peripheral_clk")) {
		ctx.shift = 0;
		ctx.mask = 0xF;
	} else if (!strcmp(name, "sdram_clk")) {
		ctx.shift = 4;
		ctx.mask = 0xF;
	} else if (!strcmp(name, "bus_clk")) {
		ctx.shift = 8;
		ctx.mask = 0xF;
	} else if (!strcmp(name, "sh_clk")) {
		ctx.shift = 12;
		ctx.mask = 0xF;
	} else if (!strcmp(name, "umem_clk")) {
		ctx.shift = 16;
		ctx.mask = 0xF;
	} else if (!strcmp(name, "cpu_clk")) {
		ctx.shift = 20;
		ctx.mask = 7;
	}
	return ctx;
}

/**
 * sh7722_find_divisors - find divisor for setting rate
 *
 * All sh7722 clocks use the same set of multipliers/divisors. This function
 * chooses correct divisor to set the rate of clock with parent clock that
 * generates frequency of 'parent_rate'
 *
 * @parent_rate: rate of parent clock
 * @rate: requested rate to be set
 */
static int sh7722_find_divisors(unsigned long parent_rate, unsigned rate)
{
	unsigned div2 = parent_rate * 2 / rate;
	int index;

	if (rate > parent_rate)
		return -EINVAL;

	for (index = 1; index < ARRAY_SIZE(divisors2); index++) {
		if (div2 > divisors2[index] && div2 <= divisors2[index])
			break;
	}
	if (index >= ARRAY_SIZE(divisors2))
		index = ARRAY_SIZE(divisors2) - 1;
	return divisors2[index];
}

static void sh7722_frqcr_recalc(struct clk *clk)
{
	struct frqcr_context ctx = sh7722_get_clk_context(clk->name);
	unsigned long frqcr = ctrl_inl(FRQCR);
	int index;

	index = (frqcr >> ctx.shift) & ctx.mask;
	clk->rate = clk->parent->rate * 2 / divisors2[index];
}

static int sh7722_frqcr_set_rate(struct clk *clk, unsigned long rate,
				 int algo_id)
{
	struct frqcr_context ctx = sh7722_get_clk_context(clk->name);
	unsigned long parent_rate = clk->parent->rate;
	int div;
	unsigned long frqcr;
	int err = 0;

	/* pretty invalid */
	if (parent_rate < rate)
		return -EINVAL;

	/* look for multiplier/divisor pair */
	div = sh7722_find_divisors(parent_rate, rate);
	if (div<0)
		return div;

	/* calculate new value of clock rate */
	clk->rate = parent_rate * 2 / div;
	frqcr = ctrl_inl(FRQCR);

	/* FIXME: adjust as algo_id specifies */
	if (algo_id != NO_CHANGE) {
		int originator;
		char *algo_group_1[] = { "cpu_clk", "umem_clk", "sh_clk" };
		char *algo_group_2[] = { "sh_clk", "bus_clk" };
		char *algo_group_3[] = { "sh_clk", "sdram_clk" };
		char *algo_group_4[] = { "bus_clk", "peripheral_clk" };
		char *algo_group_5[] = { "cpu_clk", "peripheral_clk" };
		char **algo_current = NULL;
		/* 3 is the maximum number of clocks in relation */
		struct clk *ck[3];
		unsigned long values[3]; /* the same comment as above */
		int part_length = -1;
		int i;

		/*
		 * all the steps below only required if adjustion was
		 * requested
		 */
		if (algo_id == IUS_N1_N1 ||
		    algo_id == IUS_322 ||
		    algo_id == IUS_522 ||
		    algo_id == IUS_N11) {
			algo_current = algo_group_1;
			part_length = 3;
		}
		if (algo_id == SB_N1) {
			algo_current = algo_group_2;
			part_length = 2;
		}
		if (algo_id == SB3_N1 ||
		    algo_id == SB3_32 ||
		    algo_id == SB3_43 ||
		    algo_id == SB3_54) {
			algo_current = algo_group_3;
			part_length = 2;
		}
		if (algo_id == BP_N1) {
			algo_current = algo_group_4;
			part_length = 2;
		}
		if (algo_id == IP_N1) {
			algo_current = algo_group_5;
			part_length = 2;
		}
		if (!algo_current)
			goto incorrect_algo_id;

		originator = -1;
		for (i = 0; i < part_length; i ++ ) {
			if (originator >= 0 && !strcmp(clk->name,
						       algo_current[i]))
				originator = i;
			ck[i] = clk_get(NULL, algo_current[i]);
			values[i] = clk_get_rate(ck[i]);
		}

		if (originator >= 0)
			adjust_clocks(originator, adjust_algos[algo_id],
				      values, part_length);

		for (i = 0; i < part_length; i ++ ) {
			struct frqcr_context part_ctx;
			int part_div;

			if (likely(!err)) {
				part_div = sh7722_find_divisors(parent_rate,
								rate);
				if (part_div > 0) {
					part_ctx = sh7722_get_clk_context(
								ck[i]->name);
					frqcr &= ~(part_ctx.mask <<
						   part_ctx.shift);
					frqcr |= part_div << part_ctx.shift;
				} else
					err = part_div;
			}

			ck[i]->ops->recalc(ck[i]);
			clk_put(ck[i]);
		}
	}

	/* was there any error during recalculation ? If so, bail out.. */
	if (unlikely(err!=0))
		goto out_err;

	/* clear FRQCR bits */
	frqcr &= ~(ctx.mask << ctx.shift);
	frqcr |= div << ctx.shift;

	/* ...and perform actual change */
	ctrl_outl(frqcr, FRQCR);
	return 0;

incorrect_algo_id:
	return -EINVAL;
out_err:
	return err;
}

static long sh7722_frqcr_round_rate(struct clk *clk, unsigned long rate)
{
	unsigned long parent_rate = clk->parent->rate;
	int div;

	/* look for multiplier/divisor pair */
	div = sh7722_find_divisors(parent_rate, rate);
	if (div < 0)
		return clk->rate;

	/* calculate new value of clock rate */
	return parent_rate * 2 / div;
}

static struct clk_ops sh7722_frqcr_clk_ops = {
	.recalc = sh7722_frqcr_recalc,
	.set_rate = sh7722_frqcr_set_rate,
	.round_rate = sh7722_frqcr_round_rate,
};

/*
 * clock ops methods for SIU A/B and IrDA clock
 *
 */
static int sh7722_siu_which(struct clk *clk)
{
	if (!strcmp(clk->name, "siu_a_clk"))
		return 0;
	if (!strcmp(clk->name, "siu_b_clk"))
		return 1;
#if defined(CONFIG_CPU_SUBTYPE_SH7722)
	if (!strcmp(clk->name, "irda_clk"))
		return 2;
#endif
	return -EINVAL;
}

static unsigned long sh7722_siu_regs[] = {
	[0] = SCLKACR,
	[1] = SCLKBCR,
#if defined(CONFIG_CPU_SUBTYPE_SH7722)
	[2] = IrDACLKCR,
#endif
};

static int sh7722_siu_start_stop(struct clk *clk, int enable)
{
	int siu = sh7722_siu_which(clk);
	unsigned long r;

	if (siu < 0)
		return siu;
	BUG_ON(siu > 2);
	r = ctrl_inl(sh7722_siu_regs[siu]);
	if (enable)
		ctrl_outl(r & ~(1 << 8), sh7722_siu_regs[siu]);
	else
		ctrl_outl(r | (1 << 8), sh7722_siu_regs[siu]);
	return 0;
}

static void sh7722_siu_enable(struct clk *clk)
{
	sh7722_siu_start_stop(clk, 1);
}

static void sh7722_siu_disable(struct clk *clk)
{
	sh7722_siu_start_stop(clk, 0);
}

static void sh7722_video_enable(struct clk *clk)
{
	unsigned long r;

	r = ctrl_inl(VCLKCR);
	ctrl_outl( r & ~(1<<8), VCLKCR);
}

static void sh7722_video_disable(struct clk *clk)
{
	unsigned long r;

	r = ctrl_inl(VCLKCR);
	ctrl_outl( r | (1<<8), VCLKCR);
}

static int sh7722_video_set_rate(struct clk *clk, unsigned long rate,
				 int algo_id)
{
	unsigned long r;

	r = ctrl_inl(VCLKCR);
	r &= ~0x3F;
	r |= ((clk->parent->rate / rate - 1) & 0x3F);
	ctrl_outl(r, VCLKCR);
	return 0;
}

static void sh7722_video_recalc(struct clk *clk)
{
	unsigned long r;

	r = ctrl_inl(VCLKCR);
	clk->rate = clk->parent->rate / ((r & 0x3F) + 1);
}

static int sh7722_siu_set_rate(struct clk *clk, unsigned long rate, int algo_id)
{
	int siu = sh7722_siu_which(clk);
	unsigned long r;
	int div;

	if (siu < 0)
		return siu;
	BUG_ON(siu > 2);
	r = ctrl_inl(sh7722_siu_regs[siu]);
	div = sh7722_find_divisors(clk->parent->rate, rate);
	if (div < 0)
		return div;
	r = (r & ~0xF) | div;
	ctrl_outl(r, sh7722_siu_regs[siu]);
	return 0;
}

static void sh7722_siu_recalc(struct clk *clk)
{
	int siu = sh7722_siu_which(clk);
	unsigned long r;

	if (siu < 0)
		return /* siu */ ;
	BUG_ON(siu > 2);
	r = ctrl_inl(sh7722_siu_regs[siu]);
	clk->rate = clk->parent->rate * 2 / divisors2[r & 0xF];
}

static struct clk_ops sh7722_siu_clk_ops = {
	.recalc = sh7722_siu_recalc,
	.set_rate = sh7722_siu_set_rate,
	.enable = sh7722_siu_enable,
	.disable = sh7722_siu_disable,
};

static struct clk_ops sh7722_video_clk_ops = {
	.recalc = sh7722_video_recalc,
	.set_rate = sh7722_video_set_rate,
	.enable = sh7722_video_enable,
	.disable = sh7722_video_disable,
};
/*
 * and at last, clock definitions themselves
 */
static struct clk sh7722_umem_clock = {
	.name = "umem_clk",
	.ops = &sh7722_frqcr_clk_ops,
};

static struct clk sh7722_sh_clock = {
	.name = "sh_clk",
	.ops = &sh7722_frqcr_clk_ops,
};

static struct clk sh7722_peripheral_clock = {
	.name = "peripheral_clk",
	.ops = &sh7722_frqcr_clk_ops,
};

static struct clk sh7722_sdram_clock = {
	.name = "sdram_clk",
	.ops = &sh7722_frqcr_clk_ops,
};

/*
 * these three clocks - SIU A, SIU B, IrDA - share the same clk_ops
 * methods of clk_ops determine which register they should access by
 * examining clk->name field
 */
static struct clk sh7722_siu_a_clock = {
	.name = "siu_a_clk",
	.ops = &sh7722_siu_clk_ops,
};

static struct clk sh7722_siu_b_clock = {
	.name = "siu_b_clk",
	.ops = &sh7722_siu_clk_ops,
};

#if defined(CONFIG_CPU_SUBTYPE_SH7722)
static struct clk sh7722_irda_clock = {
	.name = "irda_clk",
	.ops = &sh7722_siu_clk_ops,
};
#endif

static struct clk sh7722_video_clock = {
	.name = "video_clk",
	.ops = &sh7722_video_clk_ops,
};

static struct clk *sh7722_clocks[] = {
	&sh7722_umem_clock,
	&sh7722_sh_clock,
	&sh7722_peripheral_clock,
	&sh7722_sdram_clock,
	&sh7722_siu_a_clock,
	&sh7722_siu_b_clock,
#if defined(CONFIG_CPU_SUBTYPE_SH7722)
	&sh7722_irda_clock,
#endif
	&sh7722_video_clock,
};

/*
 * init in order: master, module, bus, cpu
 */
struct clk_ops *onchip_ops[] = {
	&sh7722_master_clk_ops,
	&sh7722_module_clk_ops,
	&sh7722_frqcr_clk_ops,
	&sh7722_frqcr_clk_ops,
};

void __init
arch_init_clk_ops(struct clk_ops **ops, int type)
{
	BUG_ON(type < 0 || type > ARRAY_SIZE(onchip_ops));
	*ops = onchip_ops[type];
}

int __init arch_clk_init(void)
{
	struct clk *master;
	int i;

	master = clk_get(NULL, "master_clk");
	for (i = 0; i < ARRAY_SIZE(sh7722_clocks); i++) {
		pr_debug( "Registering clock '%s'\n", sh7722_clocks[i]->name);
		sh7722_clocks[i]->parent = master;
		clk_register(sh7722_clocks[i]);
	}
	clk_put(master);
	return 0;
}
