/*
 * Copyright (c) 2010-2015, NVIDIA CORPORATION.  All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <common.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch/gp_padctrl.h>
#include <asm/arch/pinmux.h>
#include <asm/arch/tegra.h>
#include <asm/arch-tegra/clk_rst.h>
#include <asm/arch-tegra/pmc.h>
#include <asm/arch-tegra/scu.h>
#include "cpu.h"

int get_num_cpus(void)
{
	struct apb_misc_gp_ctlr *gp;
	uint rev;
	debug("%s entry\n", __func__);

	gp = (struct apb_misc_gp_ctlr *)NV_PA_APB_MISC_GP_BASE;
	rev = (readl(&gp->hidrev) & HIDREV_CHIPID_MASK) >> HIDREV_CHIPID_SHIFT;

	switch (rev) {
	case CHIPID_TEGRA20:
		return 2;
		break;
	case CHIPID_TEGRA30:
	case CHIPID_TEGRA114:
	case CHIPID_TEGRA124:
	case CHIPID_TEGRA210:
	default:
		return 4;
		break;
	}
}

/*
 * Timing tables for each SOC for all four oscillator options.
 */
struct clk_pll_table tegra_pll_x_table[TEGRA_SOC_CNT][CLOCK_OSC_FREQ_COUNT] = {
	/*
	 * T20: 1 GHz
	 *
	 * Register   Field  Bits   Width
	 * ------------------------------
	 * PLLX_BASE  p      22:20    3
	 * PLLX_BASE  n      17: 8   10
	 * PLLX_BASE  m       4: 0    5
	 * PLLX_MISC  cpcon  11: 8    4
	 */
	{
		{ .n = 1000, .m = 13, .p = 0, .cpcon = 12 }, /* OSC: 13.0 MHz */
		{ .n =  625, .m = 12, .p = 0, .cpcon =  8 }, /* OSC: 19.2 MHz */
		{ .n = 1000, .m = 12, .p = 0, .cpcon = 12 }, /* OSC: 12.0 MHz */
		{ .n = 1000, .m = 26, .p = 0, .cpcon = 12 }, /* OSC: 26.0 MHz */
		{ .n =    0, .m =  0, .p = 0, .cpcon =  0 }, /* OSC: 38.4 MHz (N/A) */
		{ .n =    0, .m =  0, .p = 0, .cpcon =  0 }, /* OSC: 48.0 MHz (N/A) */
	},
	/*
	 * T25: 1.2 GHz
	 *
	 * Register   Field  Bits   Width
	 * ------------------------------
	 * PLLX_BASE  p      22:20    3
	 * PLLX_BASE  n      17: 8   10
	 * PLLX_BASE  m       4: 0    5
	 * PLLX_MISC  cpcon  11: 8    4
	 */
	{
		{ .n = 923, .m = 10, .p = 0, .cpcon = 12 }, /* OSC: 13.0 MHz */
		{ .n = 750, .m = 12, .p = 0, .cpcon =  8 }, /* OSC: 19.2 MHz */
		{ .n = 600, .m =  6, .p = 0, .cpcon = 12 }, /* OSC: 12.0 MHz */
		{ .n = 600, .m = 13, .p = 0, .cpcon = 12 }, /* OSC: 26.0 MHz */
		{ .n =   0, .m =  0, .p = 0, .cpcon =  0 }, /* OSC: 38.4 MHz (N/A) */
		{ .n =   0, .m =  0, .p = 0, .cpcon =  0 }, /* OSC: 48.0 MHz (N/A) */
	},
	/*
	 * T30: 600 MHz
	 *
	 * Register   Field  Bits   Width
	 * ------------------------------
	 * PLLX_BASE  p      22:20    3
	 * PLLX_BASE  n      17: 8   10
	 * PLLX_BASE  m       4: 0    5
	 * PLLX_MISC  cpcon  11: 8    4
	 */
	{
		{ .n = 600, .m = 13, .p = 0, .cpcon = 8 }, /* OSC: 13.0 MHz */
		{ .n = 500, .m = 16, .p = 0, .cpcon = 8 }, /* OSC: 19.2 MHz */
		{ .n = 600, .m = 12, .p = 0, .cpcon = 8 }, /* OSC: 12.0 MHz */
		{ .n = 600, .m = 26, .p = 0, .cpcon = 8 }, /* OSC: 26.0 MHz */
		{ .n =   0, .m =  0, .p = 0, .cpcon = 0 }, /* OSC: 38.4 MHz (N/A) */
		{ .n =   0, .m =  0, .p = 0, .cpcon = 0 }, /* OSC: 48.0 MHz (N/A) */
	},
	/*
	 * T114: 700 MHz
	 *
	 * Register   Field  Bits   Width
	 * ------------------------------
	 * PLLX_BASE  p      23:20    4
	 * PLLX_BASE  n      15: 8    8
	 * PLLX_BASE  m       7: 0    8
	 */
	{
		{ .n = 108, .m = 1, .p = 1 }, /* OSC: 13.0 MHz */
		{ .n =  73, .m = 1, .p = 1 }, /* OSC: 19.2 MHz */
		{ .n = 116, .m = 1, .p = 1 }, /* OSC: 12.0 MHz */
		{ .n = 108, .m = 2, .p = 1 }, /* OSC: 26.0 MHz */
		{ .n =   0, .m = 0, .p = 0 }, /* OSC: 38.4 MHz (N/A) */
		{ .n =   0, .m = 0, .p = 0 }, /* OSC: 48.0 MHz (N/A) */
	},

	/*
	 * T124: 700 MHz
	 *
	 * Register   Field  Bits   Width
	 * ------------------------------
	 * PLLX_BASE  p      23:20    4
	 * PLLX_BASE  n      15: 8    8
	 * PLLX_BASE  m       7: 0    8
	 */
	{
		{ .n = 108, .m = 1, .p = 1 }, /* OSC: 13.0 MHz */
		{ .n =  73, .m = 1, .p = 1 }, /* OSC: 19.2 MHz */
		{ .n = 116, .m = 1, .p = 1 }, /* OSC: 12.0 MHz */
		{ .n = 108, .m = 2, .p = 1 }, /* OSC: 26.0 MHz */
		{ .n =   0, .m = 0, .p = 0 }, /* OSC: 38.4 MHz (N/A) */
		{ .n =   0, .m = 0, .p = 0 }, /* OSC: 48.0 MHz (N/A) */
	},

	/*
	 * T210: 700 MHz
	 *
	 * Register   Field  Bits   Width
	 * ------------------------------
	 * PLLX_BASE  p      24:20    5
	 * PLLX_BASE  n      15: 8    8
	 * PLLX_BASE  m       7: 0    8
	 */
	{
		{ .n = 108, .m = 1, .p = 1 }, /* OSC: 13.0 MHz = 702   MHz*/
		{ .n =  73, .m = 1, .p = 1 }, /* OSC: 19.2 MHz = 700.8 MHz*/
		{ .n = 116, .m = 1, .p = 1 }, /* OSC: 12.0 MHz = 696   MHz*/
		{ .n = 108, .m = 2, .p = 1 }, /* OSC: 26.0 MHz = 702   MHz*/
		{ .n =  36, .m = 1, .p = 1 }, /* OSC: 38.4 MHz = 691.2 MHz */
		{ .n =  58, .m = 2, .p = 1 }, /* OSC: 48.0 MHz = 696   MHz */
	},
};

static inline void pllx_set_iddq(void)
{
#if defined(CONFIG_TEGRA124) || defined(CONFIG_TEGRA210)
	struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
	u32 reg;
	debug("%s entry\n", __func__);

	/* Disable IDDQ */
	reg = readl(&clkrst->crc_pllx_misc3);
	reg &= ~PLLX_IDDQ_MASK;
	writel(reg, &clkrst->crc_pllx_misc3);
	udelay(2);
	debug("%s: IDDQ: PLLX IDDQ = 0x%08X\n", __func__,
	      readl(&clkrst->crc_pllx_misc3));
#endif
}

int pllx_set_rate(struct clk_pll_simple *pll , u32 divn, u32 divm,
		u32 divp, u32 cpcon)
{
	struct clk_pll_info *pllinfo = &tegra_pll_info_table[CLOCK_ID_XCPU];
	int chip = tegra_get_chip();
	u32 reg;
	debug("%s entry\n", __func__);

	/* If PLLX is already enabled, just return */
	if (readl(&pll->pll_base) & PLL_ENABLE_MASK) {
		debug("%s: PLLX already enabled, returning\n", __func__);
		return 0;
	}

	pllx_set_iddq();

	/* Set BYPASS, m, n and p to PLLX_BASE */
	reg = PLL_BYPASS_MASK | (divm << pllinfo->m_shift);
	reg |= (divn << pllinfo->n_shift) | (divp << pllinfo->p_shift);
	writel(reg, &pll->pll_base);

	/* Set cpcon to PLLX_MISC */
	if (chip == CHIPID_TEGRA20 || chip == CHIPID_TEGRA30)
		reg = (cpcon << pllinfo->kcp_shift);
	else
		reg = 0;

	/*
	 * TODO(twarren@nvidia.com) Check which SoCs use DCCON
	 * and add to pllinfo table if needed!
	 */
	 /* Set dccon to PLLX_MISC if freq > 600MHz */
	if (divn > 600)
		reg |= (1 << PLL_DCCON_SHIFT);
	writel(reg, &pll->pll_misc);

	/* Disable BYPASS */
	reg = readl(&pll->pll_base);
	reg &= ~PLL_BYPASS_MASK;
	writel(reg, &pll->pll_base);
	debug("%s: base = 0x%08X\n", __func__, reg);

	/* Set lock_enable to PLLX_MISC if lock_ena is valid (i.e. 0-31) */
	reg = readl(&pll->pll_misc);
	if (pllinfo->lock_ena < 32)
		reg |= (1 << pllinfo->lock_ena);
	writel(reg, &pll->pll_misc);
	debug("%s: misc = 0x%08X\n", __func__, reg);

	/* Enable PLLX last, once it's all configured */
	reg = readl(&pll->pll_base);
	reg |= PLL_ENABLE_MASK;
	writel(reg, &pll->pll_base);
	debug("%s: base final = 0x%08X\n", __func__, reg);

	return 0;
}

void init_pllx(void)
{
	struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
	struct clk_pll_simple *pll = &clkrst->crc_pll_simple[SIMPLE_PLLX];
	int soc_type, sku_info, chip_sku;
	enum clock_osc_freq osc;
	struct clk_pll_table *sel;
	debug("%s entry\n", __func__);

	/* get SOC (chip) type */
	soc_type = tegra_get_chip();
	debug("%s: SoC = 0x%02X\n", __func__, soc_type);

	/* get SKU info */
	sku_info = tegra_get_sku_info();
	debug("%s: SKU info byte = 0x%02X\n", __func__, sku_info);

	/* get chip SKU, combo of the above info */
	chip_sku = tegra_get_chip_sku();
	debug("%s: Chip SKU = %d\n", __func__, chip_sku);

	/* get osc freq */
	osc = clock_get_osc_freq();
	debug("%s: osc = %d\n", __func__, osc);

	/* set pllx */
	sel = &tegra_pll_x_table[chip_sku][osc];
	pllx_set_rate(pll, sel->n, sel->m, sel->p, sel->cpcon);
}

void enable_cpu_clock(int enable)
{
	struct clk_rst_ctlr *clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;
	u32 clk;
	debug("%s entry\n", __func__);

	/*
	 * NOTE:
	 * Regardless of whether the request is to enable or disable the CPU
	 * clock, every processor in the CPU complex except the master (CPU 0)
	 * will have it's clock stopped because the AVP only talks to the
	 * master.
	 */

	if (enable) {
		/* Initialize PLLX */
		init_pllx();

		/* Wait until all clocks are stable */
		udelay(PLL_STABILIZATION_DELAY);

		writel(CCLK_BURST_POLICY, &clkrst->crc_cclk_brst_pol);
		writel(SUPER_CCLK_DIVIDER, &clkrst->crc_super_cclk_div);
	}

	/*
	 * Read the register containing the individual CPU clock enables and
	 * always stop the clocks to CPUs > 0.
	 */
	clk = readl(&clkrst->crc_clk_cpu_cmplx);
	clk |= 1 << CPU1_CLK_STP_SHIFT;
	if (get_num_cpus() == 4)
		clk |= (1 << CPU2_CLK_STP_SHIFT) + (1 << CPU3_CLK_STP_SHIFT);

	/* Stop/Unstop the CPU clock */
	clk &= ~CPU0_CLK_STP_MASK;
	clk |= !enable << CPU0_CLK_STP_SHIFT;
	writel(clk, &clkrst->crc_clk_cpu_cmplx);

	clock_enable(PERIPH_ID_CPU);
}

static int is_cpu_powered(void)
{
	struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;

	return (readl(&pmc->pmc_pwrgate_status) & CPU_PWRED) ? 1 : 0;
}

static void remove_cpu_io_clamps(void)
{
	struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
	u32 reg;
	debug("%s entry\n", __func__);

	/* Remove the clamps on the CPU I/O signals */
	reg = readl(&pmc->pmc_remove_clamping);
	reg |= CPU_CLMP;
	writel(reg, &pmc->pmc_remove_clamping);

	/* Give I/O signals time to stabilize */
	udelay(IO_STABILIZATION_DELAY);
}

void powerup_cpu(void)
{
	struct pmc_ctlr *pmc = (struct pmc_ctlr *)NV_PA_PMC_BASE;
	u32 reg;
	int timeout = IO_STABILIZATION_DELAY;
	debug("%s entry\n", __func__);

	if (!is_cpu_powered()) {
		/* Toggle the CPU power state (OFF -> ON) */
		reg = readl(&pmc->pmc_pwrgate_toggle);
		reg &= PARTID_CP;
		reg |= START_CP;
		writel(reg, &pmc->pmc_pwrgate_toggle);

		/* Wait for the power to come up */
		while (!is_cpu_powered()) {
			if (timeout-- == 0)
				printf("CPU failed to power up!\n");
			else
				udelay(10);
		}

		/*
		 * Remove the I/O clamps from CPU power partition.
		 * Recommended only on a Warm boot, if the CPU partition gets
		 * power gated. Shouldn't cause any harm when called after a
		 * cold boot according to HW, probably just redundant.
		 */
		remove_cpu_io_clamps();
	}
}

void reset_A9_cpu(int reset)
{
	/*
	* NOTE:  Regardless of whether the request is to hold the CPU in reset
	*        or take it out of reset, every processor in the CPU complex
	*        except the master (CPU 0) will be held in reset because the
	*        AVP only talks to the master. The AVP does not know that there
	*        are multiple processors in the CPU complex.
	*/
	int mask = crc_rst_cpu | crc_rst_de | crc_rst_debug;
	int num_cpus = get_num_cpus();
	int cpu;

	debug("%s entry\n", __func__);
	/* Hold CPUs 1 onwards in reset, and CPU 0 if asked */
	for (cpu = 1; cpu < num_cpus; cpu++)
		reset_cmplx_set_enable(cpu, mask, 1);
	reset_cmplx_set_enable(0, mask, reset);

	/* Enable/Disable master CPU reset */
	reset_set_enable(PERIPH_ID_CPU, reset);
}

void clock_enable_coresight(int enable)
{
	u32 rst, src = 2;

	debug("%s entry\n", __func__);
	clock_set_enable(PERIPH_ID_CORESIGHT, enable);
	reset_set_enable(PERIPH_ID_CORESIGHT, !enable);

	if (enable) {
		/*
		 * Put CoreSight on PLLP_OUT0 and divide it down as per
		 * PLLP base frequency based on SoC type (T20/T30+).
		 * Clock divider request would setup CSITE clock as 144MHz
		 * for PLLP base 216MHz and 204MHz for PLLP base 408MHz
		 */
		src = CLK_DIVIDER(NVBL_PLLP_KHZ, CSITE_KHZ);
		clock_ll_set_source_divisor(PERIPH_ID_CSI, 0, src);

		/* Unlock the CPU CoreSight interfaces */
		rst = CORESIGHT_UNLOCK;
		writel(rst, CSITE_CPU_DBG0_LAR);
		writel(rst, CSITE_CPU_DBG1_LAR);
		if (get_num_cpus() == 4) {
			writel(rst, CSITE_CPU_DBG2_LAR);
			writel(rst, CSITE_CPU_DBG3_LAR);
		}
	}
}

void halt_avp(void)
{
	debug("%s entry\n", __func__);

	for (;;) {
		writel(HALT_COP_EVENT_JTAG | (FLOW_MODE_STOP << 29),
		       FLOW_CTLR_HALT_COP_EVENTS);
	}
}
