/*
 * Keystone2: pll initialization
 *
 * (C) Copyright 2012-2014
 *     Texas Instruments Incorporated, <www.ti.com>
 *
 * SPDX-License-Identifier:     GPL-2.0+
 */

#include <common.h>
#include <asm/arch/clock.h>
#include <asm/arch/clock_defs.h>

/* DEV and ARM speed definitions as specified in DEVSPEED register */
int __weak speeds[DEVSPEED_NUMSPDS] = {
	SPD1000,
	SPD1200,
	SPD1350,
	SPD1400,
	SPD1500,
	SPD1400,
	SPD1350,
	SPD1200,
	SPD1000,
	SPD800,
};

const struct keystone_pll_regs keystone_pll_regs[] = {
	[CORE_PLL]	= {KS2_MAINPLLCTL0, KS2_MAINPLLCTL1},
	[PASS_PLL]	= {KS2_PASSPLLCTL0, KS2_PASSPLLCTL1},
	[TETRIS_PLL]	= {KS2_ARMPLLCTL0, KS2_ARMPLLCTL1},
	[DDR3A_PLL]	= {KS2_DDR3APLLCTL0, KS2_DDR3APLLCTL1},
	[DDR3B_PLL]	= {KS2_DDR3BPLLCTL0, KS2_DDR3BPLLCTL1},
};

static void wait_for_completion(const struct pll_init_data *data)
{
	int i;
	for (i = 0; i < 100; i++) {
		sdelay(450);
		if (!(pllctl_reg_read(data->pll, stat) & PLLSTAT_GOSTAT_MASK))
			break;
	}
}

static inline void bypass_main_pll(const struct pll_init_data *data)
{
	pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLENSRC_MASK |
			   PLLCTL_PLLEN_MASK);

	/* 4 cycles of reference clock CLKIN*/
	sdelay(340);
}

static void configure_mult_div(const struct pll_init_data *data)
{
	u32 pllm, plld, bwadj;

	pllm = data->pll_m - 1;
	plld = (data->pll_d - 1) & CFG_PLLCTL0_PLLD_MASK;

	/* Program Multiplier */
	if (data->pll == MAIN_PLL)
		pllctl_reg_write(data->pll, mult, pllm & PLLM_MULT_LO_MASK);

	clrsetbits_le32(keystone_pll_regs[data->pll].reg0,
			CFG_PLLCTL0_PLLM_MASK,
			pllm << CFG_PLLCTL0_PLLM_SHIFT);

	/* Program BWADJ */
	bwadj = (data->pll_m - 1) >> 1; /* Divide pllm by 2 */
	clrsetbits_le32(keystone_pll_regs[data->pll].reg0,
			CFG_PLLCTL0_BWADJ_MASK,
			(bwadj << CFG_PLLCTL0_BWADJ_SHIFT) &
			CFG_PLLCTL0_BWADJ_MASK);
	bwadj = bwadj >> CFG_PLLCTL0_BWADJ_BITS;
	clrsetbits_le32(keystone_pll_regs[data->pll].reg1,
			CFG_PLLCTL1_BWADJ_MASK, bwadj);

	/* Program Divider */
	clrsetbits_le32(keystone_pll_regs[data->pll].reg0,
			CFG_PLLCTL0_PLLD_MASK, plld);
}

void configure_main_pll(const struct pll_init_data *data)
{
	u32 tmp, pllod, i, alnctl_val = 0;
	u32 *offset;

	pllod = data->pll_od - 1;

	/* 100 micro sec for stabilization */
	sdelay(210000);

	tmp = pllctl_reg_read(data->pll, secctl);

	/* Check for Bypass */
	if (tmp & SECCTL_BYPASS_MASK) {
		setbits_le32(keystone_pll_regs[data->pll].reg1,
			     CFG_PLLCTL1_ENSAT_MASK);

		bypass_main_pll(data);

		/* Powerdown and powerup Main Pll */
		pllctl_reg_setbits(data->pll, secctl, SECCTL_BYPASS_MASK);
		pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLPWRDN_MASK);
		/* 5 micro sec */
		sdelay(21000);

		pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLPWRDN_MASK);
	} else {
		bypass_main_pll(data);
	}

	configure_mult_div(data);

	/* Program Output Divider */
	pllctl_reg_rmw(data->pll, secctl, SECCTL_OP_DIV_MASK,
		       ((pllod << SECCTL_OP_DIV_SHIFT) & SECCTL_OP_DIV_MASK));

	/* Program PLLDIVn */
	wait_for_completion(data);
	for (i = 0; i < PLLDIV_MAX; i++) {
		if (i < 3)
			offset = pllctl_reg(data->pll, div1) + i;
		else
			offset = pllctl_reg(data->pll, div4) + (i - 3);

		if (divn_val[i] != -1) {
			__raw_writel(divn_val[i] | PLLDIV_ENABLE_MASK, offset);
			alnctl_val |= BIT(i);
		}
	}

	if (alnctl_val) {
		pllctl_reg_setbits(data->pll, alnctl, alnctl_val);
		/*
		 * Set GOSET bit in PLLCMD to initiate the GO operation
		 * to change the divide
		 */
		pllctl_reg_setbits(data->pll, cmd, PLLSTAT_GOSTAT_MASK);
		wait_for_completion(data);
	}

	/* Reset PLL */
	pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLRST_MASK);
	sdelay(21000);	/* Wait for a minimum of 7 us*/
	pllctl_reg_clrbits(data->pll, ctl, PLLCTL_PLLRST_MASK);
	sdelay(105000);	/* Wait for PLL Lock time (min 50 us) */

	/* Enable PLL */
	pllctl_reg_clrbits(data->pll, secctl, SECCTL_BYPASS_MASK);
	pllctl_reg_setbits(data->pll, ctl, PLLCTL_PLLEN_MASK);
}

void configure_secondary_pll(const struct pll_init_data *data)
{
	int pllod = data->pll_od - 1;

	/* Enable Bypass mode */
	setbits_le32(keystone_pll_regs[data->pll].reg1, CFG_PLLCTL1_ENSAT_MASK);
	setbits_le32(keystone_pll_regs[data->pll].reg0,
		     CFG_PLLCTL0_BYPASS_MASK);

	/* Enable Glitch free bypass for ARM PLL */
	if (cpu_is_k2hk() && data->pll == TETRIS_PLL)
		clrbits_le32(KS2_MISC_CTRL, MISC_CTL1_ARM_PLL_EN);

	configure_mult_div(data);

	/* Program Output Divider */
	clrsetbits_le32(keystone_pll_regs[data->pll].reg0,
			CFG_PLLCTL0_CLKOD_MASK,
			(pllod << CFG_PLLCTL0_CLKOD_SHIFT) &
			CFG_PLLCTL0_CLKOD_MASK);

	/* Reset PLL */
	setbits_le32(keystone_pll_regs[data->pll].reg1, CFG_PLLCTL1_RST_MASK);
	/* Wait for 5 micro seconds */
	sdelay(21000);

	/* Select the Output of PASS PLL as input to PASS */
	if (data->pll == PASS_PLL)
		setbits_le32(keystone_pll_regs[data->pll].reg1,
			     CFG_PLLCTL1_PAPLL_MASK);

	/* Select the Output of ARM PLL as input to ARM */
	if (data->pll == TETRIS_PLL)
		setbits_le32(KS2_MISC_CTRL, MISC_CTL1_ARM_PLL_EN);

	clrbits_le32(keystone_pll_regs[data->pll].reg1, CFG_PLLCTL1_RST_MASK);
	/* Wait for 500 * REFCLK cucles * (PLLD + 1) */
	sdelay(105000);

	/* Switch to PLL mode */
	clrbits_le32(keystone_pll_regs[data->pll].reg0,
		     CFG_PLLCTL0_BYPASS_MASK);
}

void init_pll(const struct pll_init_data *data)
{
	if (data->pll == MAIN_PLL)
		configure_main_pll(data);
	else
		configure_secondary_pll(data);

	/*
	 * This is required to provide a delay between multiple
	 * consequent PPL configurations
	 */
	sdelay(210000);
}

void init_plls(void)
{
	struct pll_init_data *data;
	int pll;

	for (pll = MAIN_PLL; pll < MAX_PLL_COUNT; pll++) {
		data = get_pll_init_data(pll);
		if (data)
			init_pll(data);
	}
}

static int get_max_speed(u32 val, u32 speed_supported)
{
	int speed;

	/* Left most setbit gives the speed */
	for (speed = DEVSPEED_NUMSPDS; speed >= 0; speed--) {
		if ((val & BIT(speed)) & speed_supported)
			return speeds[speed];
	}

	/* If no bit is set, use SPD800 */
	return SPD800;
}

static inline u32 read_efuse_bootrom(void)
{
	if (cpu_is_k2hk() && (cpu_revision() <= 1))
		return __raw_readl(KS2_REV1_DEVSPEED);
	else
		return __raw_readl(KS2_EFUSE_BOOTROM);
}

int get_max_arm_speed(void)
{
	u32 armspeed = read_efuse_bootrom();

	armspeed = (armspeed & DEVSPEED_ARMSPEED_MASK) >>
		    DEVSPEED_ARMSPEED_SHIFT;

	return get_max_speed(armspeed, ARM_SUPPORTED_SPEEDS);
}

int get_max_dev_speed(void)
{
	u32 devspeed = read_efuse_bootrom();

	devspeed = (devspeed & DEVSPEED_DEVSPEED_MASK) >>
		    DEVSPEED_DEVSPEED_SHIFT;

	return get_max_speed(devspeed, DEV_SUPPORTED_SPEEDS);
}

/**
 * pll_freq_get - get pll frequency
 * @pll:	pll identifier
 */
static unsigned long pll_freq_get(int pll)
{
	unsigned long mult = 1, prediv = 1, output_div = 2;
	unsigned long ret;
	u32 tmp, reg;

	if (pll == MAIN_PLL) {
		ret = external_clk[sys_clk];
		if (pllctl_reg_read(pll, ctl) & PLLCTL_PLLEN_MASK) {
			/* PLL mode */
			tmp = __raw_readl(KS2_MAINPLLCTL0);
			prediv = (tmp & CFG_PLLCTL0_PLLD_MASK) + 1;
			mult = ((tmp & CFG_PLLCTL0_PLLM_HI_MASK) >>
				CFG_PLLCTL0_PLLM_SHIFT |
				(pllctl_reg_read(pll, mult) &
				 PLLM_MULT_LO_MASK)) + 1;
			output_div = ((pllctl_reg_read(pll, secctl) &
				       SECCTL_OP_DIV_MASK) >>
				       SECCTL_OP_DIV_SHIFT) + 1;

			ret = ret / prediv / output_div * mult;
		}
	} else {
		switch (pll) {
		case PASS_PLL:
			ret = external_clk[pa_clk];
			reg = KS2_PASSPLLCTL0;
			break;
		case TETRIS_PLL:
			ret = external_clk[tetris_clk];
			reg = KS2_ARMPLLCTL0;
			break;
		case DDR3A_PLL:
			ret = external_clk[ddr3a_clk];
			reg = KS2_DDR3APLLCTL0;
			break;
		case DDR3B_PLL:
			ret = external_clk[ddr3b_clk];
			reg = KS2_DDR3BPLLCTL0;
			break;
		default:
			return 0;
		}

		tmp = __raw_readl(reg);

		if (!(tmp & CFG_PLLCTL0_BYPASS_MASK)) {
			/* Bypass disabled */
			prediv = (tmp & CFG_PLLCTL0_PLLD_MASK) + 1;
			mult = ((tmp & CFG_PLLCTL0_PLLM_MASK) >>
				CFG_PLLCTL0_PLLM_SHIFT) + 1;
			output_div = ((tmp & CFG_PLLCTL0_CLKOD_MASK) >>
				      CFG_PLLCTL0_CLKOD_SHIFT) + 1;
			ret = ((ret / prediv) * mult) / output_div;
		}
	}

	return ret;
}

unsigned long clk_get_rate(unsigned int clk)
{
	unsigned long freq = 0;

	switch (clk) {
	case core_pll_clk:
		freq = pll_freq_get(CORE_PLL);
		break;
	case pass_pll_clk:
		freq = pll_freq_get(PASS_PLL);
		break;
	case tetris_pll_clk:
		if (!cpu_is_k2e())
			freq = pll_freq_get(TETRIS_PLL);
		break;
	case ddr3a_pll_clk:
		freq = pll_freq_get(DDR3A_PLL);
		break;
	case ddr3b_pll_clk:
		if (cpu_is_k2hk())
			freq = pll_freq_get(DDR3B_PLL);
		break;
	case sys_clk0_1_clk:
	case sys_clk0_clk:
		freq = pll_freq_get(CORE_PLL) / pll0div_read(1);
		break;
	case sys_clk1_clk:
	return pll_freq_get(CORE_PLL) / pll0div_read(2);
		break;
	case sys_clk2_clk:
		freq = pll_freq_get(CORE_PLL) / pll0div_read(3);
		break;
	case sys_clk3_clk:
		freq = pll_freq_get(CORE_PLL) / pll0div_read(4);
		break;
	case sys_clk0_2_clk:
		freq = clk_get_rate(sys_clk0_clk) / 2;
		break;
	case sys_clk0_3_clk:
		freq = clk_get_rate(sys_clk0_clk) / 3;
		break;
	case sys_clk0_4_clk:
		freq = clk_get_rate(sys_clk0_clk) / 4;
		break;
	case sys_clk0_6_clk:
		freq = clk_get_rate(sys_clk0_clk) / 6;
		break;
	case sys_clk0_8_clk:
		freq = clk_get_rate(sys_clk0_clk) / 8;
		break;
	case sys_clk0_12_clk:
		freq = clk_get_rate(sys_clk0_clk) / 12;
		break;
	case sys_clk0_24_clk:
		freq = clk_get_rate(sys_clk0_clk) / 24;
		break;
	case sys_clk1_3_clk:
		freq = clk_get_rate(sys_clk1_clk) / 3;
		break;
	case sys_clk1_4_clk:
		freq = clk_get_rate(sys_clk1_clk) / 4;
		break;
	case sys_clk1_6_clk:
		freq = clk_get_rate(sys_clk1_clk) / 6;
		break;
	case sys_clk1_12_clk:
		freq = clk_get_rate(sys_clk1_clk) / 12;
		break;
	default:
		break;
	}

	return freq;
}
