// SPDX-License-Identifier: GPL-2.0
/*
 * T-HEAD TH1520 GPU Power Sequencer Driver
 *
 * Copyright (c) 2025 Samsung Electronics Co., Ltd.
 * Author: Michal Wilczynski <m.wilczynski@samsung.com>
 *
 * This driver implements the power sequence for the Imagination BXM-4-64
 * GPU on the T-HEAD TH1520 SoC. The sequence requires coordinating resources
 * from both the sequencer's parent device node (clkgen_reset) and the GPU's
 * device node (clocks and core reset).
 *
 * The `match` function is used to acquire the GPU's resources when the
 * GPU driver requests the "gpu-power" sequence target.
 */

#include <linux/auxiliary_bus.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pwrseq/provider.h>
#include <linux/reset.h>
#include <linux/slab.h>

#include <dt-bindings/power/thead,th1520-power.h>

struct pwrseq_thead_gpu_ctx {
	struct pwrseq_device *pwrseq;
	struct reset_control *clkgen_reset;
	struct device_node *aon_node;

	/* Consumer resources */
	struct device_node *consumer_node;
	struct clk_bulk_data *clks;
	int num_clks;
	struct reset_control *gpu_reset;
};

static int pwrseq_thead_gpu_enable(struct pwrseq_device *pwrseq)
{
	struct pwrseq_thead_gpu_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
	int ret;

	if (!ctx->clks || !ctx->gpu_reset)
		return -ENODEV;

	ret = clk_bulk_prepare_enable(ctx->num_clks, ctx->clks);
	if (ret)
		return ret;

	ret = reset_control_deassert(ctx->clkgen_reset);
	if (ret)
		goto err_disable_clks;

	/*
	 * According to the hardware manual, a delay of at least 32 clock
	 * cycles is required between de-asserting the clkgen reset and
	 * de-asserting the GPU reset. Assuming a worst-case scenario with
	 * a very high GPU clock frequency, a delay of 1 microsecond is
	 * sufficient to ensure this requirement is met across all
	 * feasible GPU clock speeds.
	 */
	udelay(1);

	ret = reset_control_deassert(ctx->gpu_reset);
	if (ret)
		goto err_assert_clkgen;

	return 0;

err_assert_clkgen:
	reset_control_assert(ctx->clkgen_reset);
err_disable_clks:
	clk_bulk_disable_unprepare(ctx->num_clks, ctx->clks);
	return ret;
}

static int pwrseq_thead_gpu_disable(struct pwrseq_device *pwrseq)
{
	struct pwrseq_thead_gpu_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
	int ret = 0, err;

	if (!ctx->clks || !ctx->gpu_reset)
		return -ENODEV;

	err = reset_control_assert(ctx->gpu_reset);
	if (err)
		ret = err;

	err = reset_control_assert(ctx->clkgen_reset);
	if (err && !ret)
		ret = err;

	clk_bulk_disable_unprepare(ctx->num_clks, ctx->clks);

	/* ret stores values of the first error code */
	return ret;
}

static const struct pwrseq_unit_data pwrseq_thead_gpu_unit = {
	.name = "gpu-power-sequence",
	.enable = pwrseq_thead_gpu_enable,
	.disable = pwrseq_thead_gpu_disable,
};

static const struct pwrseq_target_data pwrseq_thead_gpu_target = {
	.name = "gpu-power",
	.unit = &pwrseq_thead_gpu_unit,
};

static const struct pwrseq_target_data *pwrseq_thead_gpu_targets[] = {
	&pwrseq_thead_gpu_target,
	NULL
};

static int pwrseq_thead_gpu_match(struct pwrseq_device *pwrseq,
				  struct device *dev)
{
	struct pwrseq_thead_gpu_ctx *ctx = pwrseq_device_get_drvdata(pwrseq);
	static const char *const clk_names[] = { "core", "sys" };
	struct of_phandle_args pwr_spec;
	int i, ret;

	/* We only match the specific T-HEAD TH1520 GPU compatible */
	if (!of_device_is_compatible(dev->of_node, "thead,th1520-gpu"))
		return PWRSEQ_NO_MATCH;

	ret = of_parse_phandle_with_args(dev->of_node, "power-domains",
					 "#power-domain-cells", 0, &pwr_spec);
	if (ret)
		return PWRSEQ_NO_MATCH;

	/* Additionally verify consumer device has AON as power-domain */
	if (pwr_spec.np != ctx->aon_node || pwr_spec.args[0] != TH1520_GPU_PD) {
		of_node_put(pwr_spec.np);
		return PWRSEQ_NO_MATCH;
	}

	of_node_put(pwr_spec.np);

	/* If a consumer is already bound, only allow a re-match from it */
	if (ctx->consumer_node)
		return ctx->consumer_node == dev->of_node ?
				PWRSEQ_MATCH_OK : PWRSEQ_NO_MATCH;

	ctx->num_clks = ARRAY_SIZE(clk_names);
	ctx->clks = kzalloc_objs(*ctx->clks, ctx->num_clks);
	if (!ctx->clks)
		return -ENOMEM;

	for (i = 0; i < ctx->num_clks; i++)
		ctx->clks[i].id = clk_names[i];

	ret = clk_bulk_get(dev, ctx->num_clks, ctx->clks);
	if (ret)
		goto err_free_clks;

	ctx->gpu_reset = reset_control_get_shared(dev, NULL);
	if (IS_ERR(ctx->gpu_reset)) {
		ret = PTR_ERR(ctx->gpu_reset);
		goto err_put_clks;
	}

	ctx->consumer_node = of_node_get(dev->of_node);

	return PWRSEQ_MATCH_OK;

err_put_clks:
	clk_bulk_put(ctx->num_clks, ctx->clks);
err_free_clks:
	kfree(ctx->clks);
	ctx->clks = NULL;

	return ret;
}

static int pwrseq_thead_gpu_probe(struct auxiliary_device *adev,
				  const struct auxiliary_device_id *id)
{
	struct device *dev = &adev->dev;
	struct device *parent_dev = dev->parent;
	struct pwrseq_thead_gpu_ctx *ctx;
	struct pwrseq_config config = {};

	ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
	if (!ctx)
		return -ENOMEM;

	ctx->aon_node = parent_dev->of_node;

	ctx->clkgen_reset =
		devm_reset_control_get_exclusive(parent_dev, "gpu-clkgen");
	if (IS_ERR(ctx->clkgen_reset))
		return dev_err_probe(
			dev, PTR_ERR(ctx->clkgen_reset),
			"Failed to get GPU clkgen reset from parent\n");

	config.parent = dev;
	config.owner = THIS_MODULE;
	config.drvdata = ctx;
	config.match = pwrseq_thead_gpu_match;
	config.targets = pwrseq_thead_gpu_targets;

	ctx->pwrseq = devm_pwrseq_device_register(dev, &config);
	if (IS_ERR(ctx->pwrseq))
		return dev_err_probe(dev, PTR_ERR(ctx->pwrseq),
				     "Failed to register power sequencer\n");

	auxiliary_set_drvdata(adev, ctx);

	return 0;
}

static void pwrseq_thead_gpu_remove(struct auxiliary_device *adev)
{
	struct pwrseq_thead_gpu_ctx *ctx = auxiliary_get_drvdata(adev);

	if (ctx->gpu_reset)
		reset_control_put(ctx->gpu_reset);

	if (ctx->clks) {
		clk_bulk_put(ctx->num_clks, ctx->clks);
		kfree(ctx->clks);
	}

	if (ctx->consumer_node)
		of_node_put(ctx->consumer_node);
}

static const struct auxiliary_device_id pwrseq_thead_gpu_id_table[] = {
	{ .name = "th1520_pm_domains.pwrseq-gpu" },
	{},
};
MODULE_DEVICE_TABLE(auxiliary, pwrseq_thead_gpu_id_table);

static struct auxiliary_driver pwrseq_thead_gpu_driver = {
	.driver = {
		.name = "pwrseq-thead-gpu",
	},
	.probe = pwrseq_thead_gpu_probe,
	.remove = pwrseq_thead_gpu_remove,
	.id_table = pwrseq_thead_gpu_id_table,
};
module_auxiliary_driver(pwrseq_thead_gpu_driver);

MODULE_AUTHOR("Michal Wilczynski <m.wilczynski@samsung.com>");
MODULE_DESCRIPTION("T-HEAD TH1520 GPU power sequencer driver");
MODULE_LICENSE("GPL");
