[U-Boot] [PATCH 05/12] ARM: socfpga: Repair A10 EMAC reset handling

Ley Foon Tan lftan.linux at gmail.com
Wed May 16 10:24:05 UTC 2018


On Sun, May 13, 2018 at 4:30 AM, Marek Vasut <marex at denx.de> wrote:
> The EMAC reset and PHY mode configuration was never working on the
> Arria10 SoC, fix this. This patch pulls out the common code into
> misc.c and passes the SoC-specific function call in as a function
> pointer.
>
> Signed-off-by: Marek Vasut <marex at denx.de>
> Cc: Chin Liang See <chin.liang.see at intel.com>
> Cc: Dinh Nguyen <dinguyen at kernel.org>
> ---
> NOTE: This should be converted to reset framework.
Yes, I have converted this to use reset framework for S10. It should
can be use for A10 and Gen5 as well.

> ---
>  arch/arm/mach-socfpga/include/mach/reset_manager.h |  2 +
>  arch/arm/mach-socfpga/misc.c                       | 65 +++++++++++++++++++++
>  arch/arm/mach-socfpga/misc_arria10.c               | 19 +++++-
>  arch/arm/mach-socfpga/misc_gen5.c                  | 67 ++--------------------
>  4 files changed, 87 insertions(+), 66 deletions(-)
>
> diff --git a/arch/arm/mach-socfpga/include/mach/reset_manager.h b/arch/arm/mach-socfpga/include/mach/reset_manager.h
> index d3ae80bc27..8ee801c635 100644
> --- a/arch/arm/mach-socfpga/include/mach/reset_manager.h
> +++ b/arch/arm/mach-socfpga/include/mach/reset_manager.h
> @@ -10,6 +10,8 @@ void reset_cpu(ulong addr);
>
>  void socfpga_per_reset(u32 reset, int set);
>  void socfpga_per_reset_all(void);
> +int socfpga_eth_reset_common(void (*resetfn)(const u8 of_reset_id,
> +                                            const u8 phymode));
>
>  #define RSTMGR_CTRL_SWWARMRSTREQ_LSB 1
>
> diff --git a/arch/arm/mach-socfpga/misc.c b/arch/arm/mach-socfpga/misc.c
> index 5c27f1984e..7bedcb36f4 100644
> --- a/arch/arm/mach-socfpga/misc.c
> +++ b/arch/arm/mach-socfpga/misc.c
> @@ -135,3 +135,68 @@ int arch_cpu_init(void)
>
>         return 0;
>  }
> +
> +#ifdef CONFIG_ETH_DESIGNWARE
> +static int dwmac_phymode_to_modereg(const char *phymode, u32 *modereg)
> +{
> +       if (!phymode)
> +               return -EINVAL;
> +
> +       if (!strcmp(phymode, "mii") || !strcmp(phymode, "gmii")) {
> +               *modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII;
> +               return 0;
> +       }
> +
> +       if (!strcmp(phymode, "rgmii")) {
> +               *modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII;
> +               return 0;
> +       }
> +
> +       if (!strcmp(phymode, "rmii")) {
> +               *modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII;
> +               return 0;
> +       }
> +
> +       return -EINVAL;
> +}
> +
> +int socfpga_eth_reset_common(void (*resetfn)(const u8 of_reset_id,
> +                                            const u8 phymode))
> +{
> +       const void *fdt = gd->fdt_blob;
> +       struct fdtdec_phandle_args args;
> +       const char *phy_mode;
> +       u32 phy_modereg;
> +       int nodes[2];   /* Max. two GMACs */
> +       int ret, count;
> +       int i, node;
> +
> +       count = fdtdec_find_aliases_for_id(fdt, "ethernet",
> +                                          COMPAT_ALTERA_SOCFPGA_DWMAC,
> +                                          nodes, ARRAY_SIZE(nodes));
> +       for (i = 0; i < count; i++) {
> +               node = nodes[i];
> +               if (node <= 0)
> +                       continue;
> +
> +               ret = fdtdec_parse_phandle_with_args(fdt, node, "resets",
> +                                                    "#reset-cells", 1, 0,
> +                                                    &args);
> +               if (ret || (args.args_count != 1)) {
> +                       debug("GMAC%i: Failed to parse DT 'resets'!\n", i);
> +                       continue;
> +               }
> +
> +               phy_mode = fdt_getprop(fdt, node, "phy-mode", NULL);
> +               ret = dwmac_phymode_to_modereg(phy_mode, &phy_modereg);
> +               if (ret) {
> +                       debug("GMAC%i: Failed to parse DT 'phy-mode'!\n", i);
> +                       continue;
> +               }
> +
> +               resetfn(args.args[0], phy_modereg);
> +       }
> +
> +       return 0;
> +}
> +#endif
> diff --git a/arch/arm/mach-socfpga/misc_arria10.c b/arch/arm/mach-socfpga/misc_arria10.c
> index f909568312..e1d80a5a76 100644
> --- a/arch/arm/mach-socfpga/misc_arria10.c
> +++ b/arch/arm/mach-socfpga/misc_arria10.c
> @@ -41,8 +41,7 @@ static struct socfpga_system_manager *sysmgr_regs =
>   * DesignWare Ethernet initialization
>   */
>  #ifdef CONFIG_ETH_DESIGNWARE
> -void dwmac_deassert_reset(const unsigned int of_reset_id,
> -                                const u32 phymode)
> +static void arria10_dwmac_reset(const u8 of_reset_id, const u8 phymode)
>  {
>         u32 reset;
>
> @@ -64,6 +63,20 @@ void dwmac_deassert_reset(const unsigned int of_reset_id,
>         /* Release the EMAC controller from reset */
>         socfpga_per_reset(reset, 0);
>  }
> +
> +static int socfpga_eth_reset(void)
> +{
> +       /* Put all GMACs into RESET state. */
> +       socfpga_per_reset(SOCFPGA_RESET(EMAC0), 1);
> +       socfpga_per_reset(SOCFPGA_RESET(EMAC1), 1);
> +       socfpga_per_reset(SOCFPGA_RESET(EMAC2), 1);
> +       return socfpga_eth_reset_common(arria10_dwmac_reset);
> +};
> +#else
> +static int socfpga_eth_reset(void)
> +{
> +       return 0;
> +};
>  #endif
>
>  #if defined(CONFIG_SPL_BUILD)
> @@ -251,6 +264,6 @@ int print_cpuinfo(void)
>  #ifdef CONFIG_ARCH_MISC_INIT
>  int arch_misc_init(void)
>  {
> -       return 0;
> +       return socfpga_eth_reset();
>  }
>  #endif
> diff --git a/arch/arm/mach-socfpga/misc_gen5.c b/arch/arm/mach-socfpga/misc_gen5.c
> index efec58d555..434373404e 100644
> --- a/arch/arm/mach-socfpga/misc_gen5.c
> +++ b/arch/arm/mach-socfpga/misc_gen5.c
> @@ -38,8 +38,7 @@ static struct scu_registers *scu_regs =
>   * DesignWare Ethernet initialization
>   */
>  #ifdef CONFIG_ETH_DESIGNWARE
> -void dwmac_deassert_reset(const unsigned int of_reset_id,
> -                                const u32 phymode)
> +static void gen5_dwmac_reset(const u8 of_reset_id, const u8 phymode)
>  {
>         u32 physhift, reset;
>
> @@ -63,71 +62,13 @@ void dwmac_deassert_reset(const unsigned int of_reset_id,
>         socfpga_per_reset(reset, 0);
>  }
>
> -static u32 dwmac_phymode_to_modereg(const char *phymode, u32 *modereg)
> -{
> -       if (!phymode)
> -               return -EINVAL;
> -
> -       if (!strcmp(phymode, "mii") || !strcmp(phymode, "gmii")) {
> -               *modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII;
> -               return 0;
> -       }
> -
> -       if (!strcmp(phymode, "rgmii")) {
> -               *modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII;
> -               return 0;
> -       }
> -
> -       if (!strcmp(phymode, "rmii")) {
> -               *modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII;
> -               return 0;
> -       }
> -
> -       return -EINVAL;
> -}
> -
>  static int socfpga_eth_reset(void)
>  {
> -       const void *fdt = gd->fdt_blob;
> -       struct fdtdec_phandle_args args;
> -       const char *phy_mode;
> -       u32 phy_modereg;
> -       int nodes[2];   /* Max. two GMACs */
> -       int ret, count;
> -       int i, node;
> -
> -       /* Put both GMACs into RESET state. */
> +       /* Put all GMACs into RESET state. */
>         socfpga_per_reset(SOCFPGA_RESET(EMAC0), 1);
>         socfpga_per_reset(SOCFPGA_RESET(EMAC1), 1);
> -
> -       count = fdtdec_find_aliases_for_id(fdt, "ethernet",
> -                                          COMPAT_ALTERA_SOCFPGA_DWMAC,
> -                                          nodes, ARRAY_SIZE(nodes));
> -       for (i = 0; i < count; i++) {
> -               node = nodes[i];
> -               if (node <= 0)
> -                       continue;
> -
> -               ret = fdtdec_parse_phandle_with_args(fdt, node, "resets",
> -                                                    "#reset-cells", 1, 0,
> -                                                    &args);
> -               if (ret || (args.args_count != 1)) {
> -                       debug("GMAC%i: Failed to parse DT 'resets'!\n", i);
> -                       continue;
> -               }
> -
> -               phy_mode = fdt_getprop(fdt, node, "phy-mode", NULL);
> -               ret = dwmac_phymode_to_modereg(phy_mode, &phy_modereg);
> -               if (ret) {
> -                       debug("GMAC%i: Failed to parse DT 'phy-mode'!\n", i);
> -                       continue;
> -               }
> -
> -               dwmac_deassert_reset(args.args[0], phy_modereg);
> -       }
> -
> -       return 0;
> -}
> +       return socfpga_eth_reset_common(gen5_dwmac_reset);
> +};
>  #else
>  static int socfpga_eth_reset(void)
>  {
> --
> 2.16.2
>
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> https://lists.denx.de/listinfo/u-boot


More information about the U-Boot mailing list