[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