ARM64: zynqmp: Add support for chip ID detection
authorMichal Simek <michal.simek@xilinx.com>
Mon, 1 Feb 2016 14:05:58 +0000 (15:05 +0100)
committerMichal Simek <michal.simek@xilinx.com>
Thu, 22 Sep 2016 05:33:21 +0000 (07:33 +0200)
Chip ID needs to be known for loading bitstream because
U-Boot checks ID from bitstream header in BIT format.
BIN format is completely unchecked.

The chipid is get from ATF via SMC.

Signed-off-by: Siva Durga Prasad Paladugu <sivadur@xilinx.com>
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
board/xilinx/zynqmp/zynqmp.c
include/zynqmppl.h

index df4fc901c1c7a8ec5a1240fbefa311c8dd4842c2..566b5e8d2afa4915bb13b6754ef43b323a1240d5 100644 (file)
 #include <asm/io.h>
 #include <usb.h>
 #include <dwc3-uboot.h>
+#include <zynqmppl.h>
 #include <i2c.h>
 #include <g_dnl.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
+    !defined(CONFIG_SPL_BUILD)
+static xilinx_desc zynqmppl = XILINX_ZYNQMP_DESC;
+
+static const struct {
+       uint32_t id;
+       char *name;
+} zynqmp_devices[] = {
+       {
+               .id = 0x10,
+               .name = "3eg",
+       },
+       {
+               .id = 0x11,
+               .name = "2eg",
+       },
+       {
+               .id = 0x20,
+               .name = "5ev",
+       },
+       {
+               .id = 0x21,
+               .name = "4ev",
+       },
+       {
+               .id = 0x30,
+               .name = "7ev",
+       },
+       {
+               .id = 0x38,
+               .name = "9eg",
+       },
+       {
+               .id = 0x39,
+               .name = "6eg",
+       },
+       {
+               .id = 0x40,
+               .name = "11eg",
+       },
+       {
+               .id = 0x50,
+               .name = "15eg",
+       },
+       {
+               .id = 0x58,
+               .name = "19eg",
+       },
+       {
+               .id = 0x59,
+               .name = "17eg",
+       },
+};
+
+static int chip_id(void)
+{
+       struct pt_regs regs;
+       regs.regs[0] = ZYNQMP_SIP_SVC_CSU_DMA_CHIPID;
+       regs.regs[1] = 0;
+       regs.regs[2] = 0;
+       regs.regs[3] = 0;
+
+       smc_call(&regs);
+
+       return regs.regs[0];
+}
+
+static char *zynqmp_get_silicon_idcode_name(void)
+{
+       uint32_t i, id;
+
+       id = chip_id();
+       for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
+               if (zynqmp_devices[i].id == id)
+                       return zynqmp_devices[i].name;
+       }
+       return "unknown";
+}
+#endif
+
+#define ZYNQMP_VERSION_SIZE    9
+
 int board_init(void)
 {
        printf("EL Level:\tEL%d\n", current_el());
 
+#if defined(CONFIG_FPGA) && defined(CONFIG_FPGA_ZYNQMPPL) && \
+    !defined(CONFIG_SPL_BUILD) || (defined(CONFIG_SPL_FPGA_SUPPORT) && \
+    defined(CONFIG_SPL_BUILD))
+       if (current_el() != 3) {
+               static char version[ZYNQMP_VERSION_SIZE];
+
+               strncat(version, "xczu", ZYNQMP_VERSION_SIZE);
+               zynqmppl.name = strncat(version,
+                                       zynqmp_get_silicon_idcode_name(),
+                                       ZYNQMP_VERSION_SIZE);
+               printf("Chip ID:\t%s\n", zynqmppl.name);
+               fpga_init();
+               fpga_add(fpga_xilinx, &zynqmppl);
+       }
+#endif
+
        return 0;
 }
 
index 002ee2aabbb89f335f67e1aa7db2996867d87eef..542ace9a03b9b6d9262bc64b0191c758e28cb500 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <xilinx.h>
 
+#define ZYNQMP_SIP_SVC_CSU_DMA_CHIPID          0xC2000018
 #define ZYNQMP_SIP_SVC_PM_FPGA_LOAD            0xC2000016
 #define ZYNQMP_FPGA_OP_INIT                    (1 << 0)
 #define ZYNQMP_FPGA_OP_LOAD                    (1 << 1)