// SPDX-License-Identifier: GPL-2.0+
/*
 * Texas Instruments System Control Interface (TI SCI) clock driver
 *
 * Copyright (C) 2018 Texas Instruments Incorporated - https://www.ti.com/
 *	Andreas Dannenberg <dannenberg@ti.com>
 *
 * Loosely based on Linux kernel sci-clk.c...
 */

#include <dm.h>
#include <errno.h>
#include <clk-uclass.h>
#include <log.h>
#include <malloc.h>
#include <dm/device_compat.h>
#include <linux/err.h>
#include <linux/soc/ti/ti_sci_protocol.h>
#include <k3-avs.h>

/**
 * struct ti_sci_clk_data - clock controller information structure
 * @sci: TI SCI handle used for communication with system controller
 */
struct ti_sci_clk_data {
	const struct ti_sci_handle *sci;
};

static int ti_sci_clk_probe(struct udevice *dev)
{
	struct ti_sci_clk_data *data = dev_get_priv(dev);

	debug("%s(dev=%p)\n", __func__, dev);

	if (!data)
		return -ENOMEM;

	/* Store handle for communication with the system controller */
	data->sci = ti_sci_get_handle(dev);
	if (IS_ERR(data->sci))
		return PTR_ERR(data->sci);

	return 0;
}

static int ti_sci_clk_of_xlate(struct clk *clk,
			       struct ofnode_phandle_args *args)
{
	debug("%s(clk=%p, args_count=%d)\n", __func__, clk, args->args_count);

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

	/*
	 * On TI SCI-based devices, the clock provider id field is used as a
	 * device ID, and the data field is used as the associated sub-ID.
	 */
	clk->id = args->args[0];
	clk->data = args->args[1];

	return 0;
}

static ulong ti_sci_clk_get_rate(struct clk *clk)
{
	struct ti_sci_clk_data *data = dev_get_priv(clk->dev);
	const struct ti_sci_handle *sci = data->sci;
	const struct ti_sci_clk_ops *cops = &sci->ops.clk_ops;
	u64 current_freq;
	int ret;

	debug("%s(clk=%p)\n", __func__, clk);

	ret = cops->get_freq(sci, clk->id, clk->data, &current_freq);
	if (ret) {
		dev_err(clk->dev, "%s: get_freq failed (%d)\n", __func__, ret);
		return ret;
	}

	debug("%s(current_freq=%llu)\n", __func__, current_freq);

	return current_freq;
}

static ulong ti_sci_clk_set_rate(struct clk *clk, ulong rate)
{
	struct ti_sci_clk_data *data = dev_get_priv(clk->dev);
	const struct ti_sci_handle *sci = data->sci;
	const struct ti_sci_clk_ops *cops = &sci->ops.clk_ops;
	int ret;
	int freq_scale_up = rate >= ti_sci_clk_get_rate(clk) ? 1 : 0;

	debug("%s(clk=%p, rate=%lu)\n", __func__, clk, rate);

	if (IS_ENABLED(CONFIG_K3_AVS0) && freq_scale_up)
		k3_avs_notify_freq(clk->id, clk->data, rate);

	ret = cops->set_freq(sci, clk->id, clk->data, 0, rate, ULONG_MAX);
	if (ret) {
		dev_err(clk->dev, "%s: set_freq failed (%d)\n", __func__, ret);
		return ret;
	}

	if (IS_ENABLED(CONFIG_K3_AVS0) && !freq_scale_up)
		k3_avs_notify_freq(clk->id, clk->data, rate);

	return rate;
}

static int ti_sci_clk_set_parent(struct clk *clk, struct clk *parent)
{
	struct ti_sci_clk_data *data = dev_get_priv(clk->dev);
	const struct ti_sci_handle *sci = data->sci;
	const struct ti_sci_clk_ops *cops = &sci->ops.clk_ops;
	u8 num_parents;
	u8 parent_cid;
	int ret;

	debug("%s(clk=%p, parent=%p)\n", __func__, clk, parent);

	/* Make sure the clock parent is valid for a given device ID */
	if (clk->id != parent->id)
		return -EINVAL;

	/* Make sure clock has parents that can be set */
	ret = cops->get_num_parents(sci, clk->id, clk->data, &num_parents);
	if (ret) {
		dev_err(clk->dev, "%s: get_num_parents failed (%d)\n",
			__func__, ret);
		return ret;
	}
	if (num_parents < 2) {
		dev_err(clk->dev, "%s: clock has no settable parents!\n",
			__func__);
		return -EINVAL;
	}

	/* Make sure parent clock ID is valid */
	parent_cid = parent->data - clk->data - 1;
	if (parent_cid >= num_parents) {
		dev_err(clk->dev, "%s: invalid parent clock!\n", __func__);
		return -EINVAL;
	}

	/* Ready to proceed to configure the new clock parent */
	ret = cops->set_parent(sci, clk->id, clk->data, parent->data);
	if (ret)
		dev_err(clk->dev, "%s: set_parent failed (%d)\n", __func__,
			ret);

	return ret;
}

static int ti_sci_clk_enable(struct clk *clk)
{
	struct ti_sci_clk_data *data = dev_get_priv(clk->dev);
	const struct ti_sci_handle *sci = data->sci;
	const struct ti_sci_clk_ops *cops = &sci->ops.clk_ops;
	int ret;

	debug("%s(clk=%p)\n", __func__, clk);

	/*
	 * Allow the System Controller to automatically manage the state of
	 * this clock. If the device is enabled, then the clock is enabled.
	 */
	ret = cops->put_clock(sci, clk->id, clk->data);
	if (ret)
		dev_err(clk->dev, "%s: put_clock failed (%d)\n", __func__, ret);

	return ret;
}

static int ti_sci_clk_disable(struct clk *clk)
{
	struct ti_sci_clk_data *data = dev_get_priv(clk->dev);
	const struct ti_sci_handle *sci = data->sci;
	const struct ti_sci_clk_ops *cops = &sci->ops.clk_ops;
	int ret;

	debug("%s(clk=%p)\n", __func__, clk);

	/* Unconditionally disable clock, regardless of state of the device */
	ret = cops->idle_clock(sci, clk->id, clk->data);
	if (ret)
		dev_err(clk->dev, "%s: idle_clock failed (%d)\n", __func__,
			ret);

	return ret;
}

static const struct udevice_id ti_sci_clk_of_match[] = {
	{ .compatible = "ti,k2g-sci-clk" },
	{ /* sentinel */ },
};

static struct clk_ops ti_sci_clk_ops = {
	.of_xlate = ti_sci_clk_of_xlate,
	.get_rate = ti_sci_clk_get_rate,
	.set_rate = ti_sci_clk_set_rate,
	.set_parent = ti_sci_clk_set_parent,
	.enable = ti_sci_clk_enable,
	.disable = ti_sci_clk_disable,
};

U_BOOT_DRIVER(ti_sci_clk) = {
	.name = "ti-sci-clk",
	.id = UCLASS_CLK,
	.of_match = ti_sci_clk_of_match,
	.probe = ti_sci_clk_probe,
	.priv_auto	= sizeof(struct ti_sci_clk_data),
	.ops = &ti_sci_clk_ops,
};
