// SPDX-License-Identifier: GPL-2.0
/*
 * Xilinx ZynqMP SOC driver
 *
 * Copyright (C) 2021 Xilinx, Inc.
 * Michal Simek <michal.simek@xilinx.com>
 *
 * Copyright (C) 2022 Weidmüller Interface GmbH & Co. KG
 * Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com>
 */

#include <common.h>
#include <dm.h>
#include <dm/device_compat.h>
#include <asm/cache.h>
#include <soc.h>
#include <zynqmp_firmware.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/hardware.h>

/*
 * Zynqmp has 4 silicon revisions
 * v0 -> 0(XCZU9EG-ES1)
 * v1 -> 1(XCZU3EG-ES1, XCZU15EG-ES1)
 * v2 -> 2(XCZU7EV-ES1, XCZU9EG-ES2, XCZU19EG-ES1)
 * v3 -> 3(Production Level)
 */
static const char zynqmp_family[] = "ZynqMP";

#define EFUSE_VCU_DIS_SHIFT	8
#define EFUSE_VCU_DIS_MASK	BIT(EFUSE_VCU_DIS_SHIFT)
#define EFUSE_GPU_DIS_SHIFT	5
#define EFUSE_GPU_DIS_MASK	BIT(EFUSE_GPU_DIS_SHIFT)
#define IDCODE_DEV_TYPE_MASK	GENMASK(27, 0)
#define IDCODE2_PL_INIT_SHIFT	9
#define IDCODE2_PL_INIT_MASK	BIT(IDCODE2_PL_INIT_SHIFT)

#define ZYNQMP_VERSION_SIZE	7

enum {
	ZYNQMP_VARIANT_EG = BIT(0),
	ZYNQMP_VARIANT_EV = BIT(1),
	ZYNQMP_VARIANT_CG = BIT(2),
	ZYNQMP_VARIANT_DR = BIT(3),
};

struct zynqmp_device {
	u32 id;
	u8 device;
	u8 variants;
};

struct soc_xilinx_zynqmp_priv {
	const char *family;
	char machine[ZYNQMP_VERSION_SIZE];
	char revision;
};

static const struct zynqmp_device zynqmp_devices[] = {
	{
		.id = 0x04688093,
		.device = 1,
		.variants = ZYNQMP_VARIANT_EG,
	},
	{
		.id = 0x04711093,
		.device = 2,
		.variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
	},
	{
		.id = 0x04710093,
		.device = 3,
		.variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
	},
	{
		.id = 0x04721093,
		.device = 4,
		.variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG |
			ZYNQMP_VARIANT_EV,
	},
	{
		.id = 0x04720093,
		.device = 5,
		.variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG |
			ZYNQMP_VARIANT_EV,
	},
	{
		.id = 0x04739093,
		.device = 6,
		.variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
	},
	{
		.id = 0x04730093,
		.device = 7,
		.variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG |
			ZYNQMP_VARIANT_EV,
	},
	{
		.id = 0x04738093,
		.device = 9,
		.variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
	},
	{
		.id = 0x04740093,
		.device = 11,
		.variants = ZYNQMP_VARIANT_EG,
	},
	{
		.id = 0x04750093,
		.device = 15,
		.variants = ZYNQMP_VARIANT_EG,
	},
	{
		.id = 0x04759093,
		.device = 17,
		.variants = ZYNQMP_VARIANT_EG,
	},
	{
		.id = 0x04758093,
		.device = 19,
		.variants = ZYNQMP_VARIANT_EG,
	},
	{
		.id = 0x047E1093,
		.device = 21,
		.variants = ZYNQMP_VARIANT_DR,
	},
	{
		.id = 0x047E3093,
		.device = 23,
		.variants = ZYNQMP_VARIANT_DR,
	},
	{
		.id = 0x047E5093,
		.device = 25,
		.variants = ZYNQMP_VARIANT_DR,
	},
	{
		.id = 0x047E4093,
		.device = 27,
		.variants = ZYNQMP_VARIANT_DR,
	},
	{
		.id = 0x047E0093,
		.device = 28,
		.variants = ZYNQMP_VARIANT_DR,
	},
	{
		.id = 0x047E2093,
		.device = 29,
		.variants = ZYNQMP_VARIANT_DR,
	},
	{
		.id = 0x047E6093,
		.device = 39,
		.variants = ZYNQMP_VARIANT_DR,
	},
	{
		.id = 0x047FD093,
		.device = 43,
		.variants = ZYNQMP_VARIANT_DR,
	},
	{
		.id = 0x047F8093,
		.device = 46,
		.variants = ZYNQMP_VARIANT_DR,
	},
	{
		.id = 0x047FF093,
		.device = 47,
		.variants = ZYNQMP_VARIANT_DR,
	},
	{
		.id = 0x047FB093,
		.device = 48,
		.variants = ZYNQMP_VARIANT_DR,
	},
	{
		.id = 0x047FE093,
		.device = 49,
		.variants = ZYNQMP_VARIANT_DR,
	},
	{
		.id = 0x046d0093,
		.device = 67,
		.variants = ZYNQMP_VARIANT_DR,
	},
	{
		.id = 0x04714093,
		.device = 24,
		.variants = 0,
	},
	{
		.id = 0x04724093,
		.device = 26,
		.variants = 0,
	},
};

static const struct zynqmp_device *zynqmp_get_device(u32 idcode)
{
	idcode &= IDCODE_DEV_TYPE_MASK;

	for (int i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
		if (zynqmp_devices[i].id == idcode)
			return &zynqmp_devices[i];
	}

	return NULL;
}

static int soc_xilinx_zynqmp_detect_machine(struct udevice *dev, u32 idcode,
					    u32 idcode2)
{
	struct soc_xilinx_zynqmp_priv *priv = dev_get_priv(dev);
	const struct zynqmp_device *device;
	int ret;

	device = zynqmp_get_device(idcode);
	if (!device)
		return 0;

	/* Add device prefix to the name */
	ret = snprintf(priv->machine, sizeof(priv->machine), "%s%d",
		       device->variants ? "zu" : "xck", device->device);
	if (ret < 0)
		return ret;

	if (device->variants & ZYNQMP_VARIANT_EV) {
		/* Devices with EV variant might be EG/CG/EV family */
		if (idcode2 & IDCODE2_PL_INIT_MASK) {
			u32 family = ((idcode2 & EFUSE_VCU_DIS_MASK) >>
				      EFUSE_VCU_DIS_SHIFT) << 1 |
				     ((idcode2 & EFUSE_GPU_DIS_MASK) >>
				      EFUSE_GPU_DIS_SHIFT);

			/*
			 * Get family name based on extended idcode values as
			 * determined on UG1087, EXTENDED_IDCODE register
			 * description
			 */
			switch (family) {
			case 0x00:
				strlcat(priv->machine, "ev",
					sizeof(priv->machine));
				break;
			case 0x10:
				strlcat(priv->machine, "eg",
					sizeof(priv->machine));
				break;
			case 0x11:
				strlcat(priv->machine, "cg",
					sizeof(priv->machine));
				break;
			default:
				/* Do not append family name*/
				break;
			}
		} else {
			/*
			 * When PL powered down the VCU Disable efuse cannot be
			 * read. So, ignore the bit and just findout if it is CG
			 * or EG/EV variant.
			 */
			strlcat(priv->machine, (idcode2 & EFUSE_GPU_DIS_MASK) ?
				"cg" : "e", sizeof(priv->machine));
		}
	} else if (device->variants & ZYNQMP_VARIANT_CG) {
		/* Devices with CG variant might be EG or CG family */
		strlcat(priv->machine, (idcode2 & EFUSE_GPU_DIS_MASK) ?
			"cg" : "eg", sizeof(priv->machine));
	} else if (device->variants & ZYNQMP_VARIANT_EG) {
		strlcat(priv->machine, "eg", sizeof(priv->machine));
	} else if (device->variants & ZYNQMP_VARIANT_DR) {
		strlcat(priv->machine, "dr", sizeof(priv->machine));
	}

	return 0;
}

static int soc_xilinx_zynqmp_get_family(struct udevice *dev, char *buf, int size)
{
	struct soc_xilinx_zynqmp_priv *priv = dev_get_priv(dev);

	return snprintf(buf, size, "%s", priv->family);
}

int soc_xilinx_zynqmp_get_machine(struct udevice *dev, char *buf, int size)
{
	struct soc_xilinx_zynqmp_priv *priv = dev_get_priv(dev);
	const char *machine = priv->machine;

	if (!machine[0])
		machine = "unknown";

	return snprintf(buf, size, "%s", machine);
}

static int soc_xilinx_zynqmp_get_revision(struct udevice *dev, char *buf, int size)
{
	struct soc_xilinx_zynqmp_priv *priv = dev_get_priv(dev);

	return snprintf(buf, size, "v%d", priv->revision);
}

static const struct soc_ops soc_xilinx_zynqmp_ops = {
	.get_family = soc_xilinx_zynqmp_get_family,
	.get_revision = soc_xilinx_zynqmp_get_revision,
	.get_machine = soc_xilinx_zynqmp_get_machine,
};

static int soc_xilinx_zynqmp_probe(struct udevice *dev)
{
	struct soc_xilinx_zynqmp_priv *priv = dev_get_priv(dev);
	u32 ret_payload[PAYLOAD_ARG_CNT];
	int ret;

	priv->family = zynqmp_family;

	if (!IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE))
		ret = zynqmp_mmio_read(ZYNQMP_PS_VERSION, &ret_payload[2]);
	else
		ret = xilinx_pm_request(PM_GET_CHIPID, 0, 0, 0, 0,
					ret_payload);
	if (ret < 0)
		return ret;

	priv->revision = ret_payload[2] & ZYNQMP_PS_VER_MASK;

	if (IS_ENABLED(CONFIG_ZYNQMP_FIRMWARE)) {
		/*
		 * Firmware returns:
		 * payload[0][31:0] = status of the operation
		 * payload[1] = IDCODE
		 * payload[2][19:0] = Version
		 * payload[2][28:20] = EXTENDED_IDCODE
		 * payload[2][29] = PL_INIT
		 */
		u32 idcode = ret_payload[1];
		u32 idcode2 = ret_payload[2] >>
				   ZYNQMP_CSU_VERSION_EMPTY_SHIFT;
		dev_dbg(dev, "IDCODE: 0x%0x, IDCODE2: 0x%0x\n", idcode,
			idcode2);

		ret = soc_xilinx_zynqmp_detect_machine(dev, idcode, idcode2);
		if (ret)
			return ret;
	}

	return 0;
}

U_BOOT_DRIVER(soc_xilinx_zynqmp) = {
	.name		= "soc_xilinx_zynqmp",
	.id		= UCLASS_SOC,
	.ops		= &soc_xilinx_zynqmp_ops,
	.probe		= soc_xilinx_zynqmp_probe,
	.priv_auto	= sizeof(struct soc_xilinx_zynqmp_priv),
	.flags		= DM_FLAG_PRE_RELOC,
};
