* supports a single RGMII PHY. This configuration also has SW control over
* all clock and reset signals to the HW block.
*/
-
#include <common.h>
#include <clk.h>
#include <dm.h>
#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_MASK 3
#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_NOT_ENABLED 0
#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB 2
+#define EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV 1
#define EQOS_MAC_RXQ_CTRL2_PSRQ0_SHIFT 0
#define EQOS_MAC_RXQ_CTRL2_PSRQ0_MASK 0xff
#define EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT 16
#define EQOS_MAC_MDIO_ADDRESS_CR_SHIFT 8
#define EQOS_MAC_MDIO_ADDRESS_CR_20_35 2
+#define EQOS_MAC_MDIO_ADDRESS_CR_250_300 5
#define EQOS_MAC_MDIO_ADDRESS_SKAP BIT(4)
#define EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT 2
#define EQOS_MAC_MDIO_ADDRESS_GOC_READ 3
struct eqos_config {
bool reg_access_always_ok;
+ int mdio_wait;
+ int swr_wait;
+ int config_mac;
+ int config_mac_mdio;
+ phy_interface_t (*interface)(struct udevice *dev);
+ struct eqos_ops *ops;
+};
+
+struct eqos_ops {
+ void (*eqos_inval_desc)(void *desc);
+ void (*eqos_flush_desc)(void *desc);
+ void (*eqos_inval_buffer)(void *buf, size_t size);
+ void (*eqos_flush_buffer)(void *buf, size_t size);
+ int (*eqos_probe_resources)(struct udevice *dev);
+ int (*eqos_remove_resources)(struct udevice *dev);
+ int (*eqos_stop_resets)(struct udevice *dev);
+ int (*eqos_start_resets)(struct udevice *dev);
+ void (*eqos_stop_clks)(struct udevice *dev);
+ int (*eqos_start_clks)(struct udevice *dev);
+ int (*eqos_calibrate_pads)(struct udevice *dev);
+ int (*eqos_disable_calibration)(struct udevice *dev);
+ int (*eqos_set_tx_clk_speed)(struct udevice *dev);
+ ulong (*eqos_get_tick_clk_rate)(struct udevice *dev);
};
struct eqos_priv {
struct clk clk_rx;
struct clk clk_ptp_ref;
struct clk clk_tx;
+ struct clk clk_ck;
struct clk clk_slave_bus;
struct mii_dev *mii;
struct phy_device *phy;
#endif
}
-static void eqos_inval_desc(void *desc)
+static void eqos_inval_desc_tegra186(void *desc)
{
#ifndef CONFIG_SYS_NONCACHED_MEMORY
unsigned long start = (unsigned long)desc & ~(ARCH_DMA_MINALIGN - 1);
#endif
}
-static void eqos_flush_desc(void *desc)
+static void eqos_inval_desc_stm32(void *desc)
+{
+#ifndef CONFIG_SYS_NONCACHED_MEMORY
+ unsigned long start = rounddown((unsigned long)desc, ARCH_DMA_MINALIGN);
+ unsigned long end = roundup((unsigned long)desc + EQOS_DESCRIPTOR_SIZE,
+ ARCH_DMA_MINALIGN);
+
+ invalidate_dcache_range(start, end);
+#endif
+}
+
+static void eqos_flush_desc_tegra186(void *desc)
{
#ifndef CONFIG_SYS_NONCACHED_MEMORY
flush_cache((unsigned long)desc, EQOS_DESCRIPTOR_SIZE);
#endif
}
-static void eqos_inval_buffer(void *buf, size_t size)
+static void eqos_flush_desc_stm32(void *desc)
+{
+#ifndef CONFIG_SYS_NONCACHED_MEMORY
+ unsigned long start = rounddown((unsigned long)desc, ARCH_DMA_MINALIGN);
+ unsigned long end = roundup((unsigned long)desc + EQOS_DESCRIPTOR_SIZE,
+ ARCH_DMA_MINALIGN);
+
+ flush_dcache_range(start, end);
+#endif
+}
+
+static void eqos_inval_buffer_tegra186(void *buf, size_t size)
{
unsigned long start = (unsigned long)buf & ~(ARCH_DMA_MINALIGN - 1);
unsigned long end = ALIGN(start + size, ARCH_DMA_MINALIGN);
invalidate_dcache_range(start, end);
}
-static void eqos_flush_buffer(void *buf, size_t size)
+static void eqos_inval_buffer_stm32(void *buf, size_t size)
+{
+ unsigned long start = rounddown((unsigned long)buf, ARCH_DMA_MINALIGN);
+ unsigned long end = roundup((unsigned long)buf + size,
+ ARCH_DMA_MINALIGN);
+
+ invalidate_dcache_range(start, end);
+}
+
+static void eqos_flush_buffer_tegra186(void *buf, size_t size)
{
flush_cache((unsigned long)buf, size);
}
+static void eqos_flush_buffer_stm32(void *buf, size_t size)
+{
+ unsigned long start = rounddown((unsigned long)buf, ARCH_DMA_MINALIGN);
+ unsigned long end = roundup((unsigned long)buf + size,
+ ARCH_DMA_MINALIGN);
+
+ flush_dcache_range(start, end);
+}
+
static int eqos_mdio_wait_idle(struct eqos_priv *eqos)
{
return wait_for_bit_le32(&eqos->mac_regs->mdio_address,
EQOS_MAC_MDIO_ADDRESS_C45E;
val |= (mdio_addr << EQOS_MAC_MDIO_ADDRESS_PA_SHIFT) |
(mdio_reg << EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT) |
- (EQOS_MAC_MDIO_ADDRESS_CR_20_35 <<
+ (eqos->config->config_mac_mdio <<
EQOS_MAC_MDIO_ADDRESS_CR_SHIFT) |
(EQOS_MAC_MDIO_ADDRESS_GOC_READ <<
EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT) |
EQOS_MAC_MDIO_ADDRESS_GB;
writel(val, &eqos->mac_regs->mdio_address);
- udelay(10);
+ udelay(eqos->config->mdio_wait);
ret = eqos_mdio_wait_idle(eqos);
if (ret) {
EQOS_MAC_MDIO_ADDRESS_C45E;
val |= (mdio_addr << EQOS_MAC_MDIO_ADDRESS_PA_SHIFT) |
(mdio_reg << EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT) |
- (EQOS_MAC_MDIO_ADDRESS_CR_20_35 <<
+ (eqos->config->config_mac_mdio <<
EQOS_MAC_MDIO_ADDRESS_CR_SHIFT) |
(EQOS_MAC_MDIO_ADDRESS_GOC_WRITE <<
EQOS_MAC_MDIO_ADDRESS_GOC_SHIFT) |
EQOS_MAC_MDIO_ADDRESS_GB;
writel(val, &eqos->mac_regs->mdio_address);
- udelay(10);
+ udelay(eqos->config->mdio_wait);
ret = eqos_mdio_wait_idle(eqos);
if (ret) {
return ret;
}
+static int eqos_start_clks_stm32(struct udevice *dev)
+{
+ struct eqos_priv *eqos = dev_get_priv(dev);
+ int ret;
+
+ debug("%s(dev=%p):\n", __func__, dev);
+
+ ret = clk_enable(&eqos->clk_master_bus);
+ if (ret < 0) {
+ pr_err("clk_enable(clk_master_bus) failed: %d", ret);
+ goto err;
+ }
+
+ ret = clk_enable(&eqos->clk_rx);
+ if (ret < 0) {
+ pr_err("clk_enable(clk_rx) failed: %d", ret);
+ goto err_disable_clk_master_bus;
+ }
+
+ ret = clk_enable(&eqos->clk_tx);
+ if (ret < 0) {
+ pr_err("clk_enable(clk_tx) failed: %d", ret);
+ goto err_disable_clk_rx;
+ }
+
+ if (clk_valid(&eqos->clk_ck)) {
+ ret = clk_enable(&eqos->clk_ck);
+ if (ret < 0) {
+ pr_err("clk_enable(clk_ck) failed: %d", ret);
+ goto err_disable_clk_tx;
+ }
+ }
+
+ debug("%s: OK\n", __func__);
+ return 0;
+
+err_disable_clk_tx:
+ clk_disable(&eqos->clk_tx);
+err_disable_clk_rx:
+ clk_disable(&eqos->clk_rx);
+err_disable_clk_master_bus:
+ clk_disable(&eqos->clk_master_bus);
+err:
+ debug("%s: FAILED: %d\n", __func__, ret);
+ return ret;
+}
+
void eqos_stop_clks_tegra186(struct udevice *dev)
{
struct eqos_priv *eqos = dev_get_priv(dev);
debug("%s: OK\n", __func__);
}
+void eqos_stop_clks_stm32(struct udevice *dev)
+{
+ struct eqos_priv *eqos = dev_get_priv(dev);
+
+ debug("%s(dev=%p):\n", __func__, dev);
+
+ clk_disable(&eqos->clk_tx);
+ clk_disable(&eqos->clk_rx);
+ clk_disable(&eqos->clk_master_bus);
+ if (clk_valid(&eqos->clk_ck))
+ clk_disable(&eqos->clk_ck);
+
+ debug("%s: OK\n", __func__);
+}
+
static int eqos_start_resets_tegra186(struct udevice *dev)
{
struct eqos_priv *eqos = dev_get_priv(dev);
return 0;
}
+static int eqos_start_resets_stm32(struct udevice *dev)
+{
+ return 0;
+}
+
static int eqos_stop_resets_tegra186(struct udevice *dev)
{
struct eqos_priv *eqos = dev_get_priv(dev);
return 0;
}
+static int eqos_stop_resets_stm32(struct udevice *dev)
+{
+ return 0;
+}
+
static int eqos_calibrate_pads_tegra186(struct udevice *dev)
{
struct eqos_priv *eqos = dev_get_priv(dev);
return clk_get_rate(&eqos->clk_slave_bus);
}
+static ulong eqos_get_tick_clk_rate_stm32(struct udevice *dev)
+{
+ struct eqos_priv *eqos = dev_get_priv(dev);
+
+ return clk_get_rate(&eqos->clk_master_bus);
+}
+
+static int eqos_calibrate_pads_stm32(struct udevice *dev)
+{
+ return 0;
+}
+
+static int eqos_disable_calibration_stm32(struct udevice *dev)
+{
+ return 0;
+}
+
static int eqos_set_full_duplex(struct udevice *dev)
{
struct eqos_priv *eqos = dev_get_priv(dev);
return 0;
}
+static int eqos_set_tx_clk_speed_stm32(struct udevice *dev)
+{
+ return 0;
+}
+
static int eqos_adjust_link(struct udevice *dev)
{
struct eqos_priv *eqos = dev_get_priv(dev);
}
if (en_calibration) {
- ret = eqos_calibrate_pads_tegra186(dev);
+ ret = eqos->config->ops->eqos_calibrate_pads(dev);
if (ret < 0) {
- pr_err("eqos_calibrate_pads_tegra186() failed: %d", ret);
+ pr_err("eqos_calibrate_pads() failed: %d",
+ ret);
return ret;
}
} else {
- ret = eqos_disable_calibration_tegra186(dev);
+ ret = eqos->config->ops->eqos_disable_calibration(dev);
if (ret < 0) {
- pr_err("eqos_disable_calibration_tegra186() failed: %d",
- ret);
+ pr_err("eqos_disable_calibration() failed: %d",
+ ret);
return ret;
}
}
-
- ret = eqos_set_tx_clk_speed_tegra186(dev);
+ ret = eqos->config->ops->eqos_set_tx_clk_speed(dev);
if (ret < 0) {
- pr_err("eqos_set_tx_clk_speed_tegra186() failed: %d", ret);
+ pr_err("eqos_set_tx_clk_speed() failed: %d", ret);
return ret;
}
eqos->tx_desc_idx = 0;
eqos->rx_desc_idx = 0;
- ret = eqos_start_clks_tegra186(dev);
+ ret = eqos->config->ops->eqos_start_clks(dev);
if (ret < 0) {
- pr_err("eqos_start_clks_tegra186() failed: %d", ret);
+ pr_err("eqos_start_clks() failed: %d", ret);
goto err;
}
- ret = eqos_start_resets_tegra186(dev);
+ ret = eqos->config->ops->eqos_start_resets(dev);
if (ret < 0) {
- pr_err("eqos_start_resets_tegra186() failed: %d", ret);
+ pr_err("eqos_start_resets() failed: %d", ret);
goto err_stop_clks;
}
eqos->reg_access_ok = true;
ret = wait_for_bit_le32(&eqos->dma_regs->mode,
- EQOS_DMA_MODE_SWR, false, 10, false);
+ EQOS_DMA_MODE_SWR, false,
+ eqos->config->swr_wait, false);
if (ret) {
pr_err("EQOS_DMA_MODE_SWR stuck");
goto err_stop_resets;
}
- ret = eqos_calibrate_pads_tegra186(dev);
+ ret = eqos->config->ops->eqos_calibrate_pads(dev);
if (ret < 0) {
- pr_err("eqos_calibrate_pads_tegra186() failed: %d", ret);
+ pr_err("eqos_calibrate_pads() failed: %d", ret);
goto err_stop_resets;
}
+ rate = eqos->config->ops->eqos_get_tick_clk_rate(dev);
- rate = eqos_get_tick_clk_rate_tegra186(dev);
val = (rate / 1000000) - 1;
writel(val, &eqos->mac_regs->us_tic_counter);
- eqos->phy = phy_connect(eqos->mii, 0, dev, 0);
+ /*
+ * if PHY was already connected and configured,
+ * don't need to reconnect/reconfigure again
+ */
if (!eqos->phy) {
- pr_err("phy_connect() failed");
- goto err_stop_resets;
- }
- ret = phy_config(eqos->phy);
- if (ret < 0) {
- pr_err("phy_config() failed: %d", ret);
- goto err_shutdown_phy;
+ eqos->phy = phy_connect(eqos->mii, 0, dev,
+ eqos->config->interface(dev));
+ if (!eqos->phy) {
+ pr_err("phy_connect() failed");
+ goto err_stop_resets;
+ }
+ ret = phy_config(eqos->phy);
+ if (ret < 0) {
+ pr_err("phy_config() failed: %d", ret);
+ goto err_shutdown_phy;
+ }
}
+
ret = phy_startup(eqos->phy);
if (ret < 0) {
pr_err("phy_startup() failed: %d", ret);
clrsetbits_le32(&eqos->mac_regs->rxq_ctrl0,
EQOS_MAC_RXQ_CTRL0_RXQ0EN_MASK <<
EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT,
- EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB <<
+ eqos->config->config_mac <<
EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT);
/* Set TX flow control parameters */
(i * EQOS_MAX_PACKET_SIZE));
rx_desc->des3 |= EQOS_DESC3_OWN | EQOS_DESC3_BUF1V;
}
- flush_cache((unsigned long)eqos->descs, EQOS_DESCRIPTORS_SIZE);
+ eqos->config->ops->eqos_flush_desc(eqos->descs);
writel(0, &eqos->dma_regs->ch0_txdesc_list_haddress);
writel((ulong)eqos->tx_descs, &eqos->dma_regs->ch0_txdesc_list_address);
err_shutdown_phy:
phy_shutdown(eqos->phy);
- eqos->phy = NULL;
err_stop_resets:
- eqos_stop_resets_tegra186(dev);
+ eqos->config->ops->eqos_stop_resets(dev);
err_stop_clks:
- eqos_stop_clks_tegra186(dev);
+ eqos->config->ops->eqos_stop_clks(dev);
err:
pr_err("FAILED: %d", ret);
return ret;
if (eqos->phy) {
phy_shutdown(eqos->phy);
- eqos->phy = NULL;
}
- eqos_stop_resets_tegra186(dev);
- eqos_stop_clks_tegra186(dev);
+ eqos->config->ops->eqos_stop_resets(dev);
+ eqos->config->ops->eqos_stop_clks(dev);
debug("%s: OK\n", __func__);
}
length);
memcpy(eqos->tx_dma_buf, packet, length);
- eqos_flush_buffer(eqos->tx_dma_buf, length);
+ eqos->config->ops->eqos_flush_buffer(eqos->tx_dma_buf, length);
tx_desc = &(eqos->tx_descs[eqos->tx_desc_idx]);
eqos->tx_desc_idx++;
*/
mb();
tx_desc->des3 = EQOS_DESC3_OWN | EQOS_DESC3_FD | EQOS_DESC3_LD | length;
- eqos_flush_desc(tx_desc);
+ eqos->config->ops->eqos_flush_desc(tx_desc);
writel((ulong)(tx_desc + 1), &eqos->dma_regs->ch0_txdesc_tail_pointer);
for (i = 0; i < 1000000; i++) {
- eqos_inval_desc(tx_desc);
+ eqos->config->ops->eqos_inval_desc(tx_desc);
if (!(readl(&tx_desc->des3) & EQOS_DESC3_OWN))
return 0;
udelay(1);
length = rx_desc->des3 & 0x7fff;
debug("%s: *packetp=%p, length=%d\n", __func__, *packetp, length);
- eqos_inval_buffer(*packetp, length);
+ eqos->config->ops->eqos_inval_buffer(*packetp, length);
return length;
}
*/
mb();
rx_desc->des3 |= EQOS_DESC3_OWN | EQOS_DESC3_BUF1V;
- eqos_flush_desc(rx_desc);
+ eqos->config->ops->eqos_flush_desc(rx_desc);
writel((ulong)rx_desc, &eqos->dma_regs->ch0_rxdesc_tail_pointer);
ret = -ENOMEM;
goto err_free_descs;
}
- debug("%s: rx_dma_buf=%p\n", __func__, eqos->rx_dma_buf);
+ debug("%s: tx_dma_buf=%p\n", __func__, eqos->tx_dma_buf);
eqos->rx_dma_buf = memalign(EQOS_BUFFER_ALIGN, EQOS_RX_BUFFER_SIZE);
if (!eqos->rx_dma_buf) {
ret = -ENOMEM;
goto err_free_tx_dma_buf;
}
- debug("%s: tx_dma_buf=%p\n", __func__, eqos->tx_dma_buf);
+ debug("%s: rx_dma_buf=%p\n", __func__, eqos->rx_dma_buf);
eqos->rx_pkt = malloc(EQOS_MAX_PACKET_SIZE);
if (!eqos->rx_pkt) {
return ret;
}
+/* board-specific Ethernet Interface initializations. */
+__weak int board_interface_eth_init(int interface_type, bool eth_clk_sel_reg,
+ bool eth_ref_clk_sel_reg)
+{
+ return 0;
+}
+
+static int eqos_probe_resources_stm32(struct udevice *dev)
+{
+ struct eqos_priv *eqos = dev_get_priv(dev);
+ int ret;
+ phy_interface_t interface;
+ bool eth_clk_sel_reg = false;
+ bool eth_ref_clk_sel_reg = false;
+
+ debug("%s(dev=%p):\n", __func__, dev);
+
+ interface = eqos->config->interface(dev);
+
+ if (interface == PHY_INTERFACE_MODE_NONE) {
+ pr_err("Invalid PHY interface\n");
+ return -EINVAL;
+ }
+
+ /* Gigabit Ethernet 125MHz clock selection. */
+ eth_clk_sel_reg = dev_read_bool(dev, "st,eth_clk_sel");
+
+ /* Ethernet 50Mhz RMII clock selection */
+ eth_ref_clk_sel_reg =
+ dev_read_bool(dev, "st,eth_ref_clk_sel");
+
+ ret = board_interface_eth_init(interface, eth_clk_sel_reg,
+ eth_ref_clk_sel_reg);
+ if (ret)
+ return -EINVAL;
+
+ ret = clk_get_by_name(dev, "stmmaceth", &eqos->clk_master_bus);
+ if (ret) {
+ pr_err("clk_get_by_name(master_bus) failed: %d", ret);
+ goto err_probe;
+ }
+
+ ret = clk_get_by_name(dev, "mac-clk-rx", &eqos->clk_rx);
+ if (ret) {
+ pr_err("clk_get_by_name(rx) failed: %d", ret);
+ goto err_free_clk_master_bus;
+ }
+
+ ret = clk_get_by_name(dev, "mac-clk-tx", &eqos->clk_tx);
+ if (ret) {
+ pr_err("clk_get_by_name(tx) failed: %d", ret);
+ goto err_free_clk_rx;
+ }
+
+ /* Get ETH_CLK clocks (optional) */
+ ret = clk_get_by_name(dev, "eth-ck", &eqos->clk_ck);
+ if (ret)
+ pr_warn("No phy clock provided %d", ret);
+
+ debug("%s: OK\n", __func__);
+ return 0;
+
+err_free_clk_rx:
+ clk_free(&eqos->clk_rx);
+err_free_clk_master_bus:
+ clk_free(&eqos->clk_master_bus);
+err_probe:
+
+ debug("%s: returns %d\n", __func__, ret);
+ return ret;
+}
+
+static phy_interface_t eqos_get_interface_stm32(struct udevice *dev)
+{
+ const char *phy_mode;
+ phy_interface_t interface = PHY_INTERFACE_MODE_NONE;
+
+ debug("%s(dev=%p):\n", __func__, dev);
+
+ phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
+ NULL);
+ if (phy_mode)
+ interface = phy_get_interface_by_name(phy_mode);
+
+ return interface;
+}
+
+static phy_interface_t eqos_get_interface_tegra186(struct udevice *dev)
+{
+ return PHY_INTERFACE_MODE_MII;
+}
+
static int eqos_remove_resources_tegra186(struct udevice *dev)
{
struct eqos_priv *eqos = dev_get_priv(dev);
return 0;
}
+static int eqos_remove_resources_stm32(struct udevice *dev)
+{
+ struct eqos_priv *eqos = dev_get_priv(dev);
+
+ debug("%s(dev=%p):\n", __func__, dev);
+
+ clk_free(&eqos->clk_tx);
+ clk_free(&eqos->clk_rx);
+ clk_free(&eqos->clk_master_bus);
+ if (clk_valid(&eqos->clk_ck))
+ clk_free(&eqos->clk_ck);
+
+ debug("%s: OK\n", __func__);
+ return 0;
+}
+
static int eqos_probe(struct udevice *dev)
{
struct eqos_priv *eqos = dev_get_priv(dev);
return ret;
}
- ret = eqos_probe_resources_tegra186(dev);
+ ret = eqos->config->ops->eqos_probe_resources(dev);
if (ret < 0) {
- pr_err("eqos_probe_resources_tegra186() failed: %d", ret);
+ pr_err("eqos_probe_resources() failed: %d", ret);
goto err_remove_resources_core;
}
eqos->mii = mdio_alloc();
if (!eqos->mii) {
pr_err("mdio_alloc() failed");
+ ret = -ENOMEM;
goto err_remove_resources_tegra;
}
eqos->mii->read = eqos_mdio_read;
err_free_mdio:
mdio_free(eqos->mii);
err_remove_resources_tegra:
- eqos_remove_resources_tegra186(dev);
+ eqos->config->ops->eqos_remove_resources(dev);
err_remove_resources_core:
eqos_remove_resources_core(dev);
mdio_unregister(eqos->mii);
mdio_free(eqos->mii);
- eqos_remove_resources_tegra186(dev);
+ eqos->config->ops->eqos_remove_resources(dev);
+
eqos_probe_resources_core(dev);
debug("%s: OK\n", __func__);
.write_hwaddr = eqos_write_hwaddr,
};
+static struct eqos_ops eqos_tegra186_ops = {
+ .eqos_inval_desc = eqos_inval_desc_tegra186,
+ .eqos_flush_desc = eqos_flush_desc_tegra186,
+ .eqos_inval_buffer = eqos_inval_buffer_tegra186,
+ .eqos_flush_buffer = eqos_flush_buffer_tegra186,
+ .eqos_probe_resources = eqos_probe_resources_tegra186,
+ .eqos_remove_resources = eqos_remove_resources_tegra186,
+ .eqos_stop_resets = eqos_stop_resets_tegra186,
+ .eqos_start_resets = eqos_start_resets_tegra186,
+ .eqos_stop_clks = eqos_stop_clks_tegra186,
+ .eqos_start_clks = eqos_start_clks_tegra186,
+ .eqos_calibrate_pads = eqos_calibrate_pads_tegra186,
+ .eqos_disable_calibration = eqos_disable_calibration_tegra186,
+ .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_tegra186,
+ .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_tegra186
+};
+
static const struct eqos_config eqos_tegra186_config = {
.reg_access_always_ok = false,
+ .mdio_wait = 10,
+ .swr_wait = 10,
+ .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB,
+ .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_20_35,
+ .interface = eqos_get_interface_tegra186,
+ .ops = &eqos_tegra186_ops
+};
+
+static struct eqos_ops eqos_stm32_ops = {
+ .eqos_inval_desc = eqos_inval_desc_stm32,
+ .eqos_flush_desc = eqos_flush_desc_stm32,
+ .eqos_inval_buffer = eqos_inval_buffer_stm32,
+ .eqos_flush_buffer = eqos_flush_buffer_stm32,
+ .eqos_probe_resources = eqos_probe_resources_stm32,
+ .eqos_remove_resources = eqos_remove_resources_stm32,
+ .eqos_stop_resets = eqos_stop_resets_stm32,
+ .eqos_start_resets = eqos_start_resets_stm32,
+ .eqos_stop_clks = eqos_stop_clks_stm32,
+ .eqos_start_clks = eqos_start_clks_stm32,
+ .eqos_calibrate_pads = eqos_calibrate_pads_stm32,
+ .eqos_disable_calibration = eqos_disable_calibration_stm32,
+ .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_stm32,
+ .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_stm32
+};
+
+static const struct eqos_config eqos_stm32_config = {
+ .reg_access_always_ok = false,
+ .mdio_wait = 10000,
+ .swr_wait = 50,
+ .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_AV,
+ .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_250_300,
+ .interface = eqos_get_interface_stm32,
+ .ops = &eqos_stm32_ops
};
static const struct udevice_id eqos_ids[] = {
.compatible = "nvidia,tegra186-eqos",
.data = (ulong)&eqos_tegra186_config
},
+ {
+ .compatible = "snps,dwmac-4.20a",
+ .data = (ulong)&eqos_stm32_config
+ },
+
{ }
};