/*
 *  linux/arch/arm/mach-omap2/clock.c
 *
 *  Copyright (C) 2005 Texas Instruments Inc.
 *  Richard Woodruff <r-woodruff2@ti.com>
 *  Created for OMAP2.
 *
 *  Cleaned up and modified to use omap shared clock framework by
 *  Tony Lindgren <tony@atomide.com>
 *
 *  Based on omap1 clock.c, Copyright (C) 2004 - 2005 Nokia corporation
 *  Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/list.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/clk.h>

#include <asm/io.h>

#include <asm/arch/clock.h>
#include <asm/arch/sram.h>
#include <asm/arch/prcm.h>

#include "clock.h"

//#define DOWN_VARIABLE_DPLL 1			/* Experimental */

static struct prcm_config *curr_prcm_set;
static struct memory_timings mem_timings;
static u32 curr_perf_level = PRCM_FULL_SPEED;

/*-------------------------------------------------------------------------
 * Omap2 specific clock functions
 *-------------------------------------------------------------------------*/

/* Recalculate SYST_CLK */
static void omap2_sys_clk_recalc(struct clk * clk)
{
	u32 div = PRCM_CLKSRC_CTRL;
	div &= (1 << 7) | (1 << 6);	/* Test if ext clk divided by 1 or 2 */
	div >>= clk->rate_offset;
	clk->rate = (clk->parent->rate / div);
	propagate_rate(clk);
}

static u32 omap2_get_dpll_rate(struct clk * tclk)
{
	int dpll_clk, dpll_mult, dpll_div, amult;

	dpll_mult = (CM_CLKSEL1_PLL >> 12) & 0x03ff;	/* 10 bits */
	dpll_div = (CM_CLKSEL1_PLL >> 8) & 0x0f;	/* 4 bits */
	dpll_clk = (tclk->parent->rate * dpll_mult) / (dpll_div + 1);
	amult = CM_CLKSEL2_PLL & 0x3;
	dpll_clk *= amult;

	return dpll_clk;
}

static void omap2_followparent_recalc(struct clk *clk)
{
	followparent_recalc(clk);
}

static void omap2_propagate_rate(struct clk * clk)
{
	if (!(clk->flags & RATE_FIXED))
		clk->rate = clk->parent->rate;

	propagate_rate(clk);
}

/* Enable an APLL if off */
static void omap2_clk_fixed_enable(struct clk *clk)
{
	u32 cval, i=0;

	if (clk->enable_bit == 0xff)			/* Parent will do it */
		return;

	cval = CM_CLKEN_PLL;

	if ((cval & (0x3 << clk->enable_bit)) == (0x3 << clk->enable_bit))
		return;

	cval &= ~(0x3 << clk->enable_bit);
	cval |= (0x3 << clk->enable_bit);
	CM_CLKEN_PLL = cval;

	if (clk == &apll96_ck)
		cval = (1 << 8);
	else if (clk == &apll54_ck)
		cval = (1 << 6);

	while (!CM_IDLEST_CKGEN & cval) {		/* Wait for lock */
		++i;
		udelay(1);
		if (i == 100000)
			break;
	}
}

/* Enables clock without considering parent dependencies or use count
 * REVISIT: Maybe change this to use clk->enable like on omap1?
 */
static int omap2_clk_enable(struct clk * clk)
{
	u32 regval32;

	if (clk->flags & ALWAYS_ENABLED)
		return 0;

	if (unlikely(clk->enable_reg == 0)) {
		printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
		       clk->name);
		return 0;
	}

	if (clk->enable_reg == (void __iomem *)&CM_CLKEN_PLL) {
		omap2_clk_fixed_enable(clk);
		return 0;
	}

	regval32 = __raw_readl(clk->enable_reg);
	regval32 |= (1 << clk->enable_bit);
	__raw_writel(regval32, clk->enable_reg);

	return 0;
}

/* Stop APLL */
static void omap2_clk_fixed_disable(struct clk *clk)
{
	u32 cval;

	if(clk->enable_bit == 0xff)		/* let parent off do it */
		return;

	cval = CM_CLKEN_PLL;
	cval &= ~(0x3 << clk->enable_bit);
	CM_CLKEN_PLL = cval;
}

/* Disables clock without considering parent dependencies or use count */
static void omap2_clk_disable(struct clk *clk)
{
	u32 regval32;

	if (clk->enable_reg == 0)
		return;

	if (clk->enable_reg == (void __iomem *)&CM_CLKEN_PLL) {
		omap2_clk_fixed_disable(clk);
		return;
	}

	regval32 = __raw_readl(clk->enable_reg);
	regval32 &= ~(1 << clk->enable_bit);
	__raw_writel(regval32, clk->enable_reg);
}

static int omap2_clk_use(struct clk *clk)
{
	int ret = 0;

	if (clk->usecount++ == 0) {
		if (likely((u32)clk->parent))
			ret = omap2_clk_use(clk->parent);

		if (unlikely(ret != 0)) {
			clk->usecount--;
			return ret;
		}

		ret = omap2_clk_enable(clk);

		if (unlikely(ret != 0) && clk->parent) {
			omap2_clk_unuse(clk->parent);
			clk->usecount--;
		}
	}

	return ret;
}

static void omap2_clk_unuse(struct clk *clk)
{
	if (clk->usecount > 0 && !(--clk->usecount)) {
		omap2_clk_disable(clk);
		if (likely((u32)clk->parent))
			omap2_clk_unuse(clk->parent);
	}
}

/*
 * Uses the current prcm set to tell if a rate is valid.
 * You can go slower, but not faster within a given rate set.
 */
static u32 omap2_dpll_round_rate(unsigned long target_rate)
{
	u32 high, low;

	if ((CM_CLKSEL2_PLL & 0x3) == 1) {	/* DPLL clockout */
		high = curr_prcm_set->dpll_speed * 2;
		low = curr_prcm_set->dpll_speed;
	} else {				/* DPLL clockout x 2 */
		high = curr_prcm_set->dpll_speed;
		low = curr_prcm_set->dpll_speed / 2;
	}

#ifdef DOWN_VARIABLE_DPLL
	if (target_rate > high)
		return high;
	else
		return target_rate;
#else
	if (target_rate > low)
		return high;
	else
		return low;
#endif

}

/*
 * Used for clocks that are part of CLKSEL_xyz governed clocks.
 * REVISIT: Maybe change to use clk->enable() functions like on omap1?
 */
static void omap2_clksel_recalc(struct clk * clk)
{
	u32 fixed = 0, div = 0;

	if (clk == &dpll_ck) {
		clk->rate = omap2_get_dpll_rate(clk);
		fixed = 1;
		div = 0;
	}

	if (clk == &iva1_mpu_int_ifck) {
		div = 2;
		fixed = 1;
	}

	if ((clk == &dss1_fck) && ((CM_CLKSEL1_CORE & (0x1f << 8)) == 0)) {
		clk->rate = sys_ck.rate;
		return;
	}

	if (!fixed) {
		div = omap2_clksel_get_divisor(clk);
		if (div == 0)
			return;
	}

	if (div != 0) {
		if (unlikely(clk->rate == clk->parent->rate / div))
			return;
		clk->rate = clk->parent->rate / div;
	}

	if (unlikely(clk->flags & RATE_PROPAGATES))
		propagate_rate(clk);
}

/*
 * Finds best divider value in an array based on the source and target
 * rates. The divider array must be sorted with smallest divider first.
 */
static inline u32 omap2_divider_from_table(u32 size, u32 *div_array,
					   u32 src_rate, u32 tgt_rate)
{
	int i, test_rate;

	if (div_array == NULL)
		return ~1;

	for (i=0; i < size; i++) {
		test_rate = src_rate / *div_array;
		if (test_rate <= tgt_rate)
			return *div_array;
		++div_array;
	}

	return ~0;	/* No acceptable divider */
}

/*
 * Find divisor for the given clock and target rate.
 *
 * Note that this will not work for clocks which are part of CONFIG_PARTICIPANT,
 * they are only settable as part of virtual_prcm set.
 */
static u32 omap2_clksel_round_rate(struct clk *tclk, u32 target_rate,
	u32 *new_div)
{
	u32 gfx_div[] = {2, 3, 4};
	u32 sysclkout_div[] = {1, 2, 4, 8, 16};
	u32 dss1_div[] = {1, 2, 3, 4, 5, 6, 8, 9, 12, 16};
	u32 vylnq_div[] = {1, 2, 3, 4, 6, 8, 9, 12, 16, 18};
	u32 best_div = ~0, asize = 0;
	u32 *div_array = NULL;

	switch (tclk->flags & SRC_RATE_SEL_MASK) {
	case CM_GFX_SEL1:
		asize = 3;
		div_array = gfx_div;
		break;
	case CM_PLL_SEL1:
		return omap2_dpll_round_rate(target_rate);
	case CM_SYSCLKOUT_SEL1:
		asize = 5;
		div_array = sysclkout_div;
		break;
	case CM_CORE_SEL1:
		if(tclk == &dss1_fck){
			if(tclk->parent == &core_ck){
				asize = 10;
				div_array = dss1_div;
			} else {
				*new_div = 0; /* fixed clk */
				return(tclk->parent->rate);
			}
		} else if((tclk == &vlynq_fck) && cpu_is_omap2420()){
			if(tclk->parent == &core_ck){
				asize = 10;
				div_array = vylnq_div;
			} else {
				*new_div = 0; /* fixed clk */
				return(tclk->parent->rate);
			}
		}
		break;
	}

	best_div = omap2_divider_from_table(asize, div_array,
	 tclk->parent->rate, target_rate);
	if (best_div == ~0){
		*new_div = 1;
		return best_div; /* signal error */
	}

	*new_div = best_div;
	return (tclk->parent->rate / best_div);
}

/* Given a clock and a rate apply a clock specific rounding function */
static long omap2_clk_round_rate(struct clk *clk, unsigned long rate)
{
	u32 new_div = 0;
	int valid_rate;

	if (clk->flags & RATE_FIXED)
		return clk->rate;

	if (clk->flags & RATE_CKCTL) {
		valid_rate = omap2_clksel_round_rate(clk, rate, &new_div);
		return valid_rate;
	}

	if (clk->round_rate != 0)
		return clk->round_rate(clk, rate);

	return clk->rate;
}

/*
 * Check the DLL lock state, and return tue if running in unlock mode.
 * This is needed to compenste for the shifted DLL value in unlock mode.
 */
static u32 omap2_dll_force_needed(void)
{
	u32 dll_state = SDRC_DLLA_CTRL;		/* dlla and dllb are a set */

	if ((dll_state & (1 << 2)) == (1 << 2))
		return 1;
	else
		return 0;
}

static void omap2_init_memory_params(u32 force_lock_to_unlock_mode)
{
	unsigned long dll_cnt;
	u32 fast_dll = 0;

	mem_timings.m_type = !((SDRC_MR_0 & 0x3) == 0x1); /* DDR = 1, SDR = 0 */

	/* 2422 es2.05 and beyond has a single SIP DDR instead of 2 like others.
	 * In the case of 2422, its ok to use CS1 instead of CS0.
	 */

#if 0	/* FIXME: Enable after 24xx cpu detection works */
	ctype = get_cpu_type();
	if (cpu_is_omap2422())
		mem_timings.base_cs = 1;
	else
#endif
		mem_timings.base_cs = 0;

	if (mem_timings.m_type != M_DDR)
		return;

	/* With DDR we need to determine the low frequency DLL value */
	if (((mem_timings.fast_dll_ctrl & (1 << 2)) == M_LOCK_CTRL))
		mem_timings.dll_mode = M_UNLOCK;
	else
		mem_timings.dll_mode = M_LOCK;

	if (mem_timings.base_cs == 0) {
		fast_dll = SDRC_DLLA_CTRL;
		dll_cnt = SDRC_DLLA_STATUS & 0xff00;
	} else {
		fast_dll = SDRC_DLLB_CTRL;
		dll_cnt = SDRC_DLLB_STATUS & 0xff00;
	}
	if (force_lock_to_unlock_mode) {
		fast_dll &= ~0xff00;
		fast_dll |= dll_cnt;		/* Current lock mode */
	}
	mem_timings.fast_dll_ctrl = fast_dll;

	/* No disruptions, DDR will be offline & C-ABI not followed */
	omap2_sram_ddr_init(&mem_timings.slow_dll_ctrl,
			    mem_timings.fast_dll_ctrl,
			    mem_timings.base_cs,
			    force_lock_to_unlock_mode);
	mem_timings.slow_dll_ctrl &= 0xff00;	/* Keep lock value */

	/* Turn status into unlock ctrl */
	mem_timings.slow_dll_ctrl |=
		((mem_timings.fast_dll_ctrl & 0xF) | (1 << 2));

	/* 90 degree phase for anything below 133Mhz */
	mem_timings.slow_dll_ctrl |= (1 << 1);
}

static u32 omap2_reprogram_sdrc(u32 level, u32 force)
{
	u32 prev = curr_perf_level, flags;

	if ((curr_perf_level == level) && !force)
		return prev;

	if (level == PRCM_HALF_SPEED) {
		local_irq_save(flags);
		PRCM_VOLTSETUP = 0xffff;
		omap2_sram_reprogram_sdrc(PRCM_HALF_SPEED,
					  mem_timings.slow_dll_ctrl,
					  mem_timings.m_type);
		curr_perf_level = PRCM_HALF_SPEED;
		local_irq_restore(flags);
	}
	if (level == PRCM_FULL_SPEED) {
		local_irq_save(flags);
		PRCM_VOLTSETUP = 0xffff;
		omap2_sram_reprogram_sdrc(PRCM_FULL_SPEED,
					  mem_timings.fast_dll_ctrl,
					  mem_timings.m_type);
		curr_perf_level = PRCM_FULL_SPEED;
		local_irq_restore(flags);
	}

	return prev;
}

static int omap2_reprogram_dpll(struct clk * clk, unsigned long rate)
{
	u32 flags, cur_rate, low, mult, div, valid_rate, done_rate;
	u32 bypass = 0;
	struct prcm_config tmpset;
	int ret = -EINVAL;

	local_irq_save(flags);
	cur_rate = omap2_get_dpll_rate(&dpll_ck);
	mult = CM_CLKSEL2_PLL & 0x3;

	if ((rate == (cur_rate / 2)) && (mult == 2)) {
		omap2_reprogram_sdrc(PRCM_HALF_SPEED, 1);
	} else if ((rate == (cur_rate * 2)) && (mult == 1)) {
		omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1);
	} else if (rate != cur_rate) {
		valid_rate = omap2_dpll_round_rate(rate);
		if (valid_rate != rate)
			goto dpll_exit;

		if ((CM_CLKSEL2_PLL & 0x3) == 1)
			low = curr_prcm_set->dpll_speed;
		else
			low = curr_prcm_set->dpll_speed / 2;

		tmpset.cm_clksel1_pll = CM_CLKSEL1_PLL;
		tmpset.cm_clksel1_pll &= ~(0x3FFF << 8);
		div = ((curr_prcm_set->xtal_speed / 1000000) - 1);
		tmpset.cm_clksel2_pll = CM_CLKSEL2_PLL;
		tmpset.cm_clksel2_pll &= ~0x3;
		if (rate > low) {
			tmpset.cm_clksel2_pll |= 0x2;
			mult = ((rate / 2) / 1000000);
			done_rate = PRCM_FULL_SPEED;
		} else {
			tmpset.cm_clksel2_pll |= 0x1;
			mult = (rate / 1000000);
			done_rate = PRCM_HALF_SPEED;
		}
		tmpset.cm_clksel1_pll |= ((div << 8) | (mult << 12));

		/* Worst case */
		tmpset.base_sdrc_rfr = V24XX_SDRC_RFR_CTRL_BYPASS;

		if (rate == curr_prcm_set->xtal_speed)	/* If asking for 1-1 */
			bypass = 1;

		omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1); /* For init_mem */

		/* Force dll lock mode */
		omap2_set_prcm(tmpset.cm_clksel1_pll, tmpset.base_sdrc_rfr,
			       bypass);

		/* Errata: ret dll entry state */
		omap2_init_memory_params(omap2_dll_force_needed());
		omap2_reprogram_sdrc(done_rate, 0);
	}
	omap2_clksel_recalc(&dpll_ck);
	ret = 0;

dpll_exit:
	local_irq_restore(flags);
	return(ret);
}

/* Just return the MPU speed */
static void omap2_mpu_recalc(struct clk * clk)
{
	clk->rate = curr_prcm_set->mpu_speed;
}

/*
 * Look for a rate equal or less than the target rate given a configuration set.
 *
 * What's not entirely clear is "which" field represents the key field.
 * Some might argue L3-DDR, others ARM, others IVA. This code is simple and
 * just uses the ARM rates.
 */
static long omap2_round_to_table_rate(struct clk * clk, unsigned long rate)
{
	struct prcm_config * ptr;
	long highest_rate;

	if (clk != &virt_prcm_set)
		return -EINVAL;

	highest_rate = -EINVAL;

	for (ptr = rate_table; ptr->mpu_speed; ptr++) {
		if (ptr->xtal_speed != sys_ck.rate)
			continue;

		highest_rate = ptr->mpu_speed;

		/* Can check only after xtal frequency check */
		if (ptr->mpu_speed <= rate)
			break;
	}
	return highest_rate;
}

/*
 * omap2_convert_field_to_div() - turn field value into integer divider
 */
static u32 omap2_clksel_to_divisor(u32 div_sel, u32 field_val)
{
	u32 i;
	u32 clkout_array[] = {1, 2, 4, 8, 16};

	if ((div_sel & SRC_RATE_SEL_MASK) == CM_SYSCLKOUT_SEL1) {
		for (i = 0; i < 5; i++) {
			if (field_val == i)
				return clkout_array[i];
		}
		return ~0;
	} else
		return field_val;
}

/*
 * Returns the CLKSEL divider register value
 * REVISIT: This should be cleaned up to work nicely with void __iomem *
 */
static u32 omap2_get_clksel(u32 *div_sel, u32 *field_mask,
			    struct clk *clk)
{
	int ret = ~0;
	u32 reg_val, div_off;
	u32 div_addr = 0;
	u32 mask = ~0;

	div_off = clk->rate_offset;

	switch ((*div_sel & SRC_RATE_SEL_MASK)) {
	case CM_MPU_SEL1:
		div_addr = (u32)&CM_CLKSEL_MPU;
		mask = 0x1f;
		break;
	case CM_DSP_SEL1:
		div_addr = (u32)&CM_CLKSEL_DSP;
		if (cpu_is_omap2420()) {
			if ((div_off == 0) || (div_off == 8))
				mask = 0x1f;
			else if (div_off == 5)
				mask = 0x3;
		} else if (cpu_is_omap2430()) {
			if (div_off == 0)
				mask = 0x1f;
			else if (div_off == 5)
				mask = 0x3;
		}
		break;
	case CM_GFX_SEL1:
		div_addr = (u32)&CM_CLKSEL_GFX;
		if (div_off == 0)
			mask = 0x7;
		break;
	case CM_MODEM_SEL1:
		div_addr = (u32)&CM_CLKSEL_MDM;
		if (div_off == 0)
			mask = 0xf;
		break;
	case CM_SYSCLKOUT_SEL1:
		div_addr = (u32)&PRCM_CLKOUT_CTRL;
		if ((div_off == 3) || (div_off = 11))
			mask= 0x3;
		break;
	case CM_CORE_SEL1:
		div_addr = (u32)&CM_CLKSEL1_CORE;
		switch (div_off) {
		case 0:					/* l3 */
		case 8:					/* dss1 */
		case 15:				/* vylnc-2420 */
		case 20:				/* ssi */
			mask = 0x1f; break;
		case 5:					/* l4 */
			mask = 0x3; break;
		case 13:				/* dss2 */
			mask = 0x1; break;
		case 25:				/* usb */
			mask = 0xf; break;
		}
	}

	*field_mask = mask;

	if (unlikely(mask == ~0))
		div_addr = 0;

	*div_sel = div_addr;

	if (unlikely(div_addr == 0))
		return ret;

	/* Isolate field */
	reg_val = __raw_readl((void __iomem *)div_addr) & (mask << div_off);

	/* Normalize back to divider value */
	reg_val >>= div_off;

	return reg_val;
}

/*
 * Return divider to be applied to parent clock.
 * Return 0 on error.
 */
static u32 omap2_clksel_get_divisor(struct clk *clk)
{
	int ret = 0;
	u32 div, div_sel, div_off, field_mask, field_val;

	/* isolate control register */
	div_sel = (SRC_RATE_SEL_MASK & clk->flags);

	div_off = clk->rate_offset;
	field_val = omap2_get_clksel(&div_sel, &field_mask, clk);
	if (div_sel == 0)
		return ret;

	div_sel = (SRC_RATE_SEL_MASK & clk->flags);
	div = omap2_clksel_to_divisor(div_sel, field_val);

	return div;
}

/* Set the clock rate for a clock source */
static int omap2_clk_set_rate(struct clk *clk, unsigned long rate)

{
	int ret = -EINVAL;
	void __iomem * reg;
	u32 div_sel, div_off, field_mask, field_val, reg_val, validrate;
	u32 new_div = 0;

	if (!(clk->flags & CONFIG_PARTICIPANT) && (clk->flags & RATE_CKCTL)) {
		if (clk == &dpll_ck)
			return omap2_reprogram_dpll(clk, rate);

		/* Isolate control register */
		div_sel = (SRC_RATE_SEL_MASK & clk->flags);
		div_off = clk->src_offset;

		validrate = omap2_clksel_round_rate(clk, rate, &new_div);
		if(validrate != rate)
			return(ret);

		field_val = omap2_get_clksel(&div_sel, &field_mask, clk);
		if (div_sel == 0)
			return ret;

		if(clk->flags & CM_SYSCLKOUT_SEL1){
			switch(new_div){
			case 16: field_val = 4; break;
			case 8:  field_val = 3; break;
			case 4:  field_val = 2; break;
			case 2:  field_val = 1; break;
			case 1:  field_val = 0; break;
			}
		}
		else
			field_val = new_div;

		reg = (void __iomem *)div_sel;

		reg_val = __raw_readl(reg);
		reg_val &= ~(field_mask << div_off);
		reg_val |= (field_val << div_off);

		__raw_writel(reg_val, reg);
		clk->rate = clk->parent->rate / field_val;

		if (clk->flags & DELAYED_APP)
			__raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL);
		ret = 0;
	} else if (clk->set_rate != 0)
		ret = clk->set_rate(clk, rate);

	if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
		propagate_rate(clk);

	return ret;
}

/* Converts encoded control register address into a full address */
static u32 omap2_get_src_field(u32 *type_to_addr, u32 reg_offset,
			       struct clk *src_clk, u32 *field_mask)
{
	u32 val = ~0, src_reg_addr = 0, mask = 0;

	/* Find target control register.*/
	switch ((*type_to_addr & SRC_RATE_SEL_MASK)) {
	case CM_CORE_SEL1:
		src_reg_addr = (u32)&CM_CLKSEL1_CORE;
		if (reg_offset == 13) {			/* DSS2_fclk */
			mask = 0x1;
			if (src_clk == &sys_ck)
				val = 0;
			if (src_clk == &func_48m_ck)
				val = 1;
		} else if (reg_offset == 8) {		/* DSS1_fclk */
			mask = 0x1f;
			if (src_clk == &sys_ck)
				val = 0;
			else if (src_clk == &core_ck)	/* divided clock */
				val = 0x10;		/* rate needs fixing */
		} else if ((reg_offset == 15) && cpu_is_omap2420()){ /*vlnyq*/
			mask = 0x1F;
			if(src_clk == &func_96m_ck)
				val = 0;
			else if (src_clk == &core_ck)
				val = 0x10;
		}
		break;
	case CM_CORE_SEL2:
		src_reg_addr = (u32)&CM_CLKSEL2_CORE;
		mask = 0x3;
		if (src_clk == &func_32k_ck)
			val = 0x0;
		if (src_clk == &sys_ck)
			val = 0x1;
		if (src_clk == &alt_ck)
			val = 0x2;
		break;
	case CM_WKUP_SEL1:
		src_reg_addr = (u32)&CM_CLKSEL2_CORE;
		mask = 0x3;
		if (src_clk == &func_32k_ck)
			val = 0x0;
		if (src_clk == &sys_ck)
			val = 0x1;
		if (src_clk == &alt_ck)
			val = 0x2;
		break;
	case CM_PLL_SEL1:
		src_reg_addr = (u32)&CM_CLKSEL1_PLL;
		mask = 0x1;
		if (reg_offset == 0x3) {
			if (src_clk == &apll96_ck)
				val = 0;
			if (src_clk == &alt_ck)
				val = 1;
		}
		else if (reg_offset == 0x5) {
			if (src_clk == &apll54_ck)
				val = 0;
			if (src_clk == &alt_ck)
				val = 1;
		}
		break;
	case CM_PLL_SEL2:
		src_reg_addr = (u32)&CM_CLKSEL2_PLL;
		mask = 0x3;
		if (src_clk == &func_32k_ck)
			val = 0x0;
		if (src_clk == &dpll_ck)
			val = 0x2;
		break;
	case CM_SYSCLKOUT_SEL1:
		src_reg_addr = (u32)&PRCM_CLKOUT_CTRL;
		mask = 0x3;
		if (src_clk == &dpll_ck)
			val = 0;
		if (src_clk == &sys_ck)
			val = 1;
		if (src_clk == &func_54m_ck)
			val = 2;
		if (src_clk == &func_96m_ck)
			val = 3;
		break;
	}

	if (val == ~0)			/* Catch errors in offset */
		*type_to_addr = 0;
	else
		*type_to_addr = src_reg_addr;
	*field_mask = mask;

	return val;
}

static int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
{
	void __iomem * reg;
	u32 src_sel, src_off, field_val, field_mask, reg_val, rate;
	int ret = -EINVAL;

	if (unlikely(clk->flags & CONFIG_PARTICIPANT))
		return ret;

	if (clk->flags & SRC_SEL_MASK) {	/* On-chip SEL collection */
		src_sel = (SRC_RATE_SEL_MASK & clk->flags);
		src_off = clk->src_offset;

		if (src_sel == 0)
			goto set_parent_error;

		field_val = omap2_get_src_field(&src_sel, src_off, new_parent,
						&field_mask);

		reg = (void __iomem *)src_sel;

		if (clk->usecount > 0)
			omap2_clk_disable(clk);

		/* Set new source value (previous dividers if any in effect) */
		reg_val = __raw_readl(reg) & ~(field_mask << src_off);
		reg_val |= (field_val << src_off);
		__raw_writel(reg_val, reg);

		if (clk->flags & DELAYED_APP)
			__raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL);

		if (clk->usecount > 0)
			omap2_clk_enable(clk);

		clk->parent = new_parent;

		/* SRC_RATE_SEL_MASK clocks follow their parents rates.*/
		if ((new_parent == &core_ck) && (clk == &dss1_fck))
			clk->rate = new_parent->rate / 0x10;
		else
			clk->rate = new_parent->rate;

		if (unlikely(clk->flags & RATE_PROPAGATES))
			propagate_rate(clk);

		return 0;
	} else {
		clk->parent = new_parent;
		rate = new_parent->rate;
		omap2_clk_set_rate(clk, rate);
		ret = 0;
	}

 set_parent_error:
	return ret;
}

/* Sets basic clocks based on the specified rate */
static int omap2_select_table_rate(struct clk * clk, unsigned long rate)
{
	u32 flags, cur_rate, done_rate, bypass = 0;
	u8 cpu_mask = 0;
	struct prcm_config *prcm;
	unsigned long found_speed = 0;

	if (clk != &virt_prcm_set)
		return -EINVAL;

	/* FIXME: Change cpu_is_omap2420() to cpu_is_omap242x() */
	if (cpu_is_omap2420())
		cpu_mask = RATE_IN_242X;
	else if (cpu_is_omap2430())
		cpu_mask = RATE_IN_243X;

	for (prcm = rate_table; prcm->mpu_speed; prcm++) {
		if (!(prcm->flags & cpu_mask))
			continue;

		if (prcm->xtal_speed != sys_ck.rate)
			continue;

		if (prcm->mpu_speed <= rate) {
			found_speed = prcm->mpu_speed;
			break;
		}
	}

	if (!found_speed) {
		printk(KERN_INFO "Could not set MPU rate to %luMHz\n",
	 rate / 1000000);
		return -EINVAL;
	}

	curr_prcm_set = prcm;
	cur_rate = omap2_get_dpll_rate(&dpll_ck);

	if (prcm->dpll_speed == cur_rate / 2) {
		omap2_reprogram_sdrc(PRCM_HALF_SPEED, 1);
	} else if (prcm->dpll_speed == cur_rate * 2) {
		omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1);
	} else if (prcm->dpll_speed != cur_rate) {
		local_irq_save(flags);

		if (prcm->dpll_speed == prcm->xtal_speed)
			bypass = 1;

		if ((prcm->cm_clksel2_pll & 0x3) == 2)
			done_rate = PRCM_FULL_SPEED;
		else
			done_rate = PRCM_HALF_SPEED;

		/* MPU divider */
		CM_CLKSEL_MPU = prcm->cm_clksel_mpu;

		/* dsp + iva1 div(2420), iva2.1(2430) */
		CM_CLKSEL_DSP = prcm->cm_clksel_dsp;

		CM_CLKSEL_GFX = prcm->cm_clksel_gfx;

		/* Major subsystem dividers */
		CM_CLKSEL1_CORE = prcm->cm_clksel1_core;
		if (cpu_is_omap2430())
			CM_CLKSEL_MDM = prcm->cm_clksel_mdm;

		/* x2 to enter init_mem */
		omap2_reprogram_sdrc(PRCM_FULL_SPEED, 1);

		omap2_set_prcm(prcm->cm_clksel1_pll, prcm->base_sdrc_rfr,
			       bypass);

		omap2_init_memory_params(omap2_dll_force_needed());
		omap2_reprogram_sdrc(done_rate, 0);

		local_irq_restore(flags);
	}
	omap2_clksel_recalc(&dpll_ck);

	return 0;
}

/*-------------------------------------------------------------------------
 * Omap2 clock reset and init functions
 *-------------------------------------------------------------------------*/

static struct clk_functions omap2_clk_functions = {
	.clk_enable		= omap2_clk_enable,
	.clk_disable		= omap2_clk_disable,
	.clk_use		= omap2_clk_use,
	.clk_unuse		= omap2_clk_unuse,
	.clk_round_rate		= omap2_clk_round_rate,
	.clk_set_rate		= omap2_clk_set_rate,
	.clk_set_parent		= omap2_clk_set_parent,
};

static void __init omap2_get_crystal_rate(struct clk *osc, struct clk *sys)
{
	u32 div, aplls, sclk = 13000000;

	aplls = CM_CLKSEL1_PLL;
	aplls &= ((1 << 23) | (1 << 24) | (1 << 25));
	aplls >>= 23;			/* Isolate field, 0,2,3 */

	if (aplls == 0)
		sclk = 19200000;
	else if (aplls == 2)
		sclk = 13000000;
	else if (aplls == 3)
		sclk = 12000000;

	div = PRCM_CLKSRC_CTRL;
	div &= ((1 << 7) | (1 << 6));
	div >>= sys->rate_offset;

	osc->rate = sclk * div;
	sys->rate = sclk;
}

#ifdef CONFIG_OMAP_RESET_CLOCKS
static void __init omap2_disable_unused_clocks(void)
{
	struct clk *ck;
	u32 regval32;

	list_for_each_entry(ck, &clocks, node) {
		if (ck->usecount > 0 || (ck->flags & ALWAYS_ENABLED) ||
			ck->enable_reg == 0)
			continue;

		regval32 = __raw_readl(ck->enable_reg);
		if ((regval32 & (1 << ck->enable_bit)) == 0)
			continue;

		printk(KERN_INFO "Disabling unused clock \"%s\"\n", ck->name);
		omap2_clk_disable(ck);
	}
}
late_initcall(omap2_disable_unused_clocks);
#endif

/*
 * Switch the MPU rate if specified on cmdline.
 * We cannot do this early until cmdline is parsed.
 */
static int __init omap2_clk_arch_init(void)
{
	if (!mpurate)
		return -EINVAL;

	if (omap2_select_table_rate(&virt_prcm_set, mpurate))
		printk(KERN_ERR "Could not find matching MPU rate\n");

	propagate_rate(&osc_ck);		/* update main root fast */
	propagate_rate(&func_32k_ck);		/* update main root slow */

	printk(KERN_INFO "Switched to new clocking rate (Crystal/DPLL/MPU): "
	       "%ld.%01ld/%ld/%ld MHz\n",
	       (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10,
	       (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ;

	return 0;
}
arch_initcall(omap2_clk_arch_init);

int __init omap2_clk_init(void)
{
	struct prcm_config *prcm;
	struct clk ** clkp;
	u32 clkrate;

	clk_init(&omap2_clk_functions);
	omap2_get_crystal_rate(&osc_ck, &sys_ck);

	for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks);
	     clkp++) {

		if ((*clkp)->flags & CLOCK_IN_OMAP242X && cpu_is_omap2420()) {
			clk_register(*clkp);
			continue;
		}

		if ((*clkp)->flags & CLOCK_IN_OMAP243X && cpu_is_omap2430()) {
			clk_register(*clkp);
			continue;
		}
	}

	/* Check the MPU rate set by bootloader */
	clkrate = omap2_get_dpll_rate(&dpll_ck);
	for (prcm = rate_table; prcm->mpu_speed; prcm++) {
		if (prcm->xtal_speed != sys_ck.rate)
			continue;
		if (prcm->dpll_speed <= clkrate)
			 break;
	}
	curr_prcm_set = prcm;

	propagate_rate(&osc_ck);		/* update main root fast */
	propagate_rate(&func_32k_ck);		/* update main root slow */

	printk(KERN_INFO "Clocking rate (Crystal/DPLL/MPU): "
	       "%ld.%01ld/%ld/%ld MHz\n",
	       (sys_ck.rate / 1000000), (sys_ck.rate / 100000) % 10,
	       (dpll_ck.rate / 1000000), (mpu_ck.rate / 1000000)) ;

	/*
	 * Only enable those clocks we will need, let the drivers
	 * enable other clocks as necessary
	 */
	clk_use(&sync_32k_ick);
	clk_use(&omapctrl_ick);
	if (cpu_is_omap2430())
		clk_use(&sdrc_ick);

	return 0;
}
