// SPDX-License-Identifier: GPL-2.0
/*
 * Rockchip IO Voltage Domain driver
 *
 * Ported from linux drivers/soc/rockchip/io-domain.c
 */

#include <dm.h>
#include <dm/device_compat.h>
#include <regmap.h>
#include <syscon.h>
#include <power/regulator.h>

#define MAX_SUPPLIES		16

/*
 * The max voltage for 1.8V and 3.3V come from the Rockchip datasheet under
 * "Recommended Operating Conditions" for "Digital GPIO".   When the typical
 * is 3.3V the max is 3.6V.  When the typical is 1.8V the max is 1.98V.
 *
 * They are used like this:
 * - If the voltage on a rail is above the "1.8" voltage (1.98V) we'll tell the
 *   SoC we're at 3.3.
 * - If the voltage on a rail is above the "3.3" voltage (3.6V) we'll consider
 *   that to be an error.
 */
#define MAX_VOLTAGE_1_8		1980000
#define MAX_VOLTAGE_3_3		3600000

#define RK3399_PMUGRF_CON0		0x180
#define RK3399_PMUGRF_CON0_VSEL		BIT(8)
#define RK3399_PMUGRF_VSEL_SUPPLY_NUM	9

#define RK3568_PMU_GRF_IO_VSEL0		0x0140
#define RK3568_PMU_GRF_IO_VSEL1		0x0144
#define RK3568_PMU_GRF_IO_VSEL2		0x0148

struct rockchip_iodomain_soc_data {
	int grf_offset;
	const char *supply_names[MAX_SUPPLIES];
	int (*write)(struct regmap *grf, uint offset, int idx, int uV);
};

static int rk3568_iodomain_write(struct regmap *grf, uint offset, int idx, int uV)
{
	u32 is_3v3 = uV > MAX_VOLTAGE_1_8;
	u32 val0, val1;
	int b;

	switch (idx) {
	case 0: /* pmuio1 */
		break;
	case 1: /* pmuio2 */
		b = idx;
		val0 = BIT(16 + b) | (is_3v3 ? 0 : BIT(b));
		b = idx + 4;
		val1 = BIT(16 + b) | (is_3v3 ? BIT(b) : 0);

		regmap_write(grf, RK3568_PMU_GRF_IO_VSEL2, val0);
		regmap_write(grf, RK3568_PMU_GRF_IO_VSEL2, val1);
		break;
	case 3: /* vccio2 */
		break;
	case 2: /* vccio1 */
	case 4: /* vccio3 */
	case 5: /* vccio4 */
	case 6: /* vccio5 */
	case 7: /* vccio6 */
	case 8: /* vccio7 */
		b = idx - 1;
		val0 = BIT(16 + b) | (is_3v3 ? 0 : BIT(b));
		val1 = BIT(16 + b) | (is_3v3 ? BIT(b) : 0);

		regmap_write(grf, RK3568_PMU_GRF_IO_VSEL0, val0);
		regmap_write(grf, RK3568_PMU_GRF_IO_VSEL1, val1);
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

static int rockchip_iodomain_write(struct regmap *grf, uint offset, int idx, int uV)
{
	u32 val;

	/* set value bit */
	val = (uV > MAX_VOLTAGE_1_8) ? 0 : 1;
	val <<= idx;

	/* apply hiword-mask */
	val |= (BIT(idx) << 16);

	return regmap_write(grf, offset, val);
}

static int rk3399_pmu_iodomain_write(struct regmap *grf, uint offset, int idx, int uV)
{
	int ret = rockchip_iodomain_write(grf, offset, idx, uV);

	if (!ret && idx == RK3399_PMUGRF_VSEL_SUPPLY_NUM) {
		/*
		 * set pmu io iodomain to also use this framework
		 * instead of a special gpio.
		 */
		u32 val = RK3399_PMUGRF_CON0_VSEL | (RK3399_PMUGRF_CON0_VSEL << 16);
		ret = regmap_write(grf, RK3399_PMUGRF_CON0, val);
	}

	return ret;
}

static const struct rockchip_iodomain_soc_data soc_data_rk3399 = {
	.grf_offset = 0xe640,
	.supply_names = {
		"bt656-supply",		/* APIO2_VDD */
		"audio-supply",		/* APIO5_VDD */
		"sdmmc-supply",		/* SDMMC0_VDD */
		"gpio1830-supply",	/* APIO4_VDD */
	},
	.write = rockchip_iodomain_write,
};

static const struct rockchip_iodomain_soc_data soc_data_rk3399_pmu = {
	.grf_offset = 0x180,
	.supply_names = {
		NULL,
		NULL,
		NULL,
		NULL,
		NULL,
		NULL,
		NULL,
		NULL,
		NULL,
		"pmu1830-supply",	/* PMUIO2_VDD */
	},
	.write = rk3399_pmu_iodomain_write,
};

static const struct rockchip_iodomain_soc_data soc_data_rk3568_pmu = {
	.grf_offset = 0x140,
	.supply_names = {
		NULL,
		"pmuio2-supply",
		"vccio1-supply",
		NULL,
		"vccio3-supply",
		"vccio4-supply",
		"vccio5-supply",
		"vccio6-supply",
		"vccio7-supply",
	},
	.write = rk3568_iodomain_write,
};

static const struct udevice_id rockchip_iodomain_ids[] = {
	{
		.compatible = "rockchip,rk3399-io-voltage-domain",
		.data = (ulong)&soc_data_rk3399,
	},
	{
		.compatible = "rockchip,rk3399-pmu-io-voltage-domain",
		.data = (ulong)&soc_data_rk3399_pmu,
	},
	{
		.compatible = "rockchip,rk3568-pmu-io-voltage-domain",
		.data = (ulong)&soc_data_rk3568_pmu,
	},
	{ }
};

static int rockchip_iodomain_bind(struct udevice *dev)
{
	/*
	 * According to the Hardware Design Guide, IO-domain configuration must
	 * be consistent with the power supply voltage (1.8V or 3.3V).
	 * Probe after bind to configure IO-domain voltage early during boot.
	 */
	dev_or_flags(dev, DM_FLAG_PROBE_AFTER_BIND);

	return 0;
}

static int rockchip_iodomain_probe(struct udevice *dev)
{
	struct rockchip_iodomain_soc_data *soc_data =
		(struct rockchip_iodomain_soc_data *)dev_get_driver_data(dev);
	struct regmap *grf;
	int ret;

	grf = syscon_get_regmap(dev_get_parent(dev));
	if (IS_ERR(grf))
		return PTR_ERR(grf);

	for (int i = 0; i < MAX_SUPPLIES; i++) {
		const char *supply_name = soc_data->supply_names[i];
		struct udevice *reg;
		int uV;

		if (!supply_name)
			continue;

		ret = device_get_supply_regulator(dev, supply_name, &reg);
		if (ret)
			continue;

		ret = regulator_autoset(reg);
		if (ret && ret != -EALREADY && ret != -EMEDIUMTYPE &&
		    ret != -ENOSYS)
			continue;

		uV = regulator_get_value(reg);
		if (uV <= 0)
			continue;

		if (uV > MAX_VOLTAGE_3_3) {
			dev_crit(dev, "%s: %d uV is too high. May damage SoC!\n",
				 supply_name, uV);
			continue;
		}

		ret = soc_data->write(grf, soc_data->grf_offset, i, uV);
		if (ret)
			dev_err(dev, "%s: Couldn't write to GRF\n", supply_name);
	}

	return 0;
}

U_BOOT_DRIVER(rockchip_iodomain) = {
	.name = "rockchip_iodomain",
	.id = UCLASS_NOP,
	.of_match = rockchip_iodomain_ids,
	.bind = rockchip_iodomain_bind,
	.probe = rockchip_iodomain_probe,
};
