[PATCH v2 0/3] xilinx: zynqmp: Silicon name cleanup

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

[PATCH v2 0/3] xilinx: zynqmp: Silicon name cleanup

Michal Simek-3
Hi,

This patch series is intended to cleanup the functions used to get
the silicon name for ZynqMPSoC devices. It make use the firmware driver
rather than SMC call and impements more understandable agorithm to
compute the device name.

v2 series contains only patches which hasn't been applied yet.
And also one more patch for adding new dr devices.

Thanks,
Ibai/Michal

Changes in v2:
- Add missing 23/39/48/49dr devices
- new patch in this series

Ibai Erkiaga (1):
  xilinx: zynqmp: refactor silicon name function

Michal Simek (2):
  xilinx: zynqmp: Add missing 43/46/47dr ID codes
  xilinx: zynqmp: Remove one static variable

 board/xilinx/zynqmp/zynqmp.c | 312 +++++++++++++++++------------------
 1 file changed, 150 insertions(+), 162 deletions(-)

--
2.28.0

Reply | Threaded
Open this post in threaded view
|

[PATCH v2 1/3] xilinx: zynqmp: refactor silicon name function

Michal Simek-3
From: Ibai Erkiaga <[hidden email]>

Current algorithm used to get the silicon name is bit complicated and
hard to follow. Updated to use more straightforward mechanism based on
the Device ID code table (Table 1-2). The full IDCODE register is used
(except device revision bits [31:28]) to get the device name and IDCODE2
value is used for identifying the variant.

Additionally to make the algorithm bit more clear it also save some space
as the devices table is slightly bit smaller.

Signed-off-by: Ibai Erkiaga <[hidden email]>
Signed-off-by: Michal Simek <[hidden email]>
---

Changes in v2:
- Add missing 23/39/48/49dr devices

 board/xilinx/zynqmp/zynqmp.c | 303 ++++++++++++++++-------------------
 1 file changed, 138 insertions(+), 165 deletions(-)

diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
index fe2e219b98c3..ef35b0e5992d 100644
--- a/board/xilinx/zynqmp/zynqmp.c
+++ b/board/xilinx/zynqmp/zynqmp.c
@@ -39,180 +39,143 @@
 
 #include "pm_cfg_obj.h"
 
+#define ZYNQMP_VERSION_SIZE 7
+#define EFUSE_VCU_DIS_MASK     0x100
+#define EFUSE_VCU_DIS_SHIFT    8
+#define EFUSE_GPU_DIS_MASK     0x20
+#define EFUSE_GPU_DIS_SHIFT    5
+#define IDCODE2_PL_INIT_MASK   0x200
+#define IDCODE2_PL_INIT_SHIFT  9
+
 DECLARE_GLOBAL_DATA_PTR;
 
 #if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
-    !defined(CONFIG_SPL_BUILD)
+    !defined(CONFIG_SPL_BUILD) || (defined(CONFIG_SPL_FPGA_SUPPORT) && \
+    defined(CONFIG_SPL_BUILD))
+
 static xilinx_desc zynqmppl = XILINX_ZYNQMP_DESC;
 
+enum {
+ ZYNQMP_VARIANT_EG = BIT(0U),
+ ZYNQMP_VARIANT_EV = BIT(1U),
+ ZYNQMP_VARIANT_CG = BIT(2U),
+ ZYNQMP_VARIANT_DR = BIT(3U),
+};
+
 static const struct {
  u32 id;
- u32 ver;
- char *name;
- bool evexists;
+ u8 device;
+ u8 variants;
 } zynqmp_devices[] = {
  {
- .id = 0x10,
- .name = "3eg",
- },
- {
- .id = 0x10,
- .ver = 0x2c,
- .name = "3cg",
- },
- {
- .id = 0x11,
- .name = "2eg",
- },
- {
- .id = 0x11,
- .ver = 0x2c,
- .name = "2cg",
- },
- {
- .id = 0x20,
- .name = "5ev",
- .evexists = 1,
- },
- {
- .id = 0x20,
- .ver = 0x100,
- .name = "5eg",
- .evexists = 1,
- },
- {
- .id = 0x20,
- .ver = 0x12c,
- .name = "5cg",
- .evexists = 1,
- },
- {
- .id = 0x21,
- .name = "4ev",
- .evexists = 1,
- },
- {
- .id = 0x21,
- .ver = 0x100,
- .name = "4eg",
- .evexists = 1,
- },
- {
- .id = 0x21,
- .ver = 0x12c,
- .name = "4cg",
- .evexists = 1,
- },
- {
- .id = 0x30,
- .name = "7ev",
- .evexists = 1,
+ .id = 0x04711093,
+ .device = 2,
+ .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
  },
  {
- .id = 0x30,
- .ver = 0x100,
- .name = "7eg",
- .evexists = 1,
+ .id = 0x04710093,
+ .device = 3,
+ .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
  },
  {
- .id = 0x30,
- .ver = 0x12c,
- .name = "7cg",
- .evexists = 1,
+ .id = 0x04721093,
+ .device = 4,
+ .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG |
+ ZYNQMP_VARIANT_EV,
  },
  {
- .id = 0x38,
- .name = "9eg",
+ .id = 0x04720093,
+ .device = 5,
+ .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG |
+ ZYNQMP_VARIANT_EV,
  },
  {
- .id = 0x38,
- .ver = 0x2c,
- .name = "9cg",
+ .id = 0x04739093,
+ .device = 6,
+ .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
  },
  {
- .id = 0x39,
- .name = "6eg",
+ .id = 0x04730093,
+ .device = 7,
+ .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG |
+ ZYNQMP_VARIANT_EV,
  },
  {
- .id = 0x39,
- .ver = 0x2c,
- .name = "6cg",
+ .id = 0x04738093,
+ .device = 9,
+ .variants = ZYNQMP_VARIANT_EG,
  },
  {
- .id = 0x40,
- .name = "11eg",
- },
- { /* For testing purpose only */
- .id = 0x50,
- .ver = 0x2c,
- .name = "15cg",
+ .id = 0x04740093,
+ .device = 11,
+ .variants = ZYNQMP_VARIANT_EG,
  },
  {
- .id = 0x50,
- .name = "15eg",
+ .id = 0x04750093,
+ .device = 15,
+ .variants = ZYNQMP_VARIANT_EG,
  },
  {
- .id = 0x58,
- .name = "19eg",
+ .id = 0x04759093,
+ .device = 17,
+ .variants = ZYNQMP_VARIANT_EG,
  },
  {
- .id = 0x59,
- .name = "17eg",
+ .id = 0x04758093,
+ .device = 19,
+ .variants = ZYNQMP_VARIANT_EG,
  },
  {
- .id = 0x61,
- .name = "21dr",
+ .id = 0x047E1093,
+ .device = 21,
+ .variants = ZYNQMP_VARIANT_DR,
  },
  {
- .id = 0x63,
- .name = "23dr",
+ .id = 0x047E3093,
+ .device = 23,
+ .variants = ZYNQMP_VARIANT_DR,
  },
  {
- .id = 0x65,
- .name = "25dr",
+ .id = 0x047E5093,
+ .device = 25,
+ .variants = ZYNQMP_VARIANT_DR,
  },
  {
- .id = 0x64,
- .name = "27dr",
+ .id = 0x047E4093,
+ .device = 27,
+ .variants = ZYNQMP_VARIANT_DR,
  },
  {
- .id = 0x60,
- .name = "28dr",
+ .id = 0x047E0093,
+ .device = 28,
+ .variants = ZYNQMP_VARIANT_DR,
  },
  {
- .id = 0x62,
- .name = "29dr",
+ .id = 0x047E2093,
+ .device = 29,
+ .variants = ZYNQMP_VARIANT_DR,
  },
  {
- .id = 0x66,
- .name = "39dr",
+ .id = 0x047E6093,
+ .device = 39,
+ .variants = ZYNQMP_VARIANT_DR,
  },
  {
- .id = 0x7b,
- .name = "48dr",
+ .id = 0x047FB093,
+ .device = 48,
+ .variants = ZYNQMP_VARIANT_DR,
  },
  {
- .id = 0x7e,
- .name = "49dr",
+ .id = 0x047FE093,
+ .device = 49,
+ .variants = ZYNQMP_VARIANT_DR,
  },
 };
-#endif
-
-#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, j;
- char *buf;
+ u32 i;
+ u32 idcode, idcode2;
  static char name[ZYNQMP_VERSION_SIZE];
  u32 ret_payload[PAYLOAD_ARG_CNT];
 
@@ -227,58 +190,68 @@ static char *zynqmp_get_silicon_idcode_name(void)
  * payload[2][29] = PL_INIT
  */
 
- /* Get IDCODE field */
- id = ret_payload[1];
- id &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK | ZYNQMP_CSU_IDCODE_SVD_MASK;
- id >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
-
- /* Shift silicon version info */
- ver = ret_payload[2] >> ZYNQMP_CSU_VERSION_EMPTY_SHIFT;
-
- debug("%s, ID: 0x%0X, Ver: 0x%0X\r\n", __func__, id, ver);
+ idcode  = ret_payload[1];
+ idcode2 = ret_payload[2] >> ZYNQMP_CSU_VERSION_EMPTY_SHIFT;
+ debug("%s, IDCODE: 0x%0X, IDCODE2: 0x%0X\r\n", __func__, idcode,
+      idcode2);
 
  for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
- 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 (zynqmp_devices[i].id == (idcode & 0x0FFFFFFF))
+ break;
  }
 
  if (i >= ARRAY_SIZE(zynqmp_devices))
  return "unknown";
 
+ /* Add device prefix to the name */
  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;
- }
-
- /*
- * 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;
+ strncat(&name[2], simple_itoa(zynqmp_devices[i].device), 2);
+
+ if (zynqmp_devices[i].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:
+ strncat(name, "ev", 2);
+ break;
+ case 0x10:
+ strncat(name, "eg", 2);
+ break;
+ case 0x11:
+ strncat(name, "cg", 2);
+ 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.
+ */
+ strncat(name, (idcode2 & EFUSE_GPU_DIS_MASK) ? "cg" :
+ "e", 2);
  }
- }
-
- if (j >= MAX_VARIANTS_EV)
- return "unknown";
-
- if (strstr(name, "eg") || strstr(name, "ev")) {
- buf = strstr(name, "e");
- *buf = '\0';
+ } else if (zynqmp_devices[i].variants & ZYNQMP_VARIANT_CG) {
+ /* Devices with CG variant might be EG or CG family */
+ strncat(name, (idcode2 & EFUSE_GPU_DIS_MASK) ? "cg" : "eg", 2);
+ } else if (zynqmp_devices[i].variants & ZYNQMP_VARIANT_EG) {
+ strncat(name, "eg", 2);
+ } else if (zynqmp_devices[i].variants & ZYNQMP_VARIANT_DR) {
+ strncat(name, "dr", 2);
+ } else {
+ debug("Variant not identified\n");
  }
 
  return name;
--
2.28.0

Reply | Threaded
Open this post in threaded view
|

[PATCH v2 2/3] xilinx: zynqmp: Add missing 43/46/47dr ID codes

Michal Simek-3
In reply to this post by Michal Simek-3
Add support for 43/46/47dr devices.

Signed-off-by: Michal Simek <[hidden email]>
---

Changes in v2:
- new patch in this series

 board/xilinx/zynqmp/zynqmp.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
index ef35b0e5992d..177e03906178 100644
--- a/board/xilinx/zynqmp/zynqmp.c
+++ b/board/xilinx/zynqmp/zynqmp.c
@@ -160,6 +160,21 @@ static const struct {
  .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,
--
2.28.0

Reply | Threaded
Open this post in threaded view
|

[PATCH v2 3/3] xilinx: zynqmp: Remove one static variable

Michal Simek-3
In reply to this post by Michal Simek-3
There is no reason to have name variable saved in BSS section when it
doesn't need to be really used. That's why remove static from variable
definition and use strdup() to duplicate string with exact size from malloc
area instead.

Signed-off-by: Michal Simek <[hidden email]>
---

(no changes since v1)

 board/xilinx/zynqmp/zynqmp.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
index 177e03906178..f5a88ac5d040 100644
--- a/board/xilinx/zynqmp/zynqmp.c
+++ b/board/xilinx/zynqmp/zynqmp.c
@@ -191,7 +191,7 @@ static char *zynqmp_get_silicon_idcode_name(void)
 {
  u32 i;
  u32 idcode, idcode2;
- static char name[ZYNQMP_VERSION_SIZE];
+ char name[ZYNQMP_VERSION_SIZE];
  u32 ret_payload[PAYLOAD_ARG_CNT];
 
  xilinx_pm_request(PM_GET_CHIPID, 0, 0, 0, 0, ret_payload);
@@ -219,7 +219,7 @@ static char *zynqmp_get_silicon_idcode_name(void)
  return "unknown";
 
  /* Add device prefix to the name */
- strncat(name, "zu", 2);
+ strncpy(name, "zu", ZYNQMP_VERSION_SIZE);
  strncat(&name[2], simple_itoa(zynqmp_devices[i].device), 2);
 
  if (zynqmp_devices[i].variants & ZYNQMP_VARIANT_EV) {
@@ -269,7 +269,7 @@ static char *zynqmp_get_silicon_idcode_name(void)
  debug("Variant not identified\n");
  }
 
- return name;
+ return strdup(name);
 }
 #endif
 
--
2.28.0

Reply | Threaded
Open this post in threaded view
|

Re: [PATCH v2 0/3] xilinx: zynqmp: Silicon name cleanup

Michal Simek-4
In reply to this post by Michal Simek-3
pá 11. 9. 2020 v 10:12 odesílatel Michal Simek <[hidden email]> napsal:

>
> Hi,
>
> This patch series is intended to cleanup the functions used to get
> the silicon name for ZynqMPSoC devices. It make use the firmware driver
> rather than SMC call and impements more understandable agorithm to
> compute the device name.
>
> v2 series contains only patches which hasn't been applied yet.
> And also one more patch for adding new dr devices.
>
> Thanks,
> Ibai/Michal
>
> Changes in v2:
> - Add missing 23/39/48/49dr devices
> - new patch in this series
>
> Ibai Erkiaga (1):
>   xilinx: zynqmp: refactor silicon name function
>
> Michal Simek (2):
>   xilinx: zynqmp: Add missing 43/46/47dr ID codes
>   xilinx: zynqmp: Remove one static variable
>
>  board/xilinx/zynqmp/zynqmp.c | 312 +++++++++++++++++------------------
>  1 file changed, 150 insertions(+), 162 deletions(-)
>
> --
> 2.28.0
>

Applied.
M

--
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs