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

#include <common.h>
#include <dm.h>
#include <errno.h>
#include <power-domain-uclass.h>
#include <linux/soc/ti/ti_sci_protocol.h>
#include <dt-bindings/soc/ti,sci_pm_domain.h>

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

static int ti_sci_power_domain_probe(struct udevice *dev)
{
	struct ti_sci_power_domain_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_power_domain_request(struct power_domain *pd)
{
	debug("%s(pd=%p)\n", __func__, pd);
	return 0;
}

static int ti_sci_power_domain_free(struct power_domain *pd)
{
	debug("%s(pd=%p)\n", __func__, pd);
	return 0;
}

static int ti_sci_power_domain_on(struct power_domain *pd)
{
	struct ti_sci_power_domain_data *data = dev_get_priv(pd->dev);
	const struct ti_sci_handle *sci = data->sci;
	const struct ti_sci_dev_ops *dops = &sci->ops.dev_ops;
	u8 flags = (uintptr_t)pd->priv;
	int ret;

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

	if (flags & TI_SCI_PD_EXCLUSIVE)
		ret = dops->get_device_exclusive(sci, pd->id);
	else
		ret = dops->get_device(sci, pd->id);

	if (ret)
		dev_err(pd->dev, "%s: get_device(%lu) failed (%d)\n",
			__func__, pd->id, ret);

	return ret;
}

static int ti_sci_power_domain_off(struct power_domain *pd)
{
	struct ti_sci_power_domain_data *data = dev_get_priv(pd->dev);
	const struct ti_sci_handle *sci = data->sci;
	const struct ti_sci_dev_ops *dops = &sci->ops.dev_ops;
	int ret;

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

	ret = dops->put_device(sci, pd->id);
	if (ret)
		dev_err(pd->dev, "%s: put_device(%lu) failed (%d)\n",
			__func__, pd->id, ret);

	return ret;
}

static int ti_sci_power_domain_of_xlate(struct power_domain *pd,
					struct ofnode_phandle_args *args)
{
	u8 flags;

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

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

	pd->id = args->args[0];
	/* By default request for device exclusive */
	flags = TI_SCI_PD_EXCLUSIVE;
	if (args->args_count == 2)
		flags = args->args[1] & TI_SCI_PD_EXCLUSIVE;
	pd->priv = (void *)(uintptr_t)flags;

	return 0;
}

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

static struct power_domain_ops ti_sci_power_domain_ops = {
	.request = ti_sci_power_domain_request,
	.rfree = ti_sci_power_domain_free,
	.on = ti_sci_power_domain_on,
	.off = ti_sci_power_domain_off,
	.of_xlate = ti_sci_power_domain_of_xlate,
};

U_BOOT_DRIVER(ti_sci_pm_domains) = {
	.name = "ti-sci-pm-domains",
	.id = UCLASS_POWER_DOMAIN,
	.of_match = ti_sci_power_domain_of_match,
	.probe = ti_sci_power_domain_probe,
	.priv_auto_alloc_size = sizeof(struct ti_sci_power_domain_data),
	.ops = &ti_sci_power_domain_ops,
};
