ARM: socfpga: Repair A10 EMAC reset handling

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@denx.de>
Cc: Chin Liang See <chin.liang.see@intel.com>
Cc: Dinh Nguyen <dinguyen@kernel.org>
diff --git a/arch/arm/mach-socfpga/include/mach/reset_manager.h b/arch/arm/mach-socfpga/include/mach/reset_manager.h
index d3ae80b..8ee801c 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 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 5c27f19..7bedcb3 100644
--- a/arch/arm/mach-socfpga/misc.c
+++ b/arch/arm/mach-socfpga/misc.c
@@ -135,3 +135,68 @@
 
 	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 f909568..e1d80a5 100644
--- a/arch/arm/mach-socfpga/misc_arria10.c
+++ b/arch/arm/mach-socfpga/misc_arria10.c
@@ -41,8 +41,7 @@
  * 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 @@
 	/* 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 @@
 #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 efec58d..4343734 100644
--- a/arch/arm/mach-socfpga/misc_gen5.c
+++ b/arch/arm/mach-socfpga/misc_gen5.c
@@ -38,8 +38,7 @@
  * 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 @@
 	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)
 {