All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v2 0/6]     - Add Ethernet support for stm32mpu
@ 2019-05-17 13:08 Christophe Roullier
  2019-05-17 13:08 ` [U-Boot] [PATCH v2 1/6] stm32mp1: clk: use the correct identifier for ethck Christophe Roullier
                   ` (5 more replies)
  0 siblings, 6 replies; 15+ messages in thread
From: Christophe Roullier @ 2019-05-17 13:08 UTC (permalink / raw)
  To: u-boot

       Support all PHY config:
         PHY_MODE (MII,GMII, RMII, RGMII)
         Phy wo crystal (25Mhz and 50 Mhz), No 125Mhz from PHY config

Changes in v2:
-remark from Joe Hershberger to replace "int interface" with "phy_interface_t interface"
 and manage return values "-1", "0" with PHY_INTERFACE_MODE_NONE and PHY_INTERFACE_MODE_MII

Christophe Roullier (5):
  board: stm32mp1: Add board_interface_eth_init
  net: dwc_eth_qos: add Ethernet stm32mp1 support
  ARM: dts: stm32: Add Ethernet support on stm32mp1
  stm32mp1: Add Ethernet support for stm32mp1 board
  configs: stm32mp15: Enable Ethernet feature

Patrick Delaunay (1):
  stm32mp1: clk: use the correct identifier for ethck

 arch/arm/dts/stm32mp157-pinctrl.dtsi |   9 +-
 arch/arm/dts/stm32mp157c-ev1.dts     |   2 +-
 arch/arm/dts/stm32mp157c.dtsi        |  16 +-
 board/st/stm32mp1/stm32mp1.c         |  68 ++++-
 configs/stm32mp15_basic_defconfig    |   2 +
 drivers/clk/clk_stm32mp1.c           |   2 +-
 drivers/net/dwc_eth_qos.c            | 435 +++++++++++++++++++++++----
 include/configs/stm32mp1.h           |  12 +-
 8 files changed, 480 insertions(+), 66 deletions(-)

-- 
2.17.1

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [U-Boot] [PATCH v2 1/6] stm32mp1: clk: use the correct identifier for ethck
  2019-05-17 13:08 [U-Boot] [PATCH v2 0/6] - Add Ethernet support for stm32mpu Christophe Roullier
@ 2019-05-17 13:08 ` Christophe Roullier
  2019-06-11  7:34   ` Patrice CHOTARD
  2019-05-17 13:08 ` [U-Boot] [PATCH v2 2/6] board: stm32mp1: Add board_interface_eth_init Christophe Roullier
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 15+ messages in thread
From: Christophe Roullier @ 2019-05-17 13:08 UTC (permalink / raw)
  To: u-boot

From: Patrick Delaunay <patrick.delaunay@st.com>

ETHCK_K is the identifier the kernel clock for ETH in kernel
binding, selected by ETHKSELR / gated by ETHCKEN = BIT(7).
U-Boot driver need to use the same identifier, so change ETHCK
to ETHCK_K.

Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
Signed-off-by: Christophe Roullier <christophe.roullier@st.com>
---

Changes in v2: None

 drivers/clk/clk_stm32mp1.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/clk/clk_stm32mp1.c b/drivers/clk/clk_stm32mp1.c
index 24859fd054e..422176f3dde 100644
--- a/drivers/clk/clk_stm32mp1.c
+++ b/drivers/clk/clk_stm32mp1.c
@@ -555,7 +555,7 @@ static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = {
 
 	STM32MP1_CLK_SET_CLR(RCC_MP_AHB5ENSETR, 0, GPIOZ, _UNKNOWN_SEL),
 
-	STM32MP1_CLK_SET_CLR(RCC_MP_AHB6ENSETR, 7, ETHCK, _ETH_SEL),
+	STM32MP1_CLK_SET_CLR(RCC_MP_AHB6ENSETR, 7, ETHCK_K, _ETH_SEL),
 	STM32MP1_CLK_SET_CLR(RCC_MP_AHB6ENSETR, 8, ETHTX, _UNKNOWN_SEL),
 	STM32MP1_CLK_SET_CLR(RCC_MP_AHB6ENSETR, 9, ETHRX, _UNKNOWN_SEL),
 	STM32MP1_CLK_SET_CLR_F(RCC_MP_AHB6ENSETR, 10, ETHMAC, _ACLK),
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [U-Boot] [PATCH v2 2/6] board: stm32mp1: Add board_interface_eth_init
  2019-05-17 13:08 [U-Boot] [PATCH v2 0/6] - Add Ethernet support for stm32mpu Christophe Roullier
  2019-05-17 13:08 ` [U-Boot] [PATCH v2 1/6] stm32mp1: clk: use the correct identifier for ethck Christophe Roullier
@ 2019-05-17 13:08 ` Christophe Roullier
  2019-06-11  7:34   ` Patrice CHOTARD
  2019-05-17 13:08 ` [U-Boot] [PATCH v2 3/6] net: dwc_eth_qos: add Ethernet stm32mp1 support Christophe Roullier
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 15+ messages in thread
From: Christophe Roullier @ 2019-05-17 13:08 UTC (permalink / raw)
  To: u-boot

Called to configure Ethernet PHY interface selection and
configure clock selection in RCC Ethernet clock tree.

Signed-off-by: Christophe Roullier <christophe.roullier@st.com>
---

Changes in v2: None

 board/st/stm32mp1/stm32mp1.c | 68 ++++++++++++++++++++++++++++++++++--
 1 file changed, 65 insertions(+), 3 deletions(-)

diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
index 76917b022ed..e120fc57223 100644
--- a/board/st/stm32mp1/stm32mp1.c
+++ b/board/st/stm32mp1/stm32mp1.c
@@ -51,9 +51,9 @@
 #define SYSCFG_PMCSETR_ETH_SELMII	BIT(20)
 
 #define SYSCFG_PMCSETR_ETH_SEL_MASK	GENMASK(23, 21)
-#define SYSCFG_PMCSETR_ETH_SEL_GMII_MII	(0 << 21)
-#define SYSCFG_PMCSETR_ETH_SEL_RGMII	(1 << 21)
-#define SYSCFG_PMCSETR_ETH_SEL_RMII	(4 << 21)
+#define SYSCFG_PMCSETR_ETH_SEL_GMII_MII	0
+#define SYSCFG_PMCSETR_ETH_SEL_RGMII	BIT(21)
+#define SYSCFG_PMCSETR_ETH_SEL_RMII	BIT(23)
 
 /*
  * Get a global data pointer
@@ -504,3 +504,65 @@ void board_quiesce_devices(void)
 {
 	setup_led(LEDST_OFF);
 }
+
+/* board interface eth init */
+/* this is a weak define that we are overriding */
+int board_interface_eth_init(phy_interface_t interface_type,
+			     bool eth_clk_sel_reg, bool eth_ref_clk_sel_reg)
+{
+	u8 *syscfg;
+	u32 value;
+
+	syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG);
+
+	if (!syscfg)
+		return -ENODEV;
+
+	switch (interface_type) {
+	case PHY_INTERFACE_MODE_MII:
+		value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII |
+			SYSCFG_PMCSETR_ETH_REF_CLK_SEL;
+		debug("%s: PHY_INTERFACE_MODE_MII\n", __func__);
+		break;
+	case PHY_INTERFACE_MODE_GMII:
+		if (eth_clk_sel_reg)
+			value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII |
+				SYSCFG_PMCSETR_ETH_CLK_SEL;
+		else
+			value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII;
+		debug("%s: PHY_INTERFACE_MODE_GMII\n", __func__);
+		break;
+	case PHY_INTERFACE_MODE_RMII:
+		if (eth_ref_clk_sel_reg)
+			value = SYSCFG_PMCSETR_ETH_SEL_RMII |
+				SYSCFG_PMCSETR_ETH_REF_CLK_SEL;
+		else
+			value = SYSCFG_PMCSETR_ETH_SEL_RMII;
+		debug("%s: PHY_INTERFACE_MODE_RMII\n", __func__);
+		break;
+	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+		if (eth_clk_sel_reg)
+			value = SYSCFG_PMCSETR_ETH_SEL_RGMII |
+				SYSCFG_PMCSETR_ETH_CLK_SEL;
+		else
+			value = SYSCFG_PMCSETR_ETH_SEL_RGMII;
+		debug("%s: PHY_INTERFACE_MODE_RGMII\n", __func__);
+		break;
+	default:
+		debug("%s: Do not manage %d interface\n",
+		      __func__, interface_type);
+		/* Do not manage others interfaces */
+		return -EINVAL;
+	}
+
+	/* clear and set ETH configuration bits */
+	writel(SYSCFG_PMCSETR_ETH_SEL_MASK | SYSCFG_PMCSETR_ETH_SELMII |
+	       SYSCFG_PMCSETR_ETH_REF_CLK_SEL | SYSCFG_PMCSETR_ETH_CLK_SEL,
+	       syscfg + SYSCFG_PMCCLRR);
+	writel(value, syscfg + SYSCFG_PMCSETR);
+
+	return 0;
+}
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [U-Boot] [PATCH v2 3/6] net: dwc_eth_qos: add Ethernet stm32mp1 support
  2019-05-17 13:08 [U-Boot] [PATCH v2 0/6] - Add Ethernet support for stm32mpu Christophe Roullier
  2019-05-17 13:08 ` [U-Boot] [PATCH v2 1/6] stm32mp1: clk: use the correct identifier for ethck Christophe Roullier
  2019-05-17 13:08 ` [U-Boot] [PATCH v2 2/6] board: stm32mp1: Add board_interface_eth_init Christophe Roullier
@ 2019-05-17 13:08 ` Christophe Roullier
  2019-06-01 10:58   ` Joe Hershberger
  2019-06-11  7:35   ` Patrice CHOTARD
  2019-05-17 13:08 ` [U-Boot] [PATCH v2 4/6] ARM: dts: stm32: Add Ethernet support on stm32mp1 Christophe Roullier
                   ` (2 subsequent siblings)
  5 siblings, 2 replies; 15+ messages in thread
From: Christophe Roullier @ 2019-05-17 13:08 UTC (permalink / raw)
  To: u-boot

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

Signed-off-by: Christophe Roullier <christophe.roullier@st.com>
---

Changes in v2: None

 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..cee16ffd256 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;
+	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 {
@@ -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;
+	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);
@@ -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

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [U-Boot] [PATCH v2 4/6] ARM: dts: stm32: Add Ethernet support on stm32mp1
  2019-05-17 13:08 [U-Boot] [PATCH v2 0/6] - Add Ethernet support for stm32mpu Christophe Roullier
                   ` (2 preceding siblings ...)
  2019-05-17 13:08 ` [U-Boot] [PATCH v2 3/6] net: dwc_eth_qos: add Ethernet stm32mp1 support Christophe Roullier
@ 2019-05-17 13:08 ` Christophe Roullier
  2019-06-11  7:35   ` Patrice CHOTARD
  2019-05-17 13:08 ` [U-Boot] [PATCH v2 5/6] stm32mp1: Add Ethernet support for stm32mp1 board Christophe Roullier
  2019-05-17 13:08 ` [U-Boot] [PATCH v2 6/6] configs: stm32mp15: Enable Ethernet feature Christophe Roullier
  5 siblings, 1 reply; 15+ messages in thread
From: Christophe Roullier @ 2019-05-17 13:08 UTC (permalink / raw)
  To: u-boot

This patch add Ethernet support on stm32mp157 eval board

Signed-off-by: Christophe Roullier <christophe.roullier@st.com>
---

Changes in v2: None

 arch/arm/dts/stm32mp157-pinctrl.dtsi |  9 +++++++--
 arch/arm/dts/stm32mp157c-ev1.dts     |  2 +-
 arch/arm/dts/stm32mp157c.dtsi        | 16 ++++++++++------
 3 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/arch/arm/dts/stm32mp157-pinctrl.dtsi b/arch/arm/dts/stm32mp157-pinctrl.dtsi
index 0aae69b0a04..1962267033d 100644
--- a/arch/arm/dts/stm32mp157-pinctrl.dtsi
+++ b/arch/arm/dts/stm32mp157-pinctrl.dtsi
@@ -173,13 +173,18 @@
 						 <STM32_PINMUX('C', 2, AF11)>, /* ETH_RGMII_TXD2 */
 						 <STM32_PINMUX('E', 2, AF11)>, /* ETH_RGMII_TXD3 */
 						 <STM32_PINMUX('B', 11, AF11)>, /* ETH_RGMII_TX_CTL */
-						 <STM32_PINMUX('A', 2, AF11)>, /* ETH_MDIO */
 						 <STM32_PINMUX('C', 1, AF11)>; /* ETH_MDC */
 					bias-disable;
 					drive-push-pull;
-					slew-rate = <3>;
+					slew-rate = <2>;
 				};
 				pins2 {
+					pinmux = <STM32_PINMUX('A', 2, AF11)>; /* ETH_MDIO */
+					bias-disable;
+					drive-push-pull;
+					slew-rate = <0>;
+				};
+				pins3 {
 					pinmux = <STM32_PINMUX('C', 4, AF11)>, /* ETH_RGMII_RXD0 */
 						 <STM32_PINMUX('C', 5, AF11)>, /* ETH_RGMII_RXD1 */
 						 <STM32_PINMUX('B', 0, AF11)>, /* ETH_RGMII_RXD2 */
diff --git a/arch/arm/dts/stm32mp157c-ev1.dts b/arch/arm/dts/stm32mp157c-ev1.dts
index a6ee37924fe..d2232004410 100644
--- a/arch/arm/dts/stm32mp157c-ev1.dts
+++ b/arch/arm/dts/stm32mp157c-ev1.dts
@@ -78,7 +78,7 @@
 	pinctrl-0 = <&ethernet0_rgmii_pins_a>;
 	pinctrl-1 = <&ethernet0_rgmii_pins_sleep_a>;
 	pinctrl-names = "default", "sleep";
-	phy-mode = "rgmii";
+	phy-mode = "rgmii-id";
 	max-speed = <1000>;
 	phy-handle = <&phy0>;
 
diff --git a/arch/arm/dts/stm32mp157c.dtsi b/arch/arm/dts/stm32mp157c.dtsi
index 94634336a5e..82177b50afe 100644
--- a/arch/arm/dts/stm32mp157c.dtsi
+++ b/arch/arm/dts/stm32mp157c.dtsi
@@ -1087,21 +1087,25 @@
 			compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a";
 			reg = <0x5800a000 0x2000>;
 			reg-names = "stmmaceth";
-			interrupts-extended = <&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
-			interrupt-names = "macirq";
+			interrupts-extended =
+				<&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
+				<&intc GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
+				<&exti 70 1>;
+			interrupt-names = "macirq",
+					  "eth_wake_irq",
+					  "stm32_pwr_wakeup";
 			clock-names = "stmmaceth",
 				      "mac-clk-tx",
 				      "mac-clk-rx",
-				      "ethstp",
-				      "syscfg-clk";
+				      "ethstp";
 			clocks = <&rcc ETHMAC>,
 				 <&rcc ETHTX>,
 				 <&rcc ETHRX>,
-				 <&rcc ETHSTP>,
-				 <&rcc SYSCFG>;
+				 <&rcc ETHSTP>;
 			st,syscon = <&syscfg 0x4>;
 			snps,mixed-burst;
 			snps,pbl = <2>;
+			snps,en-tx-lpi-clockgating;
 			snps,axi-config = <&stmmac_axi_config_0>;
 			snps,tso;
 			status = "disabled";
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [U-Boot] [PATCH v2 5/6] stm32mp1: Add Ethernet support for stm32mp1 board
  2019-05-17 13:08 [U-Boot] [PATCH v2 0/6] - Add Ethernet support for stm32mpu Christophe Roullier
                   ` (3 preceding siblings ...)
  2019-05-17 13:08 ` [U-Boot] [PATCH v2 4/6] ARM: dts: stm32: Add Ethernet support on stm32mp1 Christophe Roullier
@ 2019-05-17 13:08 ` Christophe Roullier
  2019-06-11  7:35   ` Patrice CHOTARD
  2019-05-17 13:08 ` [U-Boot] [PATCH v2 6/6] configs: stm32mp15: Enable Ethernet feature Christophe Roullier
  5 siblings, 1 reply; 15+ messages in thread
From: Christophe Roullier @ 2019-05-17 13:08 UTC (permalink / raw)
  To: u-boot

Add default SERVERIP address
Enable noncached memory region required by ethernet driver
Add PXE support

Signed-off-by: Christophe Roullier <christophe.roullier@st.com>
---

Changes in v2: None

 include/configs/stm32mp1.h | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/include/configs/stm32mp1.h b/include/configs/stm32mp1.h
index fd6c97a0c61..cc14f6169b9 100644
--- a/include/configs/stm32mp1.h
+++ b/include/configs/stm32mp1.h
@@ -78,6 +78,14 @@
 /*MMC SD*/
 #define CONFIG_SYS_MMC_MAX_DEVICE	3
 
+/* Ethernet need */
+#ifdef CONFIG_DWC_ETH_QOS
+#define CONFIG_SYS_NONCACHED_MEMORY	(1 * SZ_1M)	/* 1M */
+#define CONFIG_SERVERIP                 192.168.1.1
+#define CONFIG_BOOTP_SERVERIP
+#define CONFIG_SYS_AUTOLOAD		"no"
+#endif
+
 /*****************************************************************************/
 #ifdef CONFIG_DISTRO_DEFAULTS
 /*****************************************************************************/
@@ -87,7 +95,9 @@
 #define BOOT_TARGET_DEVICES(func) \
 	func(MMC, mmc, 1) \
 	func(MMC, mmc, 0) \
-	func(MMC, mmc, 2)
+	func(MMC, mmc, 2) \
+	func(PXE, pxe, na)
+
 /*
  * bootcmd for stm32mp1:
  * for serial/usb: execute the stm32prog command
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [U-Boot] [PATCH v2 6/6] configs: stm32mp15: Enable Ethernet feature
  2019-05-17 13:08 [U-Boot] [PATCH v2 0/6] - Add Ethernet support for stm32mpu Christophe Roullier
                   ` (4 preceding siblings ...)
  2019-05-17 13:08 ` [U-Boot] [PATCH v2 5/6] stm32mp1: Add Ethernet support for stm32mp1 board Christophe Roullier
@ 2019-05-17 13:08 ` Christophe Roullier
  2019-06-01 10:53   ` Joe Hershberger
  2019-06-11  7:35   ` Patrice CHOTARD
  5 siblings, 2 replies; 15+ messages in thread
From: Christophe Roullier @ 2019-05-17 13:08 UTC (permalink / raw)
  To: u-boot

This allows to enable Ethernet and use driver for
Synopsys Ethernet QoS device

Signed-off-by: Christophe Roullier <christophe.roullier@st.com>
---

Changes in v2:
-remark from Joe Hershberger to replace "int interface" with "phy_interface_t interface"
 and manage return values "-1", "0" with PHY_INTERFACE_MODE_NONE and PHY_INTERFACE_MODE_MII

 configs/stm32mp15_basic_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig
index 0ea9dff43de..7456cc9a163 100644
--- a/configs/stm32mp15_basic_defconfig
+++ b/configs/stm32mp15_basic_defconfig
@@ -55,6 +55,8 @@ CONFIG_LED_GPIO=y
 CONFIG_DM_MMC=y
 CONFIG_SUPPORT_EMMC_BOOT=y
 CONFIG_STM32_SDMMC2=y
+CONFIG_DM_ETH=y
+CONFIG_DWC_ETH_QOS=y
 CONFIG_PHY=y
 CONFIG_PHY_STM32_USBPHYC=y
 CONFIG_PINCONF=y
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [U-Boot] [PATCH v2 6/6] configs: stm32mp15: Enable Ethernet feature
  2019-05-17 13:08 ` [U-Boot] [PATCH v2 6/6] configs: stm32mp15: Enable Ethernet feature Christophe Roullier
@ 2019-06-01 10:53   ` Joe Hershberger
  2019-06-11  7:35   ` Patrice CHOTARD
  1 sibling, 0 replies; 15+ messages in thread
From: Joe Hershberger @ 2019-06-01 10:53 UTC (permalink / raw)
  To: u-boot

On Fri, May 17, 2019 at 8:19 AM Christophe Roullier
<christophe.roullier@st.com> wrote:
>
> This allows to enable Ethernet and use driver for
> Synopsys Ethernet QoS device
>
> Signed-off-by: Christophe Roullier <christophe.roullier@st.com>

Acked-by: Joe Hershberger <joe.hershberger@ni.com>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [U-Boot] [PATCH v2 3/6] net: dwc_eth_qos: add Ethernet stm32mp1 support
  2019-05-17 13:08 ` [U-Boot] [PATCH v2 3/6] net: dwc_eth_qos: add Ethernet stm32mp1 support Christophe Roullier
@ 2019-06-01 10:58   ` Joe Hershberger
  2019-06-11  7:35   ` Patrice CHOTARD
  1 sibling, 0 replies; 15+ messages in thread
From: Joe Hershberger @ 2019-06-01 10:58 UTC (permalink / raw)
  To: u-boot

On Fri, May 17, 2019 at 8:17 AM Christophe Roullier
<christophe.roullier@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
>
> Signed-off-by: Christophe Roullier <christophe.roullier@st.com>

Acked-by: Joe Hershberger <joe.hershberger@ni.com>

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [U-Boot] [PATCH v2 1/6] stm32mp1: clk: use the correct identifier for ethck
  2019-05-17 13:08 ` [U-Boot] [PATCH v2 1/6] stm32mp1: clk: use the correct identifier for ethck Christophe Roullier
@ 2019-06-11  7:34   ` Patrice CHOTARD
  0 siblings, 0 replies; 15+ messages in thread
From: Patrice CHOTARD @ 2019-06-11  7:34 UTC (permalink / raw)
  To: u-boot



On 5/17/19 3:08 PM, Christophe Roullier wrote:
> From: Patrick Delaunay <patrick.delaunay@st.com>
> 
> ETHCK_K is the identifier the kernel clock for ETH in kernel
> binding, selected by ETHKSELR / gated by ETHCKEN = BIT(7).
> U-Boot driver need to use the same identifier, so change ETHCK
> to ETHCK_K.
> 
> Signed-off-by: Patrick Delaunay <patrick.delaunay@st.com>
> Signed-off-by: Christophe Roullier <christophe.roullier@st.com>
> ---
> 
> Changes in v2: None
> 
>  drivers/clk/clk_stm32mp1.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/clk/clk_stm32mp1.c b/drivers/clk/clk_stm32mp1.c
> index 24859fd054e..422176f3dde 100644
> --- a/drivers/clk/clk_stm32mp1.c
> +++ b/drivers/clk/clk_stm32mp1.c
> @@ -555,7 +555,7 @@ static const struct stm32mp1_clk_gate stm32mp1_clk_gate[] = {
>  
>  	STM32MP1_CLK_SET_CLR(RCC_MP_AHB5ENSETR, 0, GPIOZ, _UNKNOWN_SEL),
>  
> -	STM32MP1_CLK_SET_CLR(RCC_MP_AHB6ENSETR, 7, ETHCK, _ETH_SEL),
> +	STM32MP1_CLK_SET_CLR(RCC_MP_AHB6ENSETR, 7, ETHCK_K, _ETH_SEL),
>  	STM32MP1_CLK_SET_CLR(RCC_MP_AHB6ENSETR, 8, ETHTX, _UNKNOWN_SEL),
>  	STM32MP1_CLK_SET_CLR(RCC_MP_AHB6ENSETR, 9, ETHRX, _UNKNOWN_SEL),
>  	STM32MP1_CLK_SET_CLR_F(RCC_MP_AHB6ENSETR, 10, ETHMAC, _ACLK),
> 


Applied

Thanks

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [U-Boot] [PATCH v2 2/6] board: stm32mp1: Add board_interface_eth_init
  2019-05-17 13:08 ` [U-Boot] [PATCH v2 2/6] board: stm32mp1: Add board_interface_eth_init Christophe Roullier
@ 2019-06-11  7:34   ` Patrice CHOTARD
  0 siblings, 0 replies; 15+ messages in thread
From: Patrice CHOTARD @ 2019-06-11  7:34 UTC (permalink / raw)
  To: u-boot



On 5/17/19 3:08 PM, Christophe Roullier wrote:
> Called to configure Ethernet PHY interface selection and
> configure clock selection in RCC Ethernet clock tree.
> 
> Signed-off-by: Christophe Roullier <christophe.roullier@st.com>
> ---
> 
> Changes in v2: None
> 
>  board/st/stm32mp1/stm32mp1.c | 68 ++++++++++++++++++++++++++++++++++--
>  1 file changed, 65 insertions(+), 3 deletions(-)
> 
> diff --git a/board/st/stm32mp1/stm32mp1.c b/board/st/stm32mp1/stm32mp1.c
> index 76917b022ed..e120fc57223 100644
> --- a/board/st/stm32mp1/stm32mp1.c
> +++ b/board/st/stm32mp1/stm32mp1.c
> @@ -51,9 +51,9 @@
>  #define SYSCFG_PMCSETR_ETH_SELMII	BIT(20)
>  
>  #define SYSCFG_PMCSETR_ETH_SEL_MASK	GENMASK(23, 21)
> -#define SYSCFG_PMCSETR_ETH_SEL_GMII_MII	(0 << 21)
> -#define SYSCFG_PMCSETR_ETH_SEL_RGMII	(1 << 21)
> -#define SYSCFG_PMCSETR_ETH_SEL_RMII	(4 << 21)
> +#define SYSCFG_PMCSETR_ETH_SEL_GMII_MII	0
> +#define SYSCFG_PMCSETR_ETH_SEL_RGMII	BIT(21)
> +#define SYSCFG_PMCSETR_ETH_SEL_RMII	BIT(23)
>  
>  /*
>   * Get a global data pointer
> @@ -504,3 +504,65 @@ void board_quiesce_devices(void)
>  {
>  	setup_led(LEDST_OFF);
>  }
> +
> +/* board interface eth init */
> +/* this is a weak define that we are overriding */
> +int board_interface_eth_init(phy_interface_t interface_type,
> +			     bool eth_clk_sel_reg, bool eth_ref_clk_sel_reg)
> +{
> +	u8 *syscfg;
> +	u32 value;
> +
> +	syscfg = (u8 *)syscon_get_first_range(STM32MP_SYSCON_SYSCFG);
> +
> +	if (!syscfg)
> +		return -ENODEV;
> +
> +	switch (interface_type) {
> +	case PHY_INTERFACE_MODE_MII:
> +		value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII |
> +			SYSCFG_PMCSETR_ETH_REF_CLK_SEL;
> +		debug("%s: PHY_INTERFACE_MODE_MII\n", __func__);
> +		break;
> +	case PHY_INTERFACE_MODE_GMII:
> +		if (eth_clk_sel_reg)
> +			value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII |
> +				SYSCFG_PMCSETR_ETH_CLK_SEL;
> +		else
> +			value = SYSCFG_PMCSETR_ETH_SEL_GMII_MII;
> +		debug("%s: PHY_INTERFACE_MODE_GMII\n", __func__);
> +		break;
> +	case PHY_INTERFACE_MODE_RMII:
> +		if (eth_ref_clk_sel_reg)
> +			value = SYSCFG_PMCSETR_ETH_SEL_RMII |
> +				SYSCFG_PMCSETR_ETH_REF_CLK_SEL;
> +		else
> +			value = SYSCFG_PMCSETR_ETH_SEL_RMII;
> +		debug("%s: PHY_INTERFACE_MODE_RMII\n", __func__);
> +		break;
> +	case PHY_INTERFACE_MODE_RGMII:
> +	case PHY_INTERFACE_MODE_RGMII_ID:
> +	case PHY_INTERFACE_MODE_RGMII_RXID:
> +	case PHY_INTERFACE_MODE_RGMII_TXID:
> +		if (eth_clk_sel_reg)
> +			value = SYSCFG_PMCSETR_ETH_SEL_RGMII |
> +				SYSCFG_PMCSETR_ETH_CLK_SEL;
> +		else
> +			value = SYSCFG_PMCSETR_ETH_SEL_RGMII;
> +		debug("%s: PHY_INTERFACE_MODE_RGMII\n", __func__);
> +		break;
> +	default:
> +		debug("%s: Do not manage %d interface\n",
> +		      __func__, interface_type);
> +		/* Do not manage others interfaces */
> +		return -EINVAL;
> +	}
> +
> +	/* clear and set ETH configuration bits */
> +	writel(SYSCFG_PMCSETR_ETH_SEL_MASK | SYSCFG_PMCSETR_ETH_SELMII |
> +	       SYSCFG_PMCSETR_ETH_REF_CLK_SEL | SYSCFG_PMCSETR_ETH_CLK_SEL,
> +	       syscfg + SYSCFG_PMCCLRR);
> +	writel(value, syscfg + SYSCFG_PMCSETR);
> +
> +	return 0;
> +}
> 


Applied

Thanks

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [U-Boot] [PATCH v2 3/6] net: dwc_eth_qos: add Ethernet stm32mp1 support
  2019-05-17 13:08 ` [U-Boot] [PATCH v2 3/6] net: dwc_eth_qos: add Ethernet stm32mp1 support Christophe Roullier
  2019-06-01 10:58   ` Joe Hershberger
@ 2019-06-11  7:35   ` Patrice CHOTARD
  1 sibling, 0 replies; 15+ messages in thread
From: Patrice CHOTARD @ 2019-06-11  7:35 UTC (permalink / raw)
  To: u-boot



On 5/17/19 3:08 PM, Christophe Roullier 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
> 
> Signed-off-by: Christophe Roullier <christophe.roullier@st.com>
> ---
> 
> Changes in v2: None
> 
>  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..cee16ffd256 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;
> +	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 {
> @@ -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;
> +	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);
> @@ -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
> +	},
> +
>  	{ }
>  };
>  
> 

Applied

Thanks

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [U-Boot] [PATCH v2 4/6] ARM: dts: stm32: Add Ethernet support on stm32mp1
  2019-05-17 13:08 ` [U-Boot] [PATCH v2 4/6] ARM: dts: stm32: Add Ethernet support on stm32mp1 Christophe Roullier
@ 2019-06-11  7:35   ` Patrice CHOTARD
  0 siblings, 0 replies; 15+ messages in thread
From: Patrice CHOTARD @ 2019-06-11  7:35 UTC (permalink / raw)
  To: u-boot



On 5/17/19 3:08 PM, Christophe Roullier wrote:
> This patch add Ethernet support on stm32mp157 eval board
> 
> Signed-off-by: Christophe Roullier <christophe.roullier@st.com>
> ---
> 
> Changes in v2: None
> 
>  arch/arm/dts/stm32mp157-pinctrl.dtsi |  9 +++++++--
>  arch/arm/dts/stm32mp157c-ev1.dts     |  2 +-
>  arch/arm/dts/stm32mp157c.dtsi        | 16 ++++++++++------
>  3 files changed, 18 insertions(+), 9 deletions(-)
> 
> diff --git a/arch/arm/dts/stm32mp157-pinctrl.dtsi b/arch/arm/dts/stm32mp157-pinctrl.dtsi
> index 0aae69b0a04..1962267033d 100644
> --- a/arch/arm/dts/stm32mp157-pinctrl.dtsi
> +++ b/arch/arm/dts/stm32mp157-pinctrl.dtsi
> @@ -173,13 +173,18 @@
>  						 <STM32_PINMUX('C', 2, AF11)>, /* ETH_RGMII_TXD2 */
>  						 <STM32_PINMUX('E', 2, AF11)>, /* ETH_RGMII_TXD3 */
>  						 <STM32_PINMUX('B', 11, AF11)>, /* ETH_RGMII_TX_CTL */
> -						 <STM32_PINMUX('A', 2, AF11)>, /* ETH_MDIO */
>  						 <STM32_PINMUX('C', 1, AF11)>; /* ETH_MDC */
>  					bias-disable;
>  					drive-push-pull;
> -					slew-rate = <3>;
> +					slew-rate = <2>;
>  				};
>  				pins2 {
> +					pinmux = <STM32_PINMUX('A', 2, AF11)>; /* ETH_MDIO */
> +					bias-disable;
> +					drive-push-pull;
> +					slew-rate = <0>;
> +				};
> +				pins3 {
>  					pinmux = <STM32_PINMUX('C', 4, AF11)>, /* ETH_RGMII_RXD0 */
>  						 <STM32_PINMUX('C', 5, AF11)>, /* ETH_RGMII_RXD1 */
>  						 <STM32_PINMUX('B', 0, AF11)>, /* ETH_RGMII_RXD2 */
> diff --git a/arch/arm/dts/stm32mp157c-ev1.dts b/arch/arm/dts/stm32mp157c-ev1.dts
> index a6ee37924fe..d2232004410 100644
> --- a/arch/arm/dts/stm32mp157c-ev1.dts
> +++ b/arch/arm/dts/stm32mp157c-ev1.dts
> @@ -78,7 +78,7 @@
>  	pinctrl-0 = <&ethernet0_rgmii_pins_a>;
>  	pinctrl-1 = <&ethernet0_rgmii_pins_sleep_a>;
>  	pinctrl-names = "default", "sleep";
> -	phy-mode = "rgmii";
> +	phy-mode = "rgmii-id";
>  	max-speed = <1000>;
>  	phy-handle = <&phy0>;
>  
> diff --git a/arch/arm/dts/stm32mp157c.dtsi b/arch/arm/dts/stm32mp157c.dtsi
> index 94634336a5e..82177b50afe 100644
> --- a/arch/arm/dts/stm32mp157c.dtsi
> +++ b/arch/arm/dts/stm32mp157c.dtsi
> @@ -1087,21 +1087,25 @@
>  			compatible = "st,stm32mp1-dwmac", "snps,dwmac-4.20a";
>  			reg = <0x5800a000 0x2000>;
>  			reg-names = "stmmaceth";
> -			interrupts-extended = <&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>;
> -			interrupt-names = "macirq";
> +			interrupts-extended =
> +				<&intc GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
> +				<&intc GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
> +				<&exti 70 1>;
> +			interrupt-names = "macirq",
> +					  "eth_wake_irq",
> +					  "stm32_pwr_wakeup";
>  			clock-names = "stmmaceth",
>  				      "mac-clk-tx",
>  				      "mac-clk-rx",
> -				      "ethstp",
> -				      "syscfg-clk";
> +				      "ethstp";
>  			clocks = <&rcc ETHMAC>,
>  				 <&rcc ETHTX>,
>  				 <&rcc ETHRX>,
> -				 <&rcc ETHSTP>,
> -				 <&rcc SYSCFG>;
> +				 <&rcc ETHSTP>;
>  			st,syscon = <&syscfg 0x4>;
>  			snps,mixed-burst;
>  			snps,pbl = <2>;
> +			snps,en-tx-lpi-clockgating;
>  			snps,axi-config = <&stmmac_axi_config_0>;
>  			snps,tso;
>  			status = "disabled";
> 

Applied

Thanks

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [U-Boot] [PATCH v2 5/6] stm32mp1: Add Ethernet support for stm32mp1 board
  2019-05-17 13:08 ` [U-Boot] [PATCH v2 5/6] stm32mp1: Add Ethernet support for stm32mp1 board Christophe Roullier
@ 2019-06-11  7:35   ` Patrice CHOTARD
  0 siblings, 0 replies; 15+ messages in thread
From: Patrice CHOTARD @ 2019-06-11  7:35 UTC (permalink / raw)
  To: u-boot



On 5/17/19 3:08 PM, Christophe Roullier wrote:
> Add default SERVERIP address
> Enable noncached memory region required by ethernet driver
> Add PXE support
> 
> Signed-off-by: Christophe Roullier <christophe.roullier@st.com>
> ---
> 
> Changes in v2: None
> 
>  include/configs/stm32mp1.h | 12 +++++++++++-
>  1 file changed, 11 insertions(+), 1 deletion(-)
> 
> diff --git a/include/configs/stm32mp1.h b/include/configs/stm32mp1.h
> index fd6c97a0c61..cc14f6169b9 100644
> --- a/include/configs/stm32mp1.h
> +++ b/include/configs/stm32mp1.h
> @@ -78,6 +78,14 @@
>  /*MMC SD*/
>  #define CONFIG_SYS_MMC_MAX_DEVICE	3
>  
> +/* Ethernet need */
> +#ifdef CONFIG_DWC_ETH_QOS
> +#define CONFIG_SYS_NONCACHED_MEMORY	(1 * SZ_1M)	/* 1M */
> +#define CONFIG_SERVERIP                 192.168.1.1
> +#define CONFIG_BOOTP_SERVERIP
> +#define CONFIG_SYS_AUTOLOAD		"no"
> +#endif
> +
>  /*****************************************************************************/
>  #ifdef CONFIG_DISTRO_DEFAULTS
>  /*****************************************************************************/
> @@ -87,7 +95,9 @@
>  #define BOOT_TARGET_DEVICES(func) \
>  	func(MMC, mmc, 1) \
>  	func(MMC, mmc, 0) \
> -	func(MMC, mmc, 2)
> +	func(MMC, mmc, 2) \
> +	func(PXE, pxe, na)
> +
>  /*
>   * bootcmd for stm32mp1:
>   * for serial/usb: execute the stm32prog command
> 

Applied

Thanks

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [U-Boot] [PATCH v2 6/6] configs: stm32mp15: Enable Ethernet feature
  2019-05-17 13:08 ` [U-Boot] [PATCH v2 6/6] configs: stm32mp15: Enable Ethernet feature Christophe Roullier
  2019-06-01 10:53   ` Joe Hershberger
@ 2019-06-11  7:35   ` Patrice CHOTARD
  1 sibling, 0 replies; 15+ messages in thread
From: Patrice CHOTARD @ 2019-06-11  7:35 UTC (permalink / raw)
  To: u-boot



On 5/17/19 3:08 PM, Christophe Roullier wrote:
> This allows to enable Ethernet and use driver for
> Synopsys Ethernet QoS device
> 
> Signed-off-by: Christophe Roullier <christophe.roullier@st.com>
> ---
> 
> Changes in v2:
> -remark from Joe Hershberger to replace "int interface" with "phy_interface_t interface"
>  and manage return values "-1", "0" with PHY_INTERFACE_MODE_NONE and PHY_INTERFACE_MODE_MII
> 
>  configs/stm32mp15_basic_defconfig | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/configs/stm32mp15_basic_defconfig b/configs/stm32mp15_basic_defconfig
> index 0ea9dff43de..7456cc9a163 100644
> --- a/configs/stm32mp15_basic_defconfig
> +++ b/configs/stm32mp15_basic_defconfig
> @@ -55,6 +55,8 @@ CONFIG_LED_GPIO=y
>  CONFIG_DM_MMC=y
>  CONFIG_SUPPORT_EMMC_BOOT=y
>  CONFIG_STM32_SDMMC2=y
> +CONFIG_DM_ETH=y
> +CONFIG_DWC_ETH_QOS=y
>  CONFIG_PHY=y
>  CONFIG_PHY_STM32_USBPHYC=y
>  CONFIG_PINCONF=y
> 

Applied

Thanks

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2019-06-11  7:35 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-17 13:08 [U-Boot] [PATCH v2 0/6] - Add Ethernet support for stm32mpu Christophe Roullier
2019-05-17 13:08 ` [U-Boot] [PATCH v2 1/6] stm32mp1: clk: use the correct identifier for ethck Christophe Roullier
2019-06-11  7:34   ` Patrice CHOTARD
2019-05-17 13:08 ` [U-Boot] [PATCH v2 2/6] board: stm32mp1: Add board_interface_eth_init Christophe Roullier
2019-06-11  7:34   ` Patrice CHOTARD
2019-05-17 13:08 ` [U-Boot] [PATCH v2 3/6] net: dwc_eth_qos: add Ethernet stm32mp1 support Christophe Roullier
2019-06-01 10:58   ` Joe Hershberger
2019-06-11  7:35   ` Patrice CHOTARD
2019-05-17 13:08 ` [U-Boot] [PATCH v2 4/6] ARM: dts: stm32: Add Ethernet support on stm32mp1 Christophe Roullier
2019-06-11  7:35   ` Patrice CHOTARD
2019-05-17 13:08 ` [U-Boot] [PATCH v2 5/6] stm32mp1: Add Ethernet support for stm32mp1 board Christophe Roullier
2019-06-11  7:35   ` Patrice CHOTARD
2019-05-17 13:08 ` [U-Boot] [PATCH v2 6/6] configs: stm32mp15: Enable Ethernet feature Christophe Roullier
2019-06-01 10:53   ` Joe Hershberger
2019-06-11  7:35   ` Patrice CHOTARD

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.