/*
 * clkt_clksel.c - OMAP2/3/4 clksel clock functions
 *
 * Copyright (C) 2005-2008 Texas Instruments, Inc.
 * Copyright (C) 2004-2010 Nokia Corporation
 *
 * Contacts:
 * Richard Woodruff <r-woodruff2@ti.com>
 * Paul Walmsley
 *
 * 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.
 *
 *
 * clksel clocks are clocks that do not have a fixed parent, or that
 * can divide their parent's rate, or possibly both at the same time, based
 * on the contents of a hardware register bitfield.
 *
 * All of the various mux and divider settings can be encoded into
 * struct clksel* data structures, and then these can be autogenerated
 * from some hardware database for each new chip generation.  This
 * should avoid the need to write, review, and validate a lot of new
 * clock code for each new chip, since it can be exported from the SoC
 * design flow.  This is now done on OMAP4.
 *
 * The fusion of mux and divider clocks is a software creation.  In
 * hardware reality, the multiplexer (parent selection) and the
 * divider exist separately.  XXX At some point these clksel clocks
 * should be split into "divider" clocks and "mux" clocks to better
 * match the hardware.
 *
 * (The name "clksel" comes from the name of the corresponding
 * register field in the OMAP2/3 family of SoCs.)
 *
 * XXX Currently these clocks are only used in the OMAP2/3/4 code, but
 * many of the OMAP1 clocks should be convertible to use this
 * mechanism.
 */
#undef DEBUG

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

#include <plat/clock.h>

#include "clock.h"

/* Private functions */

/**
 * _get_clksel_by_parent() - return clksel struct for a given clk & parent
 * @clk: OMAP struct clk ptr to inspect
 * @src_clk: OMAP struct clk ptr of the parent clk to search for
 *
 * Scan the struct clksel array associated with the clock to find
 * the element associated with the supplied parent clock address.
 * Returns a pointer to the struct clksel on success or NULL on error.
 */
static const struct clksel *_get_clksel_by_parent(struct clk *clk,
						  struct clk *src_clk)
{
	const struct clksel *clks;

	for (clks = clk->clksel; clks->parent; clks++)
		if (clks->parent == src_clk)
			break; /* Found the requested parent */

	if (!clks->parent) {
		/* This indicates a data problem */
		WARN(1, "clock: Could not find parent clock %s in clksel array "
		     "of clock %s\n", src_clk->name, clk->name);
		return NULL;
	}

	return clks;
}

/**
 * _get_div_and_fieldval() - find the new clksel divisor and field value to use
 * @src_clk: planned new parent struct clk *
 * @clk: struct clk * that is being reparented
 * @field_val: pointer to a u32 to contain the register data for the divisor
 *
 * Given an intended new parent struct clk * @src_clk, and the struct
 * clk * @clk to the clock that is being reparented, find the
 * appropriate rate divisor for the new clock (returned as the return
 * value), and the corresponding register bitfield data to program to
 * reach that divisor (returned in the u32 pointed to by @field_val).
 * Returns 0 on error, or returns the newly-selected divisor upon
 * success (in this latter case, the corresponding register bitfield
 * value is passed back in the variable pointed to by @field_val)
 */
static u8 _get_div_and_fieldval(struct clk *src_clk, struct clk *clk,
				u32 *field_val)
{
	const struct clksel *clks;
	const struct clksel_rate *clkr, *max_clkr = NULL;
	u8 max_div = 0;

	clks = _get_clksel_by_parent(clk, src_clk);
	if (!clks)
		return 0;

	/*
	 * Find the highest divisor (e.g., the one resulting in the
	 * lowest rate) to use as the default.  This should avoid
	 * clock rates that are too high for the device.  XXX A better
	 * solution here would be to try to determine if there is a
	 * divisor matching the original clock rate before the parent
	 * switch, and if it cannot be found, to fall back to the
	 * highest divisor.
	 */
	for (clkr = clks->rates; clkr->div; clkr++) {
		if (!(clkr->flags & cpu_mask))
			continue;

		if (clkr->div > max_div) {
			max_div = clkr->div;
			max_clkr = clkr;
		}
	}

	if (max_div == 0) {
		/* This indicates an error in the clksel data */
		WARN(1, "clock: Could not find divisor for clock %s parent %s"
		     "\n", clk->name, src_clk->parent->name);
		return 0;
	}

	*field_val = max_clkr->val;

	return max_div;
}

/**
 * _write_clksel_reg() - program a clock's clksel register in hardware
 * @clk: struct clk * to program
 * @v: clksel bitfield value to program (with LSB at bit 0)
 *
 * Shift the clksel register bitfield value @v to its appropriate
 * location in the clksel register and write it in.  This function
 * will ensure that the write to the clksel_reg reaches its
 * destination before returning -- important since PRM and CM register
 * accesses can be quite slow compared to ARM cycles -- but does not
 * take into account any time the hardware might take to switch the
 * clock source.
 */
static void _write_clksel_reg(struct clk *clk, u32 field_val)
{
	u32 v;

	v = __raw_readl(clk->clksel_reg);
	v &= ~clk->clksel_mask;
	v |= field_val << __ffs(clk->clksel_mask);
	__raw_writel(v, clk->clksel_reg);

	v = __raw_readl(clk->clksel_reg); /* OCP barrier */
}

/**
 * _clksel_to_divisor() - turn clksel field value into integer divider
 * @clk: OMAP struct clk to use
 * @field_val: register field value to find
 *
 * Given a struct clk of a rate-selectable clksel clock, and a register field
 * value to search for, find the corresponding clock divisor.  The register
 * field value should be pre-masked and shifted down so the LSB is at bit 0
 * before calling.  Returns 0 on error or returns the actual integer divisor
 * upon success.
 */
static u32 _clksel_to_divisor(struct clk *clk, u32 field_val)
{
	const struct clksel *clks;
	const struct clksel_rate *clkr;

	clks = _get_clksel_by_parent(clk, clk->parent);
	if (!clks)
		return 0;

	for (clkr = clks->rates; clkr->div; clkr++) {
		if (!(clkr->flags & cpu_mask))
			continue;

		if (clkr->val == field_val)
			break;
	}

	if (!clkr->div) {
		/* This indicates a data error */
		WARN(1, "clock: Could not find fieldval %d for clock %s parent "
		     "%s\n", field_val, clk->name, clk->parent->name);
		return 0;
	}

	return clkr->div;
}

/**
 * _divisor_to_clksel() - turn clksel integer divisor into a field value
 * @clk: OMAP struct clk to use
 * @div: integer divisor to search for
 *
 * Given a struct clk of a rate-selectable clksel clock, and a clock
 * divisor, find the corresponding register field value.  Returns the
 * register field value _before_ left-shifting (i.e., LSB is at bit
 * 0); or returns 0xFFFFFFFF (~0) upon error.
 */
static u32 _divisor_to_clksel(struct clk *clk, u32 div)
{
	const struct clksel *clks;
	const struct clksel_rate *clkr;

	/* should never happen */
	WARN_ON(div == 0);

	clks = _get_clksel_by_parent(clk, clk->parent);
	if (!clks)
		return ~0;

	for (clkr = clks->rates; clkr->div; clkr++) {
		if (!(clkr->flags & cpu_mask))
			continue;

		if (clkr->div == div)
			break;
	}

	if (!clkr->div) {
		pr_err("clock: Could not find divisor %d for clock %s parent "
		       "%s\n", div, clk->name, clk->parent->name);
		return ~0;
	}

	return clkr->val;
}

/**
 * _read_divisor() - get current divisor applied to parent clock (from hdwr)
 * @clk: OMAP struct clk to use.
 *
 * Read the current divisor register value for @clk that is programmed
 * into the hardware, convert it into the actual divisor value, and
 * return it; or return 0 on error.
 */
static u32 _read_divisor(struct clk *clk)
{
	u32 v;

	if (!clk->clksel || !clk->clksel_mask)
		return 0;

	v = __raw_readl(clk->clksel_reg);
	v &= clk->clksel_mask;
	v >>= __ffs(clk->clksel_mask);

	return _clksel_to_divisor(clk, v);
}

/* Public functions */

/**
 * omap2_clksel_round_rate_div() - find divisor for the given clock and rate
 * @clk: OMAP struct clk to use
 * @target_rate: desired clock rate
 * @new_div: ptr to where we should store the divisor
 *
 * Finds 'best' divider value in an array based on the source and target
 * rates.  The divider array must be sorted with smallest divider first.
 * This function is also used by the DPLL3 M2 divider code.
 *
 * Returns the rounded clock rate or returns 0xffffffff on error.
 */
u32 omap2_clksel_round_rate_div(struct clk *clk, unsigned long target_rate,
				u32 *new_div)
{
	unsigned long test_rate;
	const struct clksel *clks;
	const struct clksel_rate *clkr;
	u32 last_div = 0;

	if (!clk->clksel || !clk->clksel_mask)
		return ~0;

	pr_debug("clock: clksel_round_rate_div: %s target_rate %ld\n",
		 clk->name, target_rate);

	*new_div = 1;

	clks = _get_clksel_by_parent(clk, clk->parent);
	if (!clks)
		return ~0;

	for (clkr = clks->rates; clkr->div; clkr++) {
		if (!(clkr->flags & cpu_mask))
			continue;

		/* Sanity check */
		if (clkr->div <= last_div)
			pr_err("clock: clksel_rate table not sorted "
			       "for clock %s", clk->name);

		last_div = clkr->div;

		test_rate = clk->parent->rate / clkr->div;

		if (test_rate <= target_rate)
			break; /* found it */
	}

	if (!clkr->div) {
		pr_err("clock: Could not find divisor for target "
		       "rate %ld for clock %s parent %s\n", target_rate,
		       clk->name, clk->parent->name);
		return ~0;
	}

	*new_div = clkr->div;

	pr_debug("clock: new_div = %d, new_rate = %ld\n", *new_div,
		 (clk->parent->rate / clkr->div));

	return clk->parent->rate / clkr->div;
}

/*
 * Clocktype interface functions to the OMAP clock code
 * (i.e., those used in struct clk field function pointers, etc.)
 */

/**
 * omap2_init_clksel_parent() - set a clksel clk's parent field from the hdwr
 * @clk: OMAP clock struct ptr to use
 *
 * Given a pointer @clk to a source-selectable struct clk, read the
 * hardware register and determine what its parent is currently set
 * to.  Update @clk's .parent field with the appropriate clk ptr.  No
 * return value.
 */
void omap2_init_clksel_parent(struct clk *clk)
{
	const struct clksel *clks;
	const struct clksel_rate *clkr;
	u32 r, found = 0;

	if (!clk->clksel || !clk->clksel_mask)
		return;

	r = __raw_readl(clk->clksel_reg) & clk->clksel_mask;
	r >>= __ffs(clk->clksel_mask);

	for (clks = clk->clksel; clks->parent && !found; clks++) {
		for (clkr = clks->rates; clkr->div && !found; clkr++) {
			if (!(clkr->flags & cpu_mask))
				continue;

			if (clkr->val == r) {
				if (clk->parent != clks->parent) {
					pr_debug("clock: inited %s parent "
						 "to %s (was %s)\n",
						 clk->name, clks->parent->name,
						 ((clk->parent) ?
						  clk->parent->name : "NULL"));
					clk_reparent(clk, clks->parent);
				};
				found = 1;
			}
		}
	}

	/* This indicates a data error */
	WARN(!found, "clock: %s: init parent: could not find regval %0x\n",
	     clk->name, r);

	return;
}

/**
 * omap2_clksel_recalc() - function ptr to pass via struct clk .recalc field
 * @clk: struct clk *
 *
 * This function is intended to be called only by the clock framework.
 * Each clksel clock should have its struct clk .recalc field set to this
 * function.  Returns the clock's current rate, based on its parent's rate
 * and its current divisor setting in the hardware.
 */
unsigned long omap2_clksel_recalc(struct clk *clk)
{
	unsigned long rate;
	u32 div = 0;

	div = _read_divisor(clk);
	if (div == 0)
		return clk->rate;

	rate = clk->parent->rate / div;

	pr_debug("clock: %s: recalc'd rate is %ld (div %d)\n", clk->name,
		 rate, div);

	return rate;
}

/**
 * omap2_clksel_round_rate() - find rounded rate for the given clock and rate
 * @clk: OMAP struct clk to use
 * @target_rate: desired clock rate
 *
 * This function is intended to be called only by the clock framework.
 * Finds best target rate based on the source clock and possible dividers.
 * rates. The divider array must be sorted with smallest divider first.
 *
 * Returns the rounded clock rate or returns 0xffffffff on error.
 */
long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate)
{
	u32 new_div;

	return omap2_clksel_round_rate_div(clk, target_rate, &new_div);
}

/**
 * omap2_clksel_set_rate() - program clock rate in hardware
 * @clk: struct clk * to program rate
 * @rate: target rate to program
 *
 * This function is intended to be called only by the clock framework.
 * Program @clk's rate to @rate in the hardware.  The clock can be
 * either enabled or disabled when this happens, although if the clock
 * is enabled, some downstream devices may glitch or behave
 * unpredictably when the clock rate is changed - this depends on the
 * hardware. This function does not currently check the usecount of
 * the clock, so if multiple drivers are using the clock, and the rate
 * is changed, they will all be affected without any notification.
 * Returns -EINVAL upon error, or 0 upon success.
 */
int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
{
	u32 field_val, validrate, new_div = 0;

	if (!clk->clksel || !clk->clksel_mask)
		return -EINVAL;

	validrate = omap2_clksel_round_rate_div(clk, rate, &new_div);
	if (validrate != rate)
		return -EINVAL;

	field_val = _divisor_to_clksel(clk, new_div);
	if (field_val == ~0)
		return -EINVAL;

	_write_clksel_reg(clk, field_val);

	clk->rate = clk->parent->rate / new_div;

	pr_debug("clock: %s: set rate to %ld\n", clk->name, clk->rate);

	return 0;
}

/*
 * Clksel parent setting function - not passed in struct clk function
 * pointer - instead, the OMAP clock code currently assumes that any
 * parent-setting clock is a clksel clock, and calls
 * omap2_clksel_set_parent() by default
 */

/**
 * omap2_clksel_set_parent() - change a clock's parent clock
 * @clk: struct clk * of the child clock
 * @new_parent: struct clk * of the new parent clock
 *
 * This function is intended to be called only by the clock framework.
 * Change the parent clock of clock @clk to @new_parent.  This is
 * intended to be used while @clk is disabled.  This function does not
 * currently check the usecount of the clock, so if multiple drivers
 * are using the clock, and the parent is changed, they will all be
 * affected without any notification.  Returns -EINVAL upon error, or
 * 0 upon success.
 */
int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent)
{
	u32 field_val = 0;
	u32 parent_div;

	if (!clk->clksel || !clk->clksel_mask)
		return -EINVAL;

	parent_div = _get_div_and_fieldval(new_parent, clk, &field_val);
	if (!parent_div)
		return -EINVAL;

	_write_clksel_reg(clk, field_val);

	clk_reparent(clk, new_parent);

	/* CLKSEL clocks follow their parents' rates, divided by a divisor */
	clk->rate = new_parent->rate;

	if (parent_div > 0)
		clk->rate /= parent_div;

	pr_debug("clock: %s: set parent to %s (new rate %ld)\n",
		 clk->name, clk->parent->name, clk->rate);

	return 0;
}
