[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