[v2 04/17] arm: socfpga: Add handoff data support for Intel N5X device

Ley Foon Tan lftan.linux at gmail.com
Fri May 14 11:12:52 CEST 2021


On Fri, Apr 30, 2021 at 3:39 PM Siew Chin Lim
<elly.siew.chin.lim at intel.com> wrote:
>
> N5X support both HPS handoff data and DDR handoff data.
> Existing HPS handoff functions are restructured to support both existing
> devices and N5X device.
>
> Signed-off-by: Siew Chin Lim <elly.siew.chin.lim at intel.com>
> Signed-off-by: Tien Fong Chee <tien.fong.chee at intel.com>
>
> ---
> v2:
> - Enabled auto detect the endianness from the magic word
> - Merged and simplifying the big and little endian flow
> ---
>  .../mach-socfpga/include/mach/handoff_soc64.h |  38 +++++-
>  arch/arm/mach-socfpga/system_manager_soc64.c  |  18 +--
>  arch/arm/mach-socfpga/wrap_handoff_soc64.c    | 126 +++++++++++++-----
>  3 files changed, 136 insertions(+), 46 deletions(-)

[...]

>
> @@ -10,12 +10,54 @@
>  #include <errno.h>
>  #include "log.h"
>
> -int socfpga_get_handoff_size(void *handoff_address, enum endianness endian)
> +static enum endianness check_endianness(u32 handoff)
> +{
> +       switch (handoff) {
> +       case SOC64_HANDOFF_MAGIC_BOOT:
> +       case SOC64_HANDOFF_MAGIC_MUX:
> +       case SOC64_HANDOFF_MAGIC_IOCTL:
> +       case SOC64_HANDOFF_MAGIC_FPGA:
> +       case SOC64_HANDOFF_MAGIC_DELAY:
> +       case SOC64_HANDOFF_MAGIC_CLOCK:
> +       case SOC64_HANDOFF_MAGIC_MISC:
> +               return BIG_ENDIAN;
> +#if IS_ENABLED(CONFIG_TARGET_SOCFPGA_N5X)
> +       case SOC64_HANDOFF_DDR_UMCTL2_MAGIC:
> +               debug("%s: umctl2 handoff data\n", __func__);
> +               return LITTLE_ENDIAN;
> +       case SOC64_HANDOFF_DDR_PHY_MAGIC:
> +               debug("%s: PHY handoff data\n", __func__);
> +               return LITTLE_ENDIAN;
> +       case SOC64_HANDOFF_DDR_PHY_INIT_ENGINE_MAGIC:
> +               debug("%s: PHY engine handoff data\n", __func__);
> +               return LITTLE_ENDIAN;
Can merge to one 'return' and print the 'handoff' if needed.

> +#endif
> +       default:
> +               debug("%s: Unknown endianness!!\n", __func__);
> +               return UNKNOWN_ENDIANNESS;
> +       }
> +}
> +
> +int socfpga_get_handoff_size(void *handoff_address)
>  {
>         u32 size;
> +       enum endianness endian_t;
> +
> +       /* Checking handoff data is little endian ? */
> +       endian_t = check_endianness(readl(handoff_address));
> +
> +       if (endian_t == UNKNOWN_ENDIANNESS) {
> +               /* Trying to check handoff data is big endian? */
> +               endian_t = check_endianness(swab32(readl(handoff_address)));
> +               if (endian_t == UNKNOWN_ENDIANNESS) {
> +                       debug("%s: Cannot find HANDOFF MAGIC ", __func__);
> +                       debug("at addr 0x%p\n", (u32 *)handoff_address);
> +                       return -EPERM;
> +               }
> +       }
>
>         size = readl(handoff_address + SOC64_HANDOFF_OFFSET_LENGTH);
> -       if (endian == BIG_ENDIAN)
> +       if (endian_t == BIG_ENDIAN)
>                 size = swab32(size);
>
>         size = (size - SOC64_HANDOFF_OFFSET_DATA) / sizeof(u32);
> @@ -26,41 +68,61 @@ int socfpga_get_handoff_size(void *handoff_address, enum endianness endian)
>         return size;
>  }
>
> -int socfpga_handoff_read(void *handoff_address, void *table, u32 table_len,
> -                        enum endianness big_endian)
> +int socfpga_handoff_read(void *handoff_address, void *table, u32 table_len)
>  {
> -       u32 temp, i;
> +       u32 temp;
>         u32 *table_x32 = table;
> +       u32 i = 0;
> +       enum endianness endian_t;
> +
> +       /* Checking handoff data is little endian ? */
> +       endian_t = check_endianness(readl(handoff_address));
This code is similar in socfpga_get_handoff_size(). Can have a
function to get the endianness.

>
> -       debug("%s: handoff addr = 0x%p ", __func__, (u32 *)handoff_address);
> -
> -       if (big_endian) {
> -               if (swab32(readl(SOC64_HANDOFF_BASE)) == SOC64_HANDOFF_MAGIC_BOOT) {
> -                       debug("Handoff table address = 0x%p ", table_x32);
> -                       debug("table length = 0x%x\n", table_len);
> -                       debug("%s: handoff data =\n{\n", __func__);
> -
> -                       for (i = 0; i < table_len; i++) {
> -                               temp = readl(handoff_address +
> -                                            SOC64_HANDOFF_OFFSET_DATA +
> -                                            (i * sizeof(u32)));
> -                               *table_x32 = swab32(temp);
> -
> -                               if (!(i % 2))
> -                                       debug(" No.%d Addr 0x%08x: ", i,
> -                                             *table_x32);
> -                               else
> -                                       debug(" 0x%08x\n", *table_x32);
> -
> -                               table_x32++;
> -                       }
> -                       debug("\n}\n");
> -               } else {
> -                       debug("%s: Cannot find SOC64_HANDOFF_MAGIC_BOOT ", __func__);
> -                       debug("at addr  0x%p\n", (u32 *)handoff_address);
> +       if (endian_t == UNKNOWN_ENDIANNESS) {
> +               /* Trying to check handoff data is big endian? */
> +               endian_t = check_endianness(swab32(readl(handoff_address)));
> +               if (endian_t == UNKNOWN_ENDIANNESS) {
> +                       debug("%s: Cannot find HANDOFF MAGIC ", __func__);
> +                       debug("at addr 0x%p\n", (u32 *)handoff_address);
>                         return -EPERM;
>                 }
>         }
>
> +       temp = readl(handoff_address + SOC64_HANDOFF_OFFSET_DATA +
> +                   (i * sizeof(u32)));
When this can't be done in the 'for' loop below?

> +
> +       if (endian_t == BIG_ENDIAN) {
> +               debug("%s: Handoff addr = 0x%p ", __func__, (u32 *)handoff_address);
> +               debug("Handoff table address = 0x%p ", table_x32);
> +               debug("table length = 0x%x\n", table_len);
> +               debug("%s: handoff data =\n{\n", __func__);
> +               *table_x32 = swab32(temp);
> +       } else if (endian_t == LITTLE_ENDIAN) {
> +               debug(" {\n");
> +               *table_x32 = temp;
> +       }
> +
> +       debug(" No.%d Addr 0x%08x: ", i, *table_x32);
> +
> +       for (i = 1; i < table_len; i++) {
> +               table_x32++;
> +
> +               temp = readl(handoff_address +
> +                            SOC64_HANDOFF_OFFSET_DATA +
> +                            (i * sizeof(u32)));
> +
> +               if (endian_t == BIG_ENDIAN)
> +                       *table_x32 = swab32(temp);
> +               else if (endian_t == LITTLE_ENDIAN)
> +                       *table_x32 = temp;
> +
> +               if (!(i % 2))
> +                       debug(" No.%d Addr 0x%08x: ", i,
> +                             *table_x32);
> +               else
> +                       debug(" 0x%08x\n", *table_x32);
> +       }
> +       debug("\n}\n");
> +
>         return 0;
>  }

Regards
Ley Foon


More information about the U-Boot mailing list