plat: zynqmp: Add support for CG/EG/EV device detection

Read ipdisable reg which needs to be used for cg/eg/ev device detection.
ATF runs in EL3 that's why this read can be done directly.

Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Signed-off-by: Siva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
index 7a2a4f6..7d15d70 100644
--- a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
+++ b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c
@@ -60,6 +60,7 @@
 #if LOG_LEVEL >= LOG_LEVEL_NOTICE
 static const struct {
 	unsigned int id;
+	unsigned int ver;
 	char *name;
 } zynqmp_devices[] = {
 	{
@@ -67,33 +68,88 @@
 		.name = "3EG",
 	},
 	{
+		.id = 0x10,
+		.ver = 0x2c,
+		.name = "3CG",
+	},
+	{
 		.id = 0x11,
 		.name = "2EG",
 	},
 	{
+		.id = 0x11,
+		.ver = 0x2c,
+		.name = "2CG",
+	},
+	{
 		.id = 0x20,
 		.name = "5EV",
 	},
 	{
+		.id = 0x20,
+		.ver = 0x100,
+		.name = "5EG",
+	},
+	{
+		.id = 0x20,
+		.ver = 0x12c,
+		.name = "5CG",
+	},
+	{
 		.id = 0x21,
 		.name = "4EV",
 	},
 	{
+		.id = 0x21,
+		.ver = 0x100,
+		.name = "4EG",
+	},
+	{
+		.id = 0x21,
+		.ver = 0x12c,
+		.name = "4CG",
+	},
+	{
 		.id = 0x30,
 		.name = "7EV",
 	},
 	{
+		.id = 0x30,
+		.ver = 0x100,
+		.name = "7EG",
+	},
+	{
+		.id = 0x30,
+		.ver = 0x12c,
+		.name = "7CG",
+	},
+	{
 		.id = 0x38,
 		.name = "9EG",
 	},
 	{
+		.id = 0x38,
+		.ver = 0x2c,
+		.name = "9CG",
+	},
+	{
 		.id = 0x39,
 		.name = "6EG",
 	},
 	{
+		.id = 0x39,
+		.ver = 0x2c,
+		.name = "6CG",
+	},
+	{
 		.id = 0x40,
 		.name = "11EG",
 	},
+	{ /* For testing purpose only */
+		.id = 0x50,
+		.ver = 0x2c,
+		.name = "15CG",
+	},
 	{
 		.id = 0x50,
 		.name = "15EG",
@@ -144,13 +200,26 @@
 	return id;
 }
 
+static unsigned int zynqmp_get_silicon_id2(void)
+{
+	uint32_t id;
+
+	id = mmio_read_32(EFUSE_BASEADDR + EFUSE_IPDISABLE_OFFSET);
+	id &= EFUSE_IPDISABLE_VERSION;
+
+	return id;
+}
+
 static char *zynqmp_get_silicon_idcode_name(void)
 {
-	unsigned int id;
+	unsigned int id, ver;
+	size_t i;
 
 	id = zynqmp_get_silicon_id();
-	for (size_t i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
-		if (zynqmp_devices[i].id == id)
+	ver = zynqmp_get_silicon_id2();
+
+	for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
+		if (zynqmp_devices[i].id == id && zynqmp_devices[i].ver == ver)
 			return zynqmp_devices[i].name;
 	}
 	return "UNKN";
diff --git a/plat/xilinx/zynqmp/zynqmp_def.h b/plat/xilinx/zynqmp/zynqmp_def.h
index 42bce35..793be8b 100644
--- a/plat/xilinx/zynqmp/zynqmp_def.h
+++ b/plat/xilinx/zynqmp/zynqmp_def.h
@@ -174,6 +174,11 @@
 
 #define ZYNQMP_CSU_VERSION_OFFSET	0x44
 
+/* Efuse */
+#define EFUSE_BASEADDR		0xFFCC0000
+#define EFUSE_IPDISABLE_OFFSET	0x1018
+#define EFUSE_IPDISABLE_VERSION	0x1FFU
+
 /* Access control register defines */
 #define ACTLR_EL3_L2ACTLR_BIT	(1 << 6)
 #define ACTLR_EL3_CPUACTLR_BIT	(1 << 0)