/* SPDX-License-Identifier: GPL-2.0-only */

#include <assert.h>
#include <commonlib/helpers.h>
#include <delay.h>
#include <device/mmio.h>
#include <soc/clock.h>
#include <timer.h>
#include <types.h>

/* Clock Branch Operations */
static bool clock_is_off(u32 *cbcr_addr)
{
	return (read32(cbcr_addr) & CLK_CTL_OFF_BMSK);
}

enum cb_err clock_enable_vote(void *cbcr_addr, void *vote_addr,
				uint32_t vote_bit)
{
	int count = 100;

	setbits32(vote_addr, BIT(vote_bit));

	/* Ensure clock is enabled */
	while (count-- > 0) {
		if (!clock_is_off(cbcr_addr))
			return CB_SUCCESS;
		udelay(1);
	}
	printk(BIOS_ERR, "ERROR: Failed to enable clock, register val: 0x%x\n",
			read32(cbcr_addr));
	return CB_ERR;
}

enum cb_err clock_enable(void *cbcr_addr)
{
	int count = 100;

	/* Set clock enable bit */
	setbits32(cbcr_addr, BIT(CLK_CTL_EN_SHFT));

	/* Ensure clock is enabled */
	while (count-- > 0) {
		if (!clock_is_off(cbcr_addr))
			return CB_SUCCESS;
		udelay(1);
	}
	printk(BIOS_ERR, "ERROR: Failed to enable clock, register val: 0x%x\n",
			read32(cbcr_addr));
	return CB_ERR;
}

/* Clock Block Reset Operations */
void clock_reset_bcr(void *bcr_addr, bool assert)
{
	if (assert)
		setbits32(bcr_addr, BIT(CLK_CTL_BCR_BLK_SHFT));
	else
		clrbits32(bcr_addr, BIT(CLK_CTL_BCR_BLK_SHFT));
}

/* Clock GDSC Operations */
enum cb_err enable_and_poll_gdsc_status(void *gdscr_addr)
{
	if (read32(gdscr_addr) & CLK_CTL_OFF_BMSK)
		return CB_SUCCESS;

	clrbits32(gdscr_addr, BIT(GDSC_ENABLE_BIT));

	/* Ensure gdsc is enabled */
	if (!wait_us(100, (read32(gdscr_addr) & CLK_CTL_OFF_BMSK)))
		return CB_ERR;

	return CB_SUCCESS;
}

/* Clock Root clock Generator with MND Operations */
static void clock_configure_mnd(struct clock_rcg *clk, uint32_t m, uint32_t n,
				uint32_t d_2)
{
	struct clock_rcg_mnd *mnd = (struct clock_rcg_mnd *)clk;

	setbits32(&clk->rcg_cfg,
			RCG_MODE_DUAL_EDGE << CLK_CTL_CFG_MODE_SHFT);

	write32(&mnd->m, m & CLK_CTL_RCG_MND_BMSK);
	write32(&mnd->n, ~(n-m) & CLK_CTL_RCG_MND_BMSK);
	write32(&mnd->d_2, ~(d_2) & CLK_CTL_RCG_MND_BMSK);
}

/* Clock Root clock Generator Operations */
enum cb_err clock_configure(struct clock_rcg *clk,
			struct clock_freq_config *clk_cfg, uint32_t hz,
			uint32_t num_perfs)
{
	uint32_t reg_val, idx;

	for (idx = 0; idx < num_perfs; idx++)
		if (hz <= clk_cfg[idx].hz)
			break;

	reg_val = (clk_cfg[idx].src << CLK_CTL_CFG_SRC_SEL_SHFT) |
			(clk_cfg[idx].div << CLK_CTL_CFG_SRC_DIV_SHFT);

	/* Set clock config */
	write32(&clk->rcg_cfg, reg_val);

	if (clk_cfg[idx].m != 0)
		clock_configure_mnd(clk, clk_cfg[idx].m, clk_cfg[idx].n,
				clk_cfg[idx].d_2);

	/* Commit config to RCG */
	setbits32(&clk->rcg_cmd, BIT(CLK_CTL_CMD_UPDATE_SHFT));

	return CB_SUCCESS;
}

/* Clock Root clock Generator with DFS Operations */
void clock_configure_dfsr_table(int qup, struct clock_freq_config *clk_cfg,
		uint32_t num_perfs)
{
	struct qupv3_clock *qup_clk;
	unsigned int idx, s = qup % QUP_WRAP1_S0;
	uint32_t reg_val;

	qup_clk = qup < QUP_WRAP1_S0 ?
				&gcc->qup_wrap0_s[s] : &gcc->qup_wrap1_s[s];

	clrsetbits32(&qup_clk->dfsr_clk.cmd_dfsr,
			BIT(CLK_CTL_CMD_RCG_SW_CTL_SHFT),
			BIT(CLK_CTL_CMD_DFSR_SHFT));

	for (idx = 0; idx < num_perfs; idx++) {
		reg_val = (clk_cfg[idx].src << CLK_CTL_CFG_SRC_SEL_SHFT) |
			(clk_cfg[idx].div << CLK_CTL_CFG_SRC_DIV_SHFT);

		write32(&qup_clk->dfsr_clk.perf_dfsr[idx], reg_val);

		if (clk_cfg[idx].m == 0)
			continue;

		setbits32(&qup_clk->dfsr_clk.perf_dfsr[idx],
				RCG_MODE_DUAL_EDGE << CLK_CTL_CFG_MODE_SHFT);

		reg_val = clk_cfg[idx].m & CLK_CTL_RCG_MND_BMSK;
		write32(&qup_clk->dfsr_clk.perf_m_dfsr[idx], reg_val);

		reg_val = ~(clk_cfg[idx].n - clk_cfg[idx].m)
				& CLK_CTL_RCG_MND_BMSK;
		write32(&qup_clk->dfsr_clk.perf_n_dfsr[idx], reg_val);

		reg_val = ~(clk_cfg[idx].d_2) & CLK_CTL_RCG_MND_BMSK;
		write32(&qup_clk->dfsr_clk.perf_d_dfsr[idx], reg_val);
	}
}

/* General Purpose PLL configuration and enable Operations */
enum cb_err clock_configure_enable_gpll(struct alpha_pll_reg_val_config *cfg,
					bool enable, int br_enable)
{
	if (cfg->l_val)
		write32(cfg->reg_l, cfg->l_val);

	if (cfg->cal_l_val)
		write32(cfg->reg_cal_l, cfg->cal_l_val);

	if (cfg->alpha_val)
		write32(cfg->reg_alpha, cfg->alpha_val);

	if (cfg->user_ctl_val)
		write32(cfg->reg_user_ctl, cfg->user_ctl_val);

	if (cfg->user_ctl_hi_val)
		write32(cfg->reg_user_ctl_hi, cfg->user_ctl_hi_val);

	if (cfg->user_ctl_hi1_val)
		write32(cfg->reg_user_ctl_hi1, cfg->user_ctl_hi1_val);

	if (cfg->config_ctl_val)
		write32(cfg->reg_config_ctl, cfg->config_ctl_val);

	if (cfg->config_ctl_hi_val)
		write32(cfg->reg_config_ctl_hi, cfg->config_ctl_hi_val);

	if (cfg->config_ctl_hi1_val)
		write32(cfg->reg_config_ctl_hi1, cfg->config_ctl_hi1_val);

	if (cfg->fsm_enable)
		setbits32(cfg->reg_mode, BIT(PLL_FSM_EN_SHFT));

	if (enable) {
		setbits32(cfg->reg_opmode, BIT(PLL_STANDBY_MODE));

		/*
		* H/W requires a 1us delay between placing PLL in STANDBY and
		* de-asserting the reset.
		*/
		udelay(1);
		setbits32(cfg->reg_mode, BIT(PLL_RESET_N_SHFT));

		/*
		* H/W requires a 10us delay between de-asserting the reset and
		* enabling the PLL branch bit.
		*/
		udelay(10);
		setbits32(cfg->reg_apcs_pll_br_en, BIT(br_enable));

		/* Wait for Lock Detection */
		if (!wait_us(100, read32(cfg->reg_mode) & PLL_LOCK_DET_BMSK)) {
			printk(BIOS_ERR, "ERROR: PLL did not lock!\n");
			return CB_ERR;
		}
	}

	return CB_SUCCESS;
}

enum cb_err agera_pll_enable(struct alpha_pll_reg_val_config *cfg)
{
	setbits32(cfg->reg_mode, BIT(PLL_BYPASSNL_SHFT));

	/*
	* H/W requires a 5us delay between disabling the bypass and
	* de-asserting the reset.
	*/
	udelay(5);
	setbits32(cfg->reg_mode, BIT(PLL_RESET_SHFT));

	if (!wait_us(100, read32(cfg->reg_mode) & PLL_LOCK_DET_BMSK)) {
		printk(BIOS_ERR, "ERROR: CPU PLL did not lock!\n");
		return CB_ERR;
	}

	setbits32(cfg->reg_mode, BIT(PLL_OUTCTRL_SHFT));

	return CB_SUCCESS;
}

enum cb_err zonda_pll_enable(struct alpha_pll_reg_val_config *cfg)
{
	setbits32(cfg->reg_mode, BIT(PLL_BYPASSNL_SHFT));

	/*
	* H/W requires a 1us delay between disabling the bypass and
	* de-asserting the reset.
	*/
	udelay(1);
	setbits32(cfg->reg_mode, BIT(PLL_RESET_SHFT));
	setbits32(cfg->reg_opmode, PLL_RUN_MODE);

	if (!wait_us(100, read32(cfg->reg_mode) & PLL_LOCK_DET_BMSK)) {
		printk(BIOS_ERR, "ERROR: CPU PLL did not lock!\n");
		return CB_ERR;
	}

	setbits32(cfg->reg_user_ctl, PLL_USERCTL_BMSK);
	setbits32(cfg->reg_mode, BIT(PLL_OUTCTRL_SHFT));

	return CB_SUCCESS;
}

/* Bring subsystem out of RESET */
void clock_reset_subsystem(u32 *misc, u32 shft)
{
	clrbits32(misc, BIT(shft));
}
