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(u32 reset, int set);
|
||||||
void socfpga_per_reset_all(void);
|
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
|
#define RSTMGR_CTRL_SWWARMRSTREQ_LSB 1
|
||||||
|
|
||||||
|
@ -120,71 +120,6 @@ int arch_cpu_init(void)
|
|||||||
return 0;
|
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
|
#ifndef CONFIG_SPL_BUILD
|
||||||
static int do_bridge(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
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 {
|
static const struct {
|
||||||
const u16 pn;
|
const u16 pn;
|
||||||
const char *name;
|
const char *name;
|
||||||
@ -178,7 +136,7 @@ int arch_misc_init(void)
|
|||||||
env_set("bootmode", bsel_str[bsel].mode);
|
env_set("bootmode", bsel_str[bsel].mode);
|
||||||
if (fpga_id >= 0)
|
if (fpga_id >= 0)
|
||||||
env_set("fpgatype", socfpga_fpga_model[fpga_id].var);
|
env_set("fpgatype", socfpga_fpga_model[fpga_id].var);
|
||||||
return socfpga_eth_reset();
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -172,7 +172,7 @@ static int send_reconfig_data(const void *rbf_data, size_t rbf_size,
|
|||||||
u32 resp_windex = 0;
|
u32 resp_windex = 0;
|
||||||
u32 resp_count = 0;
|
u32 resp_count = 0;
|
||||||
u32 xfer_count = 0;
|
u32 xfer_count = 0;
|
||||||
u8 resp_err = 0;
|
int resp_err = 0;
|
||||||
u8 cmd_id = 1;
|
u8 cmd_id = 1;
|
||||||
u32 args[3];
|
u32 args[3];
|
||||||
int ret;
|
int ret;
|
||||||
@ -195,11 +195,9 @@ static int send_reconfig_data(const void *rbf_data, size_t rbf_size,
|
|||||||
rbf_size = 0;
|
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);
|
MBOX_CMD_INDIRECT, 3, args);
|
||||||
if (ret) {
|
if (!resp_err) {
|
||||||
resp_err = 1;
|
|
||||||
} else {
|
|
||||||
xfer_count++;
|
xfer_count++;
|
||||||
cmd_id = add_transfer(xfer_pending,
|
cmd_id = add_transfer(xfer_pending,
|
||||||
MBOX_RESP_BUFFER_SIZE,
|
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 */
|
/* Check for response's status */
|
||||||
if (!resp_err) {
|
if (!resp_err) {
|
||||||
ret = MBOX_RESP_ERR_GET(resp_hdr);
|
resp_err = MBOX_RESP_ERR_GET(resp_hdr);
|
||||||
debug("Response error code: %08x\n", ret);
|
debug("Response error code: %08x\n", resp_err);
|
||||||
/* Error in response */
|
|
||||||
if (ret)
|
|
||||||
resp_err = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = get_and_clr_transfer(xfer_pending,
|
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)
|
if (resp_err && !xfer_count)
|
||||||
return ret;
|
return resp_err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include <memalign.h>
|
#include <memalign.h>
|
||||||
#include <mmc.h>
|
#include <mmc.h>
|
||||||
#include <dwmmc.h>
|
#include <dwmmc.h>
|
||||||
|
#include <wait_bit.h>
|
||||||
|
|
||||||
#define PAGE_SIZE 4096
|
#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);
|
dwmci_wait_reset(host, DWMCI_CTRL_FIFO_RESET);
|
||||||
|
|
||||||
|
/* Clear IDMAC interrupt */
|
||||||
|
dwmci_writel(host, DWMCI_IDSTS, 0xFFFFFFFF);
|
||||||
|
|
||||||
data_start = (ulong)cur_idmac;
|
data_start = (ulong)cur_idmac;
|
||||||
dwmci_writel(host, DWMCI_DBADDR, (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 */
|
/* only dma mode need it */
|
||||||
if (!host->fifo_mode) {
|
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_readl(host, DWMCI_CTRL);
|
||||||
ctrl &= ~(DWMCI_DMA_EN);
|
ctrl &= ~(DWMCI_DMA_EN);
|
||||||
dwmci_writel(host, DWMCI_CTRL, ctrl);
|
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_CLKENA, 0);
|
||||||
dwmci_writel(host, DWMCI_CLKSRC, 0);
|
dwmci_writel(host, DWMCI_CLKSRC, 0);
|
||||||
|
|
||||||
|
if (!host->fifo_mode)
|
||||||
|
dwmci_writel(host, DWMCI_IDINTEN, DWMCI_IDINTEN_MASK);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,12 +156,15 @@ config ETH_SANDBOX_RAW
|
|||||||
config ETH_DESIGNWARE
|
config ETH_DESIGNWARE
|
||||||
bool "Synopsys Designware Ethernet MAC"
|
bool "Synopsys Designware Ethernet MAC"
|
||||||
select PHYLIB
|
select PHYLIB
|
||||||
|
imply ETH_DESIGNWARE_SOCFPGA if ARCH_SOCFPGA
|
||||||
help
|
help
|
||||||
This MAC is present in SoCs from various vendors. It supports
|
This MAC is present in SoCs from various vendors. It supports
|
||||||
100Mbit and 1 Gbit operation. You must enable CONFIG_PHYLIB to
|
100Mbit and 1 Gbit operation. You must enable CONFIG_PHYLIB to
|
||||||
provide the PHY (physical media interface).
|
provide the PHY (physical media interface).
|
||||||
|
|
||||||
config ETH_DESIGNWARE_SOCFPGA
|
config ETH_DESIGNWARE_SOCFPGA
|
||||||
|
select REGMAP
|
||||||
|
select SYSCON
|
||||||
bool "Altera SoCFPGA extras for Synopsys Designware Ethernet MAC"
|
bool "Altera SoCFPGA extras for Synopsys Designware Ethernet MAC"
|
||||||
depends on DM_ETH && ETH_DESIGNWARE
|
depends on DM_ETH && ETH_DESIGNWARE
|
||||||
help
|
help
|
||||||
|
@ -17,16 +17,10 @@
|
|||||||
|
|
||||||
#include <asm/arch/system_manager.h>
|
#include <asm/arch/system_manager.h>
|
||||||
|
|
||||||
enum dwmac_type {
|
|
||||||
DWMAC_SOCFPGA_GEN5 = 0,
|
|
||||||
DWMAC_SOCFPGA_ARRIA10,
|
|
||||||
DWMAC_SOCFPGA_STRATIX10,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct dwmac_socfpga_platdata {
|
struct dwmac_socfpga_platdata {
|
||||||
struct dw_eth_pdata dw_eth_pdata;
|
struct dw_eth_pdata dw_eth_pdata;
|
||||||
enum dwmac_type type;
|
|
||||||
void *phy_intf;
|
void *phy_intf;
|
||||||
|
u32 reg_shift;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int dwmac_socfpga_ofdata_to_platdata(struct udevice *dev)
|
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];
|
pdata->phy_intf = range + args.args[0];
|
||||||
|
pdata->reg_shift = args.args[1];
|
||||||
/*
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
return designware_eth_ofdata_to_platdata(dev);
|
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 eth_pdata *edata = &pdata->dw_eth_pdata.eth_pdata;
|
||||||
struct reset_ctl_bulk reset_bulk;
|
struct reset_ctl_bulk reset_bulk;
|
||||||
int ret;
|
int ret;
|
||||||
u8 modereg;
|
u32 modereg;
|
||||||
|
u32 modemask;
|
||||||
|
|
||||||
if (pdata->type == DWMAC_SOCFPGA_ARRIA10) {
|
switch (edata->phy_interface) {
|
||||||
switch (edata->phy_interface) {
|
case PHY_INTERFACE_MODE_MII:
|
||||||
case PHY_INTERFACE_MODE_MII:
|
case PHY_INTERFACE_MODE_GMII:
|
||||||
case PHY_INTERFACE_MODE_GMII:
|
modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII;
|
||||||
modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII;
|
break;
|
||||||
break;
|
case PHY_INTERFACE_MODE_RMII:
|
||||||
case PHY_INTERFACE_MODE_RMII:
|
modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII;
|
||||||
modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII;
|
break;
|
||||||
break;
|
case PHY_INTERFACE_MODE_RGMII:
|
||||||
case PHY_INTERFACE_MODE_RGMII:
|
modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII;
|
||||||
modereg = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII;
|
break;
|
||||||
break;
|
default:
|
||||||
default:
|
dev_err(dev, "Unsupported PHY mode\n");
|
||||||
dev_err(dev, "Unsupported PHY mode\n");
|
return -EINVAL;
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
return designware_eth_probe(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,6 +130,13 @@
|
|||||||
/* UHS register */
|
/* UHS register */
|
||||||
#define DWMCI_DDR_MODE (1 << 16)
|
#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 */
|
/* quirks */
|
||||||
#define DWMCI_QUIRK_DISABLE_SMU (1 << 0)
|
#define DWMCI_QUIRK_DISABLE_SMU (1 << 0)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user