// 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 <common.h>
#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,
};
