From 6a895d039ba7ddcff3d49836b6642573792d7067 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Sun, 3 May 2020 22:41:15 +0800 Subject: net: Update eQos driver and FEC driver to use eth phy interfaces Update eQoS and fec ethernet drivers to support shared MDIO framework Signed-off-by: Ye Li Signed-off-by: Peng Fan --- drivers/net/dwc_eth_qos.c | 45 +++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) (limited to 'drivers/net/dwc_eth_qos.c') diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 60dfd17a74d..bdddbdef7f0 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -41,6 +41,7 @@ #include #include #include +#include /* Core registers */ @@ -1083,7 +1084,14 @@ static int eqos_start(struct udevice *dev) * don't need to reconnect/reconfigure again */ if (!eqos->phy) { - eqos->phy = phy_connect(eqos->mii, eqos->phyaddr, dev, + int addr = -1; +#ifdef CONFIG_DM_ETH_PHY + addr = eth_phy_get_addr(dev); +#endif +#ifdef DWC_NET_PHYADDR + addr = DWC_NET_PHYADDR; +#endif + eqos->phy = phy_connect(eqos->mii, addr, dev, eqos->config->interface(dev)); if (!eqos->phy) { pr_err("phy_connect() failed"); @@ -1820,23 +1828,32 @@ static int eqos_probe(struct udevice *dev) goto err_remove_resources_core; } - eqos->mii = mdio_alloc(); +#ifdef CONFIG_DM_ETH_PHY + eqos->mii = eth_phy_get_mdio_bus(dev); +#endif if (!eqos->mii) { - pr_err("mdio_alloc() failed"); - ret = -ENOMEM; - goto err_remove_resources_tegra; - } - eqos->mii->read = eqos_mdio_read; - eqos->mii->write = eqos_mdio_write; - eqos->mii->priv = eqos; - strcpy(eqos->mii->name, dev->name); + 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; + eqos->mii->write = eqos_mdio_write; + eqos->mii->priv = eqos; + strcpy(eqos->mii->name, dev->name); - ret = mdio_register(eqos->mii); - if (ret < 0) { - pr_err("mdio_register() failed: %d", ret); - goto err_free_mdio; + ret = mdio_register(eqos->mii); + if (ret < 0) { + pr_err("mdio_register() failed: %d", ret); + goto err_free_mdio; + } } +#ifdef CONFIG_DM_ETH_PHY + eth_phy_set_mdio_bus(dev, eqos->mii); +#endif + debug("%s: OK\n", __func__); return 0; -- cgit v1.2.3 From 3a97da12ee7bfa132d4ffb1ed1b224213cf81056 Mon Sep 17 00:00:00 2001 From: Fugang Duan Date: Sun, 3 May 2020 22:41:17 +0800 Subject: net: dwc_eth_qos: add dwc eqos for imx support Add dwc eqos for imx support. Reviewed-by: Ye Li Signed-off-by: Fugang Duan Signed-off-by: Peng Fan --- drivers/net/dwc_eth_qos.c | 185 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 171 insertions(+), 14 deletions(-) (limited to 'drivers/net/dwc_eth_qos.c') diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index bdddbdef7f0..75c70663c9e 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -81,6 +81,7 @@ struct eqos_mac_regs { #define EQOS_MAC_CONFIGURATION_PS BIT(15) #define EQOS_MAC_CONFIGURATION_FES BIT(14) #define EQOS_MAC_CONFIGURATION_DM BIT(13) +#define EQOS_MAC_CONFIGURATION_LM BIT(12) #define EQOS_MAC_CONFIGURATION_TE BIT(1) #define EQOS_MAC_CONFIGURATION_RE BIT(0) @@ -102,11 +103,19 @@ struct eqos_mac_regs { #define EQOS_MAC_RXQ_CTRL2_PSRQ0_SHIFT 0 #define EQOS_MAC_RXQ_CTRL2_PSRQ0_MASK 0xff +#define EQOS_MAC_HW_FEATURE0_MMCSEL_SHIFT 8 +#define EQOS_MAC_HW_FEATURE0_HDSEL_SHIFT 2 +#define EQOS_MAC_HW_FEATURE0_GMIISEL_SHIFT 1 +#define EQOS_MAC_HW_FEATURE0_MIISEL_SHIFT 0 + #define EQOS_MAC_HW_FEATURE1_TXFIFOSIZE_SHIFT 6 #define EQOS_MAC_HW_FEATURE1_TXFIFOSIZE_MASK 0x1f #define EQOS_MAC_HW_FEATURE1_RXFIFOSIZE_SHIFT 0 #define EQOS_MAC_HW_FEATURE1_RXFIFOSIZE_MASK 0x1f +#define EQOS_MAC_HW_FEATURE3_ASP_SHIFT 28 +#define EQOS_MAC_HW_FEATURE3_ASP_MASK 0x3 + #define EQOS_MAC_MDIO_ADDRESS_PA_SHIFT 21 #define EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT 16 #define EQOS_MAC_MDIO_ADDRESS_CR_SHIFT 8 @@ -154,6 +163,8 @@ struct eqos_mtl_regs { #define EQOS_MTL_RXQ0_OPERATION_MODE_RFA_MASK 0x3f #define EQOS_MTL_RXQ0_OPERATION_MODE_EHFC BIT(7) #define EQOS_MTL_RXQ0_OPERATION_MODE_RSF BIT(5) +#define EQOS_MTL_RXQ0_OPERATION_MODE_FEP BIT(4) +#define EQOS_MTL_RXQ0_OPERATION_MODE_FUP BIT(3) #define EQOS_MTL_RXQ0_DEBUG_PRXQ_SHIFT 16 #define EQOS_MTL_RXQ0_DEBUG_PRXQ_MASK 0x7fff @@ -368,7 +379,7 @@ static void eqos_inval_desc_tegra186(void *desc) #endif } -static void eqos_inval_desc_stm32(void *desc) +static void eqos_inval_desc_generic(void *desc) { #ifndef CONFIG_SYS_NONCACHED_MEMORY unsigned long start = rounddown((unsigned long)desc, ARCH_DMA_MINALIGN); @@ -386,7 +397,7 @@ static void eqos_flush_desc_tegra186(void *desc) #endif } -static void eqos_flush_desc_stm32(void *desc) +static void eqos_flush_desc_generic(void *desc) { #ifndef CONFIG_SYS_NONCACHED_MEMORY unsigned long start = rounddown((unsigned long)desc, ARCH_DMA_MINALIGN); @@ -405,7 +416,7 @@ static void eqos_inval_buffer_tegra186(void *buf, size_t size) invalidate_dcache_range(start, end); } -static void eqos_inval_buffer_stm32(void *buf, size_t size) +static void eqos_inval_buffer_generic(void *buf, size_t size) { unsigned long start = rounddown((unsigned long)buf, ARCH_DMA_MINALIGN); unsigned long end = roundup((unsigned long)buf + size, @@ -419,7 +430,7 @@ 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) +static void eqos_flush_buffer_generic(void *buf, size_t size) { unsigned long start = rounddown((unsigned long)buf, ARCH_DMA_MINALIGN); unsigned long end = roundup((unsigned long)buf + size, @@ -522,6 +533,7 @@ static int eqos_mdio_write(struct mii_dev *bus, int mdio_addr, int mdio_devad, static int eqos_start_clks_tegra186(struct udevice *dev) { +#ifdef CONFIG_CLK struct eqos_priv *eqos = dev_get_priv(dev); int ret; @@ -562,10 +574,12 @@ static int eqos_start_clks_tegra186(struct udevice *dev) pr_err("clk_enable(clk_tx) failed: %d", ret); goto err_disable_clk_ptp_ref; } +#endif debug("%s: OK\n", __func__); return 0; +#ifdef CONFIG_CLK err_disable_clk_ptp_ref: clk_disable(&eqos->clk_ptp_ref); err_disable_clk_rx: @@ -577,10 +591,12 @@ err_disable_clk_slave_bus: err: debug("%s: FAILED: %d\n", __func__, ret); return ret; +#endif } static int eqos_start_clks_stm32(struct udevice *dev) { +#ifdef CONFIG_CLK struct eqos_priv *eqos = dev_get_priv(dev); int ret; @@ -611,10 +627,12 @@ static int eqos_start_clks_stm32(struct udevice *dev) goto err_disable_clk_tx; } } +#endif debug("%s: OK\n", __func__); return 0; +#ifdef CONFIG_CLK err_disable_clk_tx: clk_disable(&eqos->clk_tx); err_disable_clk_rx: @@ -624,10 +642,17 @@ err_disable_clk_master_bus: err: debug("%s: FAILED: %d\n", __func__, ret); return ret; +#endif +} + +static int eqos_start_clks_imx(struct udevice *dev) +{ + return 0; } static void eqos_stop_clks_tegra186(struct udevice *dev) { +#ifdef CONFIG_CLK struct eqos_priv *eqos = dev_get_priv(dev); debug("%s(dev=%p):\n", __func__, dev); @@ -637,12 +662,14 @@ static void eqos_stop_clks_tegra186(struct udevice *dev) clk_disable(&eqos->clk_rx); clk_disable(&eqos->clk_master_bus); clk_disable(&eqos->clk_slave_bus); +#endif debug("%s: OK\n", __func__); } static void eqos_stop_clks_stm32(struct udevice *dev) { +#ifdef CONFIG_CLK struct eqos_priv *eqos = dev_get_priv(dev); debug("%s(dev=%p):\n", __func__, dev); @@ -652,10 +679,16 @@ static void eqos_stop_clks_stm32(struct udevice *dev) clk_disable(&eqos->clk_master_bus); if (clk_valid(&eqos->clk_ck)) clk_disable(&eqos->clk_ck); +#endif debug("%s: OK\n", __func__); } +static void eqos_stop_clks_imx(struct udevice *dev) +{ + /* empty */ +} + static int eqos_start_resets_tegra186(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); @@ -723,6 +756,11 @@ static int eqos_start_resets_stm32(struct udevice *dev) return 0; } +static int eqos_start_resets_imx(struct udevice *dev) +{ + return 0; +} + static int eqos_stop_resets_tegra186(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); @@ -750,6 +788,11 @@ static int eqos_stop_resets_stm32(struct udevice *dev) return 0; } +static int eqos_stop_resets_imx(struct udevice *dev) +{ + return 0; +} + static int eqos_calibrate_pads_tegra186(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); @@ -804,16 +847,30 @@ static int eqos_disable_calibration_tegra186(struct udevice *dev) static ulong eqos_get_tick_clk_rate_tegra186(struct udevice *dev) { +#ifdef CONFIG_CLK struct eqos_priv *eqos = dev_get_priv(dev); return clk_get_rate(&eqos->clk_slave_bus); +#else + return 0; +#endif } static ulong eqos_get_tick_clk_rate_stm32(struct udevice *dev) { +#ifdef CONFIG_CLK struct eqos_priv *eqos = dev_get_priv(dev); return clk_get_rate(&eqos->clk_master_bus); +#else + return 0; +#endif +} + +static ulong eqos_get_tick_clk_rate_imx(struct udevice *dev) +{ + /* TODO: retrieve from CSR clock */ + return 100 * 1000000; } static int eqos_calibrate_pads_stm32(struct udevice *dev) @@ -821,11 +878,21 @@ static int eqos_calibrate_pads_stm32(struct udevice *dev) return 0; } +static int eqos_calibrate_pads_imx(struct udevice *dev) +{ + return 0; +} + static int eqos_disable_calibration_stm32(struct udevice *dev) { return 0; } +static int eqos_disable_calibration_imx(struct udevice *dev) +{ + return 0; +} + static int eqos_set_full_duplex(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); @@ -890,6 +957,7 @@ static int eqos_set_mii_speed_10(struct udevice *dev) static int eqos_set_tx_clk_speed_tegra186(struct udevice *dev) { +#ifdef CONFIG_CLK struct eqos_priv *eqos = dev_get_priv(dev); ulong rate; int ret; @@ -916,6 +984,7 @@ static int eqos_set_tx_clk_speed_tegra186(struct udevice *dev) pr_err("clk_set_rate(tx_clk, %lu) failed: %d", rate, ret); return ret; } +#endif return 0; } @@ -925,6 +994,11 @@ static int eqos_set_tx_clk_speed_stm32(struct udevice *dev) return 0; } +static int eqos_set_tx_clk_speed_imx(struct udevice *dev) +{ + return 0; +} + static int eqos_adjust_link(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); @@ -1131,6 +1205,7 @@ static int eqos_start(struct udevice *dev) } /* Configure MTL */ + writel(0x60, &eqos->mtl_regs->txq0_quantum_weight - 0x100); /* Enable Store and Forward mode for TX */ /* Program Tx operating mode */ @@ -1144,7 +1219,9 @@ static int eqos_start(struct udevice *dev) /* Enable Store and Forward mode for RX, since no jumbo frame */ setbits_le32(&eqos->mtl_regs->rxq0_operation_mode, - EQOS_MTL_RXQ0_OPERATION_MODE_RSF); + EQOS_MTL_RXQ0_OPERATION_MODE_RSF | + EQOS_MTL_RXQ0_OPERATION_MODE_FEP | + EQOS_MTL_RXQ0_OPERATION_MODE_FUP); /* Transmit/Receive queue fifo size; use all RAM for 1 queue */ val = readl(&eqos->mac_regs->hw_feature1); @@ -1220,6 +1297,19 @@ static int eqos_start(struct udevice *dev) eqos->config->config_mac << EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT); + clrsetbits_le32(&eqos->mac_regs->rxq_ctrl0, + EQOS_MAC_RXQ_CTRL0_RXQ0EN_MASK << + EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT, + 0x2 << + EQOS_MAC_RXQ_CTRL0_RXQ0EN_SHIFT); + + /* Multicast and Broadcast Queue Enable */ + setbits_le32(&eqos->mac_regs->unused_0a4, + 0x00100000); + /* enable promise mode */ + setbits_le32(&eqos->mac_regs->unused_004[1], + 0x1); + /* Set TX flow control parameters */ /* Set Pause Time */ setbits_le32(&eqos->mac_regs->q0_tx_flow_ctrl, @@ -1297,7 +1387,11 @@ static int eqos_start(struct udevice *dev) rx_desc->des0 = (u32)(ulong)(eqos->rx_dma_buf + (i * EQOS_MAX_PACKET_SIZE)); rx_desc->des3 = EQOS_DESC3_OWN | EQOS_DESC3_BUF1V; + mb(); eqos->config->ops->eqos_flush_desc(rx_desc); + eqos->config->ops->eqos_inval_buffer(eqos->rx_dma_buf + + (i * EQOS_MAX_PACKET_SIZE), + EQOS_MAX_PACKET_SIZE); } writel(0, &eqos->dma_regs->ch0_txdesc_list_haddress); @@ -1311,14 +1405,12 @@ static int eqos_start(struct udevice *dev) &eqos->dma_regs->ch0_rxdesc_ring_length); /* Enable everything */ - - setbits_le32(&eqos->mac_regs->configuration, - EQOS_MAC_CONFIGURATION_TE | EQOS_MAC_CONFIGURATION_RE); - setbits_le32(&eqos->dma_regs->ch0_tx_control, EQOS_DMA_CH0_TX_CONTROL_ST); setbits_le32(&eqos->dma_regs->ch0_rx_control, EQOS_DMA_CH0_RX_CONTROL_SR); + setbits_le32(&eqos->mac_regs->configuration, + EQOS_MAC_CONFIGURATION_TE | EQOS_MAC_CONFIGURATION_RE); /* TX tail pointer not written until we need to TX a packet */ /* @@ -1483,6 +1575,8 @@ static int eqos_free_pkt(struct udevice *dev, uchar *packet, int length) return -EINVAL; } + eqos->config->ops->eqos_inval_buffer(packet, length); + rx_desc = &(eqos->rx_descs[eqos->rx_desc_idx]); rx_desc->des0 = 0; @@ -1759,17 +1853,42 @@ static phy_interface_t eqos_get_interface_tegra186(struct udevice *dev) return PHY_INTERFACE_MODE_MII; } +static int eqos_probe_resources_imx(struct udevice *dev) +{ + struct eqos_priv *eqos = dev_get_priv(dev); + phy_interface_t interface; + + 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; + } + + debug("%s: OK\n", __func__); + return 0; +} + +static phy_interface_t eqos_get_interface_imx(struct udevice *dev) +{ + return PHY_INTERFACE_MODE_RGMII; +} + static int eqos_remove_resources_tegra186(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); debug("%s(dev=%p):\n", __func__, dev); +#ifdef CONFIG_CLK clk_free(&eqos->clk_tx); clk_free(&eqos->clk_ptp_ref); clk_free(&eqos->clk_rx); clk_free(&eqos->clk_slave_bus); clk_free(&eqos->clk_master_bus); +#endif dm_gpio_free(dev, &eqos->phy_reset_gpio); reset_free(&eqos->reset_ctl); @@ -1779,6 +1898,7 @@ static int eqos_remove_resources_tegra186(struct udevice *dev) static int eqos_remove_resources_stm32(struct udevice *dev) { +#ifdef CONFIG_CLK struct eqos_priv *eqos = dev_get_priv(dev); debug("%s(dev=%p):\n", __func__, dev); @@ -1788,6 +1908,7 @@ static int eqos_remove_resources_stm32(struct udevice *dev) clk_free(&eqos->clk_master_bus); if (clk_valid(&eqos->clk_ck)) clk_free(&eqos->clk_ck); +#endif if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) dm_gpio_free(dev, &eqos->phy_reset_gpio); @@ -1796,6 +1917,11 @@ static int eqos_remove_resources_stm32(struct udevice *dev) return 0; } +static int eqos_remove_resources_imx(struct udevice *dev) +{ + return 0; +} + static int eqos_probe(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); @@ -1921,10 +2047,10 @@ static const struct eqos_config eqos_tegra186_config = { }; 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_inval_desc = eqos_inval_desc_generic, + .eqos_flush_desc = eqos_flush_desc_generic, + .eqos_inval_buffer = eqos_inval_buffer_generic, + .eqos_flush_buffer = eqos_flush_buffer_generic, .eqos_probe_resources = eqos_probe_resources_stm32, .eqos_remove_resources = eqos_remove_resources_stm32, .eqos_stop_resets = eqos_stop_resets_stm32, @@ -1947,6 +2073,33 @@ static const struct eqos_config eqos_stm32_config = { .ops = &eqos_stm32_ops }; +static struct eqos_ops eqos_imx_ops = { + .eqos_inval_desc = eqos_inval_desc_generic, + .eqos_flush_desc = eqos_flush_desc_generic, + .eqos_inval_buffer = eqos_inval_buffer_generic, + .eqos_flush_buffer = eqos_flush_buffer_generic, + .eqos_probe_resources = eqos_probe_resources_imx, + .eqos_remove_resources = eqos_remove_resources_imx, + .eqos_stop_resets = eqos_stop_resets_imx, + .eqos_start_resets = eqos_start_resets_imx, + .eqos_stop_clks = eqos_stop_clks_imx, + .eqos_start_clks = eqos_start_clks_imx, + .eqos_calibrate_pads = eqos_calibrate_pads_imx, + .eqos_disable_calibration = eqos_disable_calibration_imx, + .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_imx, + .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_imx +}; + +struct eqos_config eqos_imx_config = { + .reg_access_always_ok = false, + .mdio_wait = 10000, + .swr_wait = 50, + .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB, + .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_250_300, + .interface = eqos_get_interface_imx, + .ops = &eqos_imx_ops +}; + static const struct udevice_id eqos_ids[] = { { .compatible = "nvidia,tegra186-eqos", @@ -1956,6 +2109,10 @@ static const struct udevice_id eqos_ids[] = { .compatible = "snps,dwmac-4.20a", .data = (ulong)&eqos_stm32_config }, + { + .compatible = "fsl,imx-eqos", + .data = (ulong)&eqos_imx_config + }, { } }; @@ -1963,7 +2120,7 @@ static const struct udevice_id eqos_ids[] = { U_BOOT_DRIVER(eth_eqos) = { .name = "eth_eqos", .id = UCLASS_ETH, - .of_match = eqos_ids, + .of_match = of_match_ptr(eqos_ids), .probe = eqos_probe, .remove = eqos_remove, .ops = &eqos_ops, -- cgit v1.2.3 From 0e9d23945ce0b739a6ac13c11b0fdaba09a8dacc Mon Sep 17 00:00:00 2001 From: Fugang Duan Date: Sun, 3 May 2020 22:41:18 +0800 Subject: net: eqos: implement callbaks to get interface and set txclk rate Implement the callbacks to get phy mode interface and txclk rate configuration. Reviewed-by: Ye Li Signed-off-by: Fugang Duan Signed-off-by: Peng Fan --- drivers/net/dwc_eth_qos.c | 55 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 3 deletions(-) (limited to 'drivers/net/dwc_eth_qos.c') diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index 75c70663c9e..e4fc76cc068 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -42,6 +42,10 @@ #include #include #include +#ifdef CONFIG_ARCH_IMX8M +#include +#include +#endif /* Core registers */ @@ -867,11 +871,19 @@ static ulong eqos_get_tick_clk_rate_stm32(struct udevice *dev) #endif } -static ulong eqos_get_tick_clk_rate_imx(struct udevice *dev) +__weak u32 imx_get_eqos_csr_clk(void) { - /* TODO: retrieve from CSR clock */ return 100 * 1000000; } +__weak int imx_eqos_txclk_set_rate(unsigned long rate) +{ + return 0; +} + +static ulong eqos_get_tick_clk_rate_imx(struct udevice *dev) +{ + return imx_get_eqos_csr_clk(); +} static int eqos_calibrate_pads_stm32(struct udevice *dev) { @@ -996,6 +1008,33 @@ static int eqos_set_tx_clk_speed_stm32(struct udevice *dev) static int eqos_set_tx_clk_speed_imx(struct udevice *dev) { + struct eqos_priv *eqos = dev_get_priv(dev); + ulong rate; + int ret; + + debug("%s(dev=%p):\n", __func__, dev); + + switch (eqos->phy->speed) { + case SPEED_1000: + rate = 125 * 1000 * 1000; + break; + case SPEED_100: + rate = 25 * 1000 * 1000; + break; + case SPEED_10: + rate = 2.5 * 1000 * 1000; + break; + default: + pr_err("invalid speed %d", eqos->phy->speed); + return -EINVAL; + } + + ret = imx_eqos_txclk_set_rate(rate); + if (ret < 0) { + pr_err("imx (tx_clk, %lu) failed: %d", rate, ret); + return ret; + } + return 0; } @@ -1873,7 +1912,17 @@ static int eqos_probe_resources_imx(struct udevice *dev) static phy_interface_t eqos_get_interface_imx(struct udevice *dev) { - return PHY_INTERFACE_MODE_RGMII; + 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 int eqos_remove_resources_tegra186(struct udevice *dev) -- cgit v1.2.3 From 580fab4a821d50021f251452a6a3c056f0280941 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Sun, 3 May 2020 22:41:20 +0800 Subject: eQos: Implement the read_rom_hwaddr callback Implement the read_rom_hwaddr callback to load MAC address from fuse for imx8m platforms. Reviewed-by: Fugang Duan Signed-off-by: Ye Li Signed-off-by: Peng Fan --- drivers/net/dwc_eth_qos.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers/net/dwc_eth_qos.c') diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c index e4fc76cc068..f67c5f45707 100644 --- a/drivers/net/dwc_eth_qos.c +++ b/drivers/net/dwc_eth_qos.c @@ -1145,6 +1145,16 @@ static int eqos_write_hwaddr(struct udevice *dev) return 0; } +static int eqos_read_rom_hwaddr(struct udevice *dev) +{ + struct eth_pdata *pdata = dev_get_platdata(dev); + +#ifdef CONFIG_ARCH_IMX8M + imx_get_mac_from_fuse(dev->req_seq, pdata->enetaddr); +#endif + return !is_valid_ethaddr(pdata->enetaddr); +} + static int eqos_start(struct udevice *dev) { struct eqos_priv *eqos = dev_get_priv(dev); @@ -2066,6 +2076,7 @@ static const struct eth_ops eqos_ops = { .recv = eqos_recv, .free_pkt = eqos_free_pkt, .write_hwaddr = eqos_write_hwaddr, + .read_rom_hwaddr = eqos_read_rom_hwaddr, }; static struct eqos_ops eqos_tegra186_ops = { -- cgit v1.2.3