arm64: zynqmp: Add support for CG/EG/EV device detection
authorMichal Simek <michal.simek@xilinx.com>
Tue, 22 Aug 2017 12:58:53 +0000 (14:58 +0200)
committerMichal Simek <michal.simek@xilinx.com>
Tue, 28 Nov 2017 15:09:01 +0000 (16:09 +0100)
Version string has unused fields 31:20 which can be used for exporting 9
bits from efuse IPDISABLE regs to recognize eg/cg/ev devices.

These efuse bits are setup for certain devices.

Signed-off-by: Michal Simek <michal.simek@xilinx.com>
arch/arm/include/asm/arch-zynqmp/hardware.h
arch/arm/include/asm/arch-zynqmp/sys_proto.h
board/xilinx/zynqmp/zynqmp.c

index 5f2c98d633e39a90babaf84d7361e2f373542a06..327046bf1b29f4f406c996dc52ccd26bbb474564 100644 (file)
@@ -128,6 +128,8 @@ struct apu_regs {
 #define ZYNQMP_CSU_VERSION_VELOCE      0x2
 #define ZYNQMP_CSU_VERSION_QEMU                0x3
 
+#define ZYNQMP_CSU_VERSION_EMPTY_SHIFT         20
+
 #define ZYNQMP_SILICON_VER_MASK                0xF000
 #define ZYNQMP_SILICON_VER_SHIFT       12
 
index db1d5ef306f8a5b6d576716d204cdb46ea469631..f256c7d4a996beecfd9db9eac9af60c37bc74eef 100644 (file)
@@ -15,6 +15,7 @@
 enum {
        IDCODE,
        VERSION,
+       IDCODE2,
 };
 
 enum {
index 5e22cc54ba69bba6c1fe908b35b25c059592d6ba..2b1d8119f56743099f7ef81dad9b50107ae58438 100644 (file)
@@ -28,40 +28,96 @@ static xilinx_desc zynqmppl = XILINX_ZYNQMP_DESC;
 
 static const struct {
        u32 id;
+       u32 ver;
        char *name;
 } 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",
        },
+       {
+               .id = 0x20,
+               .ver = 0x100,
+               .name = "5eg",
+       },
+       {
+               .id = 0x20,
+               .ver = 0x12c,
+               .name = "5cg",
+       },
        {
                .id = 0x21,
                .name = "4ev",
        },
+       {
+               .id = 0x21,
+               .ver = 0x100,
+               .name = "4eg",
+       },
+       {
+               .id = 0x21,
+               .ver = 0x12c,
+               .name = "4cg",
+       },
        {
                .id = 0x30,
                .name = "7ev",
        },
+       {
+               .id = 0x30,
+               .ver = 0x100,
+               .name = "7eg",
+       },
+       {
+               .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",
@@ -95,6 +151,7 @@ int chip_id(unsigned char id)
                 * 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:
@@ -109,6 +166,11 @@ int chip_id(unsigned char id)
                        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);
                }
@@ -136,11 +198,13 @@ int chip_id(unsigned char id)
        !defined(CONFIG_SPL_BUILD)
 static char *zynqmp_get_silicon_idcode_name(void)
 {
-       u32 i, id;
+       u32 i, id, ver;
 
        id = chip_id(IDCODE);
+       ver = chip_id(IDCODE2);
+
        for (i = 0; i < ARRAY_SIZE(zynqmp_devices); i++) {
-               if (zynqmp_devices[i].id == id)
+               if (zynqmp_devices[i].id == id && zynqmp_devices[i].ver == ver)
                        return zynqmp_devices[i].name;
        }
        return "unknown";