+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_WDT)
+static struct udevice *watchdog_dev;
+#endif
+
+#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
+ !defined(CONFIG_SPL_BUILD)
+static xilinx_desc zynqmppl = XILINX_ZYNQMP_DESC;
+
+static const struct {
+ u32 id;
+ u32 ver;
+ char *name;
+ bool evexists;
+} 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",
+ },
+ {
+ .id = 0x21,
+ .name = "4ev",
+ .evexists = 1,
+ },
+ {
+ .id = 0x21,
+ .ver = 0x100,
+ .name = "4eg",
+ .evexists = 1,
+ },
+ {
+ .id = 0x21,
+ .ver = 0x12c,
+ .name = "4cg",
+ },
+ {
+ .id = 0x30,
+ .name = "7ev",
+ .evexists = 1,
+ },
+ {
+ .id = 0x30,
+ .ver = 0x100,
+ .name = "7eg",
+ .evexists = 1,
+ },
+ {
+ .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",
+ },
+ {
+ .id = 0x58,
+ .name = "19eg",
+ },
+ {
+ .id = 0x59,
+ .name = "17eg",
+ },
+ {
+ .id = 0x61,
+ .name = "21dr",
+ },
+ {
+ .id = 0x63,
+ .name = "23dr",
+ },
+ {
+ .id = 0x65,
+ .name = "25dr",
+ },
+ {
+ .id = 0x64,
+ .name = "27dr",
+ },
+ {
+ .id = 0x60,
+ .name = "28dr",
+ },
+ {
+ .id = 0x62,
+ .name = "29dr",
+ },
+};
+#endif
+
+int chip_id(unsigned char id)
+{
+ struct pt_regs regs;
+ int val = -EINVAL;
+
+ if (current_el() != 3) {
+ regs.regs[0] = ZYNQMP_SIP_SVC_CSU_DMA_CHIPID;
+ regs.regs[1] = 0;
+ regs.regs[2] = 0;
+ regs.regs[3] = 0;
+
+ smc_call(®s);
+
+ /*
+ * SMC returns:
+ * regs[0][31:0] = status of the operation
+ * regs[0][63:32] = CSU.IDCODE register
+ * regs[1][31:0] = CSU.version register
+ * regs[1][63:32] = CSU.IDCODE2 register
+ */
+ switch (id) {
+ case IDCODE:
+ regs.regs[0] = upper_32_bits(regs.regs[0]);
+ regs.regs[0] &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
+ ZYNQMP_CSU_IDCODE_SVD_MASK;
+ regs.regs[0] >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
+ val = regs.regs[0];
+ break;
+ case VERSION:
+ regs.regs[1] = lower_32_bits(regs.regs[1]);
+ regs.regs[1] &= ZYNQMP_CSU_SILICON_VER_MASK;
+ val = regs.regs[1];
+ break;
+ case IDCODE2:
+ regs.regs[1] = lower_32_bits(regs.regs[1]);
+ regs.regs[1] >>= ZYNQMP_CSU_VERSION_EMPTY_SHIFT;
+ val = regs.regs[1];
+ break;
+ default:
+ printf("%s, Invalid Req:0x%x\n", __func__, id);
+ }
+ } else {
+ switch (id) {
+ case IDCODE:
+ val = readl(ZYNQMP_CSU_IDCODE_ADDR);
+ val &= ZYNQMP_CSU_IDCODE_DEVICE_CODE_MASK |
+ ZYNQMP_CSU_IDCODE_SVD_MASK;
+ val >>= ZYNQMP_CSU_IDCODE_SVD_SHIFT;
+ break;
+ case VERSION:
+ val = readl(ZYNQMP_CSU_VER_ADDR);
+ val &= ZYNQMP_CSU_SILICON_VER_MASK;
+ break;
+ default:
+ printf("%s, Invalid Req:0x%x\n", __func__, id);
+ }
+ }
+
+ return val;
+}
+
+#define ZYNQMP_VERSION_SIZE 9
+#define ZYNQMP_PL_STATUS_BIT 9
+#define ZYNQMP_PL_STATUS_MASK BIT(ZYNQMP_PL_STATUS_BIT)
+#define ZYNQMP_CSU_VERSION_MASK ~(ZYNQMP_PL_STATUS_MASK)
+
+#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
+ !defined(CONFIG_SPL_BUILD)
+static char *zynqmp_get_silicon_idcode_name(void)
+{
+ u32 i, id, ver;
+ char *buf;
+ static char name[ZYNQMP_VERSION_SIZE];
+
+ id = chip_id(IDCODE);
+ 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 (i >= ARRAY_SIZE(zynqmp_devices))
+ return "unknown";
+
+ if (!zynqmp_devices[i].evexists)
+ return name;
+
+ if (ver & ZYNQMP_PL_STATUS_MASK)
+ return name;
+
+ if (strstr(name, "eg") || strstr(name, "ev")) {
+ buf = strstr(name, "e");
+ *buf = '\0';
+ }
+
+ return name;
+}
+#endif
+
+int board_early_init_f(void)
+{
+ int ret = 0;
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_CLK_ZYNQMP)
+ zynqmp_pmufw_version();
+#endif
+
+#if defined(CONFIG_ZYNQMP_PSU_INIT_ENABLED)
+ ret = psu_init();
+#endif
+
+#if defined(CONFIG_WDT) && !defined(CONFIG_SPL_BUILD)
+ /* bss is not cleared at time when watchdog_reset() is called */
+ watchdog_dev = NULL;
+#endif
+
+ return ret;
+}
+