// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) ASPEED Technology Inc.
 */

#include <common.h>
#include <clk-uclass.h>
#include <dm.h>
#include <asm/io.h>
#include <dm/lists.h>
#include <linux/delay.h>
#include <asm/arch/scu_ast2600.h>
#include <asm/global_data.h>
#include <dt-bindings/clock/ast2600-clock.h>
#include <dt-bindings/reset/ast2600-reset.h>

DECLARE_GLOBAL_DATA_PTR;

#define CLKIN_25M 25000000UL

/* MAC Clock Delay settings */
#define MAC12_DEF_DELAY_1G		0x0028a410
#define MAC12_DEF_DELAY_100M		0x00410410
#define MAC12_DEF_DELAY_10M		0x00410410
#define MAC34_DEF_DELAY_1G		0x00104208
#define MAC34_DEF_DELAY_100M		0x00104208
#define MAC34_DEF_DELAY_10M		0x00104208

/*
 * 3-bit encode of CPU freqeucy
 * Some code is duplicated
 */
enum ast2600_cpu_freq {
	CPU_FREQ_1200M_1,
	CPU_FREQ_1600M_1,
	CPU_FREQ_1200M_2,
	CPU_FREQ_1600M_2,
	CPU_FREQ_800M_1,
	CPU_FREQ_800M_2,
	CPU_FREQ_800M_3,
	CPU_FREQ_800M_4,
};

struct ast2600_clk_priv {
	struct ast2600_scu *scu;
};

/*
 * Clock divider/multiplier configuration struct.
 * For H-PLL and M-PLL the formula is
 * (Output Frequency) = CLKIN * ((M + 1) / (N + 1)) / (P + 1)
 * M - Numerator
 * N - Denumerator
 * P - Post Divider
 * They have the same layout in their control register.
 *
 * D-PLL and D2-PLL have extra divider (OD + 1), which is not
 * yet needed and ignored by clock configurations.
 */
union ast2600_pll_reg {
	uint32_t w;
	struct {
		unsigned int m : 13;
		unsigned int n : 6;
		unsigned int p : 4;
		unsigned int off : 1;
		unsigned int bypass : 1;
		unsigned int reset : 1;
		unsigned int reserved : 6;
	} b;
};

struct ast2600_pll_cfg {
	union ast2600_pll_reg reg;
	unsigned int ext_reg;
};

struct ast2600_pll_desc {
	uint32_t in;
	uint32_t out;
	struct ast2600_pll_cfg cfg;
};

static const struct ast2600_pll_desc ast2600_pll_lookup[] = {
	{
		.in = CLKIN_25M,
		.out = 400000000,
		.cfg.reg.b.m = 95,
		.cfg.reg.b.n = 2,
		.cfg.reg.b.p = 1,
		.cfg.ext_reg = 0x31,
	},
	{
		.in = CLKIN_25M,
		.out = 200000000,
		.cfg.reg.b.m = 127,
		.cfg.reg.b.n = 0,
		.cfg.reg.b.p = 15,
		.cfg.ext_reg = 0x3f,
	},
	{
		.in = CLKIN_25M,
		.out = 334000000,
		.cfg.reg.b.m = 667,
		.cfg.reg.b.n = 4,
		.cfg.reg.b.p = 9,
		.cfg.ext_reg = 0x14d,
	},
	{
		.in = CLKIN_25M,
		.out = 1000000000,
		.cfg.reg.b.m = 119,
		.cfg.reg.b.n = 2,
		.cfg.reg.b.p = 0,
		.cfg.ext_reg = 0x3d,
	},
	{
		.in = CLKIN_25M,
		.out = 50000000,
		.cfg.reg.b.m = 95,
		.cfg.reg.b.n = 2,
		.cfg.reg.b.p = 15,
		.cfg.ext_reg = 0x31,
	},
};

/* divisor tables */
static uint32_t axi_ahb_div0_table[] = {
	3, 2, 3, 4,
};

static uint32_t axi_ahb_div1_table[] = {
	3, 4, 6, 8,
};

static uint32_t axi_ahb_default_table[] = {
	3, 4, 3, 4, 2, 2, 2, 2,
};

extern uint32_t ast2600_get_pll_rate(struct ast2600_scu *scu, int pll_idx)
{
	union ast2600_pll_reg pll_reg;
	uint32_t hwstrap1;
	uint32_t cpu_freq;
	uint32_t mul = 1, div = 1;

	switch (pll_idx) {
	case ASPEED_CLK_APLL:
		pll_reg.w = readl(&scu->apll);
		break;
	case ASPEED_CLK_DPLL:
		pll_reg.w = readl(&scu->dpll);
		break;
	case ASPEED_CLK_EPLL:
		pll_reg.w = readl(&scu->epll);
		break;
	case ASPEED_CLK_HPLL:
		pll_reg.w = readl(&scu->hpll);
		break;
	case ASPEED_CLK_MPLL:
		pll_reg.w = readl(&scu->mpll);
		break;
	}

	if (!pll_reg.b.bypass) {
		/* F = 25Mhz * [(M + 2) / (n + 1)] / (p + 1)
		 * HPLL Numerator (M) = fix 0x5F when SCU500[10]=1
		 * Fixed 0xBF when SCU500[10]=0 and SCU500[8]=1
		 * SCU200[12:0] (default 0x8F) when SCU510[10]=0 and SCU510[8]=0
		 * HPLL Denumerator (N) =	SCU200[18:13] (default 0x2)
		 * HPLL Divider (P)	 =	SCU200[22:19] (default 0x0)
		 * HPLL Bandwidth Adj (NB) =  fix 0x2F when SCU500[10]=1
		 * Fixed 0x5F when SCU500[10]=0 and SCU500[8]=1
		 * SCU204[11:0] (default 0x31) when SCU500[10]=0 and SCU500[8]=0
		 */
		if (pll_idx == ASPEED_CLK_HPLL) {
			hwstrap1 = readl(&scu->hwstrap1);
			cpu_freq = (hwstrap1 & SCU_HWSTRAP1_CPU_FREQ_MASK) >>
				    SCU_HWSTRAP1_CPU_FREQ_SHIFT;

			switch (cpu_freq) {
			case CPU_FREQ_800M_1:
			case CPU_FREQ_800M_2:
			case CPU_FREQ_800M_3:
			case CPU_FREQ_800M_4:
				pll_reg.b.m = 0x5f;
				break;
			case CPU_FREQ_1600M_1:
			case CPU_FREQ_1600M_2:
				pll_reg.b.m = 0xbf;
				break;
			default:
				pll_reg.b.m = 0x8f;
				break;
			}
		}

		mul = (pll_reg.b.m + 1) / (pll_reg.b.n + 1);
		div = (pll_reg.b.p + 1);
	}

	return ((CLKIN_25M * mul) / div);
}

static uint32_t ast2600_get_hclk_rate(struct ast2600_scu *scu)
{
	uint32_t rate = ast2600_get_pll_rate(scu, ASPEED_CLK_HPLL);
	uint32_t axi_div, ahb_div;
	uint32_t hwstrap1 = readl(&scu->hwstrap1);
	uint32_t cpu_freq = (hwstrap1 & SCU_HWSTRAP1_CPU_FREQ_MASK) >>
			     SCU_HWSTRAP1_CPU_FREQ_SHIFT;
	uint32_t axi_ahb_ratio = (hwstrap1 & SCU_HWSTRAP1_AXI_AHB_CLK_RATIO_MASK) >>
				  SCU_HWSTRAP1_AXI_AHB_CLK_RATIO_SHIFT;

	if (hwstrap1 & SCU_HWSTRAP1_CPU_AXI_CLK_RATIO) {
		axi_ahb_div1_table[0] = axi_ahb_default_table[cpu_freq] * 2;
		axi_div = 1;
		ahb_div = axi_ahb_div1_table[axi_ahb_ratio];
	} else {
		axi_ahb_div0_table[0] = axi_ahb_default_table[cpu_freq];
		axi_div = 2;
		ahb_div = axi_ahb_div0_table[axi_ahb_ratio];
	}

	return (rate / axi_div / ahb_div);
}

static uint32_t ast2600_get_bclk_rate(struct ast2600_scu *scu)
{
	uint32_t rate = ast2600_get_pll_rate(scu, ASPEED_CLK_HPLL);
	uint32_t clksrc1 = readl(&scu->clksrc1);
	uint32_t bclk_div = (clksrc1 & SCU_CLKSRC1_BCLK_DIV_MASK) >>
			     SCU_CLKSRC1_BCLK_DIV_SHIFT;

	return (rate / ((bclk_div + 1) * 4));
}

static uint32_t ast2600_get_pclk1_rate(struct ast2600_scu *scu)
{
	uint32_t rate = ast2600_get_pll_rate(scu, ASPEED_CLK_HPLL);
	uint32_t clksrc1 = readl(&scu->clksrc1);
	uint32_t pclk_div = (clksrc1 & SCU_CLKSRC1_PCLK_DIV_MASK) >>
			     SCU_CLKSRC1_PCLK_DIV_SHIFT;

	return (rate / ((pclk_div + 1) * 4));
}

static uint32_t ast2600_get_pclk2_rate(struct ast2600_scu *scu)
{
	uint32_t rate = ast2600_get_hclk_rate(scu);
	uint32_t clksrc4 = readl(&scu->clksrc4);
	uint32_t pclk_div = (clksrc4 & SCU_CLKSRC4_PCLK_DIV_MASK) >>
			     SCU_CLKSRC4_PCLK_DIV_SHIFT;

	return (rate / ((pclk_div + 1) * 2));
}

static uint32_t ast2600_get_uxclk_in_rate(struct ast2600_scu *scu)
{
	uint32_t rate = 0;
	uint32_t clksrc5 = readl(&scu->clksrc5);
	uint32_t uxclk = (clksrc5 & SCU_CLKSRC5_UXCLK_MASK) >>
			  SCU_CLKSRC5_UXCLK_SHIFT;

	switch (uxclk) {
	case 0:
		rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL) / 4;
		break;
	case 1:
		rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL) / 2;
		break;
	case 2:
		rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL);
		break;
	case 3:
		rate = ast2600_get_hclk_rate(scu);
		break;
	}

	return rate;
}

static uint32_t ast2600_get_huxclk_in_rate(struct ast2600_scu *scu)
{
	uint32_t rate = 0;
	uint32_t clksrc5 = readl(&scu->clksrc5);
	uint32_t huxclk = (clksrc5 & SCU_CLKSRC5_HUXCLK_MASK) >>
			   SCU_CLKSRC5_HUXCLK_SHIFT;

	switch (huxclk) {
	case 0:
		rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL) / 4;
		break;
	case 1:
		rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL) / 2;
		break;
	case 2:
		rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL);
		break;
	case 3:
		rate = ast2600_get_hclk_rate(scu);
		break;
	}

	return rate;
}

static uint32_t ast2600_get_uart_uxclk_rate(struct ast2600_scu *scu)
{
	uint32_t rate = ast2600_get_uxclk_in_rate(scu);
	uint32_t uart_clkgen = readl(&scu->uart_clkgen);
	uint32_t n = (uart_clkgen & SCU_UART_CLKGEN_N_MASK) >>
		      SCU_UART_CLKGEN_N_SHIFT;
	uint32_t r = (uart_clkgen & SCU_UART_CLKGEN_R_MASK) >>
		      SCU_UART_CLKGEN_R_SHIFT;

	return ((rate * r) / (n * 2));
}

static uint32_t ast2600_get_uart_huxclk_rate(struct ast2600_scu *scu)
{
	uint32_t rate = ast2600_get_huxclk_in_rate(scu);
	uint32_t huart_clkgen = readl(&scu->huart_clkgen);
	uint32_t n = (huart_clkgen & SCU_HUART_CLKGEN_N_MASK) >>
		      SCU_HUART_CLKGEN_N_SHIFT;
	uint32_t r = (huart_clkgen & SCU_HUART_CLKGEN_R_MASK) >>
		      SCU_HUART_CLKGEN_R_SHIFT;

	return ((rate * r) / (n * 2));
}

static uint32_t ast2600_get_sdio_clk_rate(struct ast2600_scu *scu)
{
	uint32_t rate = 0;
	uint32_t clksrc4 = readl(&scu->clksrc4);
	uint32_t sdio_div = (clksrc4 & SCU_CLKSRC4_SDIO_DIV_MASK) >>
			     SCU_CLKSRC4_SDIO_DIV_SHIFT;

	if (clksrc4 & SCU_CLKSRC4_SDIO)
		rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL);
	else
		rate = ast2600_get_hclk_rate(scu);

	return (rate / ((sdio_div + 1) * 2));
}

static uint32_t ast2600_get_emmc_clk_rate(struct ast2600_scu *scu)
{
	uint32_t rate = ast2600_get_pll_rate(scu, ASPEED_CLK_HPLL);
	uint32_t clksrc1 = readl(&scu->clksrc1);
	uint32_t emmc_div = (clksrc1 & SCU_CLKSRC1_EMMC_DIV_MASK) >>
			     SCU_CLKSRC1_EMMC_DIV_SHIFT;

	return (rate / ((emmc_div + 1) * 4));
}

static uint32_t ast2600_get_uart_clk_rate(struct ast2600_scu *scu, int uart_idx)
{
	uint32_t rate = 0;
	uint32_t uart5_clk = 0;
	uint32_t clksrc2 = readl(&scu->clksrc2);
	uint32_t clksrc4 = readl(&scu->clksrc4);
	uint32_t clksrc5 = readl(&scu->clksrc5);
	uint32_t misc_ctrl1 = readl(&scu->misc_ctrl1);

	switch (uart_idx) {
	case 1:
	case 2:
	case 3:
	case 4:
	case 6:
		if (clksrc4 & BIT(uart_idx - 1))
			rate = ast2600_get_uart_huxclk_rate(scu);
		else
			rate = ast2600_get_uart_uxclk_rate(scu);
		break;
	case 5:
		/*
		 * SCU0C[12] and SCU304[14] together decide
		 * the UART5 clock generation
		 */
		if (misc_ctrl1 & SCU_MISC_CTRL1_UART5_DIV)
			uart5_clk = 0x1 << 1;

		if (clksrc2 & SCU_CLKSRC2_UART5)
			uart5_clk |= 0x1;

		switch (uart5_clk) {
		case 0:
			rate = 24000000;
			break;
		case 1:
			rate = 192000000;
			break;
		case 2:
			rate = 24000000 / 13;
			break;
		case 3:
			rate = 192000000 / 13;
			break;
		}

		break;
	case 7:
	case 8:
	case 9:
	case 10:
	case 11:
	case 12:
	case 13:
		if (clksrc5 & BIT(uart_idx - 1))
			rate = ast2600_get_uart_huxclk_rate(scu);
		else
			rate = ast2600_get_uart_uxclk_rate(scu);
		break;
	}

	return rate;
}

static ulong ast2600_clk_get_rate(struct clk *clk)
{
	struct ast2600_clk_priv *priv = dev_get_priv(clk->dev);
	ulong rate = 0;

	switch (clk->id) {
	case ASPEED_CLK_HPLL:
	case ASPEED_CLK_EPLL:
	case ASPEED_CLK_DPLL:
	case ASPEED_CLK_MPLL:
	case ASPEED_CLK_APLL:
		rate = ast2600_get_pll_rate(priv->scu, clk->id);
		break;
	case ASPEED_CLK_AHB:
		rate = ast2600_get_hclk_rate(priv->scu);
		break;
	case ASPEED_CLK_APB1:
		rate = ast2600_get_pclk1_rate(priv->scu);
		break;
	case ASPEED_CLK_APB2:
		rate = ast2600_get_pclk2_rate(priv->scu);
		break;
	case ASPEED_CLK_GATE_UART1CLK:
		rate = ast2600_get_uart_clk_rate(priv->scu, 1);
		break;
	case ASPEED_CLK_GATE_UART2CLK:
		rate = ast2600_get_uart_clk_rate(priv->scu, 2);
		break;
	case ASPEED_CLK_GATE_UART3CLK:
		rate = ast2600_get_uart_clk_rate(priv->scu, 3);
		break;
	case ASPEED_CLK_GATE_UART4CLK:
		rate = ast2600_get_uart_clk_rate(priv->scu, 4);
		break;
	case ASPEED_CLK_GATE_UART5CLK:
		rate = ast2600_get_uart_clk_rate(priv->scu, 5);
		break;
	case ASPEED_CLK_BCLK:
		rate = ast2600_get_bclk_rate(priv->scu);
		break;
	case ASPEED_CLK_SDIO:
		rate = ast2600_get_sdio_clk_rate(priv->scu);
		break;
	case ASPEED_CLK_EMMC:
		rate = ast2600_get_emmc_clk_rate(priv->scu);
		break;
	case ASPEED_CLK_UARTX:
		rate = ast2600_get_uart_uxclk_rate(priv->scu);
		break;
	case ASPEED_CLK_HUARTX:
		rate = ast2600_get_uart_huxclk_rate(priv->scu);
		break;
	default:
		debug("%s: unknown clk %ld\n", __func__, clk->id);
		return -ENOENT;
	}

	return rate;
}

/**
 * @brief	lookup PLL divider config by input/output rate
 * @param[in]	*pll - PLL descriptor
 * Return:	true - if PLL divider config is found, false - else
 * The function caller shall fill "pll->in" and "pll->out",
 * then this function will search the lookup table
 * to find a valid PLL divider configuration.
 */
static bool ast2600_search_clock_config(struct ast2600_pll_desc *pll)
{
	uint32_t i;
	const struct ast2600_pll_desc *def_desc;
	bool is_found = false;

	for (i = 0; i < ARRAY_SIZE(ast2600_pll_lookup); i++) {
		def_desc = &ast2600_pll_lookup[i];

		if (def_desc->in == pll->in && def_desc->out == pll->out) {
			is_found = true;
			pll->cfg.reg.w = def_desc->cfg.reg.w;
			pll->cfg.ext_reg = def_desc->cfg.ext_reg;
			break;
		}
	}
	return is_found;
}

static uint32_t ast2600_configure_pll(struct ast2600_scu *scu,
				 struct ast2600_pll_cfg *p_cfg, int pll_idx)
{
	uint32_t addr, addr_ext;
	uint32_t reg;

	switch (pll_idx) {
	case ASPEED_CLK_HPLL:
		addr = (uint32_t)(&scu->hpll);
		addr_ext = (uint32_t)(&scu->hpll_ext);
		break;
	case ASPEED_CLK_MPLL:
		addr = (uint32_t)(&scu->mpll);
		addr_ext = (uint32_t)(&scu->mpll_ext);
		break;
	case ASPEED_CLK_DPLL:
		addr = (uint32_t)(&scu->dpll);
		addr_ext = (uint32_t)(&scu->dpll_ext);
		break;
	case ASPEED_CLK_EPLL:
		addr = (uint32_t)(&scu->epll);
		addr_ext = (uint32_t)(&scu->epll_ext);
		break;
	case ASPEED_CLK_APLL:
		addr = (uint32_t)(&scu->apll);
		addr_ext = (uint32_t)(&scu->apll_ext);
		break;
	default:
		debug("unknown PLL index\n");
		return 1;
	}

	p_cfg->reg.b.bypass = 0;
	p_cfg->reg.b.off = 1;
	p_cfg->reg.b.reset = 1;

	reg = readl(addr);
	reg &= ~GENMASK(25, 0);
	reg |= p_cfg->reg.w;
	writel(reg, addr);

	/* write extend parameter */
	writel(p_cfg->ext_reg, addr_ext);
	udelay(100);
	p_cfg->reg.b.off = 0;
	p_cfg->reg.b.reset = 0;
	reg &= ~GENMASK(25, 0);
	reg |= p_cfg->reg.w;
	writel(reg, addr);
	while (!(readl(addr_ext) & BIT(31)))
		;

	return 0;
}

static uint32_t ast2600_configure_ddr(struct ast2600_scu *scu, ulong rate)
{
	struct ast2600_pll_desc mpll;

	mpll.in = CLKIN_25M;
	mpll.out = rate;
	if (ast2600_search_clock_config(&mpll) == false) {
		printf("error!! unable to find valid DDR clock setting\n");
		return 0;
	}
	ast2600_configure_pll(scu, &mpll.cfg, ASPEED_CLK_MPLL);

	return ast2600_get_pll_rate(scu, ASPEED_CLK_MPLL);
}

static ulong ast2600_clk_set_rate(struct clk *clk, ulong rate)
{
	struct ast2600_clk_priv *priv = dev_get_priv(clk->dev);
	ulong new_rate;

	switch (clk->id) {
	case ASPEED_CLK_MPLL:
		new_rate = ast2600_configure_ddr(priv->scu, rate);
		break;
	default:
		return -ENOENT;
	}

	return new_rate;
}

static uint32_t ast2600_configure_mac12_clk(struct ast2600_scu *scu)
{
	/* scu340[25:0]: 1G default delay */
	clrsetbits_le32(&scu->mac12_clk_delay, GENMASK(25, 0),
			MAC12_DEF_DELAY_1G);

	/* set 100M/10M default delay */
	writel(MAC12_DEF_DELAY_100M, &scu->mac12_clk_delay_100M);
	writel(MAC12_DEF_DELAY_10M, &scu->mac12_clk_delay_10M);

	/* MAC AHB = HPLL / 6 */
	clrsetbits_le32(&scu->clksrc1, SCU_CLKSRC1_MAC_DIV_MASK,
			(0x2 << SCU_CLKSRC1_MAC_DIV_SHIFT));

	return 0;
}

static uint32_t ast2600_configure_mac34_clk(struct ast2600_scu *scu)
{
	/*
	 * scu350[31]   RGMII 125M source: 0 = from IO pin
	 * scu350[25:0] MAC 1G delay
	 */
	clrsetbits_le32(&scu->mac34_clk_delay, (BIT(31) | GENMASK(25, 0)),
			MAC34_DEF_DELAY_1G);
	writel(MAC34_DEF_DELAY_100M, &scu->mac34_clk_delay_100M);
	writel(MAC34_DEF_DELAY_10M, &scu->mac34_clk_delay_10M);

	/*
	 * clock source seletion and divider
	 * scu310[26:24] : MAC AHB bus clock = HCLK / 2
	 * scu310[18:16] : RMII 50M = HCLK_200M / 4
	 */
	clrsetbits_le32(&scu->clksrc4,
			(SCU_CLKSRC4_MAC_DIV_MASK | SCU_CLKSRC4_RMII34_DIV_MASK),
			((0x0 << SCU_CLKSRC4_MAC_DIV_SHIFT)
			 | (0x3 << SCU_CLKSRC4_RMII34_DIV_SHIFT)));

	/*
	 * set driving strength
	 * scu458[3:2] : MAC4 driving strength
	 * scu458[1:0] : MAC3 driving strength
	 */
	clrsetbits_le32(&scu->pinmux16,
			SCU_PINCTRL16_MAC4_DRIVING_MASK | SCU_PINCTRL16_MAC3_DRIVING_MASK,
			(0x3 << SCU_PINCTRL16_MAC4_DRIVING_SHIFT)
			 | (0x3 << SCU_PINCTRL16_MAC3_DRIVING_SHIFT));

	return 0;
}

/**
 * ast2600 RGMII clock source tree
 * 125M from external PAD -------->|\
 * HPLL -->|\                      | |---->RGMII 125M for MAC#1 & MAC#2
 *         | |---->| divider |---->|/                             +
 * EPLL -->|/                                                     |
 *                                                                |
 * +---------<-----------|RGMIICK PAD output enable|<-------------+
 * |
 * +--------------------------->|\
 *                              | |----> RGMII 125M for MAC#3 & MAC#4
 * HCLK 200M ---->|divider|---->|/
 * To simplify the control flow:
 * 1. RGMII 1/2 always use EPLL as the internal clock source
 * 2. RGMII 3/4 always use RGMIICK pad as the RGMII 125M source
 * 125M from external PAD -------->|\
 *                                 | |---->RGMII 125M for MAC#1 & MAC#2
 *         EPLL---->| divider |--->|/                             +
 *                                                                |
 * +<--------------------|RGMIICK PAD output enable|<-------------+
 * |
 * +--------------------------->RGMII 125M for MAC#3 & MAC#4
 */
#define RGMIICK_SRC_PAD		0
#define RGMIICK_SRC_EPLL	1 /* recommended */
#define RGMIICK_SRC_HPLL	2

#define RGMIICK_DIV2	1
#define RGMIICK_DIV3	2
#define RGMIICK_DIV4	3
#define RGMIICK_DIV5	4
#define RGMIICK_DIV6	5
#define RGMIICK_DIV7	6
#define RGMIICK_DIV8	7 /* recommended */

#define RMIICK_DIV4		0
#define RMIICK_DIV8		1
#define RMIICK_DIV12	2
#define RMIICK_DIV16	3
#define RMIICK_DIV20	4 /* recommended */
#define RMIICK_DIV24	5
#define RMIICK_DIV28	6
#define RMIICK_DIV32	7

struct ast2600_mac_clk_div {
	uint32_t src; /* 0=external PAD, 1=internal PLL */
	uint32_t fin; /* divider input speed */
	uint32_t n; /* 0=div2, 1=div2, 2=div3, 3=div4,...,7=div8 */
	uint32_t fout; /* fout = fin / n */
};

struct ast2600_mac_clk_div rgmii_clk_defconfig = {
	.src = ASPEED_CLK_EPLL,
	.fin = 1000000000,
	.n = RGMIICK_DIV8,
	.fout = 125000000,
};

struct ast2600_mac_clk_div rmii_clk_defconfig = {
	.src = ASPEED_CLK_EPLL,
	.fin = 1000000000,
	.n = RMIICK_DIV20,
	.fout = 50000000,
};

static void ast2600_init_mac_pll(struct ast2600_scu *p_scu,
				 struct ast2600_mac_clk_div *p_cfg)
{
	struct ast2600_pll_desc pll;

	pll.in = CLKIN_25M;
	pll.out = p_cfg->fin;
	if (ast2600_search_clock_config(&pll) == false) {
		pr_err("unable to find valid ETHNET MAC clock setting\n");
		return;
	}
	ast2600_configure_pll(p_scu, &pll.cfg, p_cfg->src);
}

static void ast2600_init_rgmii_clk(struct ast2600_scu *p_scu,
				   struct ast2600_mac_clk_div *p_cfg)
{
	uint32_t reg_304 = readl(&p_scu->clksrc2);
	uint32_t reg_340 = readl(&p_scu->mac12_clk_delay);
	uint32_t reg_350 = readl(&p_scu->mac34_clk_delay);

	reg_340 &= ~GENMASK(31, 29);
	/* scu340[28]: RGMIICK PAD output enable (to MAC 3/4) */
	reg_340 |= BIT(28);
	if (p_cfg->src == ASPEED_CLK_EPLL || p_cfg->src == ASPEED_CLK_HPLL) {
		/*
		 * re-init PLL if the current PLL output frequency doesn't match
		 * the divider setting
		 */
		if (p_cfg->fin != ast2600_get_pll_rate(p_scu, p_cfg->src))
			ast2600_init_mac_pll(p_scu, p_cfg);
		/* scu340[31]: select RGMII 125M from internal source */
		reg_340 |= BIT(31);
	}

	reg_304 &= ~GENMASK(23, 20);

	/* set clock divider */
	reg_304 |= (p_cfg->n & 0x7) << 20;

	/* select internal clock source */
	if (p_cfg->src == ASPEED_CLK_HPLL)
		reg_304 |= BIT(23);

	/* RGMII 3/4 clock source select */
	reg_350 &= ~BIT(31);

	writel(reg_304, &p_scu->clksrc2);
	writel(reg_340, &p_scu->mac12_clk_delay);
	writel(reg_350, &p_scu->mac34_clk_delay);
}

/**
 * ast2600 RMII/NCSI clock source tree
 * HPLL -->|\
 *         | |---->| divider |----> RMII 50M for MAC#1 & MAC#2
 * EPLL -->|/
 * HCLK(SCLICLK)---->| divider |----> RMII 50M for MAC#3 & MAC#4
 */
static void ast2600_init_rmii_clk(struct ast2600_scu *p_scu,
				  struct ast2600_mac_clk_div *p_cfg)
{
	uint32_t clksrc2 = readl(&p_scu->clksrc2);
	uint32_t clksrc4 = readl(&p_scu->clksrc4);

	if (p_cfg->src == ASPEED_CLK_EPLL || p_cfg->src == ASPEED_CLK_HPLL) {
		/*
		 * re-init PLL if the current PLL output frequency doesn't match
		 * the divider setting
		 */
		if (p_cfg->fin != ast2600_get_pll_rate(p_scu, p_cfg->src))
			ast2600_init_mac_pll(p_scu, p_cfg);
	}

	clksrc2 &= ~(SCU_CLKSRC2_RMII12 | SCU_CLKSRC2_RMII12_DIV_MASK);

	/* set RMII 1/2 clock divider */
	clksrc2 |= (p_cfg->n & 0x7) << 16;

	/* RMII clock source selection */
	if (p_cfg->src == ASPEED_CLK_HPLL)
		clksrc2 |= SCU_CLKSRC2_RMII12;

	/* set RMII 3/4 clock divider */
	clksrc4 &= ~SCU_CLKSRC4_RMII34_DIV_MASK;
	clksrc4 |= (0x3 << SCU_CLKSRC4_RMII34_DIV_SHIFT);

	writel(clksrc2, &p_scu->clksrc2);
	writel(clksrc4, &p_scu->clksrc4);
}

static uint32_t ast2600_configure_mac(struct ast2600_scu *scu, int index)
{
	uint32_t reset_bit;
	uint32_t clkgate_bit;

	switch (index) {
	case 1:
		reset_bit = BIT(ASPEED_RESET_MAC1);
		clkgate_bit = SCU_CLKGATE1_MAC1;
		writel(reset_bit, &scu->modrst_ctrl1);
		udelay(100);
		writel(clkgate_bit, &scu->clkgate_clr1);
		mdelay(10);
		writel(reset_bit, &scu->modrst_clr1);
		break;
	case 2:
		reset_bit = BIT(ASPEED_RESET_MAC2);
		clkgate_bit = SCU_CLKGATE1_MAC2;
		writel(reset_bit, &scu->modrst_ctrl1);
		udelay(100);
		writel(clkgate_bit, &scu->clkgate_clr1);
		mdelay(10);
		writel(reset_bit, &scu->modrst_clr1);
		break;
	case 3:
		reset_bit = BIT(ASPEED_RESET_MAC3 - 32);
		clkgate_bit = SCU_CLKGATE2_MAC3;
		writel(reset_bit, &scu->modrst_ctrl2);
		udelay(100);
		writel(clkgate_bit, &scu->clkgate_clr2);
		mdelay(10);
		writel(reset_bit, &scu->modrst_clr2);
		break;
	case 4:
		reset_bit = BIT(ASPEED_RESET_MAC4 - 32);
		clkgate_bit = SCU_CLKGATE2_MAC4;
		writel(reset_bit, &scu->modrst_ctrl2);
		udelay(100);
		writel(clkgate_bit, &scu->clkgate_clr2);
		mdelay(10);
		writel(reset_bit, &scu->modrst_clr2);
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static void ast2600_configure_rsa_ecc_clk(struct ast2600_scu *scu)
{
	uint32_t clksrc1 = readl(&scu->clksrc1);

	/* Configure RSA clock = HPLL/3 */
	clksrc1 |= SCU_CLKSRC1_ECC_RSA;
	clksrc1 &= ~SCU_CLKSRC1_ECC_RSA_DIV_MASK;
	clksrc1 |= (2 << SCU_CLKSRC1_ECC_RSA_DIV_SHIFT);

	writel(clksrc1, &scu->clksrc1);
}

static ulong ast2600_enable_sdclk(struct ast2600_scu *scu)
{
	uint32_t reset_bit;
	uint32_t clkgate_bit;

	reset_bit = BIT(ASPEED_RESET_SD - 32);
	clkgate_bit = SCU_CLKGATE2_SDIO;

	writel(reset_bit, &scu->modrst_ctrl2);
	udelay(100);
	writel(clkgate_bit, &scu->clkgate_clr2);
	mdelay(10);
	writel(reset_bit, &scu->modrst_clr2);

	return 0;
}

static ulong ast2600_enable_extsdclk(struct ast2600_scu *scu)
{
	int i = 0;
	uint32_t div = 0;
	uint32_t rate = 0;
	uint32_t clksrc4 = readl(&scu->clksrc4);

	/*
	 * ast2600 SD controller max clk is 200Mhz
	 * use apll for clock source 800/4 = 200
	 * controller max is 200mhz
	 */
	rate = ast2600_get_pll_rate(scu, ASPEED_CLK_APLL);
	for (i = 0; i < 8; i++) {
		div = (i + 1) * 2;
		if ((rate / div) <= 200000000)
			break;
	}
	clksrc4 &= ~SCU_CLKSRC4_SDIO_DIV_MASK;
	clksrc4 |= (i << SCU_CLKSRC4_SDIO_DIV_SHIFT);
	clksrc4 |= SCU_CLKSRC4_SDIO;
	writel(clksrc4, &scu->clksrc4);

	setbits_le32(&scu->clksrc4, SCU_CLKSRC4_SDIO_EN);

	return 0;
}

static ulong ast2600_enable_emmcclk(struct ast2600_scu *scu)
{
	uint32_t reset_bit;
	uint32_t clkgate_bit;

	reset_bit = BIT(ASPEED_RESET_EMMC);
	clkgate_bit = SCU_CLKGATE1_EMMC;

	writel(reset_bit, &scu->modrst_ctrl1);
	udelay(100);
	writel(clkgate_bit, &scu->clkgate_clr1);
	mdelay(10);
	writel(reset_bit, &scu->modrst_clr1);

	return 0;
}

static ulong ast2600_enable_extemmcclk(struct ast2600_scu *scu)
{
	int i = 0;
	uint32_t div = 0;
	uint32_t rate = 0;
	uint32_t clksrc1 = readl(&scu->clksrc1);

	/*
	 * ast2600 eMMC controller max clk is 200Mhz
	 * HPll->1/2->|\
	 *				|->SCU300[11]->SCU300[14:12][1/N] +
	 * MPLL------>|/								  |
	 * +----------------------------------------------+
	 * |
	 * +---------> EMMC12C[15:8][1/N]-> eMMC clk
	 */
	rate = ast2600_get_pll_rate(scu, ASPEED_CLK_MPLL);
	for (i = 0; i < 8; i++) {
		div = (i + 1) * 2;
		if ((rate / div) <= 200000000)
			break;
	}

	clksrc1 &= ~SCU_CLKSRC1_EMMC_DIV_MASK;
	clksrc1 |= (i << SCU_CLKSRC1_EMMC_DIV_SHIFT);
	clksrc1 |= SCU_CLKSRC1_EMMC;
	writel(clksrc1, &scu->clksrc1);

	setbits_le32(&scu->clksrc1, SCU_CLKSRC1_EMMC_EN);

	return 0;
}

static ulong ast2600_enable_fsiclk(struct ast2600_scu *scu)
{
	uint32_t reset_bit;
	uint32_t clkgate_bit;

	reset_bit = BIT(ASPEED_RESET_FSI % 32);
	clkgate_bit = SCU_CLKGATE2_FSI;

	/* The FSI clock is shared between masters. If it's already on
	 * don't touch it, as that will reset the existing master.
	 */
	if (!(readl(&scu->clkgate_ctrl2) & clkgate_bit)) {
		debug("%s: already running, not touching it\n", __func__);
		return 0;
	}

	writel(reset_bit, &scu->modrst_ctrl2);
	udelay(100);
	writel(clkgate_bit, &scu->clkgate_clr2);
	mdelay(10);
	writel(reset_bit, &scu->modrst_clr2);

	return 0;
}

static ulong ast2600_enable_usbahclk(struct ast2600_scu *scu)
{
	uint32_t reset_bit;
	uint32_t clkgate_bit;

	reset_bit = BIT(ASPEED_RESET_EHCI_P1);
	clkgate_bit = SCU_CLKGATE1_USB_HUB;

	writel(reset_bit, &scu->modrst_ctrl1);
	udelay(100);
	writel(clkgate_bit, &scu->clkgate_ctrl1);
	mdelay(20);
	writel(reset_bit, &scu->modrst_clr1);

	return 0;
}

static ulong ast2600_enable_usbbhclk(struct ast2600_scu *scu)
{
	uint32_t reset_bit;
	uint32_t clkgate_bit;

	reset_bit = BIT(ASPEED_RESET_EHCI_P2);
	clkgate_bit = SCU_CLKGATE1_USB_HOST2;

	writel(reset_bit, &scu->modrst_ctrl1);
	udelay(100);
	writel(clkgate_bit, &scu->clkgate_clr1);
	mdelay(20);
	writel(reset_bit, &scu->modrst_clr1);

	return 0;
}

static ulong ast2600_enable_haceclk(struct ast2600_scu *scu)
{
	uint32_t reset_bit;
	uint32_t clkgate_bit;

	/* share the same reset control bit with ACRY */
	reset_bit = BIT(ASPEED_RESET_HACE);
	clkgate_bit = SCU_CLKGATE1_HACE;

	/*
	 * we don't do reset assertion here as HACE
	 * shares the same reset control with ACRY
	 */
	writel(clkgate_bit, &scu->clkgate_clr1);
	mdelay(20);
	writel(reset_bit, &scu->modrst_clr1);

	return 0;
}

static ulong ast2600_enable_rsaclk(struct ast2600_scu *scu)
{
	uint32_t reset_bit;
	uint32_t clkgate_bit;

	/* same reset control bit with HACE */
	reset_bit = BIT(ASPEED_RESET_HACE);
	clkgate_bit = SCU_CLKGATE1_ACRY;

	/*
	 * we don't do reset assertion here as HACE
	 * shares the same reset control with ACRY
	 */
	writel(clkgate_bit, &scu->clkgate_clr1);
	mdelay(20);
	writel(reset_bit, &scu->modrst_clr1);

	return 0;
}

static int ast2600_clk_enable(struct clk *clk)
{
	struct ast2600_clk_priv *priv = dev_get_priv(clk->dev);

	switch (clk->id) {
	case ASPEED_CLK_GATE_MAC1CLK:
		ast2600_configure_mac(priv->scu, 1);
		break;
	case ASPEED_CLK_GATE_MAC2CLK:
		ast2600_configure_mac(priv->scu, 2);
		break;
	case ASPEED_CLK_GATE_MAC3CLK:
		ast2600_configure_mac(priv->scu, 3);
		break;
	case ASPEED_CLK_GATE_MAC4CLK:
		ast2600_configure_mac(priv->scu, 4);
		break;
	case ASPEED_CLK_GATE_SDCLK:
		ast2600_enable_sdclk(priv->scu);
		break;
	case ASPEED_CLK_SDIO:
		ast2600_enable_extsdclk(priv->scu);
		break;
	case ASPEED_CLK_GATE_EMMCCLK:
		ast2600_enable_emmcclk(priv->scu);
		break;
	case ASPEED_CLK_EMMC:
		ast2600_enable_extemmcclk(priv->scu);
		break;
	case ASPEED_CLK_GATE_FSICLK:
		ast2600_enable_fsiclk(priv->scu);
		break;
	case ASPEED_CLK_GATE_USBPORT1CLK:
		ast2600_enable_usbahclk(priv->scu);
		break;
	case ASPEED_CLK_GATE_USBPORT2CLK:
		ast2600_enable_usbbhclk(priv->scu);
		break;
	case ASPEED_CLK_GATE_YCLK:
		ast2600_enable_haceclk(priv->scu);
		break;
	case ASPEED_CLK_GATE_RSACLK:
		ast2600_enable_rsaclk(priv->scu);
		break;
	default:
		debug("%s: unknown clk %ld\n", __func__, clk->id);
		return -ENOENT;
	}

	return 0;
}

struct clk_ops ast2600_clk_ops = {
	.get_rate = ast2600_clk_get_rate,
	.set_rate = ast2600_clk_set_rate,
	.enable = ast2600_clk_enable,
};

static int ast2600_clk_probe(struct udevice *dev)
{
	struct ast2600_clk_priv *priv = dev_get_priv(dev);

	priv->scu = devfdt_get_addr_ptr(dev);
	if (IS_ERR(priv->scu))
		return PTR_ERR(priv->scu);

	ast2600_init_rgmii_clk(priv->scu, &rgmii_clk_defconfig);
	ast2600_init_rmii_clk(priv->scu, &rmii_clk_defconfig);
	ast2600_configure_mac12_clk(priv->scu);
	ast2600_configure_mac34_clk(priv->scu);
	ast2600_configure_rsa_ecc_clk(priv->scu);

	return 0;
}

static int ast2600_clk_bind(struct udevice *dev)
{
	int ret;

	/* The reset driver does not have a device node, so bind it here */
	ret = device_bind_driver(gd->dm_root, "ast_sysreset", "reset", &dev);
	if (ret)
		debug("Warning: No reset driver: ret=%d\n", ret);

	return 0;
}

struct aspeed_clks {
	ulong id;
	const char *name;
};

static struct aspeed_clks aspeed_clk_names[] = {
	{ ASPEED_CLK_HPLL, "hpll" },
	{ ASPEED_CLK_MPLL, "mpll" },
	{ ASPEED_CLK_APLL, "apll" },
	{ ASPEED_CLK_EPLL, "epll" },
	{ ASPEED_CLK_DPLL, "dpll" },
	{ ASPEED_CLK_AHB, "hclk" },
	{ ASPEED_CLK_APB1, "pclk1" },
	{ ASPEED_CLK_APB2, "pclk2" },
	{ ASPEED_CLK_BCLK, "bclk" },
	{ ASPEED_CLK_UARTX, "uxclk" },
	{ ASPEED_CLK_HUARTX, "huxclk" },
};

int soc_clk_dump(void)
{
	struct udevice *dev;
	struct clk clk;
	unsigned long rate;
	int i, ret;

	ret = uclass_get_device_by_driver(UCLASS_CLK, DM_DRIVER_GET(aspeed_scu),
					  &dev);
	if (ret)
		return ret;

	printf("Clk\t\tHz\n");

	for (i = 0; i < ARRAY_SIZE(aspeed_clk_names); i++) {
		clk.id = aspeed_clk_names[i].id;
		ret = clk_request(dev, &clk);
		if (ret < 0) {
			debug("%s clk_request() failed: %d\n", __func__, ret);
			continue;
		}

		ret = clk_get_rate(&clk);
		rate = ret;

		clk_free(&clk);

		if (ret == -EINVAL) {
			printf("clk ID %lu not supported yet\n",
			       aspeed_clk_names[i].id);
			continue;
		}
		if (ret < 0) {
			printf("%s %lu: get_rate err: %d\n", __func__,
			       aspeed_clk_names[i].id, ret);
			continue;
		}

		printf("%s(%3lu):\t%lu\n", aspeed_clk_names[i].name,
		       aspeed_clk_names[i].id, rate);
	}

	return 0;
}

static const struct udevice_id ast2600_clk_ids[] = {
	{ .compatible = "aspeed,ast2600-scu", },
	{ },
};

U_BOOT_DRIVER(aspeed_ast2600_scu) = {
	.name = "aspeed_ast2600_scu",
	.id = UCLASS_CLK,
	.of_match = ast2600_clk_ids,
	.priv_auto = sizeof(struct ast2600_clk_priv),
	.ops = &ast2600_clk_ops,
	.bind = ast2600_clk_bind,
	.probe = ast2600_clk_probe,
};
