Merge branch 'master' of git://git.denx.de/u-boot-socfpga
- Misc Gen5 fixes - stratix10 bugfix - dwmmc bugfix
This commit is contained in:
commit
b78a9e2212
@ -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
|
||||
|
||||
|
@ -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[])
|
||||
{
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
u32 modereg;
|
||||
u32 modemask;
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user