From 32f99757f4af48d1e51fdc8817bfed4337dead42 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Mon, 23 Apr 2018 22:49:31 +0200 Subject: 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 Cc: Chin Liang See Cc: Dinh Nguyen --- arch/arm/mach-socfpga/misc.c | 65 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) (limited to 'arch/arm/mach-socfpga/misc.c') 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 -- cgit v1.2.3