/*
 * OMAP2xxx APLL clock control functions
 *
 * Copyright (C) 2005-2008 Texas Instruments, Inc.
 * Copyright (C) 2004-2010 Nokia Corporation
 *
 * Contacts:
 * Richard Woodruff <r-woodruff2@ti.com>
 * Paul Walmsley
 *
 * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
 * Gordon McNutt and RidgeRun, Inc.
 *
 * 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.
 */
#undef DEBUG

#include <linux/kernel.h>
#include <linux/clk.h>
#include <linux/io.h>

#include <plat/clock.h>
#include <plat/prcm.h>

#include "clock.h"
#include "clock2xxx.h"
#include "cm2xxx_3xxx.h"
#include "cm-regbits-24xx.h"

/* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */
#define EN_APLL_STOPPED			0
#define EN_APLL_LOCKED			3

/* CM_CLKSEL1_PLL.APLLS_CLKIN options (24XX) */
#define APLLS_CLKIN_19_2MHZ		0
#define APLLS_CLKIN_13MHZ		2
#define APLLS_CLKIN_12MHZ		3

void __iomem *cm_idlest_pll;

/* Private functions */

/* Enable an APLL if off */
static int omap2_clk_apll_enable(struct clk *clk, u32 status_mask)
{
	u32 cval, apll_mask;

	apll_mask = EN_APLL_LOCKED << clk->enable_bit;

	cval = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);

	if ((cval & apll_mask) == apll_mask)
		return 0;   /* apll already enabled */

	cval &= ~apll_mask;
	cval |= apll_mask;
	omap2_cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);

	omap2_cm_wait_idlest(cm_idlest_pll, status_mask,
			     OMAP24XX_CM_IDLEST_VAL, clk->name);

	/*
	 * REVISIT: Should we return an error code if omap2_wait_clock_ready()
	 * fails?
	 */
	return 0;
}

static int omap2_clk_apll96_enable(struct clk *clk)
{
	return omap2_clk_apll_enable(clk, OMAP24XX_ST_96M_APLL_MASK);
}

static int omap2_clk_apll54_enable(struct clk *clk)
{
	return omap2_clk_apll_enable(clk, OMAP24XX_ST_54M_APLL_MASK);
}

static void _apll96_allow_idle(struct clk *clk)
{
	omap2xxx_cm_set_apll96_auto_low_power_stop();
}

static void _apll96_deny_idle(struct clk *clk)
{
	omap2xxx_cm_set_apll96_disable_autoidle();
}

static void _apll54_allow_idle(struct clk *clk)
{
	omap2xxx_cm_set_apll54_auto_low_power_stop();
}

static void _apll54_deny_idle(struct clk *clk)
{
	omap2xxx_cm_set_apll54_disable_autoidle();
}

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

	cval = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
	cval &= ~(EN_APLL_LOCKED << clk->enable_bit);
	omap2_cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN);
}

/* Public data */

const struct clkops clkops_apll96 = {
	.enable		= omap2_clk_apll96_enable,
	.disable	= omap2_clk_apll_disable,
	.allow_idle	= _apll96_allow_idle,
	.deny_idle	= _apll96_deny_idle,
};

const struct clkops clkops_apll54 = {
	.enable		= omap2_clk_apll54_enable,
	.disable	= omap2_clk_apll_disable,
	.allow_idle	= _apll54_allow_idle,
	.deny_idle	= _apll54_deny_idle,
};

/* Public functions */

u32 omap2xxx_get_apll_clkin(void)
{
	u32 aplls, srate = 0;

	aplls = omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL1);
	aplls &= OMAP24XX_APLLS_CLKIN_MASK;
	aplls >>= OMAP24XX_APLLS_CLKIN_SHIFT;

	if (aplls == APLLS_CLKIN_19_2MHZ)
		srate = 19200000;
	else if (aplls == APLLS_CLKIN_13MHZ)
		srate = 13000000;
	else if (aplls == APLLS_CLKIN_12MHZ)
		srate = 12000000;

	return srate;
}

