/*
 *  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 "prcm-regs.h"
#include "memory.h"
#include "clock.h"

//#define DOWN_VARIABLE_DPLL 1			/* Experimental */

static struct prcm_config *curr_prcm_set;
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)
{
	long long dpll_clk;
	int 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 = (long long)tclk->parent->rate * dpll_mult;
	do_div(dpll_clk, 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_enable(struct clk *clk)
{
	int ret = 0;

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

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

		ret = _omap2_clk_enable(clk);

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

	return ret;
}

static void omap2_clk_disable(struct clk *clk)
{
	if (clk->usecount > 0 && !(--clk->usecount)) {
		_omap2_clk_disable(clk);
		if (likely((u32)clk->parent))
			omap2_clk_disable(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 u32 omap2_reprogram_sdrc(u32 level, u32 force)
{
	u32 slow_dll_ctrl, fast_dll_ctrl, m_type;
	u32 prev = curr_perf_level, flags;

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

	m_type = omap2_memory_get_type();
	slow_dll_ctrl = omap2_memory_get_slow_dll_ctrl();
	fast_dll_ctrl = omap2_memory_get_fast_dll_ctrl();

	if (level == PRCM_HALF_SPEED) {
		local_irq_save(flags);
		PRCM_VOLTSETUP = 0xffff;
		omap2_sram_reprogram_sdrc(PRCM_HALF_SPEED,
					  slow_dll_ctrl, 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,
					  fast_dll_ctrl, 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 = 0x7; 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_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_enable(&sync_32k_ick);
	clk_enable(&omapctrl_ick);
	if (cpu_is_omap2430())
		clk_enable(&sdrc_ick);

	return 0;
}
