On Fri, May 10, 2019 at 8:59 AM Christophe ROULLIER <christophe.roull...@st.com> wrote: > > Hi Joe, > > On 09/05/2019 23:07, Joe Hershberger wrote: > > On Fri, Apr 26, 2019 at 6:16 AM Christophe Roullier > > <christophe.roull...@st.com> wrote: > >> Synopsys GMAC 4.20 is used. And Phy mode for eval and disco is RMII > >> with PHY Realtek RTL8211 (RGMII) > >> We also support some other PHY config on stm32mp157c > >> PHY_MODE (MII,GMII, RMII, RGMII) and in normal, > >> PHY wo crystal (25Mhz and 50Mhz), No 125Mhz from PHY config > > Can you split this into separate logical patches? > > If it is possible, I would like to keep this in same patch. > > Because the choice to select phy-mode and with or without crystal is > only in eqos_probe_resources_stm32 and it is managed by DT properties.
OK. > > Thanks in advance. > > Christophe > > > Thanks, > > -Joe > > > >> Signed-off-by: Christophe Roullier<christophe.roull...@st.com> > >> --- > >> > >> drivers/net/dwc_eth_qos.c | 435 +++++++++++++++++++++++++++++++++----- > >> 1 file changed, 383 insertions(+), 52 deletions(-) > >> > >> diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c > >> index 9f1c5af46e9..a6546d5e5ce 100644 > >> --- a/drivers/net/dwc_eth_qos.c > >> +++ b/drivers/net/dwc_eth_qos.c > >> @@ -26,7 +26,6 @@ > >> * 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> > >> @@ -95,6 +94,7 @@ struct eqos_mac_regs { > >> #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 > >> @@ -108,6 +108,7 @@ struct eqos_mac_regs { > >> #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 > >> @@ -260,6 +261,29 @@ struct eqos_desc { > >> > >> struct eqos_config { > >> bool reg_access_always_ok; > >> + int mdio_wait; > >> + int swr_wait; > >> + int config_mac; > >> + int config_mac_mdio; > >> + int (*interface)(struct udevice *dev); Shouldn't the return type be phy_interface_t? > >> + 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 { > >> @@ -276,6 +300,7 @@ 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; > >> @@ -327,7 +352,7 @@ static void eqos_free_descs(void *descs) > >> #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); > >> @@ -338,14 +363,36 @@ static void eqos_inval_desc(void *desc) > >> #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); > >> @@ -353,11 +400,29 @@ static void eqos_inval_buffer(void *buf, size_t size) > >> 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, > >> @@ -386,14 +451,14 @@ static int eqos_mdio_read(struct mii_dev *bus, int > >> mdio_addr, int mdio_devad, > >> 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) { > >> @@ -432,14 +497,14 @@ static int eqos_mdio_write(struct mii_dev *bus, int > >> mdio_addr, int mdio_devad, > >> 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) { > >> @@ -509,6 +574,53 @@ err: > >> 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); > >> @@ -524,6 +636,21 @@ void eqos_stop_clks_tegra186(struct udevice *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); > >> @@ -563,6 +690,11 @@ static int eqos_start_resets_tegra186(struct udevice > >> *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); > >> @@ -573,6 +705,11 @@ static int eqos_stop_resets_tegra186(struct udevice > >> *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); > >> @@ -632,6 +769,23 @@ static ulong eqos_get_tick_clk_rate_tegra186(struct > >> udevice *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); > >> @@ -726,6 +880,11 @@ static int eqos_set_tx_clk_speed_tegra186(struct > >> udevice *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); > >> @@ -766,23 +925,23 @@ static int eqos_adjust_link(struct udevice *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; > >> } > >> > >> @@ -846,15 +1005,15 @@ static int eqos_start(struct udevice *dev) > >> 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; > >> } > >> > >> @@ -863,32 +1022,41 @@ static int eqos_start(struct udevice *dev) > >> 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); > >> @@ -993,7 +1161,7 @@ static int eqos_start(struct udevice *dev) > >> 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 */ > >> @@ -1074,7 +1242,7 @@ static int eqos_start(struct udevice *dev) > >> (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); > >> @@ -1113,11 +1281,10 @@ static int eqos_start(struct udevice *dev) > >> > >> 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; > >> @@ -1170,10 +1337,9 @@ void eqos_stop(struct udevice *dev) > >> > >> 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__); > >> } > >> @@ -1188,7 +1354,7 @@ int eqos_send(struct udevice *dev, void *packet, int > >> length) > >> 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++; > >> @@ -1203,12 +1369,12 @@ int eqos_send(struct udevice *dev, void *packet, > >> int length) > >> */ > >> 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); > >> @@ -1238,7 +1404,7 @@ int eqos_recv(struct udevice *dev, int flags, uchar > >> **packetp) > >> 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; > >> } > >> @@ -1269,7 +1435,7 @@ int eqos_free_pkt(struct udevice *dev, uchar > >> *packet, int 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); > >> > >> @@ -1304,7 +1470,7 @@ static int eqos_probe_resources_core(struct udevice > >> *dev) > >> 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) { > >> @@ -1312,7 +1478,7 @@ static int eqos_probe_resources_core(struct udevice > >> *dev) > >> 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) { > >> @@ -1424,6 +1590,98 @@ err_free_reset_eqos: > >> 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; > >> + int 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 == -1) { I think it would be better to check for PHY_INTERFACE_MODE_NONE here and return it in the DT parsing. > >> + 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 int eqos_get_interface_stm32(struct udevice *dev) Shouldn't the return type be phy_interface_t? > >> +{ > >> + const char *phy_mode; > >> + int interface = -1; I think it would be better to default this to 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_get_interface_tegra186(struct udevice *dev) Shouldn't the return type be phy_interface_t? > >> +{ > >> + return 0; This should be PHY_INTERFACE_MODE_MII. > >> +} > >> + > >> static int eqos_remove_resources_tegra186(struct udevice *dev) > >> { > >> struct eqos_priv *eqos = dev_get_priv(dev); > >> @@ -1442,6 +1700,22 @@ static int eqos_remove_resources_tegra186(struct > >> udevice *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); > >> @@ -1468,15 +1742,16 @@ static int eqos_probe(struct udevice *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; > >> @@ -1496,7 +1771,7 @@ static int eqos_probe(struct udevice *dev) > >> 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); > >> > >> @@ -1512,7 +1787,8 @@ static int eqos_remove(struct udevice *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__); > >> @@ -1528,8 +1804,58 @@ static const struct eth_ops eqos_ops = { > >> .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[] = { > >> @@ -1537,6 +1863,11 @@ 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 > >> + }, > >> + > >> { } > >> }; > >> > >> -- > >> 2.17.1 > >> > >> _______________________________________________ > >> U-Boot mailing list > >> U-Boot@lists.denx.de > >> https://lists.denx.de/listinfo/u-boot > _______________________________________________ > U-Boot mailing list > U-Boot@lists.denx.de > https://lists.denx.de/listinfo/u-boot _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot