// SPDX-License-Identifier: GPL-2.0
/*
 * RZ/G2L Clock Pulse Generator
 *
 * Copyright (C) 2021-2023 Renesas Electronics Corp.
 *
 * Based on renesas-cpg-mssr.c
 *
 * Copyright (C) 2015 Glider bvba
 * Copyright (C) 2013 Ideas On Board SPRL
 * Copyright (C) 2015 Renesas Electronics Corp.
 */

#include <asm/io.h>
#include <clk-uclass.h>
#include <dm.h>
#include <dm/device-internal.h>
#include <dm/device_compat.h>
#include <dm/devres.h>
#include <dm/lists.h>
#include <dt-bindings/clock/renesas-cpg-mssr.h>
#include <linux/clk-provider.h>
#include <linux/iopoll.h>
#include <reset-uclass.h>
#include <reset.h>

#include "rzg2l-cpg.h"

#define CLK_MON_R(reg)		(0x180 + (reg))

static ulong rzg2l_cpg_clk_get_rate_by_id(struct udevice *dev, unsigned int id);
static ulong rzg2l_cpg_clk_get_rate_by_name(struct udevice *dev, const char *name);

struct rzg2l_cpg_data {
	void __iomem *base;
	struct rzg2l_cpg_info *info;
};

/*
 * The top 16 bits of the clock ID are used to identify if it is a core clock or
 * a module clock.
 */
#define CPG_CLK_TYPE_SHIFT	16
#define CPG_CLK_ID_MASK 	0xffff
#define CPG_CLK_ID(x)		((x) & CPG_CLK_ID_MASK)
#define CPG_CLK_PACK(type, id)	(((type) << CPG_CLK_TYPE_SHIFT) | CPG_CLK_ID(id))

static inline bool is_mod_clk(unsigned int id)
{
	return (id >> CPG_CLK_TYPE_SHIFT) == CPG_MOD;
}

static int rzg2l_cpg_clk_set(struct clk *clk, bool enable)
{
	struct rzg2l_cpg_data *data =
		(struct rzg2l_cpg_data *)dev_get_driver_data(clk->dev);
	const unsigned int cpg_clk_id = CPG_CLK_ID(clk->id);
	const struct rzg2l_mod_clk *mod_clk = NULL;
	u32 value;
	unsigned int i;

	dev_dbg(clk->dev, "%s %s clock %u\n", enable ? "enable" : "disable",
		is_mod_clk(clk->id) ? "module" : "core", cpg_clk_id);
	if (!is_mod_clk(clk->id)) {
		dev_err(clk->dev, "ID %lu is not a module clock\n", clk->id);
		return -EINVAL;
	}

	for (i = 0; i < data->info->num_mod_clks; i++) {
		if (data->info->mod_clks[i].id == cpg_clk_id) {
			mod_clk = &data->info->mod_clks[i];
			break;
		}
	}

	if (!mod_clk) {
		dev_err(clk->dev, "Module clock %u not found\n", cpg_clk_id);
		return -ENODEV;
	}

	value = BIT(mod_clk->bit) << 16;
	if (enable)
		value |= BIT(mod_clk->bit);
	writel(value, data->base + mod_clk->off);

	if (enable && readl_poll_timeout(data->base + CLK_MON_R(mod_clk->off),
					 value, (value & BIT(mod_clk->bit)),
					 10)) {
		dev_err(clk->dev, "Timeout\n");
		return -ETIMEDOUT;
	}

	return 0;
}

static int rzg2l_cpg_clk_enable(struct clk *clk)
{
	return rzg2l_cpg_clk_set(clk, true);
}

static int rzg2l_cpg_clk_disable(struct clk *clk)
{
	return rzg2l_cpg_clk_set(clk, false);
}

static int rzg2l_cpg_clk_of_xlate(struct clk *clk,
				  struct ofnode_phandle_args *args)
{
	struct rzg2l_cpg_data *data =
		(struct rzg2l_cpg_data *)dev_get_driver_data(clk->dev);
	u32 cpg_clk_type, cpg_clk_id;
	bool found = false;
	unsigned int i;

	if (args->args_count != 2) {
		dev_dbg(clk->dev, "Invalid args_count: %d\n", args->args_count);
		return -EINVAL;
	}

	cpg_clk_type = args->args[0];
	cpg_clk_id = args->args[1];

	switch (cpg_clk_type) {
	case CPG_CORE:
		for (i = 0; i < data->info->num_core_clks; i++) {
			if (data->info->core_clks[i].id == cpg_clk_id) {
				found = true;
				break;
			}
		}
		if (!found) {
			dev_dbg(clk->dev,
				"Invalid second argument %u: Must be a valid core clock ID\n",
				cpg_clk_id);
			return -EINVAL;
		}
		break;
	case CPG_MOD:
		for (i = 0; i < data->info->num_mod_clks; i++) {
			if (data->info->mod_clks[i].id == cpg_clk_id) {
				found = true;
				break;
			}
		}
		if (!found) {
			dev_dbg(clk->dev,
				"Invalid second argument %u: Must be a valid module clock ID\n",
				cpg_clk_id);
			return -EINVAL;
		}
		break;
	default:
		dev_dbg(clk->dev,
			"Invalid first argument %u: Must be CPG_CORE or CPG_MOD\n",
			cpg_clk_type);
		return -EINVAL;
	}

	clk->id = CPG_CLK_PACK(cpg_clk_type, cpg_clk_id);

	return 0;
}

static ulong rzg2l_sdhi_clk_get_rate(struct udevice *dev, const struct cpg_core_clk *cc)
{
	struct rzg2l_cpg_data *data =
		(struct rzg2l_cpg_data *)dev_get_driver_data(dev);
	const ulong offset = CPG_CONF_OFFSET(cc->conf);
	const int shift = CPG_CONF_BITPOS(cc->conf);
	const u32 mask = CPG_CONF_BITMASK(cc->conf);
	unsigned int sel;

	sel = (readl(data->base + offset) >> shift) & mask;

	if (!sel || sel > cc->num_parents) {
		dev_err(dev, "Invalid SEL_SDHI%d_SET value %u\n", shift / 4, sel);
		return -EIO;
	}
	return rzg2l_cpg_clk_get_rate_by_name(dev, cc->parent_names[sel - 1]);
}

static ulong rzg2l_div_clk_get_rate(struct udevice *dev, const struct cpg_core_clk *cc)
{
	struct rzg2l_cpg_data *data =
		(struct rzg2l_cpg_data *)dev_get_driver_data(dev);
	const ulong offset = CPG_CONF_OFFSET(cc->conf);
	const int shift = CPG_CONF_BITPOS(cc->conf);
	const u32 mask = CPG_CONF_BITMASK(cc->conf);
	unsigned int sel, i;

	sel = (readl(data->base + offset) >> shift) & mask;

	for (i = 0; cc->dtable[i].div; i++) {
		if (cc->dtable[i].val == sel)
			return rzg2l_cpg_clk_get_rate_by_id(dev, cc->parent) / cc->dtable[i].div;
	}
	dev_err(dev, "Invalid selector value %u for clock %s\n", sel, cc->name);
	return -EINVAL;
}

static ulong rzg2l_core_clk_get_rate(struct udevice *dev, const struct cpg_core_clk *cc)
{
	switch (cc->type) {
	case CLK_TYPE_FF:
		const ulong parent_rate = rzg2l_cpg_clk_get_rate_by_id(dev, cc->parent);
		return parent_rate * cc->mult / cc->div;
	case CLK_TYPE_IN:
		struct clk clk_in;
		clk_get_by_name(dev, cc->name, &clk_in);
		return clk_get_rate(&clk_in);
	case CLK_TYPE_SD_MUX:
		return rzg2l_sdhi_clk_get_rate(dev, cc);
	case CLK_TYPE_DIV:
		return rzg2l_div_clk_get_rate(dev, cc);
	default:
		dev_err(dev, "get_rate needed for clock %u, type %d\n", cc->id, cc->type);
		return -ENOSYS;
	}
}

static ulong rzg2l_cpg_clk_get_rate_by_id(struct udevice *dev, unsigned int id)
{
	struct rzg2l_cpg_data *data =
		(struct rzg2l_cpg_data *)dev_get_driver_data(dev);
	const unsigned int cpg_clk_id = CPG_CLK_ID(id);
	unsigned int i;

	if (is_mod_clk(id)) {
		for (i = 0; i < data->info->num_mod_clks; i++) {
			if (data->info->mod_clks[i].id == cpg_clk_id)
				return rzg2l_cpg_clk_get_rate_by_id(dev,
								    data->info->mod_clks[i].parent);
		}

		dev_err(dev, "Module clock ID %u not found\n", cpg_clk_id);
		return -ENODEV;
	}

	for (i = 0; i < data->info->num_core_clks; i++) {
		if (data->info->core_clks[i].id == cpg_clk_id)
			return rzg2l_core_clk_get_rate(dev, &data->info->core_clks[i]);
	}

	dev_err(dev, "Core clock ID %u not found\n", cpg_clk_id);
	return -ENODEV;
}

static ulong rzg2l_cpg_clk_get_rate_by_name(struct udevice *dev, const char *name)
{
	struct rzg2l_cpg_data *data =
		(struct rzg2l_cpg_data *)dev_get_driver_data(dev);
	unsigned int i;

	for (i = 0; i < data->info->num_mod_clks; i++) {
		if (!strcmp(name, data->info->mod_clks[i].name))
			return rzg2l_cpg_clk_get_rate_by_id(dev, data->info->mod_clks[i].parent);
	}
	for (i = 0; i < data->info->num_core_clks; i++) {
		if (!strcmp(name, data->info->core_clks[i].name))
			return rzg2l_core_clk_get_rate(dev, &data->info->core_clks[i]);
	}

	dev_err(dev, "Clock name %s not found\n", name);
	return -EINVAL;
}

static ulong rzg2l_cpg_clk_get_rate(struct clk *clk)
{
	return rzg2l_cpg_clk_get_rate_by_id(clk->dev, clk->id);
}

static ulong rzg2l_sdhi_clk_set_rate(struct udevice *dev, const struct cpg_core_clk *cc, ulong rate)
{
	struct rzg2l_cpg_data *data =
		(struct rzg2l_cpg_data *)dev_get_driver_data(dev);
	const ulong offset = CPG_CONF_OFFSET(cc->conf);
	const int shift = CPG_CONF_BITPOS(cc->conf);
	int channel, new_sel, prev_sel;
	ulong target_rate;
	unsigned int i;
	u32 value;

	prev_sel = (readl(data->base + offset) >> shift) & 0x3;
	channel = shift / 4;

	/*
	 * Round the requested rate down, unless it is below the minimum
	 * supported rate. Assume that the parent clock names are listed in
	 * order of descending rate.
	 */
	for (i = 0; i < cc->num_parents; i++) {
		target_rate = rzg2l_cpg_clk_get_rate_by_name(dev, cc->parent_names[i]);
		if (rate >= target_rate) {
			new_sel = i + 1;
			break;
		}
	}
	if (!new_sel)
		new_sel = cc->num_parents - 1;

	if (new_sel == prev_sel)
		return target_rate;
	dev_dbg(dev, "sdhi set_rate rate=%lu target_rate=%lu sel=%d\n",
		rate, target_rate, new_sel);

	/*
	 * As per the HW manual, we should not directly switch from 533 MHz to
	 * 400 MHz and vice versa. To change the setting from 2’b01 (533 MHz)
	 * to 2’b10 (400 MHz) or vice versa, Switch to 2’b11 (266 MHz) first,
	 * and then switch to the target setting (2’b01 (533 MHz) or 2’b10
	 * (400 MHz)).
	 */
	if (new_sel != SEL_SDHI_266MHz && prev_sel != SEL_SDHI_266MHz) {
		u32 waitbit;
		int ret;

		dev_dbg(dev, "sdhi set_rate via 266MHz\n");
		value = (SEL_SDHI_WRITE_ENABLE | SEL_SDHI_266MHz) << shift;
		writel(value, data->base + offset);

		/* Wait for the switch to complete. */
		waitbit = channel ? CPG_CLKSTATUS_SELSDHI1_STS : CPG_CLKSTATUS_SELSDHI0_STS;
		ret = readl_poll_timeout(data->base + CPG_CLKSTATUS, value,
					 !(value & waitbit),
					 CPG_SDHI_CLK_SWITCH_STATUS_TIMEOUT_US);
		if (ret) {
			dev_err(dev, "Failed to switch SDHI%d clock source\n", channel);
			return -EIO;
		}
	}

	value = (SEL_SDHI_WRITE_ENABLE | new_sel) << shift;
	writel(value, data->base + offset);

	return target_rate;
}

static ulong rzg2l_core_clk_set_rate(struct udevice *dev, const struct cpg_core_clk *cc, ulong rate)
{
	if (cc->type == CLK_TYPE_SD_MUX)
		return rzg2l_sdhi_clk_set_rate(dev, cc, rate);

	/*
	 * The sdhi driver calls clk_set_rate for SD0_DIV4 and SD1_DIV4, even
	 * though they're in a fixed relationship with SD0 and SD1 respectively.
	 * To allow the driver to proceed, simply return the current rates
	 * without making any change.
	 */
	if (cc->id == CLK_SD0_DIV4 || cc->id == CLK_SD1_DIV4)
		return rzg2l_core_clk_get_rate(dev, cc);

	dev_err(dev, "set_rate needed for clock %u, type %d\n", cc->id, cc->type);
	return -ENOSYS;
}

static ulong rzg2l_cpg_clk_set_rate_by_id(struct udevice *dev, unsigned int id, ulong rate)
{
	struct rzg2l_cpg_data *data =
		(struct rzg2l_cpg_data *)dev_get_driver_data(dev);
	const unsigned int cpg_clk_id = CPG_CLK_ID(id);
	unsigned int i;

	if (is_mod_clk(id)) {
		for (i = 0; i < data->info->num_mod_clks; i++) {
			if (data->info->mod_clks[i].id == cpg_clk_id)
				return rzg2l_cpg_clk_set_rate_by_id(dev,
								    data->info->mod_clks[i].parent,
								    rate);
		}

		dev_err(dev, "Module clock ID %u not found\n", cpg_clk_id);
		return -ENODEV;
	}

	for (i = 0; i < data->info->num_core_clks; i++) {
		if (data->info->core_clks[i].id == cpg_clk_id)
			return rzg2l_core_clk_set_rate(dev, &data->info->core_clks[i], rate);
	}

	dev_err(dev, "Core clock ID %u not found\n", cpg_clk_id);
	return -ENODEV;
}

static ulong rzg2l_cpg_clk_set_rate(struct clk *clk, ulong rate)
{
	return rzg2l_cpg_clk_set_rate_by_id(clk->dev, clk->id, rate);
}

static const struct clk_ops rzg2l_cpg_clk_ops = {
	.enable		= rzg2l_cpg_clk_enable,
	.disable	= rzg2l_cpg_clk_disable,
	.of_xlate	= rzg2l_cpg_clk_of_xlate,
	.get_rate	= rzg2l_cpg_clk_get_rate,
	.set_rate	= rzg2l_cpg_clk_set_rate,
};

U_BOOT_DRIVER(rzg2l_cpg_clk) = {
	.name		= "rzg2l-cpg-clk",
	.id		= UCLASS_CLK,
	.ops		= &rzg2l_cpg_clk_ops,
	.flags		= DM_FLAG_VITAL,
};

static int rzg2l_cpg_rst_set(struct reset_ctl *reset_ctl, bool asserted)
{
	struct rzg2l_cpg_data *data =
		(struct rzg2l_cpg_data *)dev_get_driver_data(reset_ctl->dev);
	const struct rzg2l_reset *rst;
	u32 value;

	dev_dbg(reset_ctl->dev, "%s %lu\n", asserted ? "assert" : "deassert", reset_ctl->id);
	if (reset_ctl->id >= data->info->num_resets) {
		dev_err(reset_ctl->dev, "Invalid reset id %lu\n", reset_ctl->id);
		return -EINVAL;
	}
	rst = &data->info->resets[reset_ctl->id];

	value = BIT(rst->bit) << 16;
	if (!asserted)
		value |= BIT(rst->bit);
	writel(value, data->base + rst->off);

	return 0;
}

static int rzg2l_cpg_rst_assert(struct reset_ctl *reset_ctl)
{
	return rzg2l_cpg_rst_set(reset_ctl, true);
}

static int rzg2l_cpg_rst_deassert(struct reset_ctl *reset_ctl)
{
	return rzg2l_cpg_rst_set(reset_ctl, false);
}

static int rzg2l_cpg_rst_of_xlate(struct reset_ctl *reset_ctl,
				  struct ofnode_phandle_args *args)
{
	struct rzg2l_cpg_data *data =
		(struct rzg2l_cpg_data *)dev_get_driver_data(reset_ctl->dev);

	if (args->args[0] >= data->info->num_resets)
		return -EINVAL;

	reset_ctl->id = args->args[0];
	return 0;
}

static const struct reset_ops rzg2l_cpg_rst_ops = {
	.rst_assert	= rzg2l_cpg_rst_assert,
	.rst_deassert	= rzg2l_cpg_rst_deassert,
	.of_xlate	= rzg2l_cpg_rst_of_xlate,
};

U_BOOT_DRIVER(rzg2l_cpg_rst) = {
	.name		= "rzg2l-cpg-rst",
	.id		= UCLASS_RESET,
	.ops		= &rzg2l_cpg_rst_ops,
	.flags		= DM_FLAG_VITAL,
};

int rzg2l_cpg_bind(struct udevice *parent)
{
	struct udevice *cdev, *rdev;
	struct rzg2l_cpg_data *data;
	struct driver *drv;
	int ret;

	data = devm_kmalloc(parent, sizeof(*data), 0);
	if (!data)
		return -ENOMEM;

	data->base = dev_read_addr_ptr(parent);
	if (!data->base)
		return -EINVAL;

	data->info = (struct rzg2l_cpg_info *)dev_get_driver_data(parent);
	if (!data->info)
		return -EINVAL;

	drv = lists_driver_lookup_name("rzg2l-cpg-clk");
	if (!drv)
		return -ENOENT;

	ret = device_bind_with_driver_data(parent, drv, parent->name,
					   (ulong)data, dev_ofnode(parent),
					   &cdev);
	if (ret)
		return ret;

	drv = lists_driver_lookup_name("rzg2l-cpg-rst");
	if (!drv) {
		device_unbind(cdev);
		return -ENOENT;
	}

	ret = device_bind_with_driver_data(parent, drv, parent->name,
					   (ulong)data, dev_ofnode(parent),
					   &rdev);
	if (ret)
		device_unbind(cdev);

	return ret;
}
