// SPDX-License-Identifier: GPL-2.0
/*
 * Amlogic Meson VPU Power Domain Controller driver
 *
 * Copyright (c) 2018 BayLibre, SAS.
 * Author: Neil Armstrong <narmstrong@baylibre.com>
 */

#include <common.h>
#include <dm.h>
#include <power-domain-uclass.h>
#include <regmap.h>
#include <syscon.h>
#include <reset.h>
#include <clk.h>

enum {
	VPU_PWRC_COMPATIBLE_GX		= 0,
	VPU_PWRC_COMPATIBLE_G12A	= 1,
};

/* AO Offsets */

#define AO_RTI_GEN_PWR_SLEEP0		(0x3a << 2)

#define GEN_PWR_VPU_HDMI		BIT(8)
#define GEN_PWR_VPU_HDMI_ISO		BIT(9)

/* HHI Offsets */

#define HHI_MEM_PD_REG0			(0x40 << 2)
#define HHI_VPU_MEM_PD_REG0		(0x41 << 2)
#define HHI_VPU_MEM_PD_REG1		(0x42 << 2)
#define HHI_VPU_MEM_PD_REG2		(0x4d << 2)

struct meson_gx_pwrc_vpu_priv {
	struct regmap *regmap_ao;
	struct regmap *regmap_hhi;
	struct reset_ctl_bulk resets;
	struct clk_bulk clks;
};

static int meson_pwrc_vpu_request(struct power_domain *power_domain)
{
	return 0;
}

static int meson_pwrc_vpu_free(struct power_domain *power_domain)
{
	return 0;
}

static int meson_gx_pwrc_vpu_on(struct power_domain *power_domain)
{
	struct meson_gx_pwrc_vpu_priv *priv = dev_get_priv(power_domain->dev);
	int i, ret;

	regmap_update_bits(priv->regmap_ao, AO_RTI_GEN_PWR_SLEEP0,
			   GEN_PWR_VPU_HDMI, 0);
	udelay(20);

	/* Power Up Memories */
	for (i = 0; i < 32; i += 2) {
		regmap_update_bits(priv->regmap_hhi, HHI_VPU_MEM_PD_REG0,
				   0x3 << i, 0);
		udelay(5);
	}

	for (i = 0; i < 32; i += 2) {
		regmap_update_bits(priv->regmap_hhi, HHI_VPU_MEM_PD_REG1,
				   0x3 << i, 0);
		udelay(5);
	}

	for (i = 8; i < 16; i++) {
		regmap_update_bits(priv->regmap_hhi, HHI_MEM_PD_REG0,
				   BIT(i), 0);
		udelay(5);
	}
	udelay(20);

	ret = reset_assert_bulk(&priv->resets);
	if (ret)
		return ret;

	regmap_update_bits(priv->regmap_ao, AO_RTI_GEN_PWR_SLEEP0,
			   GEN_PWR_VPU_HDMI_ISO, 0);

	ret = reset_deassert_bulk(&priv->resets);
	if (ret)
		return ret;

	ret = clk_enable_bulk(&priv->clks);
	if (ret)
		return ret;

	return 0;
}

static int meson_g12a_pwrc_vpu_on(struct power_domain *power_domain)
{
	struct meson_gx_pwrc_vpu_priv *priv = dev_get_priv(power_domain->dev);
	int i, ret;

	regmap_update_bits(priv->regmap_ao, AO_RTI_GEN_PWR_SLEEP0,
			   GEN_PWR_VPU_HDMI, 0);
	udelay(20);

	/* Power Up Memories */
	for (i = 0; i < 32; i += 2) {
		regmap_update_bits(priv->regmap_hhi, HHI_VPU_MEM_PD_REG0,
				   0x3 << i, 0);
		udelay(5);
	}

	for (i = 0; i < 32; i += 2) {
		regmap_update_bits(priv->regmap_hhi, HHI_VPU_MEM_PD_REG1,
				   0x3 << i, 0);
		udelay(5);
	}

	for (i = 0; i < 32; i += 2) {
		regmap_update_bits(priv->regmap_hhi, HHI_VPU_MEM_PD_REG2,
				   0x3 << i, 0);
		udelay(5);
	}

	for (i = 8; i < 16; i++) {
		regmap_update_bits(priv->regmap_hhi, HHI_MEM_PD_REG0,
				   BIT(i), 0);
		udelay(5);
	}
	udelay(20);

	ret = reset_assert_bulk(&priv->resets);
	if (ret)
		return ret;

	regmap_update_bits(priv->regmap_ao, AO_RTI_GEN_PWR_SLEEP0,
			   GEN_PWR_VPU_HDMI_ISO, 0);

	ret = reset_deassert_bulk(&priv->resets);
	if (ret)
		return ret;

	ret = clk_enable_bulk(&priv->clks);
	if (ret)
		return ret;

	return 0;
}

static int meson_pwrc_vpu_on(struct power_domain *power_domain)
{
	unsigned int compat = dev_get_driver_data(power_domain->dev);

	switch (compat) {
	case VPU_PWRC_COMPATIBLE_GX:
		return meson_gx_pwrc_vpu_on(power_domain);
	case VPU_PWRC_COMPATIBLE_G12A:
		return meson_g12a_pwrc_vpu_on(power_domain);
	}

	return -EINVAL;
}

static int meson_gx_pwrc_vpu_off(struct power_domain *power_domain)
{
	struct meson_gx_pwrc_vpu_priv *priv = dev_get_priv(power_domain->dev);
	int i;

	regmap_update_bits(priv->regmap_ao, AO_RTI_GEN_PWR_SLEEP0,
			   GEN_PWR_VPU_HDMI_ISO, GEN_PWR_VPU_HDMI_ISO);
	udelay(20);

	/* Power Down Memories */
	for (i = 0; i < 32; i += 2) {
		regmap_update_bits(priv->regmap_hhi, HHI_VPU_MEM_PD_REG0,
				   0x3 << i, 0x3 << i);
		udelay(5);
	}
	for (i = 0; i < 32; i += 2) {
		regmap_update_bits(priv->regmap_hhi, HHI_VPU_MEM_PD_REG1,
				   0x3 << i, 0x3 << i);
		udelay(5);
	}
	for (i = 8; i < 16; i++) {
		regmap_update_bits(priv->regmap_hhi, HHI_MEM_PD_REG0,
				   BIT(i), BIT(i));
		udelay(5);
	}
	udelay(20);

	regmap_update_bits(priv->regmap_ao, AO_RTI_GEN_PWR_SLEEP0,
			   GEN_PWR_VPU_HDMI, GEN_PWR_VPU_HDMI);
	mdelay(20);

	clk_disable_bulk(&priv->clks);

	return 0;
}

static int meson_g12a_pwrc_vpu_off(struct power_domain *power_domain)
{
	struct meson_gx_pwrc_vpu_priv *priv = dev_get_priv(power_domain->dev);
	int i;

	regmap_update_bits(priv->regmap_ao, AO_RTI_GEN_PWR_SLEEP0,
			   GEN_PWR_VPU_HDMI_ISO, GEN_PWR_VPU_HDMI_ISO);
	udelay(20);

	/* Power Down Memories */
	for (i = 0; i < 32; i += 2) {
		regmap_update_bits(priv->regmap_hhi, HHI_VPU_MEM_PD_REG0,
				   0x3 << i, 0x3 << i);
		udelay(5);
	}
	for (i = 0; i < 32; i += 2) {
		regmap_update_bits(priv->regmap_hhi, HHI_VPU_MEM_PD_REG1,
				   0x3 << i, 0x3 << i);
		udelay(5);
	}
	for (i = 0; i < 32; i += 2) {
		regmap_update_bits(priv->regmap_hhi, HHI_VPU_MEM_PD_REG2,
				   0x3 << i, 0x3 << i);
		udelay(5);
	}
	for (i = 8; i < 16; i++) {
		regmap_update_bits(priv->regmap_hhi, HHI_MEM_PD_REG0,
				   BIT(i), BIT(i));
		udelay(5);
	}
	udelay(20);

	regmap_update_bits(priv->regmap_ao, AO_RTI_GEN_PWR_SLEEP0,
			   GEN_PWR_VPU_HDMI, GEN_PWR_VPU_HDMI);
	mdelay(20);

	clk_disable_bulk(&priv->clks);

	return 0;
}

static int meson_pwrc_vpu_off(struct power_domain *power_domain)
{
	unsigned int compat = dev_get_driver_data(power_domain->dev);

	switch (compat) {
	case VPU_PWRC_COMPATIBLE_GX:
		return meson_gx_pwrc_vpu_off(power_domain);
	case VPU_PWRC_COMPATIBLE_G12A:
		return meson_g12a_pwrc_vpu_off(power_domain);
	}

	return -EINVAL;
}

static int meson_pwrc_vpu_of_xlate(struct power_domain *power_domain,
				   struct ofnode_phandle_args *args)
{
	/* #power-domain-cells is 0 */

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

	return 0;
}

struct power_domain_ops meson_gx_pwrc_vpu_ops = {
	.free = meson_pwrc_vpu_free,
	.off = meson_pwrc_vpu_off,
	.on = meson_pwrc_vpu_on,
	.request = meson_pwrc_vpu_request,
	.of_xlate = meson_pwrc_vpu_of_xlate,
};

static const struct udevice_id meson_gx_pwrc_vpu_ids[] = {
	{
		.compatible = "amlogic,meson-gx-pwrc-vpu",
		.data = VPU_PWRC_COMPATIBLE_GX,
	},
	{
		.compatible = "amlogic,meson-g12a-pwrc-vpu",
		.data = VPU_PWRC_COMPATIBLE_G12A,
	},
	{ }
};

static int meson_gx_pwrc_vpu_probe(struct udevice *dev)
{
	struct meson_gx_pwrc_vpu_priv *priv = dev_get_priv(dev);
	u32 hhi_phandle;
	ofnode hhi_node;
	int ret;

	priv->regmap_ao = syscon_node_to_regmap(dev_get_parent(dev)->node);
	if (IS_ERR(priv->regmap_ao))
		return PTR_ERR(priv->regmap_ao);

	ret = ofnode_read_u32(dev->node, "amlogic,hhi-sysctrl",
			      &hhi_phandle);
	if (ret)
		return ret;

	hhi_node = ofnode_get_by_phandle(hhi_phandle);
	if (!ofnode_valid(hhi_node))
		return -EINVAL;

	priv->regmap_hhi = syscon_node_to_regmap(hhi_node);
	if (IS_ERR(priv->regmap_hhi))
		return PTR_ERR(priv->regmap_hhi);

	ret = reset_get_bulk(dev, &priv->resets);
	if (ret)
		return ret;

	ret = clk_get_bulk(dev, &priv->clks);
	if (ret)
		return ret;

	return 0;
}

U_BOOT_DRIVER(meson_gx_pwrc_vpu) = {
	.name = "meson_gx_pwrc_vpu",
	.id = UCLASS_POWER_DOMAIN,
	.of_match = meson_gx_pwrc_vpu_ids,
	.probe = meson_gx_pwrc_vpu_probe,
	.ops = &meson_gx_pwrc_vpu_ops,
	.priv_auto_alloc_size = sizeof(struct meson_gx_pwrc_vpu_priv),
};
