summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2019-02-18 22:12:59 -0500
committerTom Rini <trini@konsulko.com>2019-02-18 22:12:59 -0500
commitb78a9e2212d4d15fd16af41ae33d05a5c33954de (patch)
tree994b373c7178adb852da72c2f5ef91d521ffda4b
parentf14de0014c56093feecf42ca38b8ae5b3878f176 (diff)
parent5097ba6177bad8c7e09b50149cacd6fd5020f0c8 (diff)
Merge branch 'master' of git://git.denx.de/u-boot-socfpga
- Misc Gen5 fixes - stratix10 bugfix - dwmmc bugfix
-rw-r--r--arch/arm/mach-socfpga/include/mach/reset_manager.h2
-rw-r--r--arch/arm/mach-socfpga/misc.c65
-rw-r--r--arch/arm/mach-socfpga/misc_gen5.c44
-rw-r--r--drivers/fpga/stratix10.c17
-rw-r--r--drivers/mmc/dw_mmc.c19
-rw-r--r--drivers/net/Kconfig3
-rw-r--r--drivers/net/dwmac_socfpga.c87
-rw-r--r--include/dwmmc.h7
8 files changed, 69 insertions, 175 deletions
diff --git a/arch/arm/mach-socfpga/include/mach/reset_manager.h b/arch/arm/mach-socfpga/include/mach/reset_manager.h
index d9e0b33c60..42beaecdd6 100644
--- a/arch/arm/mach-socfpga/include/mach/reset_manager.h
+++ b/arch/arm/mach-socfpga/include/mach/reset_manager.h
@@ -10,8 +10,6 @@ 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 78fbe28724..e1adea143c 100644
--- a/arch/arm/mach-socfpga/misc.c
+++ b/arch/arm/mach-socfpga/misc.c
@@ -120,71 +120,6 @@ 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
-
#ifndef CONFIG_SPL_BUILD
static int do_bridge(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
diff --git a/arch/arm/mach-socfpga/misc_gen5.c b/arch/arm/mach-socfpga/misc_gen5.c
index 04f237d100..6e11ba6cb2 100644
--- a/arch/arm/mach-socfpga/misc_gen5.c
+++ b/arch/arm/mach-socfpga/misc_gen5.c
@@ -54,48 +54,6 @@ static Altera_desc altera_fpga[] = {
},
};
-/*
- * DesignWare Ethernet initialization
- */
-#ifdef CONFIG_ETH_DESIGNWARE
-static void gen5_dwmac_reset(const u8 of_reset_id, const u8 phymode)
-{
- u32 physhift, reset;
-
- if (of_reset_id == EMAC0_RESET) {
- physhift = SYSMGR_EMACGRP_CTRL_PHYSEL0_LSB;
- reset = SOCFPGA_RESET(EMAC0);
- } else if (of_reset_id == EMAC1_RESET) {
- physhift = SYSMGR_EMACGRP_CTRL_PHYSEL1_LSB;
- reset = SOCFPGA_RESET(EMAC1);
- } else {
- printf("GMAC: Invalid reset ID (%i)!\n", of_reset_id);
- return;
- }
-
- /* configure to PHY interface select choosed */
- clrsetbits_le32(&sysmgr_regs->emacgrp_ctrl,
- SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << physhift,
- phymode << physhift);
-
- /* 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);
- return socfpga_eth_reset_common(gen5_dwmac_reset);
-};
-#else
-static int socfpga_eth_reset(void)
-{
- return 0;
-};
-#endif
-
static const struct {
const u16 pn;
const char *name;
@@ -178,7 +136,7 @@ int arch_misc_init(void)
env_set("bootmode", bsel_str[bsel].mode);
if (fpga_id >= 0)
env_set("fpgatype", socfpga_fpga_model[fpga_id].var);
- return socfpga_eth_reset();
+ return 0;
}
#endif
diff --git a/drivers/fpga/stratix10.c b/drivers/fpga/stratix10.c
index aae052130e..d8e32508d4 100644
--- a/drivers/fpga/stratix10.c
+++ b/drivers/fpga/stratix10.c
@@ -172,7 +172,7 @@ static int send_reconfig_data(const void *rbf_data, size_t rbf_size,
u32 resp_windex = 0;
u32 resp_count = 0;
u32 xfer_count = 0;
- u8 resp_err = 0;
+ int resp_err = 0;
u8 cmd_id = 1;
u32 args[3];
int ret;
@@ -195,11 +195,9 @@ static int send_reconfig_data(const void *rbf_data, size_t rbf_size,
rbf_size = 0;
}
- ret = mbox_send_cmd_only(cmd_id, MBOX_RECONFIG_DATA,
+ resp_err = mbox_send_cmd_only(cmd_id, MBOX_RECONFIG_DATA,
MBOX_CMD_INDIRECT, 3, args);
- if (ret) {
- resp_err = 1;
- } else {
+ if (!resp_err) {
xfer_count++;
cmd_id = add_transfer(xfer_pending,
MBOX_RESP_BUFFER_SIZE,
@@ -222,11 +220,8 @@ static int send_reconfig_data(const void *rbf_data, size_t rbf_size,
/* Check for response's status */
if (!resp_err) {
- ret = MBOX_RESP_ERR_GET(resp_hdr);
- debug("Response error code: %08x\n", ret);
- /* Error in response */
- if (ret)
- resp_err = 1;
+ resp_err = MBOX_RESP_ERR_GET(resp_hdr);
+ debug("Response error code: %08x\n", resp_err);
}
ret = get_and_clr_transfer(xfer_pending,
@@ -239,7 +234,7 @@ static int send_reconfig_data(const void *rbf_data, size_t rbf_size,
}
if (resp_err && !xfer_count)
- return ret;
+ return resp_err;
}
}
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index 7544b84ab6..93a836eac3 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -12,6 +12,7 @@
#include <memalign.h>
#include <mmc.h>
#include <dwmmc.h>
+#include <wait_bit.h>
#define PAGE_SIZE 4096
@@ -55,6 +56,9 @@ static void dwmci_prepare_data(struct dwmci_host *host,
dwmci_wait_reset(host, DWMCI_CTRL_FIFO_RESET);
+ /* Clear IDMAC interrupt */
+ dwmci_writel(host, DWMCI_IDSTS, 0xFFFFFFFF);
+
data_start = (ulong)cur_idmac;
dwmci_writel(host, DWMCI_DBADDR, (ulong)cur_idmac);
@@ -340,6 +344,18 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
/* only dma mode need it */
if (!host->fifo_mode) {
+ if (data->flags == MMC_DATA_READ)
+ mask = DWMCI_IDINTEN_RI;
+ else
+ mask = DWMCI_IDINTEN_TI;
+ ret = wait_for_bit_le32(host->ioaddr + DWMCI_IDSTS,
+ mask, true, 1000, false);
+ if (ret)
+ debug("%s: DWMCI_IDINTEN mask 0x%x timeout.\n",
+ __func__, mask);
+ /* clear interrupts */
+ dwmci_writel(host, DWMCI_IDSTS, DWMCI_IDINTEN_MASK);
+
ctrl = dwmci_readl(host, DWMCI_CTRL);
ctrl &= ~(DWMCI_DMA_EN);
dwmci_writel(host, DWMCI_CTRL, ctrl);
@@ -494,6 +510,9 @@ static int dwmci_init(struct mmc *mmc)
dwmci_writel(host, DWMCI_CLKENA, 0);
dwmci_writel(host, DWMCI_CLKSRC, 0);
+ if (!host->fifo_mode)
+ dwmci_writel(host, DWMCI_IDINTEN, DWMCI_IDINTEN_MASK);
+
return 0;
}
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 6a570285aa..77d0b3a01f 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -156,12 +156,15 @@ config ETH_SANDBOX_RAW
config ETH_DESIGNWARE
bool "Synopsys Designware Ethernet MAC"
select PHYLIB
+ imply ETH_DESIGNWARE_SOCFPGA if ARCH_SOCFPGA
help
This MAC is present in SoCs from various vendors. It supports
100Mbit and 1 Gbit operation. You must enable CONFIG_PHYLIB to
provide the PHY (physical media interface).
config ETH_DESIGNWARE_SOCFPGA
+ select REGMAP
+ select SYSCON
bool "Altera SoCFPGA extras for Synopsys Designware Ethernet MAC"
depends on DM_ETH && ETH_DESIGNWARE
help
diff --git a/drivers/net/dwmac_socfpga.c b/drivers/net/dwmac_socfpga.c
index 08fc9677c4..b7bf5dbe69 100644
--- a/drivers/net/dwmac_socfpga.c
+++ b/drivers/net/dwmac_socfpga.c
@@ -17,16 +17,10 @@
#include <asm/arch/system_manager.h>
-enum dwmac_type {
- DWMAC_SOCFPGA_GEN5 = 0,
- DWMAC_SOCFPGA_ARRIA10,
- DWMAC_SOCFPGA_STRATIX10,
-};
-
struct dwmac_socfpga_platdata {
struct dw_eth_pdata dw_eth_pdata;
- enum dwmac_type type;
void *phy_intf;
+ u32 reg_shift;
};
static int dwmac_socfpga_ofdata_to_platdata(struct udevice *dev)
@@ -63,21 +57,7 @@ static int dwmac_socfpga_ofdata_to_platdata(struct udevice *dev)
}
pdata->phy_intf = range + args.args[0];
-
- /*
- * Sadly, the Altera DT bindings don't have SoC-specific compatibles,
- * so we have to guesstimate which SoC we are running on from the
- * DWMAC version. Luckily, Altera at least updated the DWMAC with
- * each SoC.
- */
- if (ofnode_device_is_compatible(dev->node, "snps,dwmac-3.70a"))
- pdata->type = DWMAC_SOCFPGA_GEN5;
-
- if (ofnode_device_is_compatible(dev->node, "snps,dwmac-3.72a"))
- pdata->type = DWMAC_SOCFPGA_ARRIA10;
-
- if (ofnode_device_is_compatible(dev->node, "snps,dwmac-3.74a"))
- pdata->type = DWMAC_SOCFPGA_STRATIX10;
+ pdata->reg_shift = args.args[1];
return designware_eth_ofdata_to_platdata(dev);
}
@@ -88,40 +68,39 @@ static int dwmac_socfpga_probe(struct udevice *dev)
struct eth_pdata *edata = &pdata->dw_eth_pdata.eth_pdata;
struct reset_ctl_bulk reset_bulk;
int ret;
- u8 modereg;
-
- if (pdata->type == DWMAC_SOCFPGA_ARRIA10) {
- switch (edata->phy_interface) {
- case PHY_INTERFACE_MODE_MII:
- case PHY_INTERFACE_MODE_GMII:
- modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII;
- break;
- case PHY_INTERFACE_MODE_RMII:
- modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII;
- break;
- case PHY_INTERFACE_MODE_RGMII:
- modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII;
- break;
- default:
- dev_err(dev, "Unsupported PHY mode\n");
- return -EINVAL;
- }
-
- ret = reset_get_bulk(dev, &reset_bulk);
- if (ret) {
- dev_err(dev, "Failed to get reset: %d\n", ret);
- return ret;
- }
-
- reset_assert_bulk(&reset_bulk);
-
- clrsetbits_le32(pdata->phy_intf,
- SYSMGR_EMACGRP_CTRL_PHYSEL_MASK,
- modereg);
-
- reset_release_bulk(&reset_bulk);
+ u32 modereg;
+ u32 modemask;
+
+ switch (edata->phy_interface) {
+ case PHY_INTERFACE_MODE_MII:
+ case PHY_INTERFACE_MODE_GMII:
+ modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII;
+ break;
+ case PHY_INTERFACE_MODE_RMII:
+ modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII;
+ break;
+ case PHY_INTERFACE_MODE_RGMII:
+ modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII;
+ break;
+ default:
+ dev_err(dev, "Unsupported PHY mode\n");
+ return -EINVAL;
}
+ ret = reset_get_bulk(dev, &reset_bulk);
+ if (ret) {
+ dev_err(dev, "Failed to get reset: %d\n", ret);
+ return ret;
+ }
+
+ reset_assert_bulk(&reset_bulk);
+
+ modemask = SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << pdata->reg_shift;
+ clrsetbits_le32(pdata->phy_intf, modemask,
+ modereg << pdata->reg_shift);
+
+ reset_release_bulk(&reset_bulk);
+
return designware_eth_probe(dev);
}
diff --git a/include/dwmmc.h b/include/dwmmc.h
index 4ceda5e43c..f06720dc0d 100644
--- a/include/dwmmc.h
+++ b/include/dwmmc.h
@@ -130,6 +130,13 @@
/* UHS register */
#define DWMCI_DDR_MODE (1 << 16)
+/* Internal IDMAC interrupt defines */
+#define DWMCI_IDINTEN_RI BIT(1)
+#define DWMCI_IDINTEN_TI BIT(0)
+
+#define DWMCI_IDINTEN_MASK (DWMCI_IDINTEN_TI | \
+ DWMCI_IDINTEN_RI)
+
/* quirks */
#define DWMCI_QUIRK_DISABLE_SMU (1 << 0)