// 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("can't get clk rate\n");
		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_GATE_SDEXTCLK:
		ast2600_enable_extsdclk(priv->scu);
		break;
	case ASPEED_CLK_GATE_EMMCCLK:
		ast2600_enable_emmcclk(priv->scu);
		break;
	case ASPEED_CLK_GATE_EMMCEXTCLK:
		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:
		pr_err("can't enable clk\n");
		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,
};
