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)