// 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		0x0041b75d
#define MAC12_DEF_DELAY_100M	0x00417410
#define MAC12_DEF_DELAY_10M		0x00417410
#define MAC34_DEF_DELAY_1G		0x0010438a
#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 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;
	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,
};
