// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2018 - Jian Hu <jian.hu@amlogic.com>
 * Author: Jian Hu <jian.hu@amlogic.com>
 */

#include <common.h>
#include <asm/arch/clock.h>
#include <asm/io.h>
#include <clk-uclass.h>
#include <div64.h>
#include <dm.h>
#include <dt-bindings/clock/g12-clkc.h>
#include "clk_meson.h"

/* clk81 gates */
static struct meson_gate gates[] = {
		{CLKID_MIPI_DSI_HOST,	HHI_GCLK_MPEG0, 3},
		{CLKID_ETH_PHY,		HHI_GCLK_MPEG0, 4},
		{CLKID_SPICC0,		HHI_GCLK_MPEG0, 8},
		{CLKID_I2C,		HHI_GCLK_MPEG0, 9},
		{CLKID_UART0,		HHI_GCLK_MPEG0, 13},
		{CLKID_SPICC1,		HHI_GCLK_MPEG0, 14},
		{CLKID_MIPI_DSI_PHY,	HHI_GCLK_MPEG0, 20},
		{CLKID_SD_EMMC_A,	HHI_GCLK_MPEG0, 24},
		{CLKID_SD_EMMC_B,	HHI_GCLK_MPEG0, 25},
		{CLKID_SD_EMMC_C,	HHI_GCLK_MPEG0, 26},
		{CLKID_ETH_CORE,	HHI_GCLK_MPEG1, 3},
		{CLKID_ADC,		HHI_GCLK_MPEG1, 13},
		{CLKID_UART1,		HHI_GCLK_MPEG1, 16},
		{CLKID_HTX_HDCP22,	HHI_GCLK_MPEG2, 3},
		{CLKID_HTX_PCLK,	HHI_GCLK_MPEG2, 4},
		{CLKID_UART2,		HHI_GCLK_MPEG2, 15},
		{CLKID_VCLK2_VENCI0,	HHI_GCLK_OTHER, 1},
		{CLKID_VCLK2_VENCI1,	HHI_GCLK_OTHER, 2},
		{CLKID_VCLK2_VENCP0,	HHI_GCLK_OTHER, 3},
		{CLKID_VCLK2_VENCP1,	HHI_GCLK_OTHER, 4},
		{CLKID_VCLK2_VENCT0,	HHI_GCLK_OTHER, 5},
		{CLKID_VCLK2_VENCT1,	HHI_GCLK_OTHER, 6},
		{CLKID_VCLK2_OTHER,	HHI_GCLK_OTHER, 7},
		{CLKID_VCLK2_ENCI,	HHI_GCLK_OTHER, 8},
		{CLKID_VCLK2_ENCP,	HHI_GCLK_OTHER, 9},
		{CLKID_VCLK2_ENCT,	HHI_GCLK_OTHER, 22},
		{CLKID_VCLK2_ENCL,	HHI_GCLK_OTHER, 23},
		{CLKID_VCLK2_VENCLMMC,	HHI_GCLK_OTHER, 24},
		{CLKID_VCLK2_VENCL,	HHI_GCLK_OTHER, 25},
		{CLKID_VCLK2_OTHER1,	HHI_GCLK_OTHER, 26},
		{CLKID_SPICC0_GATE,	HHI_SPICC_CLK_CNTL, 6},
		{CLKID_SPICC1_GATE,	HHI_SPICC_CLK_CNTL, 22},
		{CLKID_SARADC_GATE,	AO_SAR_CLK, 8},
		{CLKID_AO_I2C,		AO_CLK_GATE0, 2},
		{CLKID_SD_EMMC_A_P0_GATE,       HHI_SD_EMMC_CLK_CNTL, 7},
		{CLKID_SD_EMMC_B_P0_GATE,       HHI_SD_EMMC_CLK_CNTL, 23},
		{CLKID_SD_EMMC_C_P0_GATE, HHI_NAND_CLK_CNTL, 7},
};

static unsigned int spicc_parents[] = {CLKID_XTAL, CLKID_CLK81, CLKID_FCLK_DIV4,
CLKID_FCLK_DIV3, CLKID_UNREALIZED, CLKID_FCLK_DIV5, CLKID_FCLK_DIV7, CLKID_UNREALIZED};

static unsigned int saradc_parents[] = {CLKID_XTAL, CLKID_AO_CLK81};
static unsigned int sd_emmc_parents[] = {CLKID_XTAL, CLKID_FCLK_DIV2, CLKID_FCLK_DIV3,
		CLKID_FCLK_DIV5, CLKID_FCLK_DIV7, CLKID_UNREALIZED, CLKID_UNREALIZED, CLKID_UNREALIZED};


static struct meson_mux muxes[] = {
		{CLKID_SPICC0_MUX, HHI_SPICC_CLK_CNTL, 7,  7, spicc_parents, ARRAY_SIZE(spicc_parents)},
		{CLKID_SPICC1_MUX, HHI_SPICC_CLK_CNTL, 23, 7, spicc_parents, ARRAY_SIZE(spicc_parents)},
		{CLKID_SARADC_MUX, AO_SAR_CLK, 9, 3, saradc_parents, ARRAY_SIZE(saradc_parents)},
		{CLKID_SD_EMMC_A_P0_MUX, HHI_SD_EMMC_CLK_CNTL, 9, 7, sd_emmc_parents, ARRAY_SIZE(sd_emmc_parents)},
		{CLKID_SD_EMMC_B_P0_MUX, HHI_SD_EMMC_CLK_CNTL, 25, 7, sd_emmc_parents, ARRAY_SIZE(sd_emmc_parents)},
		{CLKID_SD_EMMC_C_P0_MUX, HHI_NAND_CLK_CNTL, 9, 7, sd_emmc_parents, ARRAY_SIZE(sd_emmc_parents)},
};

static struct meson_div divs[] = {
		{CLKID_SPICC0_DIV, HHI_SPICC_CLK_CNTL, 0,  6, CLKID_SPICC0_MUX},
		{CLKID_SPICC1_DIV, HHI_SPICC_CLK_CNTL, 16, 7, CLKID_SPICC1_MUX},
		{CLKID_SARADC_DIV, AO_SAR_CLK, 0, 8, CLKID_SARADC_MUX},
		{CLKID_SD_EMMC_A_P0_DIV, HHI_SD_EMMC_CLK_CNTL, 0, 7, CLKID_SD_EMMC_A_P0_MUX},
		{CLKID_SD_EMMC_B_P0_DIV, HHI_SD_EMMC_CLK_CNTL, 16, 7, CLKID_SD_EMMC_B_P0_MUX},
		{CLKID_SD_EMMC_C_P0_DIV, HHI_NAND_CLK_CNTL, 0, 7, CLKID_SD_EMMC_C_P0_MUX},
};

static struct parm meson_fixed_pll_parm[3] = {
	{HHI_FIX_PLL_CNTL0, 0, 8}, /* pm */
	{HHI_FIX_PLL_CNTL0, 10, 5}, /* pn */
	{HHI_FIX_PLL_CNTL0, 16, 2}, /* pod */
};

static struct parm meson_sys_pll_parm[3] = {
	{HHI_SYS_PLL_CNTL0, 0, 8}, /* pm */
	{HHI_SYS_PLL_CNTL0, 10, 5}, /* pn */
	{HHI_SYS_PLL_CNTL0, 16, 2}, /* pod */
};

static int meson_clk_enable(struct clk *clk)
{
	return meson_set_gate_by_id(clk, gates, ARRAY_SIZE(gates), true);
}

static int meson_clk_disable(struct clk *clk)
{
	return meson_set_gate_by_id(clk, gates, ARRAY_SIZE(gates), false);
}

static ulong meson_pll_get_rate(struct clk *clk, unsigned long id)
{
	struct meson_clk *priv = dev_get_priv(clk->dev);
	struct parm *pm, *pn, *pod;
	unsigned long parent_rate_mhz = clk_get_rate(&priv->clkin)/1000000;
	u16 n, m, od;
	u32 reg;

	switch (id) {
	case CLKID_FIXED_PLL:
		pm = &meson_fixed_pll_parm[0];
		pn = &meson_fixed_pll_parm[1];
		pod = &meson_fixed_pll_parm[2];
		break;
	case CLKID_SYS_PLL:
		pm = &meson_sys_pll_parm[0];
		pn = &meson_sys_pll_parm[1];
		pod = &meson_sys_pll_parm[2];
		break;
	default:
		return -ENOENT;
	}

	reg = readl(priv->addr + pn->reg_off);
	n = PARM_GET(pn->width, pn->shift, reg);

	reg = readl(priv->addr + pm->reg_off);
	m = PARM_GET(pm->width, pm->shift, reg);

	reg = readl(priv->addr + pod->reg_off);
	od = PARM_GET(pod->width, pod->shift, reg);

	return ((parent_rate_mhz * m / n) >> od) * 1000000;
}

static ulong meson_clk_get_rate_by_id(struct clk *clk, ulong id)
{
	ulong rate;
	struct meson_clk *priv = dev_get_priv(clk->dev);

	switch (id) {
	case CLKID_XTAL:
		rate = clk_get_rate(&priv->clkin);
		break;
	case CLKID_FIXED_PLL:
	case CLKID_SYS_PLL:
		rate = meson_pll_get_rate(clk, id);
		break;
	case CLKID_FCLK_DIV2:
		rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 2;
		break;
	case CLKID_FCLK_DIV3:
		rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 3;
		break;
	case CLKID_FCLK_DIV4:
		rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 4;
		break;
	case CLKID_FCLK_DIV5:
		rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 5;
		break;
	case CLKID_FCLK_DIV7:
		rate = meson_pll_get_rate(clk, CLKID_FIXED_PLL) / 7;
		break;
	/* clk81 has realized in rom code*/
	case CLKID_CLK81:
	case CLKID_AO_CLK81:
		rate = CLK81_RATE;
		break;
	default:
		pr_err("Unknown clock, Can not get its rate\n");
		rate = 0;
		break;
	}

	return rate;
}

static ulong meson_clk_get_rate(struct clk *clk)
{
	return meson_clk_get_rate_by_id(clk, clk->id);
}

static ulong meson_clk_set_rate(struct clk *clk, ulong rate)
{
	ulong div_parent, mux_parent, parent_rate;
	unsigned int div_val;
	struct meson_clk *priv = dev_get_priv(clk->dev);
	unsigned int i;
	struct meson_div *div = NULL;

	for (i = 0; i < ARRAY_SIZE(divs); i++) {
		if (clk->id == divs[i].index)
			div = &divs[i];
	}

	if (!div) {
		return -1;
	}

	div_parent = div->parent_index;
	mux_parent = meson_clk_get_mux_parent(clk, muxes,
					ARRAY_SIZE(muxes), div_parent);
	parent_rate = meson_clk_get_rate_by_id(clk, mux_parent);

	div_val = DIV_ROUND_CLOSEST(parent_rate, rate) - 1;

	meson_clk_set_div(priv, div, div_val);

	return 0;
}

static int meson_clk_set_parent(struct clk* clk, struct clk* parent_clk)
{
	return meson_mux_set_parent_by_id(clk, muxes, ARRAY_SIZE(muxes), parent_clk);
}

static struct clk_ops meson_clk_ops = {
	.disable	= meson_clk_disable,
	.enable		= meson_clk_enable,
	.get_rate	= meson_clk_get_rate,
	.set_rate 	= meson_clk_set_rate,
	.set_parent = meson_clk_set_parent,
};

static int meson_clk_probe(struct udevice *dev)
{
	struct meson_clk *priv = dev_get_priv(dev);

	clk_get_by_name(dev, "xtal", &priv->clkin);
	priv->addr = dev_read_addr_ptr(dev);

	debug("meson-clk: probed at addr %p\n", priv->addr);

	return 0;
}

static const struct udevice_id meson_clk_ids[] = {
	{ .compatible = "amlogic,g12a-clkc" },
	{ .compatible = "amlogic,g12a-aoclkc" },
	{ }
};

U_BOOT_DRIVER(meson_clk) = {
	.name		= "meson-clk-g12a",
	.id			= UCLASS_CLK,
	.of_match	= meson_clk_ids,
	.priv_auto_alloc_size = sizeof(struct meson_clk),
	.ops		= &meson_clk_ops,
	.probe		= meson_clk_probe,
};
