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

#include <common.h>
#include <dm.h>
#include <errno.h>
#include <log.h>
#include <malloc.h>
#include <reset-uclass.h>
#include <dm/device_compat.h>
#include <linux/err.h>
#include <linux/soc/ti/ti_sci_protocol.h>

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

static int ti_sci_reset_probe(struct udevice *dev)
{
	struct ti_sci_reset_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_reset_of_xlate(struct reset_ctl *rst,
				 struct ofnode_phandle_args *args)
{
	debug("%s(rst=%p, args_count=%d)\n", __func__, rst, 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 reset provider id field is used as a
	 * device ID, and the data field is used as the associated reset mask.
	 */
	rst->id = args->args[0];
	rst->data = args->args[1];

	return 0;
}

/**
 * ti_sci_reset_set() - program a device's reset
 * @rst: Handle to a single reset signal
 * @assert: boolean flag to indicate assert or deassert
 *
 * This is a common internal function used to assert or deassert a device's
 * reset using the TI SCI protocol. The device's reset is asserted if the
 * @assert argument is true, or deasserted if @assert argument is false.
 * The mechanism itself is a read-modify-write procedure, the current device
 * reset register is read using a TI SCI device operation, the new value is
 * set or un-set using the reset's mask, and the new reset value written by
 * using another TI SCI device operation.
 *
 * Return: 0 for successful request, else a corresponding error value
 */
static int ti_sci_reset_set(struct reset_ctl *rst, bool assert)
{
	struct ti_sci_reset_data *data = dev_get_priv(rst->dev);
	const struct ti_sci_handle *sci = data->sci;
	const struct ti_sci_dev_ops *dops = &sci->ops.dev_ops;
	u32 reset_state;
	int ret;

	ret = dops->get_device_resets(sci, rst->id, &reset_state);
	if (ret) {
		dev_err(rst->dev, "%s: get_device_resets failed (%d)\n",
			__func__, ret);
		return ret;
	}

	if (assert)
		reset_state |= rst->data;
	else
		reset_state &= ~rst->data;

	ret = dops->set_device_resets(sci, rst->id, reset_state);
	if (ret) {
		dev_err(rst->dev, "%s: set_device_resets failed (%d)\n",
			__func__, ret);
		return ret;
	}

	return 0;
}

/**
 * ti_sci_reset_assert() - assert device reset
 * @rst: Handle to a single reset signal
 *
 * This function implements the reset driver op to assert a device's reset
 * using the TI SCI protocol. This invokes the function ti_sci_reset_set()
 * with the corresponding parameters as passed in, but with the @assert
 * argument set to true for asserting the reset.
 *
 * Return: 0 for successful request, else a corresponding error value
 */
static int ti_sci_reset_assert(struct reset_ctl *rst)
{
	debug("%s(rst=%p)\n", __func__, rst);
	return ti_sci_reset_set(rst, true);
}

/**
 * ti_sci_reset_deassert() - deassert device reset
 * @rst: Handle to a single reset signal
 *
 * This function implements the reset driver op to deassert a device's reset
 * using the TI SCI protocol. This invokes the function ti_sci_reset_set()
 * with the corresponding parameters as passed in, but with the @assert
 * argument set to false for deasserting the reset.
 *
 * Return: 0 for successful request, else a corresponding error value
 */
static int ti_sci_reset_deassert(struct reset_ctl *rst)
{
	debug("%s(rst=%p)\n", __func__, rst);
	return ti_sci_reset_set(rst, false);
}

/**
 * ti_sci_reset_status() - check device reset status
 * @rst: Handle to a single reset signal
 *
 * This function implements the reset driver op to return the status of a
 * device's reset using the TI SCI protocol. The reset register value is read
 * by invoking the TI SCI device operation .get_device_resets(), and the
 * status of the specific reset is extracted and returned using this reset's
 * reset mask.
 *
 * Return: 0 if reset is deasserted, or a non-zero value if reset is asserted
 */
static int ti_sci_reset_status(struct reset_ctl *rst)
{
	struct ti_sci_reset_data *data = dev_get_priv(rst->dev);
	const struct ti_sci_handle *sci = data->sci;
	const struct ti_sci_dev_ops *dops = &sci->ops.dev_ops;
	u32 reset_state;
	int ret;

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

	ret = dops->get_device_resets(sci, rst->id, &reset_state);
	if (ret) {
		dev_err(rst->dev, "%s: get_device_resets failed (%d)\n",
			__func__, ret);
		return ret;
	}

	return reset_state & rst->data;
}

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

static struct reset_ops ti_sci_reset_ops = {
	.of_xlate = ti_sci_reset_of_xlate,
	.rst_assert = ti_sci_reset_assert,
	.rst_deassert = ti_sci_reset_deassert,
	.rst_status = ti_sci_reset_status,
};

U_BOOT_DRIVER(ti_sci_reset) = {
	.name = "ti-sci-reset",
	.id = UCLASS_RESET,
	.of_match = ti_sci_reset_of_match,
	.probe = ti_sci_reset_probe,
	.priv_auto	= sizeof(struct ti_sci_reset_data),
	.ops = &ti_sci_reset_ops,
};
