// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
/*
 * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
 */

#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/t7-clkc.h>
#include "clk_meson.h"

/* change it later */
#define SYS_CLK		166666666

/* clk81 gates, sys_clk */
static struct meson_gate gates[] = {
	{CLKID_SPICC_A_GATE, T7_CLKCTRL_SPICC_CLK_CTRL, 6},
	{CLKID_SPICC_B_GATE, T7_CLKCTRL_SPICC_CLK_CTRL, 22},
	{CLKID_SPICC_C_GATE, T7_CLKCTRL_SPICC_CLK_CTRL1, 6},
	{CLKID_SPICC_D_GATE, T7_CLKCTRL_SPICC_CLK_CTRL1, 22},
	{CLKID_SPICC_E_GATE, T7_CLKCTRL_SPICC_CLK_CTRL2, 6},
	{CLKID_SPICC_F_GATE, T7_CLKCTRL_SPICC_CLK_CTRL2, 22},
	{CLKID_SAR_ADC_GATE, T7_CLKCTRL_SAR_CLK_CTRL0, 8},
	{CLKID_SD_EMMC_A_GATE, T7_CLKCTRL_SD_EMMC_CLK_CTRL, 7},
	{CLKID_SD_EMMC_B_GATE, T7_CLKCTRL_SD_EMMC_CLK_CTRL, 23},
	{CLKID_SD_EMMC_C_GATE, T7_CLKCTRL_NAND_CLK_CTRL, 7},
};

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

static unsigned int saradc_parents[] = {CLKID_XTAL, CLKID_SYS_CLK};

static unsigned int sd_emmc_parents[] = {CLKID_XTAL, CLKID_FCLK_DIV2,
CLKID_FCLK_DIV3, CLKID_UNREALIZED, CLKID_UNREALIZED,
CLKID_UNREALIZED, CLKID_UNREALIZED, CLKID_GP0_PLL};

static struct meson_mux muxes[] = {
	{CLKID_SPICC_A_MUX, T7_CLKCTRL_SPICC_CLK_CTRL, 7,  0x7, spicc_parents, ARRAY_SIZE(spicc_parents)},
	{CLKID_SPICC_B_MUX, T7_CLKCTRL_SPICC_CLK_CTRL, 23,  0x7, spicc_parents, ARRAY_SIZE(spicc_parents)},
	{CLKID_SPICC_C_MUX, T7_CLKCTRL_SPICC_CLK_CTRL1, 7,  0x7, spicc_parents, ARRAY_SIZE(spicc_parents)},
	{CLKID_SPICC_D_MUX, T7_CLKCTRL_SPICC_CLK_CTRL1, 23,  0x7, spicc_parents, ARRAY_SIZE(spicc_parents)},
	{CLKID_SPICC_E_MUX, T7_CLKCTRL_SPICC_CLK_CTRL2, 7,  0x7, spicc_parents, ARRAY_SIZE(spicc_parents)},
	{CLKID_SPICC_F_MUX, T7_CLKCTRL_SPICC_CLK_CTRL2, 23,  0x7, spicc_parents, ARRAY_SIZE(spicc_parents)},
	{CLKID_SARADC_MUX, T7_CLKCTRL_SAR_CLK_CTRL0, 9, 0x3, saradc_parents, ARRAY_SIZE(saradc_parents)},
	{CLKID_SD_EMMC_A_MUX, T7_CLKCTRL_SD_EMMC_CLK_CTRL, 9, 0x7, sd_emmc_parents, ARRAY_SIZE(sd_emmc_parents)},
	{CLKID_SD_EMMC_B_MUX, T7_CLKCTRL_SD_EMMC_CLK_CTRL, 25, 0x7, sd_emmc_parents, ARRAY_SIZE(sd_emmc_parents)},
	{CLKID_SD_EMMC_C_MUX, T7_CLKCTRL_NAND_CLK_CTRL, 9, 0x7, sd_emmc_parents, ARRAY_SIZE(sd_emmc_parents)},
};

static struct meson_div divs[] = {
	{CLKID_SPICC_A_DIV, T7_CLKCTRL_SPICC_CLK_CTRL, 0, 6, CLKID_SPICC_A_MUX},
	{CLKID_SPICC_B_DIV, T7_CLKCTRL_SPICC_CLK_CTRL, 16, 6, CLKID_SPICC_B_MUX},
	{CLKID_SPICC_C_DIV, T7_CLKCTRL_SPICC_CLK_CTRL1, 0, 6, CLKID_SPICC_C_MUX},
	{CLKID_SPICC_D_DIV, T7_CLKCTRL_SPICC_CLK_CTRL1, 16, 6, CLKID_SPICC_D_MUX},
	{CLKID_SPICC_E_DIV, T7_CLKCTRL_SPICC_CLK_CTRL2, 0, 6, CLKID_SPICC_E_MUX},
	{CLKID_SPICC_F_DIV, T7_CLKCTRL_SPICC_CLK_CTRL2, 16, 6, CLKID_SPICC_F_MUX},
	{CLKID_SARADC_DIV, T7_CLKCTRL_SAR_CLK_CTRL0, 0, 8, CLKID_SARADC_MUX},
	{CLKID_SD_EMMC_A_DIV, T7_CLKCTRL_SD_EMMC_CLK_CTRL, 0, 7, CLKID_SD_EMMC_A_MUX},
	{CLKID_SD_EMMC_B_DIV, T7_CLKCTRL_SD_EMMC_CLK_CTRL, 16, 7, CLKID_SD_EMMC_B_MUX},
	{CLKID_SD_EMMC_C_DIV, T7_CLKCTRL_NAND_CLK_CTRL, 0, 7, CLKID_SD_EMMC_C_MUX},
};

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

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

static struct parm meson_gp0_pll_parm[3] = {
	{T7_ANACTRL_GP0PLL_CTRL0, 0, 8}, /* pm */
	{T7_ANACTRL_GP0PLL_CTRL0, 10, 5}, /* pn */
	{T7_ANACTRL_GP0PLL_CTRL0, 16, 3}, /* 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;
	case CLKID_GP0_PLL:
		pm = &meson_gp0_pll_parm[0];
		pn = &meson_gp0_pll_parm[1];
		pod = &meson_gp0_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);

	/* there is OD in C1 */
	 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:
	case CLKID_GP0_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;
	case CLKID_FCLK_DIV2P5:
		rate = (meson_pll_get_rate(clk, CLKID_FIXED_PLL) * 2) / 5;
		break;
	/* sys clk has realized in rom code*/
	case CLKID_SYS_CLK:
		rate = SYS_CLK;
		break;
	default:
		/* only for DIV type, others such as GATE/MUX is always 0 */
		rate = priv->actual_rate;
		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];
	}
	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;

	priv->actual_rate = DIV_ROUND_CLOSEST(parent_rate, div_val + 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,t7-clkc" },
	{ }
};

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