arm64: zynqmp: Fix logic in CG/EG/EV detection
authorSiva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
Fri, 26 Oct 2018 12:17:55 +0000 (17:47 +0530)
committerMichal Simek <michal.simek@xilinx.com>
Mon, 26 Nov 2018 09:50:54 +0000 (10:50 +0100)
The VCU disable bit(8) in IP disable register of efuse
is valid only if PL powered up and hence PL powerup status
has to be considered while determining the CG part also.
This patch considers the PL powerup status and ignores the VCU
disable bit if PL not powered up.
This fixes the issue of "unknown" id for CG parts if PL not powered up
and VCU bit(8) is not set.

Signed-off-by: Siva Durga Prasad Paladugu <siva.durga.paladugu@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
board/xilinx/zynqmp/zynqmp.c

index af91cde7c89467dedf17c8f87b7b378e3512bfbc..168cf5c14b4565d068803e668f92bb74e6ce86dd 100644 (file)
@@ -72,6 +72,7 @@ static const struct {
                .id = 0x20,
                .ver = 0x12c,
                .name = "5cg",
+               .evexists = 1,
        },
        {
                .id = 0x21,
@@ -88,6 +89,7 @@ static const struct {
                .id = 0x21,
                .ver = 0x12c,
                .name = "4cg",
+               .evexists = 1,
        },
        {
                .id = 0x30,
@@ -104,6 +106,7 @@ static const struct {
                .id = 0x30,
                .ver = 0x12c,
                .name = "7cg",
+               .evexists = 1,
        },
        {
                .id = 0x38,
@@ -234,14 +237,18 @@ int chip_id(unsigned char id)
 
 #define ZYNQMP_VERSION_SIZE            9
 #define ZYNQMP_PL_STATUS_BIT           9
+#define ZYNQMP_IPDIS_VCU_BIT           8
 #define ZYNQMP_PL_STATUS_MASK          BIT(ZYNQMP_PL_STATUS_BIT)
 #define ZYNQMP_CSU_VERSION_MASK                ~(ZYNQMP_PL_STATUS_MASK)
+#define ZYNQMP_CSU_VCUDIS_VER_MASK     ZYNQMP_CSU_VERSION_MASK & \
+                                       ~BIT(ZYNQMP_IPDIS_VCU_BIT)
+#define MAX_VARIANTS_EV                        3
 
 #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
        !defined(CONFIG_SPL_BUILD)
 static char *zynqmp_get_silicon_idcode_name(void)
 {
-       u32 i, id, ver;
+       u32 i, id, ver, j;
        char *buf;
        static char name[ZYNQMP_VERSION_SIZE];
 
@@ -249,24 +256,43 @@ static char *zynqmp_get_silicon_idcode_name(void)
        ver = chip_id(IDCODE2);
 
        for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
-               if ((zynqmp_devices[i].id == id) &&
-                   (zynqmp_devices[i].ver == (ver &
-                   ZYNQMP_CSU_VERSION_MASK))) {
-                       strncat(name, "zu", 2);
-                       strncat(name, zynqmp_devices[i].name,
-                               ZYNQMP_VERSION_SIZE - 3);
-                       break;
+               if (zynqmp_devices[i].id == id) {
+                       if (zynqmp_devices[i].evexists &&
+                           !(ver & ZYNQMP_PL_STATUS_MASK))
+                               break;
+                       if (zynqmp_devices[i].ver == (ver &
+                           ZYNQMP_CSU_VERSION_MASK))
+                               break;
                }
        }
 
        if (i >= ARRAY_SIZE(zynqmp_devices))
                return "unknown";
 
-       if (!zynqmp_devices[i].evexists)
+       strncat(name, "zu", 2);
+       if (!zynqmp_devices[i].evexists ||
+           (ver & ZYNQMP_PL_STATUS_MASK)) {
+               strncat(name, zynqmp_devices[i].name,
+                       ZYNQMP_VERSION_SIZE - 3);
                return name;
+       }
 
-       if (ver & ZYNQMP_PL_STATUS_MASK)
-               return name;
+       /*
+        * Here we are means, PL not powered up and ev variant
+        * exists. So, we need to ignore VCU disable bit(8) in
+        * version and findout if its CG or EG/EV variant.
+        */
+       for (j = 0; j < MAX_VARIANTS_EV; j++, i++) {
+               if ((zynqmp_devices[i].ver & ~BIT(ZYNQMP_IPDIS_VCU_BIT)) ==
+                   (ver & ZYNQMP_CSU_VCUDIS_VER_MASK)) {
+                       strncat(name, zynqmp_devices[i].name,
+                               ZYNQMP_VERSION_SIZE - 3);
+                       break;
+               }
+       }
+
+       if (j >= MAX_VARIANTS_EV)
+               return "unknown";
 
        if (strstr(name, "eg") || strstr(name, "ev")) {
                buf = strstr(name, "e");