All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/7] rockchip: Add GMAC support for RK3568 and RK3588
@ 2023-10-01 19:17 Jonas Karlman
  2023-10-01 19:17 ` [PATCH v2 1/7] net: dwc_eth_qos: Drop unused rx_pkt from eqos_priv Jonas Karlman
                   ` (6 more replies)
  0 siblings, 7 replies; 15+ messages in thread
From: Jonas Karlman @ 2023-10-01 19:17 UTC (permalink / raw)
  To: Kever Yang, Simon Glass, Philipp Tomsich
  Cc: David Wu, Eugen Hristev, Frank Wunderlich, Nicolas Frattaroli,
	u-boot, Jonas Karlman

This series adds a glue driver, dwc_eth_qos_rockchip, to support GMAC
on RK356x and RK3588.

rk_gmac_ops used in this series has been ported from mainline linux.

Patch 1-3 does some minor cleanup in dwc_eth_qos driver.
Patch 4 add glue driver with RK3568 support.
Patch 5 add support for RK3588 to glue driver.
Patch 6-7 update defconfigs to enable use of the new driver.

Changes in v2:
- Add comment about ported code intentionally left close to 1:1 with linux
- Add lubancat-2-rk3568_defconfig changes
- Add rock5b-rk3588_defconfig changes
- Collect r-b tags

Dependencies:
- "rockchip: Port IO-domain driver for RK3568 from linux" [1]

dhcp and ping commands has been tested on the followin devices:
- RK3566: Quartz64 Model A and SOQuartz on Blade
- RK3568: ROCK 3 Model A
- RK3588: ROCK 5 Model A

This series can also be found at [2].

[1] https://patchwork.ozlabs.org/cover/1823769/
[2] https://github.com/Kwiboo/u-boot-rockchip/commits/rk35xx-gmac-v2

Jonas Karlman (7):
  net: dwc_eth_qos: Drop unused rx_pkt from eqos_priv
  net: dwc_eth_qos: Return error code when start fails
  net: dwc_eth_qos: Stop spam of RX packet not available message
  net: dwc_eth_qos: Add glue driver for GMAC on Rockchip RK3568
  net: dwc_eth_qos_rockchip: Add support for RK3588
  configs: rockchip: Enable ethernet driver on RK356x boards
  configs: rockchip: Enable ethernet driver on RK3588 boards

 configs/evb-rk3568_defconfig              |   6 +-
 configs/evb-rk3588_defconfig              |   5 +-
 configs/lubancat-2-rk3568_defconfig       |   3 +
 configs/nanopi-r5s-rk3568_defconfig       |   3 +
 configs/neu6a-io-rk3588_defconfig         |   2 -
 configs/neu6b-io-rk3588_defconfig         |   2 -
 configs/odroid-m1-rk3568_defconfig        |   3 +
 configs/quartz64-a-rk3566_defconfig       |   3 +
 configs/quartz64-b-rk3566_defconfig       |   3 +
 configs/radxa-cm3-io-rk3566_defconfig     |   6 +-
 configs/rock-3a-rk3568_defconfig          |   5 +-
 configs/rock5a-rk3588s_defconfig          |   5 +-
 configs/rock5b-rk3588_defconfig           |   3 +-
 configs/soquartz-blade-rk3566_defconfig   |   3 +
 configs/soquartz-cm4-rk3566_defconfig     |   3 +
 configs/soquartz-model-a-rk3566_defconfig |   3 +
 drivers/net/Kconfig                       |   8 +
 drivers/net/Makefile                      |   1 +
 drivers/net/dwc_eth_qos.c                 |  33 +-
 drivers/net/dwc_eth_qos.h                 |   3 +-
 drivers/net/dwc_eth_qos_rockchip.c        | 522 ++++++++++++++++++++++
 21 files changed, 590 insertions(+), 35 deletions(-)
 create mode 100644 drivers/net/dwc_eth_qos_rockchip.c

-- 
2.42.0


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

* [PATCH v2 1/7] net: dwc_eth_qos: Drop unused rx_pkt from eqos_priv
  2023-10-01 19:17 [PATCH v2 0/7] rockchip: Add GMAC support for RK3568 and RK3588 Jonas Karlman
@ 2023-10-01 19:17 ` Jonas Karlman
  2023-10-06 20:32   ` Ramon Fried
  2023-10-01 19:17 ` [PATCH v2 2/7] net: dwc_eth_qos: Return error code when start fails Jonas Karlman
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 15+ messages in thread
From: Jonas Karlman @ 2023-10-01 19:17 UTC (permalink / raw)
  To: Kever Yang, Simon Glass, Philipp Tomsich, Joe Hershberger, Ramon Fried
  Cc: David Wu, Eugen Hristev, Frank Wunderlich, Nicolas Frattaroli,
	u-boot, Jonas Karlman

rx_pkt is allocated and not used for anything, remove it.

Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
---
v2:
- Collect r-b tag

 drivers/net/dwc_eth_qos.c | 11 -----------
 drivers/net/dwc_eth_qos.h |  1 -
 2 files changed, 12 deletions(-)

diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
index 1e92bd9ca9c0..555eaee3bbc3 100644
--- a/drivers/net/dwc_eth_qos.c
+++ b/drivers/net/dwc_eth_qos.c
@@ -1314,22 +1314,12 @@ static int eqos_probe_resources_core(struct udevice *dev)
 	}
 	debug("%s: rx_dma_buf=%p\n", __func__, eqos->rx_dma_buf);
 
-	eqos->rx_pkt = malloc(EQOS_MAX_PACKET_SIZE);
-	if (!eqos->rx_pkt) {
-		debug("%s: malloc(rx_pkt) failed\n", __func__);
-		ret = -ENOMEM;
-		goto err_free_rx_dma_buf;
-	}
-	debug("%s: rx_pkt=%p\n", __func__, eqos->rx_pkt);
-
 	eqos->config->ops->eqos_inval_buffer(eqos->rx_dma_buf,
 			EQOS_MAX_PACKET_SIZE * EQOS_DESCRIPTORS_RX);
 
 	debug("%s: OK\n", __func__);
 	return 0;
 
-err_free_rx_dma_buf:
-	free(eqos->rx_dma_buf);
 err_free_tx_dma_buf:
 	free(eqos->tx_dma_buf);
 err_free_descs:
@@ -1348,7 +1338,6 @@ static int eqos_remove_resources_core(struct udevice *dev)
 
 	debug("%s(dev=%p):\n", __func__, dev);
 
-	free(eqos->rx_pkt);
 	free(eqos->rx_dma_buf);
 	free(eqos->tx_dma_buf);
 	eqos_free_descs(eqos->rx_descs);
diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h
index a6b719af809f..06a082da72ef 100644
--- a/drivers/net/dwc_eth_qos.h
+++ b/drivers/net/dwc_eth_qos.h
@@ -273,7 +273,6 @@ struct eqos_priv {
 	unsigned int desc_per_cacheline;
 	void *tx_dma_buf;
 	void *rx_dma_buf;
-	void *rx_pkt;
 	bool started;
 	bool reg_access_ok;
 	bool clk_ck_enabled;
-- 
2.42.0


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

* [PATCH v2 2/7] net: dwc_eth_qos: Return error code when start fails
  2023-10-01 19:17 [PATCH v2 0/7] rockchip: Add GMAC support for RK3568 and RK3588 Jonas Karlman
  2023-10-01 19:17 ` [PATCH v2 1/7] net: dwc_eth_qos: Drop unused rx_pkt from eqos_priv Jonas Karlman
@ 2023-10-01 19:17 ` Jonas Karlman
  2023-10-06 20:32   ` Ramon Fried
  2023-10-01 19:17 ` [PATCH v2 3/7] net: dwc_eth_qos: Stop spam of RX packet not available message Jonas Karlman
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 15+ messages in thread
From: Jonas Karlman @ 2023-10-01 19:17 UTC (permalink / raw)
  To: Kever Yang, Simon Glass, Philipp Tomsich, Joe Hershberger, Ramon Fried
  Cc: David Wu, Eugen Hristev, Frank Wunderlich, Nicolas Frattaroli,
	u-boot, Jonas Karlman

Return error code when phy_connect fails or no link can be established.

Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
---
v2:
- Collect r-b tag

 drivers/net/dwc_eth_qos.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
index 555eaee3bbc3..7565e716823a 100644
--- a/drivers/net/dwc_eth_qos.c
+++ b/drivers/net/dwc_eth_qos.c
@@ -811,6 +811,7 @@ static int eqos_start(struct udevice *dev)
 
 		if (!eqos->phy) {
 			pr_err("phy_connect() failed");
+			ret = -ENODEV;
 			goto err_stop_resets;
 		}
 
@@ -838,6 +839,7 @@ static int eqos_start(struct udevice *dev)
 
 	if (!eqos->phy->link) {
 		pr_err("No link");
+		ret = -EAGAIN;
 		goto err_shutdown_phy;
 	}
 
-- 
2.42.0


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

* [PATCH v2 3/7] net: dwc_eth_qos: Stop spam of RX packet not available message
  2023-10-01 19:17 [PATCH v2 0/7] rockchip: Add GMAC support for RK3568 and RK3588 Jonas Karlman
  2023-10-01 19:17 ` [PATCH v2 1/7] net: dwc_eth_qos: Drop unused rx_pkt from eqos_priv Jonas Karlman
  2023-10-01 19:17 ` [PATCH v2 2/7] net: dwc_eth_qos: Return error code when start fails Jonas Karlman
@ 2023-10-01 19:17 ` Jonas Karlman
  2023-10-06 20:32   ` Ramon Fried
  2023-10-01 19:17 ` [PATCH v2 4/7] net: dwc_eth_qos: Add glue driver for GMAC on Rockchip RK3568 Jonas Karlman
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 15+ messages in thread
From: Jonas Karlman @ 2023-10-01 19:17 UTC (permalink / raw)
  To: Kever Yang, Simon Glass, Philipp Tomsich, Joe Hershberger, Ramon Fried
  Cc: David Wu, Eugen Hristev, Frank Wunderlich, Nicolas Frattaroli,
	u-boot, Jonas Karlman

Remove spam of RX packet not available debug messages when waiting to
receive a packet.

Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
---
v2:
- Collect r-b tag

 drivers/net/dwc_eth_qos.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
index 7565e716823a..24fb3fac1f12 100644
--- a/drivers/net/dwc_eth_qos.c
+++ b/drivers/net/dwc_eth_qos.c
@@ -1193,14 +1193,12 @@ static int eqos_recv(struct udevice *dev, int flags, uchar **packetp)
 	struct eqos_desc *rx_desc;
 	int length;
 
-	debug("%s(dev=%p, flags=%x):\n", __func__, dev, flags);
-
 	rx_desc = eqos_get_desc(eqos, eqos->rx_desc_idx, true);
 	eqos->config->ops->eqos_inval_desc(rx_desc);
-	if (rx_desc->des3 & EQOS_DESC3_OWN) {
-		debug("%s: RX packet not available\n", __func__);
+	if (rx_desc->des3 & EQOS_DESC3_OWN)
 		return -EAGAIN;
-	}
+
+	debug("%s(dev=%p, flags=%x):\n", __func__, dev, flags);
 
 	*packetp = eqos->rx_dma_buf +
 		(eqos->rx_desc_idx * EQOS_MAX_PACKET_SIZE);
-- 
2.42.0


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

* [PATCH v2 4/7] net: dwc_eth_qos: Add glue driver for GMAC on Rockchip RK3568
  2023-10-01 19:17 [PATCH v2 0/7] rockchip: Add GMAC support for RK3568 and RK3588 Jonas Karlman
                   ` (2 preceding siblings ...)
  2023-10-01 19:17 ` [PATCH v2 3/7] net: dwc_eth_qos: Stop spam of RX packet not available message Jonas Karlman
@ 2023-10-01 19:17 ` Jonas Karlman
  2023-10-06 20:33   ` Ramon Fried
  2023-10-01 19:17 ` [PATCH v2 5/7] net: dwc_eth_qos_rockchip: Add support for RK3588 Jonas Karlman
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 15+ messages in thread
From: Jonas Karlman @ 2023-10-01 19:17 UTC (permalink / raw)
  To: Kever Yang, Simon Glass, Philipp Tomsich, Joe Hershberger, Ramon Fried
  Cc: David Wu, Eugen Hristev, Frank Wunderlich, Nicolas Frattaroli,
	u-boot, Jonas Karlman, Ezequiel Garcia

Add a new glue driver for Rockchip SoCs, i.e RK3568, with a GMAC based
on Synopsys DWC Ethernet QoS IP.

rk_gmac_ops was ported from linux commit:
3bb3d6b1c195 ("net: stmmac: Add RK3566/RK3568 SoC support")

Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
---
Cc: David Wu <david.wu@rock-chips.com>
Cc: Ezequiel Garcia <ezequiel@collabora.com>
---
v2:
- Add comment about ported code intentionally left close to 1:1 with linux
- Collect r-b tag

 drivers/net/Kconfig                |   8 +
 drivers/net/Makefile               |   1 +
 drivers/net/dwc_eth_qos.c          |   8 +-
 drivers/net/dwc_eth_qos.h          |   2 +
 drivers/net/dwc_eth_qos_rockchip.c | 357 +++++++++++++++++++++++++++++
 5 files changed, 374 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/dwc_eth_qos_rockchip.c

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 0ed39a61e4de..29304fd77759 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -225,6 +225,14 @@ config DWC_ETH_QOS_IMX
 	  The Synopsys Designware Ethernet QOS IP block with the specific
 	  configuration used in IMX soc.
 
+config DWC_ETH_QOS_ROCKCHIP
+	bool "Synopsys DWC Ethernet QOS device support for Rockchip SoCs"
+	depends on DWC_ETH_QOS
+	select DM_ETH_PHY
+	help
+	  The Synopsys Designware Ethernet QOS IP block with specific
+	  configuration used in Rockchip SoCs.
+
 config DWC_ETH_QOS_STM32
 	bool "Synopsys DWC Ethernet QOS device support for STM32"
 	depends on DWC_ETH_QOS
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index d4af253b6f28..1d444f5b4a69 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -20,6 +20,7 @@ obj-$(CONFIG_DRIVER_DM9000) += dm9000x.o
 obj-$(CONFIG_DSA_SANDBOX) += dsa_sandbox.o
 obj-$(CONFIG_DWC_ETH_QOS) += dwc_eth_qos.o
 obj-$(CONFIG_DWC_ETH_QOS_IMX) += dwc_eth_qos_imx.o
+obj-$(CONFIG_DWC_ETH_QOS_ROCKCHIP) += dwc_eth_qos_rockchip.o
 obj-$(CONFIG_DWC_ETH_QOS_QCOM) += dwc_eth_qos_qcom.o
 obj-$(CONFIG_DWC_ETH_QOS_STARFIVE) += dwc_eth_qos_starfive.o
 obj-$(CONFIG_E1000) += e1000.o
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
index 24fb3fac1f12..9fb98a2c3c74 100644
--- a/drivers/net/dwc_eth_qos.c
+++ b/drivers/net/dwc_eth_qos.c
@@ -1707,7 +1707,12 @@ static const struct udevice_id eqos_ids[] = {
 		.data = (ulong)&eqos_imx_config
 	},
 #endif
-
+#if IS_ENABLED(CONFIG_DWC_ETH_QOS_ROCKCHIP)
+	{
+		.compatible = "rockchip,rk3568-gmac",
+		.data = (ulong)&eqos_rockchip_config
+	},
+#endif
 #if IS_ENABLED(CONFIG_DWC_ETH_QOS_QCOM)
 	{
 		.compatible = "qcom,qcs404-ethqos",
@@ -1720,7 +1725,6 @@ static const struct udevice_id eqos_ids[] = {
 		.data = (ulong)&eqos_jh7110_config
 	},
 #endif
-
 	{ }
 };
 
diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h
index 06a082da72ef..e3222e1e17e5 100644
--- a/drivers/net/dwc_eth_qos.h
+++ b/drivers/net/dwc_eth_qos.h
@@ -82,6 +82,7 @@ struct eqos_mac_regs {
 #define EQOS_MAC_MDIO_ADDRESS_PA_SHIFT			21
 #define EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT			16
 #define EQOS_MAC_MDIO_ADDRESS_CR_SHIFT			8
+#define EQOS_MAC_MDIO_ADDRESS_CR_100_150		1
 #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)
@@ -287,5 +288,6 @@ void eqos_flush_buffer_generic(void *buf, size_t size);
 int eqos_null_ops(struct udevice *dev);
 
 extern struct eqos_config eqos_imx_config;
+extern struct eqos_config eqos_rockchip_config;
 extern struct eqos_config eqos_qcom_config;
 extern struct eqos_config eqos_jh7110_config;
diff --git a/drivers/net/dwc_eth_qos_rockchip.c b/drivers/net/dwc_eth_qos_rockchip.c
new file mode 100644
index 000000000000..05edc098f50d
--- /dev/null
+++ b/drivers/net/dwc_eth_qos_rockchip.c
@@ -0,0 +1,357 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright Contributors to the U-Boot project.
+ *
+ * rk_gmac_ops ported from linux drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+ *
+ * Ported code is intentionally left as close as possible with linux counter
+ * part in order to simplify future porting of fixes and support for other SoCs.
+ */
+
+#include <common.h>
+#include <clk.h>
+#include <dm.h>
+#include <dm/device_compat.h>
+#include <net.h>
+#include <phy.h>
+#include <regmap.h>
+#include <reset.h>
+#include <syscon.h>
+#include <asm/gpio.h>
+#include <linux/delay.h>
+
+#include "dwc_eth_qos.h"
+
+struct rk_gmac_ops {
+	const char *compatible;
+	int (*set_to_rgmii)(struct udevice *dev,
+			    int tx_delay, int rx_delay);
+	int (*set_to_rmii)(struct udevice *dev);
+	int (*set_gmac_speed)(struct udevice *dev);
+	u32 regs[3];
+};
+
+struct rockchip_platform_data {
+	struct reset_ctl_bulk resets;
+	const struct rk_gmac_ops *ops;
+	int id;
+	struct regmap *grf;
+};
+
+#define HIWORD_UPDATE(val, mask, shift) \
+		((val) << (shift) | (mask) << ((shift) + 16))
+
+#define GRF_BIT(nr)	(BIT(nr) | BIT((nr) + 16))
+#define GRF_CLR_BIT(nr)	(BIT((nr) + 16))
+
+#define RK3568_GRF_GMAC0_CON0		0x0380
+#define RK3568_GRF_GMAC0_CON1		0x0384
+#define RK3568_GRF_GMAC1_CON0		0x0388
+#define RK3568_GRF_GMAC1_CON1		0x038c
+
+/* RK3568_GRF_GMAC0_CON1 && RK3568_GRF_GMAC1_CON1 */
+#define RK3568_GMAC_PHY_INTF_SEL_RGMII	\
+		(GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
+#define RK3568_GMAC_PHY_INTF_SEL_RMII	\
+		(GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
+#define RK3568_GMAC_FLOW_CTRL			GRF_BIT(3)
+#define RK3568_GMAC_FLOW_CTRL_CLR		GRF_CLR_BIT(3)
+#define RK3568_GMAC_RXCLK_DLY_ENABLE		GRF_BIT(1)
+#define RK3568_GMAC_RXCLK_DLY_DISABLE		GRF_CLR_BIT(1)
+#define RK3568_GMAC_TXCLK_DLY_ENABLE		GRF_BIT(0)
+#define RK3568_GMAC_TXCLK_DLY_DISABLE		GRF_CLR_BIT(0)
+
+/* RK3568_GRF_GMAC0_CON0 && RK3568_GRF_GMAC1_CON0 */
+#define RK3568_GMAC_CLK_RX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 8)
+#define RK3568_GMAC_CLK_TX_DL_CFG(val)	HIWORD_UPDATE(val, 0x7F, 0)
+
+static int rk3568_set_to_rgmii(struct udevice *dev,
+			       int tx_delay, int rx_delay)
+{
+	struct eth_pdata *pdata = dev_get_plat(dev);
+	struct rockchip_platform_data *data = pdata->priv_pdata;
+	u32 con0, con1;
+
+	con0 = (data->id == 1) ? RK3568_GRF_GMAC1_CON0 :
+				 RK3568_GRF_GMAC0_CON0;
+	con1 = (data->id == 1) ? RK3568_GRF_GMAC1_CON1 :
+				 RK3568_GRF_GMAC0_CON1;
+
+	regmap_write(data->grf, con0,
+		     RK3568_GMAC_CLK_RX_DL_CFG(rx_delay) |
+		     RK3568_GMAC_CLK_TX_DL_CFG(tx_delay));
+
+	regmap_write(data->grf, con1,
+		     RK3568_GMAC_PHY_INTF_SEL_RGMII |
+		     RK3568_GMAC_RXCLK_DLY_ENABLE |
+		     RK3568_GMAC_TXCLK_DLY_ENABLE);
+
+	return 0;
+}
+
+static int rk3568_set_to_rmii(struct udevice *dev)
+{
+	struct eth_pdata *pdata = dev_get_plat(dev);
+	struct rockchip_platform_data *data = pdata->priv_pdata;
+	u32 con1;
+
+	con1 = (data->id == 1) ? RK3568_GRF_GMAC1_CON1 :
+				 RK3568_GRF_GMAC0_CON1;
+	regmap_write(data->grf, con1, RK3568_GMAC_PHY_INTF_SEL_RMII);
+
+	return 0;
+}
+
+static int rk3568_set_gmac_speed(struct udevice *dev)
+{
+	struct eqos_priv *eqos = dev_get_priv(dev);
+	ulong rate;
+	int ret;
+
+	switch (eqos->phy->speed) {
+	case SPEED_10:
+		rate = 2500000;
+		break;
+	case SPEED_100:
+		rate = 25000000;
+		break;
+	case SPEED_1000:
+		rate = 125000000;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	ret = clk_set_rate(&eqos->clk_tx, rate);
+	if (ret < 0)
+		return ret;
+
+	return 0;
+}
+
+static const struct rk_gmac_ops rk_gmac_ops[] = {
+	{
+		.compatible = "rockchip,rk3568-gmac",
+		.set_to_rgmii = rk3568_set_to_rgmii,
+		.set_to_rmii = rk3568_set_to_rmii,
+		.set_gmac_speed = rk3568_set_gmac_speed,
+		.regs = {
+			0xfe2a0000, /* gmac0 */
+			0xfe010000, /* gmac1 */
+			0x0, /* sentinel */
+		},
+	},
+	{ }
+};
+
+static const struct rk_gmac_ops *get_rk_gmac_ops(struct udevice *dev)
+{
+	const struct rk_gmac_ops *ops = rk_gmac_ops;
+
+	while (ops->compatible) {
+		if (device_is_compatible(dev, ops->compatible))
+			return ops;
+		ops++;
+	}
+
+	return NULL;
+}
+
+static int eqos_probe_resources_rk(struct udevice *dev)
+{
+	struct eqos_priv *eqos = dev_get_priv(dev);
+	struct eth_pdata *pdata = dev_get_plat(dev);
+	struct rockchip_platform_data *data;
+	int reset_flags = GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE;
+	int ret;
+
+	data = calloc(1, sizeof(struct rockchip_platform_data));
+	if (!data)
+		return -ENOMEM;
+
+	data->ops = get_rk_gmac_ops(dev);
+	if (!data->ops) {
+		ret = -EINVAL;
+		goto err_free;
+	}
+
+	for (int i = 0; data->ops->regs[i]; i++) {
+		if (data->ops->regs[i] == (u32)eqos->regs) {
+			data->id = i;
+			break;
+		}
+	}
+
+	pdata->priv_pdata = data;
+	pdata->phy_interface = eqos->config->interface(dev);
+	pdata->max_speed = eqos->max_speed;
+
+	if (pdata->phy_interface == PHY_INTERFACE_MODE_NA) {
+		pr_err("Invalid PHY interface\n");
+		ret = -EINVAL;
+		goto err_free;
+	}
+
+	data->grf = syscon_regmap_lookup_by_phandle(dev, "rockchip,grf");
+	if (IS_ERR(data->grf)) {
+		dev_err(dev, "Missing rockchip,grf property\n");
+		ret = -EINVAL;
+		goto err_free;
+	}
+
+	ret = reset_get_bulk(dev, &data->resets);
+	if (ret < 0)
+		goto err_free;
+
+	reset_assert_bulk(&data->resets);
+
+	ret = clk_get_by_name(dev, "stmmaceth", &eqos->clk_master_bus);
+	if (ret) {
+		dev_dbg(dev, "clk_get_by_name(stmmaceth) failed: %d", ret);
+		goto err_release_resets;
+	}
+
+	ret = clk_get_by_name(dev, "clk_mac_speed", &eqos->clk_tx);
+	if (ret) {
+		dev_dbg(dev, "clk_get_by_name(clk_mac_speed) failed: %d", ret);
+		goto err_free_clk_master_bus;
+	}
+
+	/* snps,reset props are deprecated, do bare minimum to support them */
+	if (dev_read_bool(dev, "snps,reset-active-low"))
+		reset_flags |= GPIOD_ACTIVE_LOW;
+
+	dev_read_u32_array(dev, "snps,reset-delays-us", eqos->reset_delays, 3);
+
+	gpio_request_by_name(dev, "snps,reset-gpio", 0,
+			     &eqos->phy_reset_gpio, reset_flags);
+
+	return 0;
+
+err_free_clk_master_bus:
+	clk_free(&eqos->clk_master_bus);
+err_release_resets:
+	reset_release_bulk(&data->resets);
+err_free:
+	free(data);
+
+	return ret;
+}
+
+static int eqos_remove_resources_rk(struct udevice *dev)
+{
+	struct eqos_priv *eqos = dev_get_priv(dev);
+	struct eth_pdata *pdata = dev_get_plat(dev);
+	struct rockchip_platform_data *data = pdata->priv_pdata;
+
+	if (dm_gpio_is_valid(&eqos->phy_reset_gpio))
+		dm_gpio_free(dev, &eqos->phy_reset_gpio);
+
+	clk_free(&eqos->clk_tx);
+	clk_free(&eqos->clk_master_bus);
+	reset_release_bulk(&data->resets);
+	free(data);
+
+	return 0;
+}
+
+static int eqos_stop_resets_rk(struct udevice *dev)
+{
+	struct eth_pdata *pdata = dev_get_plat(dev);
+	struct rockchip_platform_data *data = pdata->priv_pdata;
+
+	return reset_assert_bulk(&data->resets);
+}
+
+static int eqos_start_resets_rk(struct udevice *dev)
+{
+	struct eth_pdata *pdata = dev_get_plat(dev);
+	struct rockchip_platform_data *data = pdata->priv_pdata;
+
+	return reset_deassert_bulk(&data->resets);
+}
+
+static int eqos_stop_clks_rk(struct udevice *dev)
+{
+	return 0;
+}
+
+static int eqos_start_clks_rk(struct udevice *dev)
+{
+	struct eqos_priv *eqos = dev_get_priv(dev);
+	struct eth_pdata *pdata = dev_get_plat(dev);
+	struct rockchip_platform_data *data = pdata->priv_pdata;
+	int tx_delay, rx_delay, ret;
+
+	if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) {
+		udelay(eqos->reset_delays[1]);
+
+		ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 0);
+		if (ret < 0)
+			return ret;
+
+		udelay(eqos->reset_delays[2]);
+	}
+
+	tx_delay = dev_read_u32_default(dev, "tx_delay", 0x30);
+	rx_delay = dev_read_u32_default(dev, "rx_delay", 0x10);
+
+	switch (pdata->phy_interface) {
+	case PHY_INTERFACE_MODE_RGMII:
+		return data->ops->set_to_rgmii(dev, tx_delay, rx_delay);
+	case PHY_INTERFACE_MODE_RGMII_ID:
+		return data->ops->set_to_rgmii(dev, 0, 0);
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+		return data->ops->set_to_rgmii(dev, tx_delay, 0);
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+		return data->ops->set_to_rgmii(dev, 0, rx_delay);
+	case PHY_INTERFACE_MODE_RMII:
+		return data->ops->set_to_rmii(dev);
+	}
+
+	return -EINVAL;
+}
+
+static int eqos_set_tx_clk_speed_rk(struct udevice *dev)
+{
+	struct eth_pdata *pdata = dev_get_plat(dev);
+	struct rockchip_platform_data *data = pdata->priv_pdata;
+
+	return data->ops->set_gmac_speed(dev);
+}
+
+static ulong eqos_get_tick_clk_rate_rk(struct udevice *dev)
+{
+	struct eqos_priv *eqos = dev_get_priv(dev);
+
+	return clk_get_rate(&eqos->clk_master_bus);
+}
+
+static struct eqos_ops eqos_rockchip_ops = {
+	.eqos_inval_desc = eqos_inval_desc_generic,
+	.eqos_flush_desc = eqos_flush_desc_generic,
+	.eqos_inval_buffer = eqos_inval_buffer_generic,
+	.eqos_flush_buffer = eqos_flush_buffer_generic,
+	.eqos_probe_resources = eqos_probe_resources_rk,
+	.eqos_remove_resources = eqos_remove_resources_rk,
+	.eqos_stop_resets = eqos_stop_resets_rk,
+	.eqos_start_resets = eqos_start_resets_rk,
+	.eqos_stop_clks = eqos_stop_clks_rk,
+	.eqos_start_clks = eqos_start_clks_rk,
+	.eqos_calibrate_pads = eqos_null_ops,
+	.eqos_disable_calibration = eqos_null_ops,
+	.eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_rk,
+	.eqos_get_enetaddr = eqos_null_ops,
+	.eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_rk,
+};
+
+struct eqos_config eqos_rockchip_config = {
+	.reg_access_always_ok = false,
+	.mdio_wait = 10,
+	.swr_wait = 50,
+	.config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB,
+	.config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_100_150,
+	.axi_bus_width = EQOS_AXI_WIDTH_64,
+	.interface = dev_read_phy_mode,
+	.ops = &eqos_rockchip_ops,
+};
-- 
2.42.0


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

* [PATCH v2 5/7] net: dwc_eth_qos_rockchip: Add support for RK3588
  2023-10-01 19:17 [PATCH v2 0/7] rockchip: Add GMAC support for RK3568 and RK3588 Jonas Karlman
                   ` (3 preceding siblings ...)
  2023-10-01 19:17 ` [PATCH v2 4/7] net: dwc_eth_qos: Add glue driver for GMAC on Rockchip RK3568 Jonas Karlman
@ 2023-10-01 19:17 ` Jonas Karlman
  2023-10-01 20:04   ` Sebastian Reichel
                     ` (2 more replies)
  2023-10-01 19:17 ` [PATCH v2 6/7] configs: rockchip: Enable ethernet driver on RK356x boards Jonas Karlman
  2023-10-01 19:17 ` [PATCH v2 7/7] configs: rockchip: Enable ethernet driver on RK3588 boards Jonas Karlman
  6 siblings, 3 replies; 15+ messages in thread
From: Jonas Karlman @ 2023-10-01 19:17 UTC (permalink / raw)
  To: Kever Yang, Simon Glass, Philipp Tomsich, Joe Hershberger, Ramon Fried
  Cc: David Wu, Eugen Hristev, Frank Wunderlich, Nicolas Frattaroli,
	u-boot, Jonas Karlman, Sebastian Reichel, Benjamin Gaignard

Add rk_gmac_ops and other special handling that is needed for GMAC to
work on RK3588.

rk_gmac_ops was ported from linux commits:
2f2b60a0ec28 ("net: ethernet: stmmac: dwmac-rk: Add gmac support for rk3588")
88619e77b33d ("net: stmmac: rk3588: Allow multiple gmac controller")

Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
---
Cc: David Wu <david.wu@rock-chips.com>
Cc: Sebastian Reichel <sebastian.reichel@collabora.com>
Cc: Benjamin Gaignard <benjamin.gaignard@collabora.com>
---
v2:
- Collect r-b tag

 drivers/net/dwc_eth_qos.c          |   4 +
 drivers/net/dwc_eth_qos_rockchip.c | 182 ++++++++++++++++++++++++++++-
 2 files changed, 182 insertions(+), 4 deletions(-)

diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
index 9fb98a2c3c74..dc04416865dd 100644
--- a/drivers/net/dwc_eth_qos.c
+++ b/drivers/net/dwc_eth_qos.c
@@ -1712,6 +1712,10 @@ static const struct udevice_id eqos_ids[] = {
 		.compatible = "rockchip,rk3568-gmac",
 		.data = (ulong)&eqos_rockchip_config
 	},
+	{
+		.compatible = "rockchip,rk3588-gmac",
+		.data = (ulong)&eqos_rockchip_config
+	},
 #endif
 #if IS_ENABLED(CONFIG_DWC_ETH_QOS_QCOM)
 	{
diff --git a/drivers/net/dwc_eth_qos_rockchip.c b/drivers/net/dwc_eth_qos_rockchip.c
index 05edc098f50d..20fd3a25c3dd 100644
--- a/drivers/net/dwc_eth_qos_rockchip.c
+++ b/drivers/net/dwc_eth_qos_rockchip.c
@@ -28,6 +28,7 @@ struct rk_gmac_ops {
 			    int tx_delay, int rx_delay);
 	int (*set_to_rmii)(struct udevice *dev);
 	int (*set_gmac_speed)(struct udevice *dev);
+	void (*set_clock_selection)(struct udevice *dev, bool enable);
 	u32 regs[3];
 };
 
@@ -35,7 +36,9 @@ struct rockchip_platform_data {
 	struct reset_ctl_bulk resets;
 	const struct rk_gmac_ops *ops;
 	int id;
+	bool clock_input;
 	struct regmap *grf;
+	struct regmap *php_grf;
 };
 
 #define HIWORD_UPDATE(val, mask, shift) \
@@ -129,6 +132,137 @@ static int rk3568_set_gmac_speed(struct udevice *dev)
 	return 0;
 }
 
+/* sys_grf */
+#define RK3588_GRF_GMAC_CON7			0x031c
+#define RK3588_GRF_GMAC_CON8			0x0320
+#define RK3588_GRF_GMAC_CON9			0x0324
+
+#define RK3588_GMAC_RXCLK_DLY_ENABLE(id)	GRF_BIT(2 * (id) + 3)
+#define RK3588_GMAC_RXCLK_DLY_DISABLE(id)	GRF_CLR_BIT(2 * (id) + 3)
+#define RK3588_GMAC_TXCLK_DLY_ENABLE(id)	GRF_BIT(2 * (id) + 2)
+#define RK3588_GMAC_TXCLK_DLY_DISABLE(id)	GRF_CLR_BIT(2 * (id) + 2)
+
+#define RK3588_GMAC_CLK_RX_DL_CFG(val)		HIWORD_UPDATE(val, 0xFF, 8)
+#define RK3588_GMAC_CLK_TX_DL_CFG(val)		HIWORD_UPDATE(val, 0xFF, 0)
+
+/* php_grf */
+#define RK3588_GRF_GMAC_CON0			0x0008
+#define RK3588_GRF_CLK_CON1			0x0070
+
+#define RK3588_GMAC_PHY_INTF_SEL_RGMII(id)	\
+	(GRF_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_CLR_BIT(5 + (id) * 6))
+#define RK3588_GMAC_PHY_INTF_SEL_RMII(id)	\
+	(GRF_CLR_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_BIT(5 + (id) * 6))
+
+#define RK3588_GMAC_CLK_RMII_MODE(id)		GRF_BIT(5 * (id))
+#define RK3588_GMAC_CLK_RGMII_MODE(id)		GRF_CLR_BIT(5 * (id))
+
+#define RK3588_GMAC_CLK_SELET_CRU(id)		GRF_BIT(5 * (id) + 4)
+#define RK3588_GMAC_CLK_SELET_IO(id)		GRF_CLR_BIT(5 * (id) + 4)
+
+#define RK3588_GMAC_CLK_RMII_DIV2(id)		GRF_BIT(5 * (id) + 2)
+#define RK3588_GMAC_CLK_RMII_DIV20(id)		GRF_CLR_BIT(5 * (id) + 2)
+
+#define RK3588_GMAC_CLK_RGMII_DIV1(id)		\
+			(GRF_CLR_BIT(5 * (id) + 2) | GRF_CLR_BIT(5 * (id) + 3))
+#define RK3588_GMAC_CLK_RGMII_DIV5(id)		\
+			(GRF_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3))
+#define RK3588_GMAC_CLK_RGMII_DIV50(id)		\
+			(GRF_CLR_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3))
+
+#define RK3588_GMAC_CLK_RMII_GATE(id)		GRF_BIT(5 * (id) + 1)
+#define RK3588_GMAC_CLK_RMII_NOGATE(id)		GRF_CLR_BIT(5 * (id) + 1)
+
+static int rk3588_set_to_rgmii(struct udevice *dev,
+			       int tx_delay, int rx_delay)
+{
+	struct eth_pdata *pdata = dev_get_plat(dev);
+	struct rockchip_platform_data *data = pdata->priv_pdata;
+	u32 offset_con, id = data->id;
+
+	offset_con = data->id == 1 ? RK3588_GRF_GMAC_CON9 :
+				     RK3588_GRF_GMAC_CON8;
+
+	regmap_write(data->php_grf, RK3588_GRF_GMAC_CON0,
+		     RK3588_GMAC_PHY_INTF_SEL_RGMII(id));
+
+	regmap_write(data->php_grf, RK3588_GRF_CLK_CON1,
+		     RK3588_GMAC_CLK_RGMII_MODE(id));
+
+	regmap_write(data->grf, RK3588_GRF_GMAC_CON7,
+		     RK3588_GMAC_RXCLK_DLY_ENABLE(id) |
+		     RK3588_GMAC_TXCLK_DLY_ENABLE(id));
+
+	regmap_write(data->grf, offset_con,
+		     RK3588_GMAC_CLK_RX_DL_CFG(rx_delay) |
+		     RK3588_GMAC_CLK_TX_DL_CFG(tx_delay));
+
+	return 0;
+}
+
+static int rk3588_set_to_rmii(struct udevice *dev)
+{
+	struct eth_pdata *pdata = dev_get_plat(dev);
+	struct rockchip_platform_data *data = pdata->priv_pdata;
+
+	regmap_write(data->php_grf, RK3588_GRF_GMAC_CON0,
+		     RK3588_GMAC_PHY_INTF_SEL_RMII(data->id));
+
+	regmap_write(data->php_grf, RK3588_GRF_CLK_CON1,
+		     RK3588_GMAC_CLK_RMII_MODE(data->id));
+
+	return 0;
+}
+
+static int rk3588_set_gmac_speed(struct udevice *dev)
+{
+	struct eqos_priv *eqos = dev_get_priv(dev);
+	struct eth_pdata *pdata = dev_get_plat(dev);
+	struct rockchip_platform_data *data = pdata->priv_pdata;
+	u32 val = 0, id = data->id;
+
+	switch (eqos->phy->speed) {
+	case SPEED_10:
+		if (pdata->phy_interface == PHY_INTERFACE_MODE_RMII)
+			val = RK3588_GMAC_CLK_RMII_DIV20(id);
+		else
+			val = RK3588_GMAC_CLK_RGMII_DIV50(id);
+		break;
+	case SPEED_100:
+		if (pdata->phy_interface == PHY_INTERFACE_MODE_RMII)
+			val = RK3588_GMAC_CLK_RMII_DIV2(id);
+		else
+			val = RK3588_GMAC_CLK_RGMII_DIV5(id);
+		break;
+	case SPEED_1000:
+		if (pdata->phy_interface != PHY_INTERFACE_MODE_RMII)
+			val = RK3588_GMAC_CLK_RGMII_DIV1(id);
+		else
+			return -EINVAL;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	regmap_write(data->php_grf, RK3588_GRF_CLK_CON1, val);
+
+	return 0;
+}
+
+static void rk3588_set_clock_selection(struct udevice *dev, bool enable)
+{
+	struct eth_pdata *pdata = dev_get_plat(dev);
+	struct rockchip_platform_data *data = pdata->priv_pdata;
+
+	u32 val = data->clock_input ? RK3588_GMAC_CLK_SELET_IO(data->id) :
+				      RK3588_GMAC_CLK_SELET_CRU(data->id);
+
+	val |= enable ? RK3588_GMAC_CLK_RMII_NOGATE(data->id) :
+			RK3588_GMAC_CLK_RMII_GATE(data->id);
+
+	regmap_write(data->php_grf, RK3588_GRF_CLK_CON1, val);
+}
+
 static const struct rk_gmac_ops rk_gmac_ops[] = {
 	{
 		.compatible = "rockchip,rk3568-gmac",
@@ -141,6 +275,18 @@ static const struct rk_gmac_ops rk_gmac_ops[] = {
 			0x0, /* sentinel */
 		},
 	},
+	{
+		.compatible = "rockchip,rk3588-gmac",
+		.set_to_rgmii = rk3588_set_to_rgmii,
+		.set_to_rmii = rk3588_set_to_rmii,
+		.set_gmac_speed = rk3588_set_gmac_speed,
+		.set_clock_selection = rk3588_set_clock_selection,
+		.regs = {
+			0xfe1b0000, /* gmac0 */
+			0xfe1c0000, /* gmac1 */
+			0x0, /* sentinel */
+		},
+	},
 	{ }
 };
 
@@ -162,6 +308,7 @@ static int eqos_probe_resources_rk(struct udevice *dev)
 	struct eqos_priv *eqos = dev_get_priv(dev);
 	struct eth_pdata *pdata = dev_get_plat(dev);
 	struct rockchip_platform_data *data;
+	const char *clock_in_out;
 	int reset_flags = GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE;
 	int ret;
 
@@ -199,6 +346,16 @@ static int eqos_probe_resources_rk(struct udevice *dev)
 		goto err_free;
 	}
 
+	if (device_is_compatible(dev, "rockchip,rk3588-gmac")) {
+		data->php_grf =
+			syscon_regmap_lookup_by_phandle(dev, "rockchip,php-grf");
+		if (IS_ERR(data->php_grf)) {
+			dev_err(dev, "Missing rockchip,php-grf property\n");
+			ret = -EINVAL;
+			goto err_free;
+		}
+	}
+
 	ret = reset_get_bulk(dev, &data->resets);
 	if (ret < 0)
 		goto err_free;
@@ -211,12 +368,20 @@ static int eqos_probe_resources_rk(struct udevice *dev)
 		goto err_release_resets;
 	}
 
-	ret = clk_get_by_name(dev, "clk_mac_speed", &eqos->clk_tx);
-	if (ret) {
-		dev_dbg(dev, "clk_get_by_name(clk_mac_speed) failed: %d", ret);
-		goto err_free_clk_master_bus;
+	if (device_is_compatible(dev, "rockchip,rk3568-gmac")) {
+		ret = clk_get_by_name(dev, "clk_mac_speed", &eqos->clk_tx);
+		if (ret) {
+			dev_dbg(dev, "clk_get_by_name(clk_mac_speed) failed: %d", ret);
+			goto err_free_clk_master_bus;
+		}
 	}
 
+	clock_in_out = dev_read_string(dev, "clock_in_out");
+	if (clock_in_out && !strcmp(clock_in_out, "input"))
+		data->clock_input = true;
+	else
+		data->clock_input = false;
+
 	/* snps,reset props are deprecated, do bare minimum to support them */
 	if (dev_read_bool(dev, "snps,reset-active-low"))
 		reset_flags |= GPIOD_ACTIVE_LOW;
@@ -273,6 +438,12 @@ static int eqos_start_resets_rk(struct udevice *dev)
 
 static int eqos_stop_clks_rk(struct udevice *dev)
 {
+	struct eth_pdata *pdata = dev_get_plat(dev);
+	struct rockchip_platform_data *data = pdata->priv_pdata;
+
+	if (data->ops->set_clock_selection)
+		data->ops->set_clock_selection(dev, false);
+
 	return 0;
 }
 
@@ -293,6 +464,9 @@ static int eqos_start_clks_rk(struct udevice *dev)
 		udelay(eqos->reset_delays[2]);
 	}
 
+	if (data->ops->set_clock_selection)
+		data->ops->set_clock_selection(dev, true);
+
 	tx_delay = dev_read_u32_default(dev, "tx_delay", 0x30);
 	rx_delay = dev_read_u32_default(dev, "rx_delay", 0x10);
 
-- 
2.42.0


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

* [PATCH v2 6/7] configs: rockchip: Enable ethernet driver on RK356x boards
  2023-10-01 19:17 [PATCH v2 0/7] rockchip: Add GMAC support for RK3568 and RK3588 Jonas Karlman
                   ` (4 preceding siblings ...)
  2023-10-01 19:17 ` [PATCH v2 5/7] net: dwc_eth_qos_rockchip: Add support for RK3588 Jonas Karlman
@ 2023-10-01 19:17 ` Jonas Karlman
  2023-10-01 19:17 ` [PATCH v2 7/7] configs: rockchip: Enable ethernet driver on RK3588 boards Jonas Karlman
  6 siblings, 0 replies; 15+ messages in thread
From: Jonas Karlman @ 2023-10-01 19:17 UTC (permalink / raw)
  To: Kever Yang, Simon Glass, Philipp Tomsich, Joseph Chen, Andy Yan,
	Tianling Shen, Jonas Karlman, Nicolas Frattaroli, Jagan Teki,
	Akash Gajjar
  Cc: David Wu, Eugen Hristev, Frank Wunderlich, u-boot

Enable DWC_ETH_QOS_ROCKCHIP and related PHY driver on RK356x boards that
have an enabled gmac node.

Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
---
v2:
- Collect r-b tag
- Update evb-rk3568_defconfig changes
- Add lubancat-2-rk3568_defconfig changes

 configs/evb-rk3568_defconfig              | 6 ++++--
 configs/lubancat-2-rk3568_defconfig       | 3 +++
 configs/nanopi-r5s-rk3568_defconfig       | 3 +++
 configs/odroid-m1-rk3568_defconfig        | 3 +++
 configs/quartz64-a-rk3566_defconfig       | 3 +++
 configs/quartz64-b-rk3566_defconfig       | 3 +++
 configs/radxa-cm3-io-rk3566_defconfig     | 6 ++++--
 configs/rock-3a-rk3568_defconfig          | 5 +++--
 configs/soquartz-blade-rk3566_defconfig   | 3 +++
 configs/soquartz-cm4-rk3566_defconfig     | 3 +++
 configs/soquartz-model-a-rk3566_defconfig | 3 +++
 11 files changed, 35 insertions(+), 6 deletions(-)

diff --git a/configs/evb-rk3568_defconfig b/configs/evb-rk3568_defconfig
index 5f3fab7304c2..cb9b87ff12cb 100644
--- a/configs/evb-rk3568_defconfig
+++ b/configs/evb-rk3568_defconfig
@@ -46,6 +46,7 @@ CONFIG_CMD_REGULATOR=y
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_OF_LIVE=y
 CONFIG_OF_SPL_REMOVE_PROPS="pinctrl-0 pinctrl-names clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_SPL_REGMAP=y
 CONFIG_SPL_SYSCON=y
 CONFIG_SPL_CLK=y
@@ -58,8 +59,9 @@ CONFIG_MMC_DW_ROCKCHIP=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_ROCKCHIP=y
-CONFIG_ETH_DESIGNWARE=y
-CONFIG_GMAC_ROCKCHIP=y
+CONFIG_PHY_REALTEK=y
+CONFIG_DWC_ETH_QOS=y
+CONFIG_DWC_ETH_QOS_ROCKCHIP=y
 CONFIG_DM_PMIC=y
 CONFIG_PMIC_RK8XX=y
 CONFIG_REGULATOR_RK8XX=y
diff --git a/configs/lubancat-2-rk3568_defconfig b/configs/lubancat-2-rk3568_defconfig
index b01d3bd2a1a2..80ae6ec3a2e9 100644
--- a/configs/lubancat-2-rk3568_defconfig
+++ b/configs/lubancat-2-rk3568_defconfig
@@ -61,6 +61,9 @@ CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_ROCKCHIP=y
 # CONFIG_SPI_FLASH is not set
+CONFIG_PHY_REALTEK=y
+CONFIG_DWC_ETH_QOS=y
+CONFIG_DWC_ETH_QOS_ROCKCHIP=y
 CONFIG_PHY_ROCKCHIP_INNO_USB2=y
 CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y
 CONFIG_SPL_PINCTRL=y
diff --git a/configs/nanopi-r5s-rk3568_defconfig b/configs/nanopi-r5s-rk3568_defconfig
index c278ce083d9a..2736d382a352 100644
--- a/configs/nanopi-r5s-rk3568_defconfig
+++ b/configs/nanopi-r5s-rk3568_defconfig
@@ -65,6 +65,9 @@ CONFIG_MMC_DW_ROCKCHIP=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_ROCKCHIP=y
+CONFIG_PHY_REALTEK=y
+CONFIG_DWC_ETH_QOS=y
+CONFIG_DWC_ETH_QOS_ROCKCHIP=y
 CONFIG_RTL8169=y
 CONFIG_NVME_PCI=y
 CONFIG_PCIE_DW_ROCKCHIP=y
diff --git a/configs/odroid-m1-rk3568_defconfig b/configs/odroid-m1-rk3568_defconfig
index 3dda5c1f9170..96b4e9ecdaff 100644
--- a/configs/odroid-m1-rk3568_defconfig
+++ b/configs/odroid-m1-rk3568_defconfig
@@ -82,6 +82,9 @@ CONFIG_SF_DEFAULT_BUS=4
 CONFIG_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_SPI_FLASH_MTD=y
+CONFIG_PHY_REALTEK=y
+CONFIG_DWC_ETH_QOS=y
+CONFIG_DWC_ETH_QOS_ROCKCHIP=y
 CONFIG_NVME_PCI=y
 CONFIG_PCIE_DW_ROCKCHIP=y
 CONFIG_PHY_ROCKCHIP_INNO_USB2=y
diff --git a/configs/quartz64-a-rk3566_defconfig b/configs/quartz64-a-rk3566_defconfig
index 6853cd6c44b4..bf4d4cd2b8ed 100644
--- a/configs/quartz64-a-rk3566_defconfig
+++ b/configs/quartz64-a-rk3566_defconfig
@@ -81,6 +81,9 @@ CONFIG_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPI_FLASH_GIGADEVICE=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_PHY_MOTORCOMM=y
+CONFIG_DWC_ETH_QOS=y
+CONFIG_DWC_ETH_QOS_ROCKCHIP=y
 CONFIG_NVME_PCI=y
 CONFIG_PCIE_DW_ROCKCHIP=y
 CONFIG_PHY_ROCKCHIP_INNO_USB2=y
diff --git a/configs/quartz64-b-rk3566_defconfig b/configs/quartz64-b-rk3566_defconfig
index aa29fff14643..358687ab5d7f 100644
--- a/configs/quartz64-b-rk3566_defconfig
+++ b/configs/quartz64-b-rk3566_defconfig
@@ -79,6 +79,9 @@ CONFIG_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPI_FLASH_GIGADEVICE=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_SPI_FLASH_WINBOND=y
+CONFIG_PHY_REALTEK=y
+CONFIG_DWC_ETH_QOS=y
+CONFIG_DWC_ETH_QOS_ROCKCHIP=y
 CONFIG_NVME_PCI=y
 CONFIG_PCIE_DW_ROCKCHIP=y
 CONFIG_PHY_ROCKCHIP_INNO_USB2=y
diff --git a/configs/radxa-cm3-io-rk3566_defconfig b/configs/radxa-cm3-io-rk3566_defconfig
index f89777184ceb..4b606dcb8e94 100644
--- a/configs/radxa-cm3-io-rk3566_defconfig
+++ b/configs/radxa-cm3-io-rk3566_defconfig
@@ -47,6 +47,7 @@ CONFIG_CMD_REGULATOR=y
 CONFIG_SPL_OF_CONTROL=y
 CONFIG_OF_LIVE=y
 CONFIG_OF_SPL_REMOVE_PROPS="clock-names interrupt-parent assigned-clocks assigned-clock-rates assigned-clock-parents"
+CONFIG_SPL_DM_SEQ_ALIAS=y
 CONFIG_SPL_REGMAP=y
 CONFIG_SPL_SYSCON=y
 CONFIG_SPL_CLK=y
@@ -59,8 +60,9 @@ CONFIG_MMC_DW_ROCKCHIP=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_ROCKCHIP=y
-CONFIG_ETH_DESIGNWARE=y
-CONFIG_GMAC_ROCKCHIP=y
+CONFIG_PHY_REALTEK=y
+CONFIG_DWC_ETH_QOS=y
+CONFIG_DWC_ETH_QOS_ROCKCHIP=y
 CONFIG_PHY_ROCKCHIP_INNO_USB2=y
 CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y
 CONFIG_SPL_PINCTRL=y
diff --git a/configs/rock-3a-rk3568_defconfig b/configs/rock-3a-rk3568_defconfig
index 409aa95acf06..28d157dbd7a7 100644
--- a/configs/rock-3a-rk3568_defconfig
+++ b/configs/rock-3a-rk3568_defconfig
@@ -77,8 +77,9 @@ CONFIG_SF_DEFAULT_BUS=4
 CONFIG_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_SPI_FLASH_XTX=y
-CONFIG_ETH_DESIGNWARE=y
-CONFIG_GMAC_ROCKCHIP=y
+CONFIG_PHY_REALTEK=y
+CONFIG_DWC_ETH_QOS=y
+CONFIG_DWC_ETH_QOS_ROCKCHIP=y
 CONFIG_NVME_PCI=y
 CONFIG_PCIE_DW_ROCKCHIP=y
 CONFIG_PHY_ROCKCHIP_INNO_USB2=y
diff --git a/configs/soquartz-blade-rk3566_defconfig b/configs/soquartz-blade-rk3566_defconfig
index 181c284e73e9..1d993a5b71b0 100644
--- a/configs/soquartz-blade-rk3566_defconfig
+++ b/configs/soquartz-blade-rk3566_defconfig
@@ -67,6 +67,9 @@ CONFIG_MMC_DW_ROCKCHIP=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_ROCKCHIP=y
+CONFIG_PHY_MOTORCOMM=y
+CONFIG_DWC_ETH_QOS=y
+CONFIG_DWC_ETH_QOS_ROCKCHIP=y
 CONFIG_NVME_PCI=y
 CONFIG_PCIE_DW_ROCKCHIP=y
 CONFIG_PHY_ROCKCHIP_INNO_USB2=y
diff --git a/configs/soquartz-cm4-rk3566_defconfig b/configs/soquartz-cm4-rk3566_defconfig
index 7e290351477e..f01aa7269a1c 100644
--- a/configs/soquartz-cm4-rk3566_defconfig
+++ b/configs/soquartz-cm4-rk3566_defconfig
@@ -67,6 +67,9 @@ CONFIG_MMC_DW_ROCKCHIP=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_ROCKCHIP=y
+CONFIG_PHY_MOTORCOMM=y
+CONFIG_DWC_ETH_QOS=y
+CONFIG_DWC_ETH_QOS_ROCKCHIP=y
 CONFIG_NVME_PCI=y
 CONFIG_PCIE_DW_ROCKCHIP=y
 CONFIG_PHY_ROCKCHIP_INNO_USB2=y
diff --git a/configs/soquartz-model-a-rk3566_defconfig b/configs/soquartz-model-a-rk3566_defconfig
index a0884a797d58..2f3145745d58 100644
--- a/configs/soquartz-model-a-rk3566_defconfig
+++ b/configs/soquartz-model-a-rk3566_defconfig
@@ -68,6 +68,9 @@ CONFIG_MMC_DW_ROCKCHIP=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_ROCKCHIP=y
+CONFIG_PHY_MOTORCOMM=y
+CONFIG_DWC_ETH_QOS=y
+CONFIG_DWC_ETH_QOS_ROCKCHIP=y
 CONFIG_NVME_PCI=y
 CONFIG_PCIE_DW_ROCKCHIP=y
 CONFIG_PHY_ROCKCHIP_INNO_USB2=y
-- 
2.42.0


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

* [PATCH v2 7/7] configs: rockchip: Enable ethernet driver on RK3588 boards
  2023-10-01 19:17 [PATCH v2 0/7] rockchip: Add GMAC support for RK3568 and RK3588 Jonas Karlman
                   ` (5 preceding siblings ...)
  2023-10-01 19:17 ` [PATCH v2 6/7] configs: rockchip: Enable ethernet driver on RK356x boards Jonas Karlman
@ 2023-10-01 19:17 ` Jonas Karlman
  6 siblings, 0 replies; 15+ messages in thread
From: Jonas Karlman @ 2023-10-01 19:17 UTC (permalink / raw)
  To: Kever Yang, Simon Glass, Philipp Tomsich, Jagan Teki,
	Eugen Hristev, Jonas Karlman
  Cc: David Wu, Frank Wunderlich, Nicolas Frattaroli, u-boot

Enable DWC_ETH_QOS_ROCKCHIP and related PHY driver on RK3588 boards that
have an enabled gmac node and drop ETH_DESIGNWARE and GMAC_ROCKCHIP for
remaining RK3588 boards.

Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
---
v2:
- Collect r-b tag
- Remove already meged rock5a-rk3588s_defconfig change
- Add rock5b-rk3588_defconfig changes

 configs/evb-rk3588_defconfig      | 5 +++--
 configs/neu6a-io-rk3588_defconfig | 2 --
 configs/neu6b-io-rk3588_defconfig | 2 --
 configs/rock5a-rk3588s_defconfig  | 5 +++--
 configs/rock5b-rk3588_defconfig   | 3 +--
 5 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/configs/evb-rk3588_defconfig b/configs/evb-rk3588_defconfig
index f49c2ca686a8..0b7b4f2f627a 100644
--- a/configs/evb-rk3588_defconfig
+++ b/configs/evb-rk3588_defconfig
@@ -58,8 +58,9 @@ CONFIG_MMC_DW_ROCKCHIP=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_ROCKCHIP=y
-CONFIG_ETH_DESIGNWARE=y
-CONFIG_GMAC_ROCKCHIP=y
+CONFIG_PHY_REALTEK=y
+CONFIG_DWC_ETH_QOS=y
+CONFIG_DWC_ETH_QOS_ROCKCHIP=y
 CONFIG_REGULATOR_PWM=y
 CONFIG_PWM_ROCKCHIP=y
 CONFIG_SPL_RAM=y
diff --git a/configs/neu6a-io-rk3588_defconfig b/configs/neu6a-io-rk3588_defconfig
index 09729a0ea429..d5301c630b2a 100644
--- a/configs/neu6a-io-rk3588_defconfig
+++ b/configs/neu6a-io-rk3588_defconfig
@@ -53,8 +53,6 @@ CONFIG_MMC_DW_ROCKCHIP=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_ROCKCHIP=y
-CONFIG_ETH_DESIGNWARE=y
-CONFIG_GMAC_ROCKCHIP=y
 CONFIG_REGULATOR_PWM=y
 CONFIG_PWM_ROCKCHIP=y
 CONFIG_SPL_RAM=y
diff --git a/configs/neu6b-io-rk3588_defconfig b/configs/neu6b-io-rk3588_defconfig
index c7bc3b1965f0..b13c9b5db1b0 100644
--- a/configs/neu6b-io-rk3588_defconfig
+++ b/configs/neu6b-io-rk3588_defconfig
@@ -53,8 +53,6 @@ CONFIG_MMC_DW_ROCKCHIP=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_ROCKCHIP=y
-CONFIG_ETH_DESIGNWARE=y
-CONFIG_GMAC_ROCKCHIP=y
 CONFIG_REGULATOR_PWM=y
 CONFIG_PWM_ROCKCHIP=y
 CONFIG_SPL_RAM=y
diff --git a/configs/rock5a-rk3588s_defconfig b/configs/rock5a-rk3588s_defconfig
index 39e352509a5c..bccdb1e3ecd6 100644
--- a/configs/rock5a-rk3588s_defconfig
+++ b/configs/rock5a-rk3588s_defconfig
@@ -58,8 +58,9 @@ CONFIG_MMC_DW_ROCKCHIP=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_SDMA=y
 CONFIG_MMC_SDHCI_ROCKCHIP=y
-CONFIG_ETH_DESIGNWARE=y
-CONFIG_GMAC_ROCKCHIP=y
+CONFIG_PHY_REALTEK=y
+CONFIG_DWC_ETH_QOS=y
+CONFIG_DWC_ETH_QOS_ROCKCHIP=y
 CONFIG_SPL_PINCTRL=y
 CONFIG_REGULATOR_PWM=y
 CONFIG_PWM_ROCKCHIP=y
diff --git a/configs/rock5b-rk3588_defconfig b/configs/rock5b-rk3588_defconfig
index 3fa65cbf9b07..6428aab42033 100644
--- a/configs/rock5b-rk3588_defconfig
+++ b/configs/rock5b-rk3588_defconfig
@@ -78,9 +78,8 @@ CONFIG_SF_DEFAULT_BUS=5
 CONFIG_SPI_FLASH_SFDP_SUPPORT=y
 CONFIG_SPI_FLASH_MACRONIX=y
 CONFIG_SPI_FLASH_XTX=y
-CONFIG_ETH_DESIGNWARE=y
+CONFIG_PHYLIB=y
 CONFIG_RTL8169=y
-CONFIG_GMAC_ROCKCHIP=y
 CONFIG_PCIE_DW_ROCKCHIP=y
 CONFIG_PHY_ROCKCHIP_INNO_USB2=y
 CONFIG_PHY_ROCKCHIP_NANENG_COMBOPHY=y
-- 
2.42.0


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

* Re: [PATCH v2 5/7] net: dwc_eth_qos_rockchip: Add support for RK3588
  2023-10-01 19:17 ` [PATCH v2 5/7] net: dwc_eth_qos_rockchip: Add support for RK3588 Jonas Karlman
@ 2023-10-01 20:04   ` Sebastian Reichel
  2023-10-06 20:35   ` Ramon Fried
  2024-01-29 14:45   ` Stefan Agner
  2 siblings, 0 replies; 15+ messages in thread
From: Sebastian Reichel @ 2023-10-01 20:04 UTC (permalink / raw)
  To: Jonas Karlman
  Cc: Kever Yang, Simon Glass, Philipp Tomsich, Joe Hershberger,
	Ramon Fried, David Wu, Eugen Hristev, Frank Wunderlich,
	Nicolas Frattaroli, u-boot, Benjamin Gaignard

[-- Attachment #1: Type: text/plain, Size: 10230 bytes --]

Hi,

On Sun, Oct 01, 2023 at 07:17:20PM +0000, Jonas Karlman wrote:
> Add rk_gmac_ops and other special handling that is needed for GMAC to
> work on RK3588.
> 
> rk_gmac_ops was ported from linux commits:
> 2f2b60a0ec28 ("net: ethernet: stmmac: dwmac-rk: Add gmac support for rk3588")
> 88619e77b33d ("net: stmmac: rk3588: Allow multiple gmac controller")
> 
> Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
> Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
> ---
> Cc: David Wu <david.wu@rock-chips.com>
> Cc: Sebastian Reichel <sebastian.reichel@collabora.com>
> Cc: Benjamin Gaignard <benjamin.gaignard@collabora.com>
> ---

Looks like I've send my R-b to v1 while you were preparing v2.
Since nothing changed this is still:

Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>

Greetings,

-- Sebastian

> v2:
> - Collect r-b tag
> 
>  drivers/net/dwc_eth_qos.c          |   4 +
>  drivers/net/dwc_eth_qos_rockchip.c | 182 ++++++++++++++++++++++++++++-
>  2 files changed, 182 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
> index 9fb98a2c3c74..dc04416865dd 100644
> --- a/drivers/net/dwc_eth_qos.c
> +++ b/drivers/net/dwc_eth_qos.c
> @@ -1712,6 +1712,10 @@ static const struct udevice_id eqos_ids[] = {
>  		.compatible = "rockchip,rk3568-gmac",
>  		.data = (ulong)&eqos_rockchip_config
>  	},
> +	{
> +		.compatible = "rockchip,rk3588-gmac",
> +		.data = (ulong)&eqos_rockchip_config
> +	},
>  #endif
>  #if IS_ENABLED(CONFIG_DWC_ETH_QOS_QCOM)
>  	{
> diff --git a/drivers/net/dwc_eth_qos_rockchip.c b/drivers/net/dwc_eth_qos_rockchip.c
> index 05edc098f50d..20fd3a25c3dd 100644
> --- a/drivers/net/dwc_eth_qos_rockchip.c
> +++ b/drivers/net/dwc_eth_qos_rockchip.c
> @@ -28,6 +28,7 @@ struct rk_gmac_ops {
>  			    int tx_delay, int rx_delay);
>  	int (*set_to_rmii)(struct udevice *dev);
>  	int (*set_gmac_speed)(struct udevice *dev);
> +	void (*set_clock_selection)(struct udevice *dev, bool enable);
>  	u32 regs[3];
>  };
>  
> @@ -35,7 +36,9 @@ struct rockchip_platform_data {
>  	struct reset_ctl_bulk resets;
>  	const struct rk_gmac_ops *ops;
>  	int id;
> +	bool clock_input;
>  	struct regmap *grf;
> +	struct regmap *php_grf;
>  };
>  
>  #define HIWORD_UPDATE(val, mask, shift) \
> @@ -129,6 +132,137 @@ static int rk3568_set_gmac_speed(struct udevice *dev)
>  	return 0;
>  }
>  
> +/* sys_grf */
> +#define RK3588_GRF_GMAC_CON7			0x031c
> +#define RK3588_GRF_GMAC_CON8			0x0320
> +#define RK3588_GRF_GMAC_CON9			0x0324
> +
> +#define RK3588_GMAC_RXCLK_DLY_ENABLE(id)	GRF_BIT(2 * (id) + 3)
> +#define RK3588_GMAC_RXCLK_DLY_DISABLE(id)	GRF_CLR_BIT(2 * (id) + 3)
> +#define RK3588_GMAC_TXCLK_DLY_ENABLE(id)	GRF_BIT(2 * (id) + 2)
> +#define RK3588_GMAC_TXCLK_DLY_DISABLE(id)	GRF_CLR_BIT(2 * (id) + 2)
> +
> +#define RK3588_GMAC_CLK_RX_DL_CFG(val)		HIWORD_UPDATE(val, 0xFF, 8)
> +#define RK3588_GMAC_CLK_TX_DL_CFG(val)		HIWORD_UPDATE(val, 0xFF, 0)
> +
> +/* php_grf */
> +#define RK3588_GRF_GMAC_CON0			0x0008
> +#define RK3588_GRF_CLK_CON1			0x0070
> +
> +#define RK3588_GMAC_PHY_INTF_SEL_RGMII(id)	\
> +	(GRF_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_CLR_BIT(5 + (id) * 6))
> +#define RK3588_GMAC_PHY_INTF_SEL_RMII(id)	\
> +	(GRF_CLR_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_BIT(5 + (id) * 6))
> +
> +#define RK3588_GMAC_CLK_RMII_MODE(id)		GRF_BIT(5 * (id))
> +#define RK3588_GMAC_CLK_RGMII_MODE(id)		GRF_CLR_BIT(5 * (id))
> +
> +#define RK3588_GMAC_CLK_SELET_CRU(id)		GRF_BIT(5 * (id) + 4)
> +#define RK3588_GMAC_CLK_SELET_IO(id)		GRF_CLR_BIT(5 * (id) + 4)
> +
> +#define RK3588_GMAC_CLK_RMII_DIV2(id)		GRF_BIT(5 * (id) + 2)
> +#define RK3588_GMAC_CLK_RMII_DIV20(id)		GRF_CLR_BIT(5 * (id) + 2)
> +
> +#define RK3588_GMAC_CLK_RGMII_DIV1(id)		\
> +			(GRF_CLR_BIT(5 * (id) + 2) | GRF_CLR_BIT(5 * (id) + 3))
> +#define RK3588_GMAC_CLK_RGMII_DIV5(id)		\
> +			(GRF_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3))
> +#define RK3588_GMAC_CLK_RGMII_DIV50(id)		\
> +			(GRF_CLR_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3))
> +
> +#define RK3588_GMAC_CLK_RMII_GATE(id)		GRF_BIT(5 * (id) + 1)
> +#define RK3588_GMAC_CLK_RMII_NOGATE(id)		GRF_CLR_BIT(5 * (id) + 1)
> +
> +static int rk3588_set_to_rgmii(struct udevice *dev,
> +			       int tx_delay, int rx_delay)
> +{
> +	struct eth_pdata *pdata = dev_get_plat(dev);
> +	struct rockchip_platform_data *data = pdata->priv_pdata;
> +	u32 offset_con, id = data->id;
> +
> +	offset_con = data->id == 1 ? RK3588_GRF_GMAC_CON9 :
> +				     RK3588_GRF_GMAC_CON8;
> +
> +	regmap_write(data->php_grf, RK3588_GRF_GMAC_CON0,
> +		     RK3588_GMAC_PHY_INTF_SEL_RGMII(id));
> +
> +	regmap_write(data->php_grf, RK3588_GRF_CLK_CON1,
> +		     RK3588_GMAC_CLK_RGMII_MODE(id));
> +
> +	regmap_write(data->grf, RK3588_GRF_GMAC_CON7,
> +		     RK3588_GMAC_RXCLK_DLY_ENABLE(id) |
> +		     RK3588_GMAC_TXCLK_DLY_ENABLE(id));
> +
> +	regmap_write(data->grf, offset_con,
> +		     RK3588_GMAC_CLK_RX_DL_CFG(rx_delay) |
> +		     RK3588_GMAC_CLK_TX_DL_CFG(tx_delay));
> +
> +	return 0;
> +}
> +
> +static int rk3588_set_to_rmii(struct udevice *dev)
> +{
> +	struct eth_pdata *pdata = dev_get_plat(dev);
> +	struct rockchip_platform_data *data = pdata->priv_pdata;
> +
> +	regmap_write(data->php_grf, RK3588_GRF_GMAC_CON0,
> +		     RK3588_GMAC_PHY_INTF_SEL_RMII(data->id));
> +
> +	regmap_write(data->php_grf, RK3588_GRF_CLK_CON1,
> +		     RK3588_GMAC_CLK_RMII_MODE(data->id));
> +
> +	return 0;
> +}
> +
> +static int rk3588_set_gmac_speed(struct udevice *dev)
> +{
> +	struct eqos_priv *eqos = dev_get_priv(dev);
> +	struct eth_pdata *pdata = dev_get_plat(dev);
> +	struct rockchip_platform_data *data = pdata->priv_pdata;
> +	u32 val = 0, id = data->id;
> +
> +	switch (eqos->phy->speed) {
> +	case SPEED_10:
> +		if (pdata->phy_interface == PHY_INTERFACE_MODE_RMII)
> +			val = RK3588_GMAC_CLK_RMII_DIV20(id);
> +		else
> +			val = RK3588_GMAC_CLK_RGMII_DIV50(id);
> +		break;
> +	case SPEED_100:
> +		if (pdata->phy_interface == PHY_INTERFACE_MODE_RMII)
> +			val = RK3588_GMAC_CLK_RMII_DIV2(id);
> +		else
> +			val = RK3588_GMAC_CLK_RGMII_DIV5(id);
> +		break;
> +	case SPEED_1000:
> +		if (pdata->phy_interface != PHY_INTERFACE_MODE_RMII)
> +			val = RK3588_GMAC_CLK_RGMII_DIV1(id);
> +		else
> +			return -EINVAL;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	regmap_write(data->php_grf, RK3588_GRF_CLK_CON1, val);
> +
> +	return 0;
> +}
> +
> +static void rk3588_set_clock_selection(struct udevice *dev, bool enable)
> +{
> +	struct eth_pdata *pdata = dev_get_plat(dev);
> +	struct rockchip_platform_data *data = pdata->priv_pdata;
> +
> +	u32 val = data->clock_input ? RK3588_GMAC_CLK_SELET_IO(data->id) :
> +				      RK3588_GMAC_CLK_SELET_CRU(data->id);
> +
> +	val |= enable ? RK3588_GMAC_CLK_RMII_NOGATE(data->id) :
> +			RK3588_GMAC_CLK_RMII_GATE(data->id);
> +
> +	regmap_write(data->php_grf, RK3588_GRF_CLK_CON1, val);
> +}
> +
>  static const struct rk_gmac_ops rk_gmac_ops[] = {
>  	{
>  		.compatible = "rockchip,rk3568-gmac",
> @@ -141,6 +275,18 @@ static const struct rk_gmac_ops rk_gmac_ops[] = {
>  			0x0, /* sentinel */
>  		},
>  	},
> +	{
> +		.compatible = "rockchip,rk3588-gmac",
> +		.set_to_rgmii = rk3588_set_to_rgmii,
> +		.set_to_rmii = rk3588_set_to_rmii,
> +		.set_gmac_speed = rk3588_set_gmac_speed,
> +		.set_clock_selection = rk3588_set_clock_selection,
> +		.regs = {
> +			0xfe1b0000, /* gmac0 */
> +			0xfe1c0000, /* gmac1 */
> +			0x0, /* sentinel */
> +		},
> +	},
>  	{ }
>  };
>  
> @@ -162,6 +308,7 @@ static int eqos_probe_resources_rk(struct udevice *dev)
>  	struct eqos_priv *eqos = dev_get_priv(dev);
>  	struct eth_pdata *pdata = dev_get_plat(dev);
>  	struct rockchip_platform_data *data;
> +	const char *clock_in_out;
>  	int reset_flags = GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE;
>  	int ret;
>  
> @@ -199,6 +346,16 @@ static int eqos_probe_resources_rk(struct udevice *dev)
>  		goto err_free;
>  	}
>  
> +	if (device_is_compatible(dev, "rockchip,rk3588-gmac")) {
> +		data->php_grf =
> +			syscon_regmap_lookup_by_phandle(dev, "rockchip,php-grf");
> +		if (IS_ERR(data->php_grf)) {
> +			dev_err(dev, "Missing rockchip,php-grf property\n");
> +			ret = -EINVAL;
> +			goto err_free;
> +		}
> +	}
> +
>  	ret = reset_get_bulk(dev, &data->resets);
>  	if (ret < 0)
>  		goto err_free;
> @@ -211,12 +368,20 @@ static int eqos_probe_resources_rk(struct udevice *dev)
>  		goto err_release_resets;
>  	}
>  
> -	ret = clk_get_by_name(dev, "clk_mac_speed", &eqos->clk_tx);
> -	if (ret) {
> -		dev_dbg(dev, "clk_get_by_name(clk_mac_speed) failed: %d", ret);
> -		goto err_free_clk_master_bus;
> +	if (device_is_compatible(dev, "rockchip,rk3568-gmac")) {
> +		ret = clk_get_by_name(dev, "clk_mac_speed", &eqos->clk_tx);
> +		if (ret) {
> +			dev_dbg(dev, "clk_get_by_name(clk_mac_speed) failed: %d", ret);
> +			goto err_free_clk_master_bus;
> +		}
>  	}
>  
> +	clock_in_out = dev_read_string(dev, "clock_in_out");
> +	if (clock_in_out && !strcmp(clock_in_out, "input"))
> +		data->clock_input = true;
> +	else
> +		data->clock_input = false;
> +
>  	/* snps,reset props are deprecated, do bare minimum to support them */
>  	if (dev_read_bool(dev, "snps,reset-active-low"))
>  		reset_flags |= GPIOD_ACTIVE_LOW;
> @@ -273,6 +438,12 @@ static int eqos_start_resets_rk(struct udevice *dev)
>  
>  static int eqos_stop_clks_rk(struct udevice *dev)
>  {
> +	struct eth_pdata *pdata = dev_get_plat(dev);
> +	struct rockchip_platform_data *data = pdata->priv_pdata;
> +
> +	if (data->ops->set_clock_selection)
> +		data->ops->set_clock_selection(dev, false);
> +
>  	return 0;
>  }
>  
> @@ -293,6 +464,9 @@ static int eqos_start_clks_rk(struct udevice *dev)
>  		udelay(eqos->reset_delays[2]);
>  	}
>  
> +	if (data->ops->set_clock_selection)
> +		data->ops->set_clock_selection(dev, true);
> +
>  	tx_delay = dev_read_u32_default(dev, "tx_delay", 0x30);
>  	rx_delay = dev_read_u32_default(dev, "rx_delay", 0x10);
>  
> -- 
> 2.42.0
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

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

* Re: [PATCH v2 1/7] net: dwc_eth_qos: Drop unused rx_pkt from eqos_priv
  2023-10-01 19:17 ` [PATCH v2 1/7] net: dwc_eth_qos: Drop unused rx_pkt from eqos_priv Jonas Karlman
@ 2023-10-06 20:32   ` Ramon Fried
  0 siblings, 0 replies; 15+ messages in thread
From: Ramon Fried @ 2023-10-06 20:32 UTC (permalink / raw)
  To: Jonas Karlman
  Cc: Kever Yang, Simon Glass, Philipp Tomsich, Joe Hershberger,
	David Wu, Eugen Hristev, Frank Wunderlich, Nicolas Frattaroli,
	u-boot

On Sun, Oct 1, 2023 at 10:17 PM Jonas Karlman <jonas@kwiboo.se> wrote:
>
> rx_pkt is allocated and not used for anything, remove it.
>
> Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
> Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
> ---
> v2:
> - Collect r-b tag
>
>  drivers/net/dwc_eth_qos.c | 11 -----------
>  drivers/net/dwc_eth_qos.h |  1 -
>  2 files changed, 12 deletions(-)
>
> diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
> index 1e92bd9ca9c0..555eaee3bbc3 100644
> --- a/drivers/net/dwc_eth_qos.c
> +++ b/drivers/net/dwc_eth_qos.c
> @@ -1314,22 +1314,12 @@ static int eqos_probe_resources_core(struct udevice *dev)
>         }
>         debug("%s: rx_dma_buf=%p\n", __func__, eqos->rx_dma_buf);
>
> -       eqos->rx_pkt = malloc(EQOS_MAX_PACKET_SIZE);
> -       if (!eqos->rx_pkt) {
> -               debug("%s: malloc(rx_pkt) failed\n", __func__);
> -               ret = -ENOMEM;
> -               goto err_free_rx_dma_buf;
> -       }
> -       debug("%s: rx_pkt=%p\n", __func__, eqos->rx_pkt);
> -
>         eqos->config->ops->eqos_inval_buffer(eqos->rx_dma_buf,
>                         EQOS_MAX_PACKET_SIZE * EQOS_DESCRIPTORS_RX);
>
>         debug("%s: OK\n", __func__);
>         return 0;
>
> -err_free_rx_dma_buf:
> -       free(eqos->rx_dma_buf);
>  err_free_tx_dma_buf:
>         free(eqos->tx_dma_buf);
>  err_free_descs:
> @@ -1348,7 +1338,6 @@ static int eqos_remove_resources_core(struct udevice *dev)
>
>         debug("%s(dev=%p):\n", __func__, dev);
>
> -       free(eqos->rx_pkt);
>         free(eqos->rx_dma_buf);
>         free(eqos->tx_dma_buf);
>         eqos_free_descs(eqos->rx_descs);
> diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h
> index a6b719af809f..06a082da72ef 100644
> --- a/drivers/net/dwc_eth_qos.h
> +++ b/drivers/net/dwc_eth_qos.h
> @@ -273,7 +273,6 @@ struct eqos_priv {
>         unsigned int desc_per_cacheline;
>         void *tx_dma_buf;
>         void *rx_dma_buf;
> -       void *rx_pkt;
>         bool started;
>         bool reg_access_ok;
>         bool clk_ck_enabled;
> --
> 2.42.0
>
Reviewed-by: Ramon Fried <rfried.dev@gmail.com>

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

* Re: [PATCH v2 2/7] net: dwc_eth_qos: Return error code when start fails
  2023-10-01 19:17 ` [PATCH v2 2/7] net: dwc_eth_qos: Return error code when start fails Jonas Karlman
@ 2023-10-06 20:32   ` Ramon Fried
  0 siblings, 0 replies; 15+ messages in thread
From: Ramon Fried @ 2023-10-06 20:32 UTC (permalink / raw)
  To: Jonas Karlman
  Cc: Kever Yang, Simon Glass, Philipp Tomsich, Joe Hershberger,
	David Wu, Eugen Hristev, Frank Wunderlich, Nicolas Frattaroli,
	u-boot

On Sun, Oct 1, 2023 at 10:17 PM Jonas Karlman <jonas@kwiboo.se> wrote:
>
> Return error code when phy_connect fails or no link can be established.
>
> Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
> Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
> ---
> v2:
> - Collect r-b tag
>
>  drivers/net/dwc_eth_qos.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
> index 555eaee3bbc3..7565e716823a 100644
> --- a/drivers/net/dwc_eth_qos.c
> +++ b/drivers/net/dwc_eth_qos.c
> @@ -811,6 +811,7 @@ static int eqos_start(struct udevice *dev)
>
>                 if (!eqos->phy) {
>                         pr_err("phy_connect() failed");
> +                       ret = -ENODEV;
>                         goto err_stop_resets;
>                 }
>
> @@ -838,6 +839,7 @@ static int eqos_start(struct udevice *dev)
>
>         if (!eqos->phy->link) {
>                 pr_err("No link");
> +               ret = -EAGAIN;
>                 goto err_shutdown_phy;
>         }
>
> --
> 2.42.0
>
Reviewed-by: Ramon Fried <rfried.dev@gmail.com>

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

* Re: [PATCH v2 3/7] net: dwc_eth_qos: Stop spam of RX packet not available message
  2023-10-01 19:17 ` [PATCH v2 3/7] net: dwc_eth_qos: Stop spam of RX packet not available message Jonas Karlman
@ 2023-10-06 20:32   ` Ramon Fried
  0 siblings, 0 replies; 15+ messages in thread
From: Ramon Fried @ 2023-10-06 20:32 UTC (permalink / raw)
  To: Jonas Karlman
  Cc: Kever Yang, Simon Glass, Philipp Tomsich, Joe Hershberger,
	David Wu, Eugen Hristev, Frank Wunderlich, Nicolas Frattaroli,
	u-boot

On Sun, Oct 1, 2023 at 10:17 PM Jonas Karlman <jonas@kwiboo.se> wrote:
>
> Remove spam of RX packet not available debug messages when waiting to
> receive a packet.
>
> Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
> Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
> ---
> v2:
> - Collect r-b tag
>
>  drivers/net/dwc_eth_qos.c | 8 +++-----
>  1 file changed, 3 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
> index 7565e716823a..24fb3fac1f12 100644
> --- a/drivers/net/dwc_eth_qos.c
> +++ b/drivers/net/dwc_eth_qos.c
> @@ -1193,14 +1193,12 @@ static int eqos_recv(struct udevice *dev, int flags, uchar **packetp)
>         struct eqos_desc *rx_desc;
>         int length;
>
> -       debug("%s(dev=%p, flags=%x):\n", __func__, dev, flags);
> -
>         rx_desc = eqos_get_desc(eqos, eqos->rx_desc_idx, true);
>         eqos->config->ops->eqos_inval_desc(rx_desc);
> -       if (rx_desc->des3 & EQOS_DESC3_OWN) {
> -               debug("%s: RX packet not available\n", __func__);
> +       if (rx_desc->des3 & EQOS_DESC3_OWN)
>                 return -EAGAIN;
> -       }
> +
> +       debug("%s(dev=%p, flags=%x):\n", __func__, dev, flags);
>
>         *packetp = eqos->rx_dma_buf +
>                 (eqos->rx_desc_idx * EQOS_MAX_PACKET_SIZE);
> --
> 2.42.0
>
Reviewed-by: Ramon Fried <rfried.dev@gmail.com>

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

* Re: [PATCH v2 4/7] net: dwc_eth_qos: Add glue driver for GMAC on Rockchip RK3568
  2023-10-01 19:17 ` [PATCH v2 4/7] net: dwc_eth_qos: Add glue driver for GMAC on Rockchip RK3568 Jonas Karlman
@ 2023-10-06 20:33   ` Ramon Fried
  0 siblings, 0 replies; 15+ messages in thread
From: Ramon Fried @ 2023-10-06 20:33 UTC (permalink / raw)
  To: Jonas Karlman
  Cc: Kever Yang, Simon Glass, Philipp Tomsich, Joe Hershberger,
	David Wu, Eugen Hristev, Frank Wunderlich, Nicolas Frattaroli,
	u-boot, Ezequiel Garcia

On Sun, Oct 1, 2023 at 10:17 PM Jonas Karlman <jonas@kwiboo.se> wrote:
>
> Add a new glue driver for Rockchip SoCs, i.e RK3568, with a GMAC based
> on Synopsys DWC Ethernet QoS IP.
>
> rk_gmac_ops was ported from linux commit:
> 3bb3d6b1c195 ("net: stmmac: Add RK3566/RK3568 SoC support")
>
> Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
> Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
> ---
> Cc: David Wu <david.wu@rock-chips.com>
> Cc: Ezequiel Garcia <ezequiel@collabora.com>
> ---
> v2:
> - Add comment about ported code intentionally left close to 1:1 with linux
> - Collect r-b tag
>
>  drivers/net/Kconfig                |   8 +
>  drivers/net/Makefile               |   1 +
>  drivers/net/dwc_eth_qos.c          |   8 +-
>  drivers/net/dwc_eth_qos.h          |   2 +
>  drivers/net/dwc_eth_qos_rockchip.c | 357 +++++++++++++++++++++++++++++
>  5 files changed, 374 insertions(+), 2 deletions(-)
>  create mode 100644 drivers/net/dwc_eth_qos_rockchip.c
>
> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
> index 0ed39a61e4de..29304fd77759 100644
> --- a/drivers/net/Kconfig
> +++ b/drivers/net/Kconfig
> @@ -225,6 +225,14 @@ config DWC_ETH_QOS_IMX
>           The Synopsys Designware Ethernet QOS IP block with the specific
>           configuration used in IMX soc.
>
> +config DWC_ETH_QOS_ROCKCHIP
> +       bool "Synopsys DWC Ethernet QOS device support for Rockchip SoCs"
> +       depends on DWC_ETH_QOS
> +       select DM_ETH_PHY
> +       help
> +         The Synopsys Designware Ethernet QOS IP block with specific
> +         configuration used in Rockchip SoCs.
> +
>  config DWC_ETH_QOS_STM32
>         bool "Synopsys DWC Ethernet QOS device support for STM32"
>         depends on DWC_ETH_QOS
> diff --git a/drivers/net/Makefile b/drivers/net/Makefile
> index d4af253b6f28..1d444f5b4a69 100644
> --- a/drivers/net/Makefile
> +++ b/drivers/net/Makefile
> @@ -20,6 +20,7 @@ obj-$(CONFIG_DRIVER_DM9000) += dm9000x.o
>  obj-$(CONFIG_DSA_SANDBOX) += dsa_sandbox.o
>  obj-$(CONFIG_DWC_ETH_QOS) += dwc_eth_qos.o
>  obj-$(CONFIG_DWC_ETH_QOS_IMX) += dwc_eth_qos_imx.o
> +obj-$(CONFIG_DWC_ETH_QOS_ROCKCHIP) += dwc_eth_qos_rockchip.o
>  obj-$(CONFIG_DWC_ETH_QOS_QCOM) += dwc_eth_qos_qcom.o
>  obj-$(CONFIG_DWC_ETH_QOS_STARFIVE) += dwc_eth_qos_starfive.o
>  obj-$(CONFIG_E1000) += e1000.o
> diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
> index 24fb3fac1f12..9fb98a2c3c74 100644
> --- a/drivers/net/dwc_eth_qos.c
> +++ b/drivers/net/dwc_eth_qos.c
> @@ -1707,7 +1707,12 @@ static const struct udevice_id eqos_ids[] = {
>                 .data = (ulong)&eqos_imx_config
>         },
>  #endif
> -
> +#if IS_ENABLED(CONFIG_DWC_ETH_QOS_ROCKCHIP)
> +       {
> +               .compatible = "rockchip,rk3568-gmac",
> +               .data = (ulong)&eqos_rockchip_config
> +       },
> +#endif
>  #if IS_ENABLED(CONFIG_DWC_ETH_QOS_QCOM)
>         {
>                 .compatible = "qcom,qcs404-ethqos",
> @@ -1720,7 +1725,6 @@ static const struct udevice_id eqos_ids[] = {
>                 .data = (ulong)&eqos_jh7110_config
>         },
>  #endif
> -
>         { }
>  };
>
> diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h
> index 06a082da72ef..e3222e1e17e5 100644
> --- a/drivers/net/dwc_eth_qos.h
> +++ b/drivers/net/dwc_eth_qos.h
> @@ -82,6 +82,7 @@ struct eqos_mac_regs {
>  #define EQOS_MAC_MDIO_ADDRESS_PA_SHIFT                 21
>  #define EQOS_MAC_MDIO_ADDRESS_RDA_SHIFT                        16
>  #define EQOS_MAC_MDIO_ADDRESS_CR_SHIFT                 8
> +#define EQOS_MAC_MDIO_ADDRESS_CR_100_150               1
>  #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)
> @@ -287,5 +288,6 @@ void eqos_flush_buffer_generic(void *buf, size_t size);
>  int eqos_null_ops(struct udevice *dev);
>
>  extern struct eqos_config eqos_imx_config;
> +extern struct eqos_config eqos_rockchip_config;
>  extern struct eqos_config eqos_qcom_config;
>  extern struct eqos_config eqos_jh7110_config;
> diff --git a/drivers/net/dwc_eth_qos_rockchip.c b/drivers/net/dwc_eth_qos_rockchip.c
> new file mode 100644
> index 000000000000..05edc098f50d
> --- /dev/null
> +++ b/drivers/net/dwc_eth_qos_rockchip.c
> @@ -0,0 +1,357 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright Contributors to the U-Boot project.
> + *
> + * rk_gmac_ops ported from linux drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
> + *
> + * Ported code is intentionally left as close as possible with linux counter
> + * part in order to simplify future porting of fixes and support for other SoCs.
> + */
> +
> +#include <common.h>
> +#include <clk.h>
> +#include <dm.h>
> +#include <dm/device_compat.h>
> +#include <net.h>
> +#include <phy.h>
> +#include <regmap.h>
> +#include <reset.h>
> +#include <syscon.h>
> +#include <asm/gpio.h>
> +#include <linux/delay.h>
> +
> +#include "dwc_eth_qos.h"
> +
> +struct rk_gmac_ops {
> +       const char *compatible;
> +       int (*set_to_rgmii)(struct udevice *dev,
> +                           int tx_delay, int rx_delay);
> +       int (*set_to_rmii)(struct udevice *dev);
> +       int (*set_gmac_speed)(struct udevice *dev);
> +       u32 regs[3];
> +};
> +
> +struct rockchip_platform_data {
> +       struct reset_ctl_bulk resets;
> +       const struct rk_gmac_ops *ops;
> +       int id;
> +       struct regmap *grf;
> +};
> +
> +#define HIWORD_UPDATE(val, mask, shift) \
> +               ((val) << (shift) | (mask) << ((shift) + 16))
> +
> +#define GRF_BIT(nr)    (BIT(nr) | BIT((nr) + 16))
> +#define GRF_CLR_BIT(nr)        (BIT((nr) + 16))
> +
> +#define RK3568_GRF_GMAC0_CON0          0x0380
> +#define RK3568_GRF_GMAC0_CON1          0x0384
> +#define RK3568_GRF_GMAC1_CON0          0x0388
> +#define RK3568_GRF_GMAC1_CON1          0x038c
> +
> +/* RK3568_GRF_GMAC0_CON1 && RK3568_GRF_GMAC1_CON1 */
> +#define RK3568_GMAC_PHY_INTF_SEL_RGMII \
> +               (GRF_BIT(4) | GRF_CLR_BIT(5) | GRF_CLR_BIT(6))
> +#define RK3568_GMAC_PHY_INTF_SEL_RMII  \
> +               (GRF_CLR_BIT(4) | GRF_CLR_BIT(5) | GRF_BIT(6))
> +#define RK3568_GMAC_FLOW_CTRL                  GRF_BIT(3)
> +#define RK3568_GMAC_FLOW_CTRL_CLR              GRF_CLR_BIT(3)
> +#define RK3568_GMAC_RXCLK_DLY_ENABLE           GRF_BIT(1)
> +#define RK3568_GMAC_RXCLK_DLY_DISABLE          GRF_CLR_BIT(1)
> +#define RK3568_GMAC_TXCLK_DLY_ENABLE           GRF_BIT(0)
> +#define RK3568_GMAC_TXCLK_DLY_DISABLE          GRF_CLR_BIT(0)
> +
> +/* RK3568_GRF_GMAC0_CON0 && RK3568_GRF_GMAC1_CON0 */
> +#define RK3568_GMAC_CLK_RX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 8)
> +#define RK3568_GMAC_CLK_TX_DL_CFG(val) HIWORD_UPDATE(val, 0x7F, 0)
> +
> +static int rk3568_set_to_rgmii(struct udevice *dev,
> +                              int tx_delay, int rx_delay)
> +{
> +       struct eth_pdata *pdata = dev_get_plat(dev);
> +       struct rockchip_platform_data *data = pdata->priv_pdata;
> +       u32 con0, con1;
> +
> +       con0 = (data->id == 1) ? RK3568_GRF_GMAC1_CON0 :
> +                                RK3568_GRF_GMAC0_CON0;
> +       con1 = (data->id == 1) ? RK3568_GRF_GMAC1_CON1 :
> +                                RK3568_GRF_GMAC0_CON1;
> +
> +       regmap_write(data->grf, con0,
> +                    RK3568_GMAC_CLK_RX_DL_CFG(rx_delay) |
> +                    RK3568_GMAC_CLK_TX_DL_CFG(tx_delay));
> +
> +       regmap_write(data->grf, con1,
> +                    RK3568_GMAC_PHY_INTF_SEL_RGMII |
> +                    RK3568_GMAC_RXCLK_DLY_ENABLE |
> +                    RK3568_GMAC_TXCLK_DLY_ENABLE);
> +
> +       return 0;
> +}
> +
> +static int rk3568_set_to_rmii(struct udevice *dev)
> +{
> +       struct eth_pdata *pdata = dev_get_plat(dev);
> +       struct rockchip_platform_data *data = pdata->priv_pdata;
> +       u32 con1;
> +
> +       con1 = (data->id == 1) ? RK3568_GRF_GMAC1_CON1 :
> +                                RK3568_GRF_GMAC0_CON1;
> +       regmap_write(data->grf, con1, RK3568_GMAC_PHY_INTF_SEL_RMII);
> +
> +       return 0;
> +}
> +
> +static int rk3568_set_gmac_speed(struct udevice *dev)
> +{
> +       struct eqos_priv *eqos = dev_get_priv(dev);
> +       ulong rate;
> +       int ret;
> +
> +       switch (eqos->phy->speed) {
> +       case SPEED_10:
> +               rate = 2500000;
> +               break;
> +       case SPEED_100:
> +               rate = 25000000;
> +               break;
> +       case SPEED_1000:
> +               rate = 125000000;
> +               break;
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       ret = clk_set_rate(&eqos->clk_tx, rate);
> +       if (ret < 0)
> +               return ret;
> +
> +       return 0;
> +}
> +
> +static const struct rk_gmac_ops rk_gmac_ops[] = {
> +       {
> +               .compatible = "rockchip,rk3568-gmac",
> +               .set_to_rgmii = rk3568_set_to_rgmii,
> +               .set_to_rmii = rk3568_set_to_rmii,
> +               .set_gmac_speed = rk3568_set_gmac_speed,
> +               .regs = {
> +                       0xfe2a0000, /* gmac0 */
> +                       0xfe010000, /* gmac1 */
> +                       0x0, /* sentinel */
> +               },
> +       },
> +       { }
> +};
> +
> +static const struct rk_gmac_ops *get_rk_gmac_ops(struct udevice *dev)
> +{
> +       const struct rk_gmac_ops *ops = rk_gmac_ops;
> +
> +       while (ops->compatible) {
> +               if (device_is_compatible(dev, ops->compatible))
> +                       return ops;
> +               ops++;
> +       }
> +
> +       return NULL;
> +}
> +
> +static int eqos_probe_resources_rk(struct udevice *dev)
> +{
> +       struct eqos_priv *eqos = dev_get_priv(dev);
> +       struct eth_pdata *pdata = dev_get_plat(dev);
> +       struct rockchip_platform_data *data;
> +       int reset_flags = GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE;
> +       int ret;
> +
> +       data = calloc(1, sizeof(struct rockchip_platform_data));
> +       if (!data)
> +               return -ENOMEM;
> +
> +       data->ops = get_rk_gmac_ops(dev);
> +       if (!data->ops) {
> +               ret = -EINVAL;
> +               goto err_free;
> +       }
> +
> +       for (int i = 0; data->ops->regs[i]; i++) {
> +               if (data->ops->regs[i] == (u32)eqos->regs) {
> +                       data->id = i;
> +                       break;
> +               }
> +       }
> +
> +       pdata->priv_pdata = data;
> +       pdata->phy_interface = eqos->config->interface(dev);
> +       pdata->max_speed = eqos->max_speed;
> +
> +       if (pdata->phy_interface == PHY_INTERFACE_MODE_NA) {
> +               pr_err("Invalid PHY interface\n");
> +               ret = -EINVAL;
> +               goto err_free;
> +       }
> +
> +       data->grf = syscon_regmap_lookup_by_phandle(dev, "rockchip,grf");
> +       if (IS_ERR(data->grf)) {
> +               dev_err(dev, "Missing rockchip,grf property\n");
> +               ret = -EINVAL;
> +               goto err_free;
> +       }
> +
> +       ret = reset_get_bulk(dev, &data->resets);
> +       if (ret < 0)
> +               goto err_free;
> +
> +       reset_assert_bulk(&data->resets);
> +
> +       ret = clk_get_by_name(dev, "stmmaceth", &eqos->clk_master_bus);
> +       if (ret) {
> +               dev_dbg(dev, "clk_get_by_name(stmmaceth) failed: %d", ret);
> +               goto err_release_resets;
> +       }
> +
> +       ret = clk_get_by_name(dev, "clk_mac_speed", &eqos->clk_tx);
> +       if (ret) {
> +               dev_dbg(dev, "clk_get_by_name(clk_mac_speed) failed: %d", ret);
> +               goto err_free_clk_master_bus;
> +       }
> +
> +       /* snps,reset props are deprecated, do bare minimum to support them */
> +       if (dev_read_bool(dev, "snps,reset-active-low"))
> +               reset_flags |= GPIOD_ACTIVE_LOW;
> +
> +       dev_read_u32_array(dev, "snps,reset-delays-us", eqos->reset_delays, 3);
> +
> +       gpio_request_by_name(dev, "snps,reset-gpio", 0,
> +                            &eqos->phy_reset_gpio, reset_flags);
> +
> +       return 0;
> +
> +err_free_clk_master_bus:
> +       clk_free(&eqos->clk_master_bus);
> +err_release_resets:
> +       reset_release_bulk(&data->resets);
> +err_free:
> +       free(data);
> +
> +       return ret;
> +}
> +
> +static int eqos_remove_resources_rk(struct udevice *dev)
> +{
> +       struct eqos_priv *eqos = dev_get_priv(dev);
> +       struct eth_pdata *pdata = dev_get_plat(dev);
> +       struct rockchip_platform_data *data = pdata->priv_pdata;
> +
> +       if (dm_gpio_is_valid(&eqos->phy_reset_gpio))
> +               dm_gpio_free(dev, &eqos->phy_reset_gpio);
> +
> +       clk_free(&eqos->clk_tx);
> +       clk_free(&eqos->clk_master_bus);
> +       reset_release_bulk(&data->resets);
> +       free(data);
> +
> +       return 0;
> +}
> +
> +static int eqos_stop_resets_rk(struct udevice *dev)
> +{
> +       struct eth_pdata *pdata = dev_get_plat(dev);
> +       struct rockchip_platform_data *data = pdata->priv_pdata;
> +
> +       return reset_assert_bulk(&data->resets);
> +}
> +
> +static int eqos_start_resets_rk(struct udevice *dev)
> +{
> +       struct eth_pdata *pdata = dev_get_plat(dev);
> +       struct rockchip_platform_data *data = pdata->priv_pdata;
> +
> +       return reset_deassert_bulk(&data->resets);
> +}
> +
> +static int eqos_stop_clks_rk(struct udevice *dev)
> +{
> +       return 0;
> +}
> +
> +static int eqos_start_clks_rk(struct udevice *dev)
> +{
> +       struct eqos_priv *eqos = dev_get_priv(dev);
> +       struct eth_pdata *pdata = dev_get_plat(dev);
> +       struct rockchip_platform_data *data = pdata->priv_pdata;
> +       int tx_delay, rx_delay, ret;
> +
> +       if (dm_gpio_is_valid(&eqos->phy_reset_gpio)) {
> +               udelay(eqos->reset_delays[1]);
> +
> +               ret = dm_gpio_set_value(&eqos->phy_reset_gpio, 0);
> +               if (ret < 0)
> +                       return ret;
> +
> +               udelay(eqos->reset_delays[2]);
> +       }
> +
> +       tx_delay = dev_read_u32_default(dev, "tx_delay", 0x30);
> +       rx_delay = dev_read_u32_default(dev, "rx_delay", 0x10);
> +
> +       switch (pdata->phy_interface) {
> +       case PHY_INTERFACE_MODE_RGMII:
> +               return data->ops->set_to_rgmii(dev, tx_delay, rx_delay);
> +       case PHY_INTERFACE_MODE_RGMII_ID:
> +               return data->ops->set_to_rgmii(dev, 0, 0);
> +       case PHY_INTERFACE_MODE_RGMII_RXID:
> +               return data->ops->set_to_rgmii(dev, tx_delay, 0);
> +       case PHY_INTERFACE_MODE_RGMII_TXID:
> +               return data->ops->set_to_rgmii(dev, 0, rx_delay);
> +       case PHY_INTERFACE_MODE_RMII:
> +               return data->ops->set_to_rmii(dev);
> +       }
> +
> +       return -EINVAL;
> +}
> +
> +static int eqos_set_tx_clk_speed_rk(struct udevice *dev)
> +{
> +       struct eth_pdata *pdata = dev_get_plat(dev);
> +       struct rockchip_platform_data *data = pdata->priv_pdata;
> +
> +       return data->ops->set_gmac_speed(dev);
> +}
> +
> +static ulong eqos_get_tick_clk_rate_rk(struct udevice *dev)
> +{
> +       struct eqos_priv *eqos = dev_get_priv(dev);
> +
> +       return clk_get_rate(&eqos->clk_master_bus);
> +}
> +
> +static struct eqos_ops eqos_rockchip_ops = {
> +       .eqos_inval_desc = eqos_inval_desc_generic,
> +       .eqos_flush_desc = eqos_flush_desc_generic,
> +       .eqos_inval_buffer = eqos_inval_buffer_generic,
> +       .eqos_flush_buffer = eqos_flush_buffer_generic,
> +       .eqos_probe_resources = eqos_probe_resources_rk,
> +       .eqos_remove_resources = eqos_remove_resources_rk,
> +       .eqos_stop_resets = eqos_stop_resets_rk,
> +       .eqos_start_resets = eqos_start_resets_rk,
> +       .eqos_stop_clks = eqos_stop_clks_rk,
> +       .eqos_start_clks = eqos_start_clks_rk,
> +       .eqos_calibrate_pads = eqos_null_ops,
> +       .eqos_disable_calibration = eqos_null_ops,
> +       .eqos_set_tx_clk_speed = eqos_set_tx_clk_speed_rk,
> +       .eqos_get_enetaddr = eqos_null_ops,
> +       .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_rk,
> +};
> +
> +struct eqos_config eqos_rockchip_config = {
> +       .reg_access_always_ok = false,
> +       .mdio_wait = 10,
> +       .swr_wait = 50,
> +       .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB,
> +       .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_100_150,
> +       .axi_bus_width = EQOS_AXI_WIDTH_64,
> +       .interface = dev_read_phy_mode,
> +       .ops = &eqos_rockchip_ops,
> +};
> --
> 2.42.0
>
Reviewed-by: Ramon Fried <rfried.dev@gmail.com>

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

* Re: [PATCH v2 5/7] net: dwc_eth_qos_rockchip: Add support for RK3588
  2023-10-01 19:17 ` [PATCH v2 5/7] net: dwc_eth_qos_rockchip: Add support for RK3588 Jonas Karlman
  2023-10-01 20:04   ` Sebastian Reichel
@ 2023-10-06 20:35   ` Ramon Fried
  2024-01-29 14:45   ` Stefan Agner
  2 siblings, 0 replies; 15+ messages in thread
From: Ramon Fried @ 2023-10-06 20:35 UTC (permalink / raw)
  To: Jonas Karlman
  Cc: Kever Yang, Simon Glass, Philipp Tomsich, Joe Hershberger,
	David Wu, Eugen Hristev, Frank Wunderlich, Nicolas Frattaroli,
	u-boot, Sebastian Reichel, Benjamin Gaignard

On Sun, Oct 1, 2023 at 10:17 PM Jonas Karlman <jonas@kwiboo.se> wrote:
>
> Add rk_gmac_ops and other special handling that is needed for GMAC to
> work on RK3588.
>
> rk_gmac_ops was ported from linux commits:
> 2f2b60a0ec28 ("net: ethernet: stmmac: dwmac-rk: Add gmac support for rk3588")
> 88619e77b33d ("net: stmmac: rk3588: Allow multiple gmac controller")
>
> Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
> Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
> ---
> Cc: David Wu <david.wu@rock-chips.com>
> Cc: Sebastian Reichel <sebastian.reichel@collabora.com>
> Cc: Benjamin Gaignard <benjamin.gaignard@collabora.com>
> ---
> v2:
> - Collect r-b tag
>
>  drivers/net/dwc_eth_qos.c          |   4 +
>  drivers/net/dwc_eth_qos_rockchip.c | 182 ++++++++++++++++++++++++++++-
>  2 files changed, 182 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
> index 9fb98a2c3c74..dc04416865dd 100644
> --- a/drivers/net/dwc_eth_qos.c
> +++ b/drivers/net/dwc_eth_qos.c
> @@ -1712,6 +1712,10 @@ static const struct udevice_id eqos_ids[] = {
>                 .compatible = "rockchip,rk3568-gmac",
>                 .data = (ulong)&eqos_rockchip_config
>         },
> +       {
> +               .compatible = "rockchip,rk3588-gmac",
> +               .data = (ulong)&eqos_rockchip_config
> +       },
>  #endif
>  #if IS_ENABLED(CONFIG_DWC_ETH_QOS_QCOM)
>         {
> diff --git a/drivers/net/dwc_eth_qos_rockchip.c b/drivers/net/dwc_eth_qos_rockchip.c
> index 05edc098f50d..20fd3a25c3dd 100644
> --- a/drivers/net/dwc_eth_qos_rockchip.c
> +++ b/drivers/net/dwc_eth_qos_rockchip.c
> @@ -28,6 +28,7 @@ struct rk_gmac_ops {
>                             int tx_delay, int rx_delay);
>         int (*set_to_rmii)(struct udevice *dev);
>         int (*set_gmac_speed)(struct udevice *dev);
> +       void (*set_clock_selection)(struct udevice *dev, bool enable);
>         u32 regs[3];
>  };
>
> @@ -35,7 +36,9 @@ struct rockchip_platform_data {
>         struct reset_ctl_bulk resets;
>         const struct rk_gmac_ops *ops;
>         int id;
> +       bool clock_input;
>         struct regmap *grf;
> +       struct regmap *php_grf;
>  };
>
>  #define HIWORD_UPDATE(val, mask, shift) \
> @@ -129,6 +132,137 @@ static int rk3568_set_gmac_speed(struct udevice *dev)
>         return 0;
>  }
>
> +/* sys_grf */
> +#define RK3588_GRF_GMAC_CON7                   0x031c
> +#define RK3588_GRF_GMAC_CON8                   0x0320
> +#define RK3588_GRF_GMAC_CON9                   0x0324
> +
> +#define RK3588_GMAC_RXCLK_DLY_ENABLE(id)       GRF_BIT(2 * (id) + 3)
> +#define RK3588_GMAC_RXCLK_DLY_DISABLE(id)      GRF_CLR_BIT(2 * (id) + 3)
> +#define RK3588_GMAC_TXCLK_DLY_ENABLE(id)       GRF_BIT(2 * (id) + 2)
> +#define RK3588_GMAC_TXCLK_DLY_DISABLE(id)      GRF_CLR_BIT(2 * (id) + 2)
> +
> +#define RK3588_GMAC_CLK_RX_DL_CFG(val)         HIWORD_UPDATE(val, 0xFF, 8)
> +#define RK3588_GMAC_CLK_TX_DL_CFG(val)         HIWORD_UPDATE(val, 0xFF, 0)
> +
> +/* php_grf */
> +#define RK3588_GRF_GMAC_CON0                   0x0008
> +#define RK3588_GRF_CLK_CON1                    0x0070
> +
> +#define RK3588_GMAC_PHY_INTF_SEL_RGMII(id)     \
> +       (GRF_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_CLR_BIT(5 + (id) * 6))
> +#define RK3588_GMAC_PHY_INTF_SEL_RMII(id)      \
> +       (GRF_CLR_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_BIT(5 + (id) * 6))
> +
> +#define RK3588_GMAC_CLK_RMII_MODE(id)          GRF_BIT(5 * (id))
> +#define RK3588_GMAC_CLK_RGMII_MODE(id)         GRF_CLR_BIT(5 * (id))
> +
> +#define RK3588_GMAC_CLK_SELET_CRU(id)          GRF_BIT(5 * (id) + 4)
> +#define RK3588_GMAC_CLK_SELET_IO(id)           GRF_CLR_BIT(5 * (id) + 4)
> +
> +#define RK3588_GMAC_CLK_RMII_DIV2(id)          GRF_BIT(5 * (id) + 2)
> +#define RK3588_GMAC_CLK_RMII_DIV20(id)         GRF_CLR_BIT(5 * (id) + 2)
> +
> +#define RK3588_GMAC_CLK_RGMII_DIV1(id)         \
> +                       (GRF_CLR_BIT(5 * (id) + 2) | GRF_CLR_BIT(5 * (id) + 3))
> +#define RK3588_GMAC_CLK_RGMII_DIV5(id)         \
> +                       (GRF_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3))
> +#define RK3588_GMAC_CLK_RGMII_DIV50(id)                \
> +                       (GRF_CLR_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3))
> +
> +#define RK3588_GMAC_CLK_RMII_GATE(id)          GRF_BIT(5 * (id) + 1)
> +#define RK3588_GMAC_CLK_RMII_NOGATE(id)                GRF_CLR_BIT(5 * (id) + 1)
> +
> +static int rk3588_set_to_rgmii(struct udevice *dev,
> +                              int tx_delay, int rx_delay)
> +{
> +       struct eth_pdata *pdata = dev_get_plat(dev);
> +       struct rockchip_platform_data *data = pdata->priv_pdata;
> +       u32 offset_con, id = data->id;
> +
> +       offset_con = data->id == 1 ? RK3588_GRF_GMAC_CON9 :
> +                                    RK3588_GRF_GMAC_CON8;
> +
> +       regmap_write(data->php_grf, RK3588_GRF_GMAC_CON0,
> +                    RK3588_GMAC_PHY_INTF_SEL_RGMII(id));
> +
> +       regmap_write(data->php_grf, RK3588_GRF_CLK_CON1,
> +                    RK3588_GMAC_CLK_RGMII_MODE(id));
> +
> +       regmap_write(data->grf, RK3588_GRF_GMAC_CON7,
> +                    RK3588_GMAC_RXCLK_DLY_ENABLE(id) |
> +                    RK3588_GMAC_TXCLK_DLY_ENABLE(id));
> +
> +       regmap_write(data->grf, offset_con,
> +                    RK3588_GMAC_CLK_RX_DL_CFG(rx_delay) |
> +                    RK3588_GMAC_CLK_TX_DL_CFG(tx_delay));
> +
> +       return 0;
> +}
> +
> +static int rk3588_set_to_rmii(struct udevice *dev)
> +{
> +       struct eth_pdata *pdata = dev_get_plat(dev);
> +       struct rockchip_platform_data *data = pdata->priv_pdata;
> +
> +       regmap_write(data->php_grf, RK3588_GRF_GMAC_CON0,
> +                    RK3588_GMAC_PHY_INTF_SEL_RMII(data->id));
> +
> +       regmap_write(data->php_grf, RK3588_GRF_CLK_CON1,
> +                    RK3588_GMAC_CLK_RMII_MODE(data->id));
> +
> +       return 0;
> +}
> +
> +static int rk3588_set_gmac_speed(struct udevice *dev)
> +{
> +       struct eqos_priv *eqos = dev_get_priv(dev);
> +       struct eth_pdata *pdata = dev_get_plat(dev);
> +       struct rockchip_platform_data *data = pdata->priv_pdata;
> +       u32 val = 0, id = data->id;
> +
> +       switch (eqos->phy->speed) {
> +       case SPEED_10:
> +               if (pdata->phy_interface == PHY_INTERFACE_MODE_RMII)
> +                       val = RK3588_GMAC_CLK_RMII_DIV20(id);
> +               else
> +                       val = RK3588_GMAC_CLK_RGMII_DIV50(id);
> +               break;
> +       case SPEED_100:
> +               if (pdata->phy_interface == PHY_INTERFACE_MODE_RMII)
> +                       val = RK3588_GMAC_CLK_RMII_DIV2(id);
> +               else
> +                       val = RK3588_GMAC_CLK_RGMII_DIV5(id);
> +               break;
> +       case SPEED_1000:
> +               if (pdata->phy_interface != PHY_INTERFACE_MODE_RMII)
> +                       val = RK3588_GMAC_CLK_RGMII_DIV1(id);
> +               else
> +                       return -EINVAL;
> +               break;
> +       default:
> +               return -EINVAL;
> +       }
> +
> +       regmap_write(data->php_grf, RK3588_GRF_CLK_CON1, val);
> +
> +       return 0;
> +}
> +
> +static void rk3588_set_clock_selection(struct udevice *dev, bool enable)
> +{
> +       struct eth_pdata *pdata = dev_get_plat(dev);
> +       struct rockchip_platform_data *data = pdata->priv_pdata;
> +
> +       u32 val = data->clock_input ? RK3588_GMAC_CLK_SELET_IO(data->id) :
> +                                     RK3588_GMAC_CLK_SELET_CRU(data->id);
> +
> +       val |= enable ? RK3588_GMAC_CLK_RMII_NOGATE(data->id) :
> +                       RK3588_GMAC_CLK_RMII_GATE(data->id);
> +
> +       regmap_write(data->php_grf, RK3588_GRF_CLK_CON1, val);
> +}
> +
>  static const struct rk_gmac_ops rk_gmac_ops[] = {
>         {
>                 .compatible = "rockchip,rk3568-gmac",
> @@ -141,6 +275,18 @@ static const struct rk_gmac_ops rk_gmac_ops[] = {
>                         0x0, /* sentinel */
>                 },
>         },
> +       {
> +               .compatible = "rockchip,rk3588-gmac",
> +               .set_to_rgmii = rk3588_set_to_rgmii,
> +               .set_to_rmii = rk3588_set_to_rmii,
> +               .set_gmac_speed = rk3588_set_gmac_speed,
> +               .set_clock_selection = rk3588_set_clock_selection,
> +               .regs = {
> +                       0xfe1b0000, /* gmac0 */
> +                       0xfe1c0000, /* gmac1 */
> +                       0x0, /* sentinel */
> +               },
> +       },
>         { }
>  };
>
> @@ -162,6 +308,7 @@ static int eqos_probe_resources_rk(struct udevice *dev)
>         struct eqos_priv *eqos = dev_get_priv(dev);
>         struct eth_pdata *pdata = dev_get_plat(dev);
>         struct rockchip_platform_data *data;
> +       const char *clock_in_out;
>         int reset_flags = GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE;
>         int ret;
>
> @@ -199,6 +346,16 @@ static int eqos_probe_resources_rk(struct udevice *dev)
>                 goto err_free;
>         }
>
> +       if (device_is_compatible(dev, "rockchip,rk3588-gmac")) {
> +               data->php_grf =
> +                       syscon_regmap_lookup_by_phandle(dev, "rockchip,php-grf");
> +               if (IS_ERR(data->php_grf)) {
> +                       dev_err(dev, "Missing rockchip,php-grf property\n");
> +                       ret = -EINVAL;
> +                       goto err_free;
> +               }
> +       }
> +
>         ret = reset_get_bulk(dev, &data->resets);
>         if (ret < 0)
>                 goto err_free;
> @@ -211,12 +368,20 @@ static int eqos_probe_resources_rk(struct udevice *dev)
>                 goto err_release_resets;
>         }
>
> -       ret = clk_get_by_name(dev, "clk_mac_speed", &eqos->clk_tx);
> -       if (ret) {
> -               dev_dbg(dev, "clk_get_by_name(clk_mac_speed) failed: %d", ret);
> -               goto err_free_clk_master_bus;
> +       if (device_is_compatible(dev, "rockchip,rk3568-gmac")) {
> +               ret = clk_get_by_name(dev, "clk_mac_speed", &eqos->clk_tx);
> +               if (ret) {
> +                       dev_dbg(dev, "clk_get_by_name(clk_mac_speed) failed: %d", ret);
> +                       goto err_free_clk_master_bus;
> +               }
>         }
>
> +       clock_in_out = dev_read_string(dev, "clock_in_out");
> +       if (clock_in_out && !strcmp(clock_in_out, "input"))
> +               data->clock_input = true;
> +       else
> +               data->clock_input = false;
> +
>         /* snps,reset props are deprecated, do bare minimum to support them */
>         if (dev_read_bool(dev, "snps,reset-active-low"))
>                 reset_flags |= GPIOD_ACTIVE_LOW;
> @@ -273,6 +438,12 @@ static int eqos_start_resets_rk(struct udevice *dev)
>
>  static int eqos_stop_clks_rk(struct udevice *dev)
>  {
> +       struct eth_pdata *pdata = dev_get_plat(dev);
> +       struct rockchip_platform_data *data = pdata->priv_pdata;
> +
> +       if (data->ops->set_clock_selection)
> +               data->ops->set_clock_selection(dev, false);
> +
>         return 0;
>  }
>
> @@ -293,6 +464,9 @@ static int eqos_start_clks_rk(struct udevice *dev)
>                 udelay(eqos->reset_delays[2]);
>         }
>
> +       if (data->ops->set_clock_selection)
> +               data->ops->set_clock_selection(dev, true);
> +
>         tx_delay = dev_read_u32_default(dev, "tx_delay", 0x30);
>         rx_delay = dev_read_u32_default(dev, "rx_delay", 0x10);
>
> --
> 2.42.0
>
Reviewed-by: Ramon Fried <rfried.dev@gmail.com>

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

* Re: [PATCH v2 5/7] net: dwc_eth_qos_rockchip: Add support for RK3588
  2023-10-01 19:17 ` [PATCH v2 5/7] net: dwc_eth_qos_rockchip: Add support for RK3588 Jonas Karlman
  2023-10-01 20:04   ` Sebastian Reichel
  2023-10-06 20:35   ` Ramon Fried
@ 2024-01-29 14:45   ` Stefan Agner
  2 siblings, 0 replies; 15+ messages in thread
From: Stefan Agner @ 2024-01-29 14:45 UTC (permalink / raw)
  To: Jonas Karlman
  Cc: Kever Yang, Simon Glass, Philipp Tomsich, Joe Hershberger,
	Ramon Fried, David Wu, Eugen Hristev, Frank Wunderlich,
	Nicolas Frattaroli, u-boot, Sebastian Reichel, Benjamin Gaignard,
	Jan Čermák

Hi Jonas,

On 2023-10-01 21:17, Jonas Karlman wrote:
> Add rk_gmac_ops and other special handling that is needed for GMAC to
> work on RK3588.
> 
> rk_gmac_ops was ported from linux commits:
> 2f2b60a0ec28 ("net: ethernet: stmmac: dwmac-rk: Add gmac support for rk3588")
> 88619e77b33d ("net: stmmac: rk3588: Allow multiple gmac controller")

I've updated from U-Boot 2023.07.2 to 2024.01, and noticed Ethernet
issue on Linux. On a ODROID-M1 with 8GB of RAM I had a packet drop rate
of ~20%:

107 packets transmitted, 87 received, 18.6916% packet loss, time
107390ms
rtt min/avg/max/mdev = 0.337/0.405/0.889/0.076 ms

SSH connections feel very sluggy, presumably due to packet losses.

Strangely, the same build works just fine on another ODROID-M1 with 4GB
of RAM. I swapped Ethernet cable and switches to rule this out. It
really seems to bee that particular unit which is problematic.

Disabling this driver fixes the Etherent issue on Linux.

Do you have an idea what this could be? I am happy to run commands or
test patches to debug this.

--
Stefan


> 
> Signed-off-by: Jonas Karlman <jonas@kwiboo.se>
> Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
> ---
> Cc: David Wu <david.wu@rock-chips.com>
> Cc: Sebastian Reichel <sebastian.reichel@collabora.com>
> Cc: Benjamin Gaignard <benjamin.gaignard@collabora.com>
> ---
> v2:
> - Collect r-b tag
> 
>  drivers/net/dwc_eth_qos.c          |   4 +
>  drivers/net/dwc_eth_qos_rockchip.c | 182 ++++++++++++++++++++++++++++-
>  2 files changed, 182 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
> index 9fb98a2c3c74..dc04416865dd 100644
> --- a/drivers/net/dwc_eth_qos.c
> +++ b/drivers/net/dwc_eth_qos.c
> @@ -1712,6 +1712,10 @@ static const struct udevice_id eqos_ids[] = {
>  		.compatible = "rockchip,rk3568-gmac",
>  		.data = (ulong)&eqos_rockchip_config
>  	},
> +	{
> +		.compatible = "rockchip,rk3588-gmac",
> +		.data = (ulong)&eqos_rockchip_config
> +	},
>  #endif
>  #if IS_ENABLED(CONFIG_DWC_ETH_QOS_QCOM)
>  	{
> diff --git a/drivers/net/dwc_eth_qos_rockchip.c
> b/drivers/net/dwc_eth_qos_rockchip.c
> index 05edc098f50d..20fd3a25c3dd 100644
> --- a/drivers/net/dwc_eth_qos_rockchip.c
> +++ b/drivers/net/dwc_eth_qos_rockchip.c
> @@ -28,6 +28,7 @@ struct rk_gmac_ops {
>  			    int tx_delay, int rx_delay);
>  	int (*set_to_rmii)(struct udevice *dev);
>  	int (*set_gmac_speed)(struct udevice *dev);
> +	void (*set_clock_selection)(struct udevice *dev, bool enable);
>  	u32 regs[3];
>  };
>  
> @@ -35,7 +36,9 @@ struct rockchip_platform_data {
>  	struct reset_ctl_bulk resets;
>  	const struct rk_gmac_ops *ops;
>  	int id;
> +	bool clock_input;
>  	struct regmap *grf;
> +	struct regmap *php_grf;
>  };
>  
>  #define HIWORD_UPDATE(val, mask, shift) \
> @@ -129,6 +132,137 @@ static int rk3568_set_gmac_speed(struct udevice *dev)
>  	return 0;
>  }
>  
> +/* sys_grf */
> +#define RK3588_GRF_GMAC_CON7			0x031c
> +#define RK3588_GRF_GMAC_CON8			0x0320
> +#define RK3588_GRF_GMAC_CON9			0x0324
> +
> +#define RK3588_GMAC_RXCLK_DLY_ENABLE(id)	GRF_BIT(2 * (id) + 3)
> +#define RK3588_GMAC_RXCLK_DLY_DISABLE(id)	GRF_CLR_BIT(2 * (id) + 3)
> +#define RK3588_GMAC_TXCLK_DLY_ENABLE(id)	GRF_BIT(2 * (id) + 2)
> +#define RK3588_GMAC_TXCLK_DLY_DISABLE(id)	GRF_CLR_BIT(2 * (id) + 2)
> +
> +#define RK3588_GMAC_CLK_RX_DL_CFG(val)		HIWORD_UPDATE(val, 0xFF, 8)
> +#define RK3588_GMAC_CLK_TX_DL_CFG(val)		HIWORD_UPDATE(val, 0xFF, 0)
> +
> +/* php_grf */
> +#define RK3588_GRF_GMAC_CON0			0x0008
> +#define RK3588_GRF_CLK_CON1			0x0070
> +
> +#define RK3588_GMAC_PHY_INTF_SEL_RGMII(id)	\
> +	(GRF_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_CLR_BIT(5 +
> (id) * 6))
> +#define RK3588_GMAC_PHY_INTF_SEL_RMII(id)	\
> +	(GRF_CLR_BIT(3 + (id) * 6) | GRF_CLR_BIT(4 + (id) * 6) | GRF_BIT(5 +
> (id) * 6))
> +
> +#define RK3588_GMAC_CLK_RMII_MODE(id)		GRF_BIT(5 * (id))
> +#define RK3588_GMAC_CLK_RGMII_MODE(id)		GRF_CLR_BIT(5 * (id))
> +
> +#define RK3588_GMAC_CLK_SELET_CRU(id)		GRF_BIT(5 * (id) + 4)
> +#define RK3588_GMAC_CLK_SELET_IO(id)		GRF_CLR_BIT(5 * (id) + 4)
> +
> +#define RK3588_GMAC_CLK_RMII_DIV2(id)		GRF_BIT(5 * (id) + 2)
> +#define RK3588_GMAC_CLK_RMII_DIV20(id)		GRF_CLR_BIT(5 * (id) + 2)
> +
> +#define RK3588_GMAC_CLK_RGMII_DIV1(id)		\
> +			(GRF_CLR_BIT(5 * (id) + 2) | GRF_CLR_BIT(5 * (id) + 3))
> +#define RK3588_GMAC_CLK_RGMII_DIV5(id)		\
> +			(GRF_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3))
> +#define RK3588_GMAC_CLK_RGMII_DIV50(id)		\
> +			(GRF_CLR_BIT(5 * (id) + 2) | GRF_BIT(5 * (id) + 3))
> +
> +#define RK3588_GMAC_CLK_RMII_GATE(id)		GRF_BIT(5 * (id) + 1)
> +#define RK3588_GMAC_CLK_RMII_NOGATE(id)		GRF_CLR_BIT(5 * (id) + 1)
> +
> +static int rk3588_set_to_rgmii(struct udevice *dev,
> +			       int tx_delay, int rx_delay)
> +{
> +	struct eth_pdata *pdata = dev_get_plat(dev);
> +	struct rockchip_platform_data *data = pdata->priv_pdata;
> +	u32 offset_con, id = data->id;
> +
> +	offset_con = data->id == 1 ? RK3588_GRF_GMAC_CON9 :
> +				     RK3588_GRF_GMAC_CON8;
> +
> +	regmap_write(data->php_grf, RK3588_GRF_GMAC_CON0,
> +		     RK3588_GMAC_PHY_INTF_SEL_RGMII(id));
> +
> +	regmap_write(data->php_grf, RK3588_GRF_CLK_CON1,
> +		     RK3588_GMAC_CLK_RGMII_MODE(id));
> +
> +	regmap_write(data->grf, RK3588_GRF_GMAC_CON7,
> +		     RK3588_GMAC_RXCLK_DLY_ENABLE(id) |
> +		     RK3588_GMAC_TXCLK_DLY_ENABLE(id));
> +
> +	regmap_write(data->grf, offset_con,
> +		     RK3588_GMAC_CLK_RX_DL_CFG(rx_delay) |
> +		     RK3588_GMAC_CLK_TX_DL_CFG(tx_delay));
> +
> +	return 0;
> +}
> +
> +static int rk3588_set_to_rmii(struct udevice *dev)
> +{
> +	struct eth_pdata *pdata = dev_get_plat(dev);
> +	struct rockchip_platform_data *data = pdata->priv_pdata;
> +
> +	regmap_write(data->php_grf, RK3588_GRF_GMAC_CON0,
> +		     RK3588_GMAC_PHY_INTF_SEL_RMII(data->id));
> +
> +	regmap_write(data->php_grf, RK3588_GRF_CLK_CON1,
> +		     RK3588_GMAC_CLK_RMII_MODE(data->id));
> +
> +	return 0;
> +}
> +
> +static int rk3588_set_gmac_speed(struct udevice *dev)
> +{
> +	struct eqos_priv *eqos = dev_get_priv(dev);
> +	struct eth_pdata *pdata = dev_get_plat(dev);
> +	struct rockchip_platform_data *data = pdata->priv_pdata;
> +	u32 val = 0, id = data->id;
> +
> +	switch (eqos->phy->speed) {
> +	case SPEED_10:
> +		if (pdata->phy_interface == PHY_INTERFACE_MODE_RMII)
> +			val = RK3588_GMAC_CLK_RMII_DIV20(id);
> +		else
> +			val = RK3588_GMAC_CLK_RGMII_DIV50(id);
> +		break;
> +	case SPEED_100:
> +		if (pdata->phy_interface == PHY_INTERFACE_MODE_RMII)
> +			val = RK3588_GMAC_CLK_RMII_DIV2(id);
> +		else
> +			val = RK3588_GMAC_CLK_RGMII_DIV5(id);
> +		break;
> +	case SPEED_1000:
> +		if (pdata->phy_interface != PHY_INTERFACE_MODE_RMII)
> +			val = RK3588_GMAC_CLK_RGMII_DIV1(id);
> +		else
> +			return -EINVAL;
> +		break;
> +	default:
> +		return -EINVAL;
> +	}
> +
> +	regmap_write(data->php_grf, RK3588_GRF_CLK_CON1, val);
> +
> +	return 0;
> +}
> +
> +static void rk3588_set_clock_selection(struct udevice *dev, bool enable)
> +{
> +	struct eth_pdata *pdata = dev_get_plat(dev);
> +	struct rockchip_platform_data *data = pdata->priv_pdata;
> +
> +	u32 val = data->clock_input ? RK3588_GMAC_CLK_SELET_IO(data->id) :
> +				      RK3588_GMAC_CLK_SELET_CRU(data->id);
> +
> +	val |= enable ? RK3588_GMAC_CLK_RMII_NOGATE(data->id) :
> +			RK3588_GMAC_CLK_RMII_GATE(data->id);
> +
> +	regmap_write(data->php_grf, RK3588_GRF_CLK_CON1, val);
> +}
> +
>  static const struct rk_gmac_ops rk_gmac_ops[] = {
>  	{
>  		.compatible = "rockchip,rk3568-gmac",
> @@ -141,6 +275,18 @@ static const struct rk_gmac_ops rk_gmac_ops[] = {
>  			0x0, /* sentinel */
>  		},
>  	},
> +	{
> +		.compatible = "rockchip,rk3588-gmac",
> +		.set_to_rgmii = rk3588_set_to_rgmii,
> +		.set_to_rmii = rk3588_set_to_rmii,
> +		.set_gmac_speed = rk3588_set_gmac_speed,
> +		.set_clock_selection = rk3588_set_clock_selection,
> +		.regs = {
> +			0xfe1b0000, /* gmac0 */
> +			0xfe1c0000, /* gmac1 */
> +			0x0, /* sentinel */
> +		},
> +	},
>  	{ }
>  };
>  
> @@ -162,6 +308,7 @@ static int eqos_probe_resources_rk(struct udevice *dev)
>  	struct eqos_priv *eqos = dev_get_priv(dev);
>  	struct eth_pdata *pdata = dev_get_plat(dev);
>  	struct rockchip_platform_data *data;
> +	const char *clock_in_out;
>  	int reset_flags = GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE;
>  	int ret;
>  
> @@ -199,6 +346,16 @@ static int eqos_probe_resources_rk(struct udevice *dev)
>  		goto err_free;
>  	}
>  
> +	if (device_is_compatible(dev, "rockchip,rk3588-gmac")) {
> +		data->php_grf =
> +			syscon_regmap_lookup_by_phandle(dev, "rockchip,php-grf");
> +		if (IS_ERR(data->php_grf)) {
> +			dev_err(dev, "Missing rockchip,php-grf property\n");
> +			ret = -EINVAL;
> +			goto err_free;
> +		}
> +	}
> +
>  	ret = reset_get_bulk(dev, &data->resets);
>  	if (ret < 0)
>  		goto err_free;
> @@ -211,12 +368,20 @@ static int eqos_probe_resources_rk(struct udevice *dev)
>  		goto err_release_resets;
>  	}
>  
> -	ret = clk_get_by_name(dev, "clk_mac_speed", &eqos->clk_tx);
> -	if (ret) {
> -		dev_dbg(dev, "clk_get_by_name(clk_mac_speed) failed: %d", ret);
> -		goto err_free_clk_master_bus;
> +	if (device_is_compatible(dev, "rockchip,rk3568-gmac")) {
> +		ret = clk_get_by_name(dev, "clk_mac_speed", &eqos->clk_tx);
> +		if (ret) {
> +			dev_dbg(dev, "clk_get_by_name(clk_mac_speed) failed: %d", ret);
> +			goto err_free_clk_master_bus;
> +		}
>  	}
>  
> +	clock_in_out = dev_read_string(dev, "clock_in_out");
> +	if (clock_in_out && !strcmp(clock_in_out, "input"))
> +		data->clock_input = true;
> +	else
> +		data->clock_input = false;
> +
>  	/* snps,reset props are deprecated, do bare minimum to support them */
>  	if (dev_read_bool(dev, "snps,reset-active-low"))
>  		reset_flags |= GPIOD_ACTIVE_LOW;
> @@ -273,6 +438,12 @@ static int eqos_start_resets_rk(struct udevice *dev)
>  
>  static int eqos_stop_clks_rk(struct udevice *dev)
>  {
> +	struct eth_pdata *pdata = dev_get_plat(dev);
> +	struct rockchip_platform_data *data = pdata->priv_pdata;
> +
> +	if (data->ops->set_clock_selection)
> +		data->ops->set_clock_selection(dev, false);
> +
>  	return 0;
>  }
>  
> @@ -293,6 +464,9 @@ static int eqos_start_clks_rk(struct udevice *dev)
>  		udelay(eqos->reset_delays[2]);
>  	}
>  
> +	if (data->ops->set_clock_selection)
> +		data->ops->set_clock_selection(dev, true);
> +
>  	tx_delay = dev_read_u32_default(dev, "tx_delay", 0x30);
>  	rx_delay = dev_read_u32_default(dev, "rx_delay", 0x10);

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

end of thread, other threads:[~2024-01-29 14:45 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-01 19:17 [PATCH v2 0/7] rockchip: Add GMAC support for RK3568 and RK3588 Jonas Karlman
2023-10-01 19:17 ` [PATCH v2 1/7] net: dwc_eth_qos: Drop unused rx_pkt from eqos_priv Jonas Karlman
2023-10-06 20:32   ` Ramon Fried
2023-10-01 19:17 ` [PATCH v2 2/7] net: dwc_eth_qos: Return error code when start fails Jonas Karlman
2023-10-06 20:32   ` Ramon Fried
2023-10-01 19:17 ` [PATCH v2 3/7] net: dwc_eth_qos: Stop spam of RX packet not available message Jonas Karlman
2023-10-06 20:32   ` Ramon Fried
2023-10-01 19:17 ` [PATCH v2 4/7] net: dwc_eth_qos: Add glue driver for GMAC on Rockchip RK3568 Jonas Karlman
2023-10-06 20:33   ` Ramon Fried
2023-10-01 19:17 ` [PATCH v2 5/7] net: dwc_eth_qos_rockchip: Add support for RK3588 Jonas Karlman
2023-10-01 20:04   ` Sebastian Reichel
2023-10-06 20:35   ` Ramon Fried
2024-01-29 14:45   ` Stefan Agner
2023-10-01 19:17 ` [PATCH v2 6/7] configs: rockchip: Enable ethernet driver on RK356x boards Jonas Karlman
2023-10-01 19:17 ` [PATCH v2 7/7] configs: rockchip: Enable ethernet driver on RK3588 boards Jonas Karlman

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.