[PATCH 6/8] xilinx: zynqmp: refactor silicon name function
Michal Simek
monstr at monstr.eu
Wed Aug 19 09:34:53 CEST 2020
Hi,
st 5. 8. 2020 v 13:24 odesílatel Michal Simek <michal.simek at xilinx.com> napsal:
>
> From: Ibai Erkiaga <ibai.erkiaga-elorza at xilinx.com>
>
> 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 at xilinx.com>
> Signed-off-by: Michal Simek <michal.simek at xilinx.com>
> ---
>
> board/xilinx/zynqmp/zynqmp.c | 299 +++++++++++++++--------------------
> 1 file changed, 126 insertions(+), 173 deletions(-)
>
> diff --git a/board/xilinx/zynqmp/zynqmp.c b/board/xilinx/zynqmp/zynqmp.c
> index 2a430a9e4638..383125087255 100644
> --- a/board/xilinx/zynqmp/zynqmp.c
> +++ b/board/xilinx/zynqmp/zynqmp.c
> @@ -38,180 +38,123 @@
>
> #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 = 0x30,
> - .ver = 0x100,
> - .name = "7eg",
> - .evexists = 1,
> - },
> - {
> - .id = 0x30,
> - .ver = 0x12c,
> - .name = "7cg",
> - .evexists = 1,
> - },
> - {
> - .id = 0x38,
> - .name = "9eg",
> - },
> - {
> - .id = 0x38,
> - .ver = 0x2c,
> - .name = "9cg",
> + .id = 0x04711093,
> + .device = 2,
> + .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
> },
> {
> - .id = 0x39,
> - .name = "6eg",
> + .id = 0x04710093,
> + .device = 3,
> + .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
> },
> {
> - .id = 0x39,
> - .ver = 0x2c,
> - .name = "6cg",
> + .id = 0x04721093,
> + .device = 4,
> + .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG |
> + ZYNQMP_VARIANT_EV,
> },
> {
> - .id = 0x40,
> - .name = "11eg",
> - },
> - { /* For testing purpose only */
> - .id = 0x50,
> - .ver = 0x2c,
> - .name = "15cg",
> + .id = 0x04720093,
> + .device = 5,
> + .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG |
> + ZYNQMP_VARIANT_EV,
> },
> {
> - .id = 0x50,
> - .name = "15eg",
> + .id = 0x04739093,
> + .device = 6,
> + .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG,
> },
> {
> - .id = 0x58,
> - .name = "19eg",
> + .id = 0x04730093,
> + .device = 7,
> + .variants = ZYNQMP_VARIANT_EG | ZYNQMP_VARIANT_CG |
> + ZYNQMP_VARIANT_EV,
> },
> {
> - .id = 0x59,
> - .name = "17eg",
> + .id = 0x04738093,
> + .device = 9,
> + .variants = ZYNQMP_VARIANT_EG,
> },
> {
> - .id = 0x61,
> - .name = "21dr",
> + .id = 0x04740093,
> + .device = 11,
> + .variants = ZYNQMP_VARIANT_EG,
> },
> {
> - .id = 0x63,
> - .name = "23dr",
> + .id = 0x04750093,
> + .device = 15,
> + .variants = ZYNQMP_VARIANT_EG,
> },
> {
> - .id = 0x65,
> - .name = "25dr",
> + .id = 0x04759093,
> + .device = 17,
> + .variants = ZYNQMP_VARIANT_EG,
> },
> {
> - .id = 0x64,
> - .name = "27dr",
> + .id = 0x04758093,
> + .device = 19,
> + .variants = ZYNQMP_VARIANT_EG,
> },
> {
> - .id = 0x60,
> - .name = "28dr",
> + .id = 0x047E1093,
> + .device = 21,
> + .variants = ZYNQMP_VARIANT_DR,
> },
> {
> - .id = 0x62,
> - .name = "29dr",
> + .id = 0x047E5093,
> + .device = 25,
> + .variants = ZYNQMP_VARIANT_DR,
> },
> {
> - .id = 0x66,
> - .name = "39dr",
> + .id = 0x047E4093,
> + .device = 27,
> + .variants = ZYNQMP_VARIANT_DR,
> },
> {
> - .id = 0x7b,
> - .name = "48dr",
> + .id = 0x047E0093,
> + .device = 28,
> + .variants = ZYNQMP_VARIANT_DR,
> },
> {
> - .id = 0x7e,
> - .name = "49dr",
> + .id = 0x047E2093,
> + .device = 29,
> + .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 +169,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;
> --
> 2.27.0
>
Please ignore this patch because it removes support for several DR devices.
Thanks,
Michal
--
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Xilinx Microblaze
Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs
U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs
More information about the U-Boot
mailing list