summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
authorIbai Erkiaga <ibai.erkiaga-elorza@xilinx.com>2020-08-04 23:17:31 +0100
committerMichal Simek <michal.simek@xilinx.com>2020-09-23 10:31:40 +0200
commitfa793165daf74133a2aef7cb98cc9050e36f0b6c (patch)
tree087369aa412b393138c1ed330cdba494e72dc68e /board
parent2783e02da846e54387a022043f5880684dfd5e5e (diff)
xilinx: zynqmp: refactor silicon name function
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 <ibai.erkiaga-elorza@xilinx.com> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Diffstat (limited to 'board')
-rw-r--r--board/xilinx/zynqmp/zynqmp.c303
1 files changed, 138 insertions, 165 deletions
diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
index b4e7301d50..006284fdc2 100644
--- a/board/xilinx/zynqmp/zynqmp.c
+++ b/board/xilinx/zynqmp/zynqmp.c
@@ -38,180 +38,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];
@@ -226,58 +189,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;