From 494fffe70d6ebb4e4bffa4dc0a55df6b2b9a58d9 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 22 Aug 2017 14:58:53 +0200 Subject: [PATCH] arm64: zynqmp: Add support for CG/EG/EV device detection 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 --- arch/arm/include/asm/arch-zynqmp/hardware.h | 2 + arch/arm/include/asm/arch-zynqmp/sys_proto.h | 1 + board/xilinx/zynqmp/zynqmp.c | 68 +++++++++++++++++++- 3 files changed, 69 insertions(+), 2 deletions(-) diff --git a/arch/arm/include/asm/arch-zynqmp/hardware.h b/arch/arm/include/asm/arch-zynqmp/hardware.h index 5f2c98d633..327046bf1b 100644 --- a/arch/arm/include/asm/arch-zynqmp/hardware.h +++ b/arch/arm/include/asm/arch-zynqmp/hardware.h @@ -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 diff --git a/arch/arm/include/asm/arch-zynqmp/sys_proto.h b/arch/arm/include/asm/arch-zynqmp/sys_proto.h index db1d5ef306..f256c7d4a9 100644 --- a/arch/arm/include/asm/arch-zynqmp/sys_proto.h +++ b/arch/arm/include/asm/arch-zynqmp/sys_proto.h @@ -15,6 +15,7 @@ enum { IDCODE, VERSION, + IDCODE2, }; enum { diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c index 5e22cc54ba..2b1d8119f5 100644 --- a/board/xilinx/zynqmp/zynqmp.c +++ b/board/xilinx/zynqmp/zynqmp.c @@ -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"; -- 2.39.2