/*
 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *   * Neither the name of The Linux Foundation nor
 *     the names of its contributors may be used to endorse or promote
 *     products derived from this software without specific prior written
 *     permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#include <assert.h>
#include <reg.h>
#include <err.h>
#include <clock.h>
#include <clock_pll.h>
#include <clock_lib2.h>


/*=============== CXO clock ops =============*/
int cxo_clk_enable(struct clk *clk)
{
	/* Nothing to do. */
	return 0;
}

void cxo_clk_disable(struct clk *clk)
{
	/* Nothing to do. */
	return;
}


/*=============== Branch clock ops =============*/

/* Branch clock enable */
int clock_lib2_branch_clk_enable(struct clk *clk)
{
	int rc = 0;
	uint32_t cbcr_val;
	struct branch_clk *bclk = to_branch_clk(clk);

	cbcr_val  = readl(bclk->cbcr_reg);
	cbcr_val |= CBCR_BRANCH_ENABLE_BIT;
	writel(cbcr_val, bclk->cbcr_reg);

	/* wait until status shows it is enabled */
	while(readl(bclk->cbcr_reg) & CBCR_BRANCH_OFF_BIT);

	return rc;
}

/* Branch clock disable */
void clock_lib2_branch_clk_disable(struct clk *clk)
{
	uint32_t cbcr_val;
	struct branch_clk *bclk = to_branch_clk(clk);

	cbcr_val  = readl(bclk->cbcr_reg);
	cbcr_val &= ~CBCR_BRANCH_ENABLE_BIT;
	writel(cbcr_val, bclk->cbcr_reg);

	/* wait until status shows it is disabled */
	while(!(readl(bclk->cbcr_reg) & CBCR_BRANCH_OFF_BIT));
}

/* Branch clock set rate */
int clock_lib2_branch_set_rate(struct clk *c, unsigned rate)
{
	struct branch_clk *branch = to_branch_clk(c);

	if (!branch->has_sibling)
		return clk_set_rate(branch->parent, rate);

	return -1;
}


/*=============== Root clock ops =============*/

/* Root enable */
int clock_lib2_rcg_enable(struct clk *c)
{
	/* Hardware feedback from branch enable results in root being enabled.
	 * Nothing to do here.
	 */

	return 0;
}

/* Root set rate:
 * Find the entry in the frequecy table corresponding to the requested rate.
 * Enable the source clock required for the new frequency.
 * Call the set_rate function defined for this particular root clock.
 */
int clock_lib2_rcg_set_rate(struct clk *c, unsigned rate)
{
	struct rcg_clk *rclk = to_rcg_clk(c);
	struct clk_freq_tbl *nf; /* new freq */
	int rc = 0;

	/* ck if new freq is in table */
	for (nf = rclk->freq_tbl; nf->freq_hz != FREQ_END
			&& nf->freq_hz != rate; nf++)
		;

	/* Frequency not found in the table */
	if (nf->freq_hz == FREQ_END)
		return ERR_INVALID_ARGS;

	/* Check if frequency is actually changed. */
	if (nf == rclk->current_freq)
		return rc;

	/* First enable the source clock for this freq. */
	rc = clk_enable(nf->src_clk);

	if(rc)
	{
		dprintf(CRITICAL, "clock_lib2_rcg_set_rate: failed to enable clk %s ret %d\n",
									nf->src_clk->dbg_name, rc);
		ASSERT(0);
	}

	/* Perform clock-specific frequency switch operations. */
	ASSERT(rclk->set_rate);
	rclk->set_rate(rclk, nf);

	/* update current freq */
	rclk->current_freq = nf;

	return rc;
}

/* root update config: informs h/w to start using the new config values */
static void clock_lib2_rcg_update_config(struct rcg_clk *rclk)
{
	uint32_t cmd;

	cmd  = readl(rclk->cmd_reg);
	cmd |= CMD_UPDATE_BIT;
	writel(cmd, rclk->cmd_reg);

	/* Wait for frequency to be updated. */
	while(readl(rclk->cmd_reg) & CMD_UPDATE_MASK);
}

/* root set rate for clocks with half integer and MND divider */
void clock_lib2_rcg_set_rate_mnd(struct rcg_clk *rclk, struct clk_freq_tbl *freq)
{
	uint32_t cfg;

	/* Program MND values */
	writel(freq->m_val, rclk->m_reg);
	writel(freq->n_val, rclk->n_reg);
	writel(freq->d_val, rclk->d_reg);

	/* setup src select and divider */
	cfg  = readl(rclk->cfg_reg);
	cfg &= ~(CFG_SRC_SEL_MASK | CFG_SRC_DIV_MASK | CFG_MODE_MASK);
	cfg |= freq->div_src_val;
	if(freq->n_val !=0)
	{
		cfg |= (CFG_MODE_DUAL_EDGE << CFG_MODE_OFFSET);
	}
	writel(cfg, rclk->cfg_reg);

	/* Inform h/w to start using the new config. */
	clock_lib2_rcg_update_config(rclk);
}

/* root set rate for clocks with half integer divider */
void clock_lib2_rcg_set_rate_hid(struct rcg_clk *rclk, struct clk_freq_tbl *freq)
{
	uint32_t cfg;

	/* setup src select and divider */
	cfg  = readl(rclk->cfg_reg);
	cfg &= ~(CFG_SRC_SEL_MASK | CFG_SRC_DIV_MASK);
	cfg |= freq->div_src_val;
	writel(cfg, rclk->cfg_reg);

	clock_lib2_rcg_update_config(rclk);
}

/*=============== Vote clock ops =============*/

/* Vote clock enable */
int clock_lib2_vote_clk_enable(struct clk *c)
{
	uint32_t vote_regval;
	uint32_t val;
	struct vote_clk *vclk = to_local_vote_clk(c);

	vote_regval = readl(vclk->vote_reg);
	vote_regval |= vclk->en_mask;
	writel_relaxed(vote_regval, vclk->vote_reg);
	do {
		val = readl(vclk->cbcr_reg);
		val &= BRANCH_CHECK_MASK;
	}
	/*  wait until status shows it is enabled */
	while((val != BRANCH_ON_VAL) && (val != BRANCH_NOC_FSM_ON_VAL));

	return 0;
}

/* Vote clock disable */
void clock_lib2_vote_clk_disable(struct clk *c)
{
	uint32_t vote_regval;
	struct vote_clk *vclk = to_local_vote_clk(c);

	vote_regval = readl(vclk->vote_reg);
	vote_regval &= ~vclk->en_mask;
    writel_relaxed(vote_regval, vclk->vote_reg);

    /* wait until status shows it is disabled */
	while(!(readl(vclk->cbcr_reg) & CBCR_BRANCH_OFF_BIT));
}
