summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorTrent Piepho <tpiepho@kymetacorp.com>2015-11-10 23:37:07 +0000
committerSascha Hauer <s.hauer@pengutronix.de>2015-11-11 09:06:26 +0100
commit3c8f016d9b78f12602b5485152abfdbd2674b790 (patch)
treef0f4961c1e153f2e9e62f541473bf8cdfc2d5761 /arch
parent48aecb409dcbff1d13008de72a2c42af8069aec6 (diff)
downloadbarebox-3c8f016d9b78f12602b5485152abfdbd2674b790.tar.gz
barebox-3c8f016d9b78f12602b5485152abfdbd2674b790.tar.xz
socfpga: Initialize emac physels to RGMII correctly
A comment in the socfpga init said that it was "Clearing emac0 PHY interface select to 0", but this was doubly incorrect. It was setting physel for emac1, not emac0, and it was setting physel to 1 (RGMII) not 0 (GMII). All supported socfpga boards use RGMII, and use emac1, so fix the comment to reflect the code. But then extend the code to set the physel for both emac0 and emac1, so it can work on boards that use either or both emacs (which are called gmac0/1 in the dts). The Cyclone V datasheet, page 17-60 "EMAC HPS Interface Initialization", says to set physel while the EMAC is in reset. So place the EMAC in reset while changing physel. The emacs are not in reset as code earlier in the boot has already taken most of the modules out of reset. So put them back in reset while the physel is changed. The Linux kernel does it this way too. If barebox has no network support, there is not much point in configuring the emac physel lines. This would be the case for the xloader pre-bootloader config, which configures physel, doesn't use the network, loads the main barebox, which then reconfigures physel again. Make this code depend on CONFIG_NET so it's just done in the main barebox. The Linux kernel does not need barebox to do this initialization to use networking. Signed-off-by: Trent Piepho <tpiepho@kymetacorp.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-socfpga/generic.c34
1 files changed, 31 insertions, 3 deletions
diff --git a/arch/arm/mach-socfpga/generic.c b/arch/arm/mach-socfpga/generic.c
index 234dc52145..2d4afd0a7a 100644
--- a/arch/arm/mach-socfpga/generic.c
+++ b/arch/arm/mach-socfpga/generic.c
@@ -10,6 +10,7 @@
#include <linux/stat.h>
#include <asm/memory.h>
#include <mach/system-manager.h>
+#include <mach/reset-manager.h>
#include <mach/socfpga-regs.h>
#include <mach/nic301.h>
@@ -55,16 +56,43 @@ static int socfpga_detect_sdram(void)
return 0;
}
-static int socfpga_init(void)
+/* Some initialization for the EMAC */
+static void socfpga_init_emac(void)
{
- uint32_t val;
+ uint32_t rst, val;
+
+ /* No need for this without network support, e.g. xloader build */
+ if (!IS_ENABLED(CONFIG_NET))
+ return;
+
+ /* According to Cyclone V datasheet, 17-60 "EMAC HPS Interface
+ * Initialization", changing PHYSEL should be done with EMAC in reset
+ * via permodrst. */
- /* Clearing emac0 PHY interface select to 0 */
+ /* Everything, except L4WD0/1, is out of reset via socfpga_lowlevel_init() */
+ rst = readl(CYCLONE5_RSTMGR_ADDRESS + RESET_MGR_PER_MOD_RESET_OFS);
+ rst |= RSTMGR_PERMODRST_EMAC0 | RSTMGR_PERMODRST_EMAC1;
+ writel(rst, CYCLONE5_RSTMGR_ADDRESS + RESET_MGR_PER_MOD_RESET_OFS);
+
+ /* Set emac0/1 PHY interface select to RGMII. We could read phy-mode
+ * from the device tree, if it was desired to support interfaces other
+ * than RGMII. */
val = readl(CONFIG_SYSMGR_EMAC_CTRL);
+ val &= ~(SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << SYSMGR_EMACGRP_CTRL_PHYSEL0_LSB);
val &= ~(SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << SYSMGR_EMACGRP_CTRL_PHYSEL1_LSB);
+ val |= SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII << SYSMGR_EMACGRP_CTRL_PHYSEL0_LSB;
val |= SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII << SYSMGR_EMACGRP_CTRL_PHYSEL1_LSB;
writel(val, CONFIG_SYSMGR_EMAC_CTRL);
+ /* Take emac0 and emac1 out of reset */
+ rst &= ~(RSTMGR_PERMODRST_EMAC0 | RSTMGR_PERMODRST_EMAC1);
+ writel(rst, CYCLONE5_RSTMGR_ADDRESS + RESET_MGR_PER_MOD_RESET_OFS);
+}
+
+static int socfpga_init(void)
+{
+ socfpga_init_emac();
+
writel(SYSMGR_SDMMC_CTRL_DRVSEL(3) | SYSMGR_SDMMC_CTRL_SMPLSEL(0),
SYSMGR_SDMMCGRP_CTRL_REG);