// SPDX-License-Identifier: GPL-2.0+
/*
 * Renesas RCar Gen3 CPG MSSR driver
 *
 * Copyright (C) 2017 Marek Vasut <marek.vasut@gmail.com>
 *
 * Based on the following driver from Linux kernel:
 * r8a7796 Clock Pulse Generator / Module Standby and Software Reset
 *
 * Copyright (C) 2016 Glider bvba
 */

#include <common.h>
#include <clk-uclass.h>
#include <dm.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
#include <errno.h>
#include <log.h>
#include <wait_bit.h>
#include <asm/global_data.h>
#include <asm/io.h>
#include <linux/bitops.h>
#include <reset-uclass.h>

#include <dt-bindings/clock/renesas-cpg-mssr.h>

#include "renesas-cpg-mssr.h"
#include "rcar-gen3-cpg.h"

#define CPG_PLL0CR		0x00d8
#define CPG_PLL2CR		0x002c
#define CPG_PLL4CR		0x01f4

#define CPG_RPC_PREDIV_MASK	0x3
#define CPG_RPC_PREDIV_OFFSET	3
#define CPG_RPC_POSTDIV_MASK	0x7
#define CPG_RPC_POSTDIV_OFFSET	0

/*
 * SDn Clock
 */
#define CPG_SD_STP_HCK		BIT(9)
#define CPG_SD_STP_CK		BIT(8)

#define CPG_SD_STP_MASK		(CPG_SD_STP_HCK | CPG_SD_STP_CK)
#define CPG_SD_FC_MASK		(0x7 << 2 | 0x3 << 0)

#define CPG_SD_DIV_TABLE_DATA(stp_hck, stp_ck, sd_srcfc, sd_fc, sd_div) \
{ \
	.val = ((stp_hck) ? CPG_SD_STP_HCK : 0) | \
	       ((stp_ck) ? CPG_SD_STP_CK : 0) | \
	       ((sd_srcfc) << 2) | \
	       ((sd_fc) << 0), \
	.div = (sd_div), \
}

struct sd_div_table {
	u32 val;
	unsigned int div;
};

/* SDn divider
 *                     sd_srcfc   sd_fc   div
 * stp_hck   stp_ck    (div)      (div)     = sd_srcfc x sd_fc
 *-------------------------------------------------------------------
 *  0         0         0 (1)      1 (4)      4
 *  0         0         1 (2)      1 (4)      8
 *  1         0         2 (4)      1 (4)     16
 *  1         0         3 (8)      1 (4)     32
 *  1         0         4 (16)     1 (4)     64
 *  0         0         0 (1)      0 (2)      2
 *  0         0         1 (2)      0 (2)      4
 *  1         0         2 (4)      0 (2)      8
 *  1         0         3 (8)      0 (2)     16
 *  1         0         4 (16)     0 (2)     32
 */
static const struct sd_div_table cpg_sd_div_table[] = {
/*	CPG_SD_DIV_TABLE_DATA(stp_hck,  stp_ck,   sd_srcfc,   sd_fc,  sd_div) */
	CPG_SD_DIV_TABLE_DATA(0,        0,        0,          1,        4),
	CPG_SD_DIV_TABLE_DATA(0,        0,        1,          1,        8),
	CPG_SD_DIV_TABLE_DATA(1,        0,        2,          1,       16),
	CPG_SD_DIV_TABLE_DATA(1,        0,        3,          1,       32),
	CPG_SD_DIV_TABLE_DATA(1,        0,        4,          1,       64),
	CPG_SD_DIV_TABLE_DATA(0,        0,        0,          0,        2),
	CPG_SD_DIV_TABLE_DATA(0,        0,        1,          0,        4),
	CPG_SD_DIV_TABLE_DATA(1,        0,        2,          0,        8),
	CPG_SD_DIV_TABLE_DATA(1,        0,        3,          0,       16),
	CPG_SD_DIV_TABLE_DATA(1,        0,        4,          0,       32),
};

static int gen3_clk_get_parent(struct gen3_clk_priv *priv, struct clk *clk,
			       struct cpg_mssr_info *info, struct clk *parent)
{
	const struct cpg_core_clk *core;
	int ret;

	if (!renesas_clk_is_mod(clk)) {
		ret = renesas_clk_get_core(clk, info, &core);
		if (ret)
			return ret;

		if (core->type == CLK_TYPE_GEN3_MDSEL) {
			parent->dev = clk->dev;
			parent->id = core->parent >> (priv->sscg ? 16 : 0);
			parent->id &= 0xffff;
			return 0;
		}
	}

	return renesas_clk_get_parent(clk, info, parent);
}

static int gen3_clk_setup_sdif_div(struct clk *clk, ulong rate)
{
	struct gen3_clk_priv *priv = dev_get_priv(clk->dev);
	struct cpg_mssr_info *info = priv->info;
	const struct cpg_core_clk *core;
	struct clk parent;
	int ret;

	ret = gen3_clk_get_parent(priv, clk, info, &parent);
	if (ret) {
		printf("%s[%i] parent fail, ret=%i\n", __func__, __LINE__, ret);
		return ret;
	}

	if (renesas_clk_is_mod(&parent))
		return 0;

	ret = renesas_clk_get_core(&parent, info, &core);
	if (ret)
		return ret;

	if (core->type != CLK_TYPE_GEN3_SD)
		return 0;

	debug("%s[%i] SDIF offset=%x\n", __func__, __LINE__, core->offset);

	writel((rate == 400000000) ? 0x4 : 0x1, priv->base + core->offset);

	return 0;
}

static int gen3_clk_enable(struct clk *clk)
{
	struct gen3_clk_priv *priv = dev_get_priv(clk->dev);

	return renesas_clk_endisable(clk, priv->base, priv->info, true);
}

static int gen3_clk_disable(struct clk *clk)
{
	struct gen3_clk_priv *priv = dev_get_priv(clk->dev);

	return renesas_clk_endisable(clk, priv->base, priv->info, false);
}

static u64 gen3_clk_get_rate64(struct clk *clk);

static u64 gen3_clk_get_rate64_pll_mul_reg(struct gen3_clk_priv *priv,
					   struct clk *parent,
					   u32 mul_reg, u32 mult, u32 div,
					   char *name)
{
	u32 value;
	u64 rate;

	if (mul_reg) {
		value = readl(priv->base + mul_reg);
		mult = (((value >> 24) & 0x7f) + 1) * 2;
		div = 1;
	}

	rate = (gen3_clk_get_rate64(parent) * mult) / div;

	debug("%s[%i] %s clk: mult=%u div=%u => rate=%llu\n",
	      __func__, __LINE__, name, mult, div, rate);
	return rate;
}

static u64 gen3_clk_get_rate64(struct clk *clk)
{
	struct gen3_clk_priv *priv = dev_get_priv(clk->dev);
	struct cpg_mssr_info *info = priv->info;
	struct clk parent;
	const struct cpg_core_clk *core;
	const struct rcar_gen3_cpg_pll_config *pll_config =
					priv->cpg_pll_config;
	u32 value, div, prediv, postdiv;
	u64 rate = 0;
	int i, ret;

	debug("%s[%i] Clock: id=%lu\n", __func__, __LINE__, clk->id);

	ret = gen3_clk_get_parent(priv, clk, info, &parent);
	if (ret) {
		printf("%s[%i] parent fail, ret=%i\n", __func__, __LINE__, ret);
		return ret;
	}

	if (renesas_clk_is_mod(clk)) {
		rate = gen3_clk_get_rate64(&parent);
		debug("%s[%i] MOD clk: parent=%lu => rate=%llu\n",
		      __func__, __LINE__, parent.id, rate);
		return rate;
	}

	ret = renesas_clk_get_core(clk, info, &core);
	if (ret)
		return ret;

	switch (core->type) {
	case CLK_TYPE_IN:
		if (core->id == info->clk_extal_id) {
			rate = clk_get_rate(&priv->clk_extal);
			debug("%s[%i] EXTAL clk: rate=%llu\n",
			      __func__, __LINE__, rate);
			return rate;
		}

		if (core->id == info->clk_extalr_id) {
			rate = clk_get_rate(&priv->clk_extalr);
			debug("%s[%i] EXTALR clk: rate=%llu\n",
			      __func__, __LINE__, rate);
			return rate;
		}

		return -EINVAL;

	case CLK_TYPE_GEN3_MAIN:
		return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
						0, 1, pll_config->extal_div,
						"MAIN");

	case CLK_TYPE_GEN3_PLL0:
		return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
						CPG_PLL0CR, 0, 0, "PLL0");

	case CLK_TYPE_GEN3_PLL1:
		return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
						0, pll_config->pll1_mult,
						pll_config->pll1_div, "PLL1");

	case CLK_TYPE_GEN3_PLL2:
		return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
						CPG_PLL2CR, 0, 0, "PLL2");

	case CLK_TYPE_GEN3_PLL3:
		return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
						0, pll_config->pll3_mult,
						pll_config->pll3_div, "PLL3");

	case CLK_TYPE_GEN3_PLL4:
		return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
						CPG_PLL4CR, 0, 0, "PLL4");

	case CLK_TYPE_GEN4_MAIN:
		return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
						0, 1, pll_config->extal_div,
						"V3U_MAIN");

	case CLK_TYPE_GEN4_PLL1:
		return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
						0, pll_config->pll1_mult,
						pll_config->pll1_div,
						"V3U_PLL1");

	case CLK_TYPE_GEN4_PLL2X_3X:
		return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
						core->offset, 0, 0,
						"V3U_PLL2X_3X");

	case CLK_TYPE_GEN4_PLL5:
		return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
						0, pll_config->pll5_mult,
						pll_config->pll5_div,
						"V3U_PLL5");

	case CLK_TYPE_FF:
		return gen3_clk_get_rate64_pll_mul_reg(priv, &parent,
						0, core->mult, core->div,
						"FIXED");

	case CLK_TYPE_GEN3_MDSEL:
		div = (core->div >> (priv->sscg ? 16 : 0)) & 0xffff;
		rate = gen3_clk_get_rate64(&parent) / div;
		debug("%s[%i] PE clk: parent=%i div=%u => rate=%llu\n",
		      __func__, __LINE__,
		      (core->parent >> (priv->sscg ? 16 : 0)) & 0xffff,
		      div, rate);
		return rate;

	case CLK_TYPE_GEN3_SDH:	/* Fixed factor 1:1 */
		fallthrough;
	case CLK_TYPE_GEN4_SDH:	/* Fixed factor 1:1 */
		return gen3_clk_get_rate64(&parent);

	case CLK_TYPE_GEN3_SD:		/* FIXME */
		fallthrough;
	case CLK_TYPE_GEN4_SD:
		value = readl(priv->base + core->offset);
		value &= CPG_SD_STP_MASK | CPG_SD_FC_MASK;

		for (i = 0; i < ARRAY_SIZE(cpg_sd_div_table); i++) {
			if (cpg_sd_div_table[i].val != value)
				continue;

			rate = gen3_clk_get_rate64(&parent) /
			       cpg_sd_div_table[i].div;
			debug("%s[%i] SD clk: parent=%i div=%i => rate=%llu\n",
			      __func__, __LINE__,
			      core->parent, cpg_sd_div_table[i].div, rate);

			return rate;
		}

		return -EINVAL;

	case CLK_TYPE_GEN3_RPC:
	case CLK_TYPE_GEN3_RPCD2:
	case CLK_TYPE_GEN4_RPC:
	case CLK_TYPE_GEN4_RPCD2:
		rate = gen3_clk_get_rate64(&parent);

		value = readl(priv->base + CPG_RPCCKCR);

		prediv = (value >> CPG_RPC_PREDIV_OFFSET) &
			 CPG_RPC_PREDIV_MASK;
		if (prediv == 2)
			rate /= 5;
		else if (prediv == 3)
			rate /= 6;
		else
			return -EINVAL;

		postdiv = (value >> CPG_RPC_POSTDIV_OFFSET) &
			  CPG_RPC_POSTDIV_MASK;

		if (postdiv % 2 != 0) {
			rate /= postdiv + 1;

			if (core->type == CLK_TYPE_GEN3_RPCD2)
				rate /= 2;

			debug("%s[%i] RPC clk: parent=%i prediv=%i postdiv=%i => rate=%llu\n",
			      __func__, __LINE__,
			      core->parent, prediv, postdiv, rate);

			return rate;
		}

		return -EINVAL;

	}

	printf("%s[%i] unknown fail\n", __func__, __LINE__);

	return -ENOENT;
}

static ulong gen3_clk_get_rate(struct clk *clk)
{
	return gen3_clk_get_rate64(clk);
}

static ulong gen3_clk_set_rate(struct clk *clk, ulong rate)
{
	/* Force correct SD-IF divider configuration if applicable */
	gen3_clk_setup_sdif_div(clk, rate);
	return gen3_clk_get_rate64(clk);
}

static int gen3_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args)
{
	if (args->args_count != 2) {
		debug("Invalid args_count: %d\n", args->args_count);
		return -EINVAL;
	}

	clk->id = (args->args[0] << 16) | args->args[1];

	return 0;
}

const struct clk_ops gen3_clk_ops = {
	.enable		= gen3_clk_enable,
	.disable	= gen3_clk_disable,
	.get_rate	= gen3_clk_get_rate,
	.set_rate	= gen3_clk_set_rate,
	.of_xlate	= gen3_clk_of_xlate,
};

static int gen3_clk_probe(struct udevice *dev)
{
	struct gen3_clk_priv *priv = dev_get_priv(dev);
	struct cpg_mssr_info *info =
		(struct cpg_mssr_info *)dev_get_driver_data(dev);
	fdt_addr_t rst_base;
	u32 cpg_mode;
	int ret;

	priv->base = dev_read_addr_ptr(dev);
	if (!priv->base)
		return -EINVAL;

	priv->info = info;
	ret = fdt_node_offset_by_compatible(gd->fdt_blob, -1, info->reset_node);
	if (ret < 0)
		return ret;

	rst_base = fdtdec_get_addr(gd->fdt_blob, ret, "reg");
	if (rst_base == FDT_ADDR_T_NONE)
		return -EINVAL;

	cpg_mode = readl(rst_base + info->reset_modemr_offset);

	priv->cpg_pll_config =
		(struct rcar_gen3_cpg_pll_config *)info->get_pll_config(cpg_mode);
	if (!priv->cpg_pll_config->extal_div)
		return -EINVAL;

	priv->sscg = !(cpg_mode & BIT(12));

	if (info->reg_layout == CLK_REG_LAYOUT_RCAR_GEN2_AND_GEN3) {
		priv->info->status_regs = mstpsr;
		priv->info->control_regs = smstpcr;
		priv->info->reset_regs = srcr;
		priv->info->reset_clear_regs = srstclr;
	} else if (info->reg_layout == CLK_REG_LAYOUT_RCAR_V3U) {
		priv->info->status_regs = mstpsr_for_v3u;
		priv->info->control_regs = mstpcr_for_v3u;
		priv->info->reset_regs = srcr_for_v3u;
		priv->info->reset_clear_regs = srstclr_for_v3u;
	} else {
		return -EINVAL;
	}

	ret = clk_get_by_name(dev, "extal", &priv->clk_extal);
	if (ret < 0)
		return ret;

	if (info->extalr_node) {
		ret = clk_get_by_name(dev, info->extalr_node, &priv->clk_extalr);
		if (ret < 0)
			return ret;
	}

	return 0;
}

static int gen3_clk_remove(struct udevice *dev)
{
	struct gen3_clk_priv *priv = dev_get_priv(dev);

	return renesas_clk_remove(priv->base, priv->info);
}

U_BOOT_DRIVER(clk_gen3) = {
	.name		= "clk_gen3",
	.id		= UCLASS_CLK,
	.priv_auto	= sizeof(struct gen3_clk_priv),
	.ops		= &gen3_clk_ops,
	.probe		= gen3_clk_probe,
	.remove		= gen3_clk_remove,
};

static int gen3_reset_assert(struct reset_ctl *reset_ctl)
{
	struct udevice *cdev = (struct udevice *)dev_get_driver_data(reset_ctl->dev);
	struct gen3_clk_priv *priv = dev_get_priv(cdev);
	unsigned int reg = reset_ctl->id / 32;
	unsigned int bit = reset_ctl->id % 32;
	u32 bitmask = BIT(bit);

	writel(bitmask, priv->base + priv->info->reset_regs[reg]);

	return 0;
}

static int gen3_reset_deassert(struct reset_ctl *reset_ctl)
{
	struct udevice *cdev = (struct udevice *)dev_get_driver_data(reset_ctl->dev);
	struct gen3_clk_priv *priv = dev_get_priv(cdev);
	unsigned int reg = reset_ctl->id / 32;
	unsigned int bit = reset_ctl->id % 32;
	u32 bitmask = BIT(bit);

	writel(bitmask, priv->base + priv->info->reset_clear_regs[reg]);

	return 0;
}

static const struct reset_ops rst_gen3_ops = {
	.rst_assert = gen3_reset_assert,
	.rst_deassert = gen3_reset_deassert,
};

U_BOOT_DRIVER(rst_gen3) = {
	.name = "rst_gen3",
	.id = UCLASS_RESET,
	.ops = &rst_gen3_ops,
};

int gen3_cpg_bind(struct udevice *parent)
{
	struct cpg_mssr_info *info =
		(struct cpg_mssr_info *)dev_get_driver_data(parent);
	struct udevice *cdev, *rdev;
	struct driver *drv;
	int ret;

	drv = lists_driver_lookup_name("clk_gen3");
	if (!drv)
		return -ENOENT;

	ret = device_bind_with_driver_data(parent, drv, "clk_gen3", (ulong)info,
					   dev_ofnode(parent), &cdev);
	if (ret)
		return ret;

	drv = lists_driver_lookup_name("rst_gen3");
	if (!drv)
		return -ENOENT;

	ret = device_bind_with_driver_data(parent, drv, "rst_gen3", (ulong)cdev,
					   dev_ofnode(parent), &rdev);
	if (ret)
		device_unbind(cdev);

	return ret;
}
