// SPDX-License-Identifier: GPL-2.0-only

#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/reset.h>

#define PD_STATE_ON			1
#define PD_STATE_OFF			2

#define PD_RSTN_REG			0x00
#define PD_CLK_GATE_REG			0x04
#define PD_PWROFF_GATE_REG		0x08
#define PD_PSW_ON_REG			0x0c
#define PD_PSW_OFF_REG			0x10
#define PD_PSW_DELAY_REG		0x14
#define PD_OFF_DELAY_REG		0x18
#define PD_ON_DELAY_REG			0x1c
#define PD_COMMAND_REG			0x20
#define PD_STATUS_REG			0x24
#define PD_STATUS_COMPLETE			BIT(1)
#define PD_STATUS_BUSY				BIT(3)
#define PD_STATUS_STATE				GENMASK(17, 16)
#define PD_ACTIVE_CTRL_REG		0x2c
#define PD_GATE_STATUS_REG		0x30
#define PD_RSTN_STATUS				BIT(0)
#define PD_CLK_GATE_STATUS			BIT(1)
#define PD_PWROFF_GATE_STATUS			BIT(2)
#define PD_PSW_STATUS_REG		0x34

#define PD_REGS_SIZE			0x80

struct sun20i_ppu_desc {
	const char *const		*names;
	unsigned int			num_domains;
};

struct sun20i_ppu_pd {
	struct generic_pm_domain	genpd;
	void __iomem			*base;
};

#define to_sun20i_ppu_pd(_genpd) \
	container_of(_genpd, struct sun20i_ppu_pd, genpd)

static bool sun20i_ppu_pd_is_on(const struct sun20i_ppu_pd *pd)
{
	u32 status = readl(pd->base + PD_STATUS_REG);

	return FIELD_GET(PD_STATUS_STATE, status) == PD_STATE_ON;
}

static int sun20i_ppu_pd_set_power(const struct sun20i_ppu_pd *pd, bool power_on)
{
	u32 state, status;
	int ret;

	if (sun20i_ppu_pd_is_on(pd) == power_on)
		return 0;

	/* Wait for the power controller to be idle. */
	ret = readl_poll_timeout(pd->base + PD_STATUS_REG, status,
				 !(status & PD_STATUS_BUSY), 100, 1000);
	if (ret)
		return ret;

	state = power_on ? PD_STATE_ON : PD_STATE_OFF;
	writel(state, pd->base + PD_COMMAND_REG);

	/* Wait for the state transition to complete. */
	ret = readl_poll_timeout(pd->base + PD_STATUS_REG, status,
				 FIELD_GET(PD_STATUS_STATE, status) == state &&
				 (status & PD_STATUS_COMPLETE), 100, 1000);
	if (ret)
		return ret;

	/* Clear the completion flag. */
	writel(status, pd->base + PD_STATUS_REG);

	return 0;
}

static int sun20i_ppu_pd_power_on(struct generic_pm_domain *genpd)
{
	const struct sun20i_ppu_pd *pd = to_sun20i_ppu_pd(genpd);

	return sun20i_ppu_pd_set_power(pd, true);
}

static int sun20i_ppu_pd_power_off(struct generic_pm_domain *genpd)
{
	const struct sun20i_ppu_pd *pd = to_sun20i_ppu_pd(genpd);

	return sun20i_ppu_pd_set_power(pd, false);
}

static int sun20i_ppu_probe(struct platform_device *pdev)
{
	const struct sun20i_ppu_desc *desc;
	struct device *dev = &pdev->dev;
	struct genpd_onecell_data *ppu;
	struct sun20i_ppu_pd *pds;
	struct reset_control *rst;
	void __iomem *base;
	struct clk *clk;
	int ret;

	desc = of_device_get_match_data(dev);
	if (!desc)
		return -EINVAL;

	pds = devm_kcalloc(dev, desc->num_domains, sizeof(*pds), GFP_KERNEL);
	if (!pds)
		return -ENOMEM;

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

	ppu->domains = devm_kcalloc(dev, desc->num_domains,
				    sizeof(*ppu->domains), GFP_KERNEL);
	if (!ppu->domains)
		return -ENOMEM;

	ppu->num_domains = desc->num_domains;
	platform_set_drvdata(pdev, ppu);

	base = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(base))
		return PTR_ERR(base);

	clk = devm_clk_get_enabled(dev, NULL);
	if (IS_ERR(clk))
		return PTR_ERR(clk);

	rst = devm_reset_control_get_exclusive(dev, NULL);
	if (IS_ERR(rst))
		return PTR_ERR(rst);

	ret = reset_control_deassert(rst);
	if (ret)
		return ret;

	for (unsigned int i = 0; i < ppu->num_domains; ++i) {
		struct sun20i_ppu_pd *pd = &pds[i];

		pd->genpd.name		= desc->names[i];
		pd->genpd.power_off	= sun20i_ppu_pd_power_off;
		pd->genpd.power_on	= sun20i_ppu_pd_power_on;
		pd->base		= base + PD_REGS_SIZE * i;

		ret = pm_genpd_init(&pd->genpd, NULL, sun20i_ppu_pd_is_on(pd));
		if (ret) {
			dev_warn(dev, "Failed to add '%s' domain: %d\n",
				 pd->genpd.name, ret);
			continue;
		}

		ppu->domains[i] = &pd->genpd;
	}

	ret = of_genpd_add_provider_onecell(dev->of_node, ppu);
	if (ret)
		dev_warn(dev, "Failed to add provider: %d\n", ret);

	return 0;
}

static const char *const sun20i_d1_ppu_pd_names[] = {
	"CPU",
	"VE",
	"DSP",
};

static const struct sun20i_ppu_desc sun20i_d1_ppu_desc = {
	.names		= sun20i_d1_ppu_pd_names,
	.num_domains	= ARRAY_SIZE(sun20i_d1_ppu_pd_names),
};

static const struct of_device_id sun20i_ppu_of_match[] = {
	{
		.compatible	= "allwinner,sun20i-d1-ppu",
		.data		= &sun20i_d1_ppu_desc,
	},
	{ }
};
MODULE_DEVICE_TABLE(of, sun20i_ppu_of_match);

static struct platform_driver sun20i_ppu_driver = {
	.probe	= sun20i_ppu_probe,
	.driver	= {
		.name			= "sun20i-ppu",
		.of_match_table		= sun20i_ppu_of_match,
		/* Power domains cannot be removed while they are in use. */
		.suppress_bind_attrs	= true,
	},
};
module_platform_driver(sun20i_ppu_driver);

MODULE_AUTHOR("Samuel Holland <samuel@sholland.org>");
MODULE_DESCRIPTION("Allwinner D1 PPU power domain driver");
MODULE_LICENSE("GPL");
