u-boot.lists.denx.de archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/3] net: add RZ/N1 ethernet drivers
@ 2026-08-14 18:30 Ralph Siemsen
  2026-08-14 18:30 ` [PATCH v2 1/3] net: add r9a06g032 A5PSW switch driver Ralph Siemsen
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Ralph Siemsen @ 2026-08-14 18:30 UTC (permalink / raw)
  To: u-boot
  Cc: Tom Rini, Marek Vasut, Jerome Forissier, Quentin Schulz,
	Johan Jonker, Julien Stephan, David Lechner, Ralph Siemsen

The Reneas RZ/N1 contains two GMAC supported by Designware driver.
An additional compatible string is needed for this.

One of the GMAC is routed to an internal 5-port switch, which needs a
new driver (A5PSW). This driver is adapted from Linux but simplified,
only implementing basic port-based switching, not full DSA.

The second GMAC, as well as the downstream switch ports, are routed
through media converter blocks (MII/GMII/RGMII). A new driver (MIIC) is
needed to configure speed/duplex for the converters.

Signed-off-by: Ralph Siemsen <ralph.siemsen@linaro.org>
---
Changes in v2:
- split out of the series "Renesas RZ/N1 additional drivers"
  https://lore.kernel.org/u-boot/20260731-rzn1-2026-07-v1-5-af2ce80db9d8@linaro.org/
  https://lore.kernel.org/u-boot/20260731-rzn1-2026-07-v1-6-af2ce80db9d8@linaro.org/
  https://lore.kernel.org/u-boot/20260731-rzn1-2026-07-v1-7-af2ce80db9d8@linaro.org/

---
Ralph Siemsen (3):
      net: add r9a06g032 A5PSW switch driver
      net: add r9a06g032 MIIC driver
      net: designware: add r9a06g032 compatible

 drivers/net/Kconfig      |  12 ++
 drivers/net/Makefile     |   2 +
 drivers/net/designware.c |   1 +
 drivers/net/rzn1_a5psw.c | 377 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/net/rzn1_miic.c  | 193 ++++++++++++++++++++++++
 5 files changed, 585 insertions(+)
---
base-commit: 36c377b9859ffb53eb1e39ea31e8d96d1e0fe1e5
change-id: 20260811-rzn1-2026-10-net-a080caf05365

Best regards,
--  
Ralph Siemsen <ralph.siemsen@linaro.org>


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

* [PATCH v2 1/3] net: add r9a06g032 A5PSW switch driver
  2026-08-14 18:30 [PATCH v2 0/3] net: add RZ/N1 ethernet drivers Ralph Siemsen
@ 2026-08-14 18:30 ` Ralph Siemsen
  2026-08-14 22:14   ` Marek Vasut via U-Boot
  2026-08-14 18:30 ` [PATCH v2 2/3] net: add r9a06g032 MIIC driver Ralph Siemsen
  2026-08-14 18:30 ` [PATCH v2 3/3] net: designware: add r9a06g032 compatible Ralph Siemsen
  2 siblings, 1 reply; 7+ messages in thread
From: Ralph Siemsen @ 2026-08-14 18:30 UTC (permalink / raw)
  To: u-boot
  Cc: Tom Rini, Marek Vasut, Jerome Forissier, Quentin Schulz,
	Johan Jonker, Julien Stephan, David Lechner, Ralph Siemsen

Driver for the Advanced 5-port Ethernet switch (A5PSW) on RZ/N1 SoC.

The A5PSW switch is modeled using DSA framework, but without actually
tagging packets. The goal is just to support network booting over a
single Ethernet port.

This driver is loosely based on the Linux driver by Clément Léger
888cdb892b61 ("net: dsa: rzn1-a5psw: add Renesas RZ/N1 advanced 5 port
switch driver") but without any of the VLAN tagging or other features.

Signed-off-by: Ralph Siemsen <ralph.siemsen@linaro.org>
---
 drivers/net/Kconfig      |   6 +
 drivers/net/Makefile     |   1 +
 drivers/net/rzn1_a5psw.c | 377 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 384 insertions(+)

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index faa08e9ebba..edc4cb29598 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -880,6 +880,12 @@ config RENESAS_RAVB
 	  This driver implements support for the Ethernet AVB block in
 	  several Renesas R-Car and RZ SoCs.
 
+config RZN1_A5PSW
+	bool "Renesas RZ/N1 A5PSW ethernet switch"
+	help
+	  Support the Advanced 5-Port ethernet switch (A5PSW) found in
+	  the Renesas RZ/N1 SoC.
+
 config MPC8XX_FEC
 	bool "Fast Ethernet Controller on MPC8XX"
 	depends on MPC8xx
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 4c1f4094ab2..b8f270ae233 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -94,6 +94,7 @@ obj-$(CONFIG_PCNET) += pcnet.o
 obj-$(CONFIG_PIC32_ETH) += pic32_mdio.o pic32_eth.o
 obj-$(CONFIG_RENESAS_ETHER_SWITCH) += rswitch.o
 obj-$(CONFIG_RENESAS_RAVB) += ravb.o
+obj-$(CONFIG_RZN1_A5PSW) += rzn1_a5psw.o
 obj-$(CONFIG_RTL8139) += rtl8139.o
 obj-$(CONFIG_RTL8169) += rtl8169.o
 obj-$(CONFIG_SH_ETHER) += sh_eth.o
diff --git a/drivers/net/rzn1_a5psw.c b/drivers/net/rzn1_a5psw.c
new file mode 100644
index 00000000000..2733ebcdfbb
--- /dev/null
+++ b/drivers/net/rzn1_a5psw.c
@@ -0,0 +1,377 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Adapted from Linux drivers/net/dsa/rzn1_a5psw.c
+ * but without DSA tag support.
+ */
+
+#include <clk.h>
+#include <dm/device.h>
+#include <dm/device_compat.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dm/of_extra.h>
+#include <linux/bitfield.h>
+#include <linux/delay.h>
+#include <miiphy.h>
+#include <net/dsa.h>
+#include <syscon.h>
+#include <regmap.h>
+#include <reset.h>
+
+struct rzn1_a5psw_plat {
+	struct clk_bulk bulk;
+	struct regmap *regmap;
+	struct udevice *miic;
+	struct regmap *syscon;
+};
+
+/* MoreThanIP 5pt Switch regs */
+#define MT5PT_REVISION		0x0
+#define MT5PT_SCRATCH		0x4
+#define MT5PT_PORT_ENA		0x8
+#define  MT5PT_PORT_ENA_TX(x)		BIT(16 + (x))
+#define  MT5PT_PORT_ENA_RX(x)		BIT(x)
+#define  MT5PT_PORT_ENA_TXRX(x)		((MT5PT_PORT_ENA_TX(0) | MT5PT_PORT_ENA_RX(0)) << (x))
+#define MT5PT_AUTH_PORT(x)	(0x240 + (x) * 4)
+#define  MT5PT_AUTH_PORT_AUTHORIZED	BIT(0)
+#define  MT5PT_AUTH_PORT_CONTROLLED	BIT(1)
+#define  MT5PT_AUTH_PORT_EAPOL_EN	BIT(2)
+#define  MT5PT_AUTH_PORT_GUEST		BIT(3)
+#define  MT5PT_AUTH_PORT_EAPOL_PORT(x)	((x) << 12)
+#define MT5PT_MDIO_CFG_STATUS	0x700
+#define MT5PT_MDIO_COMMAND	0x704
+#define MT5PT_MDIO_DATA		0x708
+#define MT5PT_MAC_CMD_CFGn(x)	(0x808 + (x) * 0x400)
+#define  MT5PT_TX_ENA			BIT(0)
+#define  MT5PT_RX_ENA			BIT(1)
+#define  MT5PT_MBPS_1000		BIT(3)
+#define  MT5PT_HALF_DUPLEX		BIT(10)
+#define MT5PT_MAC_FRM_LENGTHn(x)	(0x814 + (x) * 0x400)
+#define MT5PT_DUMMY_NOOP	0x5000
+
+static void rzn1_switch_write(struct regmap *regmap, uint offset, uint val)
+{
+	/*
+	 * MTIP switch errata:
+	 * There is a clock-crossing issue within the switch,
+	 * which can cause writes to be corrupted.
+	 * To avoid the problem, perform a dummy write with the
+	 * same data value, prior to the actual write.
+	 */
+	regmap_write(regmap, MT5PT_DUMMY_NOOP, val);
+	regmap_write(regmap, offset, val);
+}
+
+static void rzn1_switch_port_speed_duplex(struct udevice *dev, int port, int speed, int duplex)
+{
+	struct rzn1_a5psw_plat *plat = dev_get_plat(dev);
+	struct regmap *regmap = plat->regmap;
+	u32 val;
+
+	regmap_read(regmap, MT5PT_MAC_CMD_CFGn(port), &val);
+	val &= ~(MT5PT_HALF_DUPLEX | MT5PT_MBPS_1000);
+	if (speed == SPEED_1000)
+		val |= MT5PT_MBPS_1000;
+	if (duplex == DUPLEX_HALF)
+		val |= MT5PT_HALF_DUPLEX;
+
+	rzn1_switch_write(regmap, MT5PT_MAC_CMD_CFGn(port), val);
+}
+
+static void rzn1_switch_port_enable(struct udevice *dev, int port)
+{
+	struct rzn1_a5psw_plat *plat = dev_get_plat(dev);
+	struct regmap *regmap = plat->regmap;
+	u32 val;
+
+	regmap_read(regmap, MT5PT_AUTH_PORT(port), &val);
+	val |= MT5PT_AUTH_PORT_AUTHORIZED;
+	rzn1_switch_write(regmap, MT5PT_AUTH_PORT(port), val);
+
+	regmap_read(regmap, MT5PT_PORT_ENA, &val);
+	val |= MT5PT_PORT_ENA_TXRX(port);
+	rzn1_switch_write(regmap, MT5PT_PORT_ENA, val);
+
+	/* Max frame size */
+	rzn1_switch_write(regmap, MT5PT_MAC_FRM_LENGTHn(port), 9224);
+}
+
+static void rzn1_switch_port_disable(struct udevice *dev, int port)
+{
+	struct rzn1_a5psw_plat *plat = dev_get_plat(dev);
+	struct regmap *regmap = plat->regmap;
+	u32 val;
+
+	regmap_read(regmap, MT5PT_AUTH_PORT(port), &val);
+	val &= ~MT5PT_AUTH_PORT_AUTHORIZED;
+	rzn1_switch_write(regmap, MT5PT_AUTH_PORT(port), val);
+
+	regmap_read(regmap, MT5PT_PORT_ENA, &val);
+	val &= ~MT5PT_PORT_ENA_TXRX(port);
+	rzn1_switch_write(regmap, MT5PT_PORT_ENA, val);
+}
+
+static int rzn1_phy_wait(struct udevice *dev)
+{
+	struct rzn1_a5psw_plat *plat = dev_get_plat(dev->parent);
+	struct regmap *regmap = plat->regmap;
+	u32 timeout = 100;
+	int ret;
+	u32 val;
+
+	do {
+		ret = regmap_read(regmap, MT5PT_MDIO_CFG_STATUS, &val);
+		if (ret == 0 && (val & BIT(0)) == 0)
+			return 0;
+
+		mdelay(1);
+	} while (--timeout);
+
+	return -ETIMEDOUT;
+}
+
+static int rzn1_a5psw_mdio_read(struct udevice *dev, int addr, int devad, int reg)
+{
+	struct rzn1_a5psw_plat *plat = dev_get_plat(dev->parent);
+	struct regmap *regmap = plat->regmap;
+	int ret;
+	u32 val = BIT(15) | ((addr & 0x1f) << 5) | (reg & 0x1f);
+
+	/* Clause 22 only */
+	rzn1_switch_write(regmap, MT5PT_MDIO_COMMAND, val);
+
+	ret = rzn1_phy_wait(dev);
+	if (ret) {
+		dev_warn(dev, "PHY read timeout\n");
+		return ret;
+	}
+
+	ret = regmap_read(regmap, MT5PT_MDIO_DATA, &val);
+	if (ret) {
+		dev_warn(dev, "PHY read error\n");
+		return ret;
+	}
+	val &= 0xffff;
+
+	// TODO: check CFG_STATUS for READERR
+
+	dev_dbg(dev, "addr=0x%x reg=0x%x read 0x%04x\n", addr, reg, val);
+
+	return val;
+}
+
+static int rzn1_a5psw_mdio_write(struct udevice *dev, int addr, int devad,
+				 int reg, u16 val)
+{
+	struct rzn1_a5psw_plat *plat = dev_get_plat(dev->parent);
+	struct regmap *regmap = plat->regmap;
+	int ret;
+	u32 cmd = ((addr & 0x1f) << 5) | (reg & 0x1f);
+
+	dev_dbg(dev, "addr=0x%x reg=0x%x write 0x%04x\n", addr, reg, val);
+
+	/* Clause 22 only */
+	rzn1_switch_write(regmap, MT5PT_MDIO_COMMAND, cmd);
+	rzn1_switch_write(regmap, MT5PT_MDIO_DATA, val);
+
+	ret = rzn1_phy_wait(dev);
+	if (ret) {
+		dev_warn(dev, "PHY write timeout\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct mdio_ops rzn1_a5psw_mdio_ops = {
+	.read = rzn1_a5psw_mdio_read,
+	.write = rzn1_a5psw_mdio_write,
+};
+
+static int rzn1_a5psw_mdio_bind(struct udevice *dev)
+{
+	char name[32];
+	static int num_devices;
+
+	sprintf(name, "rzn1-a5psw-mdio-%d", num_devices++);
+	device_set_name(dev, name);
+
+	return 0;
+}
+
+U_BOOT_DRIVER(rzn1_a5psw_mdio) = {
+	.name		= "rzn1_a5psw_mdio",
+	.id		= UCLASS_MDIO,
+	.ops		= &rzn1_a5psw_mdio_ops,
+	.bind		= rzn1_a5psw_mdio_bind,
+	.plat_auto	= sizeof(struct mdio_perdev_priv),
+};
+
+static int rzn1_a5psw_port_probe(struct udevice *dev, int port, struct phy_device *phy)
+{
+	/* Called once when switch is probed */
+	return phy_config(phy);
+}
+
+void rzn1_rgmii_rmii_conv_speed(struct udevice *dev, int phy,
+				int full_duplex, int speed);
+
+static int rzn1_a5psw_port_enable(struct udevice *dev, int port, struct phy_device *phy)
+{
+	struct rzn1_a5psw_plat *plat = dev_get_plat(dev);
+
+	/* CPU port is already enabled */
+	if (port == 4)
+		return 0;
+
+	/* Get speed/duplex from PHY */
+	genphy_update_link(phy);
+	if (!phy->link) {
+		dev_err(dev, "PHY %s no ethernet link\n", phy->dev->name);
+		return 0;
+	}
+	genphy_parse_link(phy);
+
+	/* Program the converter accoringly */
+	dev_info(dev, "MIIC = %p\n", plat->miic);
+	rzn1_rgmii_rmii_conv_speed(plat->miic, 4 - port, phy->duplex, phy->speed);
+
+	/* Program the switch port accordingly */
+	dev_info(dev, "%s port=%d using speed=%d\n", __func__, port, phy->speed);
+	rzn1_switch_port_speed_duplex(dev, port, phy->speed, phy->duplex);
+	rzn1_switch_port_enable(dev, port);
+	return 0;
+}
+
+static void rzn1_a5psw_port_disable(struct udevice *dev, int port, struct phy_device *phy)
+{
+	/* CPU port is already enabled */
+	if (port == 4)
+		return;
+
+	rzn1_switch_port_disable(dev, port);
+}
+
+static const struct dsa_ops rzn1_a5psw_dsa_ops = {
+	.port_probe = rzn1_a5psw_port_probe,
+	.port_enable = rzn1_a5psw_port_enable,
+	.port_disable = rzn1_a5psw_port_disable,
+};
+
+static int rzn1_a5psw_probe_mdio(struct udevice *dev)
+{
+	struct udevice *mdev;
+	const char *name;
+	ofnode node;
+	int ret;
+
+	/* bind phy ports of mdio child node to rzn1_a5psw_mdio device */
+	node = dev_read_subnode(dev, "mdio");
+	if (!ofnode_valid(node))
+		return 0;
+
+	name = ofnode_get_name(node);
+	ret = device_bind_driver_to_node(dev,
+					 "rzn1_a5psw_mdio",
+					 name, node, NULL);
+	if (ret) {
+		dev_err(dev, "failed to bind %s: %d\n", name, ret);
+	} else {
+		/* need to probe it as there is no compatible to do so */
+		ret = uclass_get_device_by_ofnode(UCLASS_MDIO, node, &mdev);
+		if (ret)
+			dev_err(dev, "failed to probe %s: %d\n", name, ret);
+	}
+
+	return ret;
+}
+
+static int rzn1_a5psw_probe(struct udevice *dev)
+{
+	struct rzn1_a5psw_plat *plat = dev_get_plat(dev);
+	int ret;
+
+	dev_dbg(dev, "%s:%d\n", __func__, __LINE__);
+
+	/* Enable clocks */
+	ret = clk_get_bulk(dev, &plat->bulk);
+	if (ret) {
+		dev_err(dev, "Failed to get clocks\n");
+		return ret;
+	}
+	ret = clk_enable_bulk(&plat->bulk);
+	if (ret) {
+		dev_err(dev, "Failed to enable clocks\n");
+		return ret;
+	}
+
+	/* Access the registers */
+	ret = regmap_init_mem(dev_ofnode(dev), &plat->regmap);
+	if (ret) {
+		dev_err(dev, "Failed to get regmap\n");
+		return ret;
+	}
+
+	/* Find the MIIC driver */
+	ret = uclass_get_device_by_name(UCLASS_MISC, "eth-miic@44030000", &plat->miic);
+	if (ret) {
+		dev_err(dev, "Failed to get MIIC\n");
+		return ret;
+	}
+	dev_dbg(dev, "got MIIC %p <%s>\n", plat->miic, plat->miic->name);
+
+	/* Upstream port is always 1Gbps */
+	rzn1_switch_port_speed_duplex(dev, 4, SPEED_1000, DUPLEX_FULL);
+	rzn1_switch_port_enable(dev, 4);
+
+	/* Some extra resets are located in system controller */
+	plat->syscon = syscon_regmap_lookup_by_phandle(dev, "syscon");
+	if (IS_ERR(plat->syscon)) {
+		dev_err(dev, "No syscon node found\n");
+		return PTR_ERR(plat->syscon);
+	}
+
+	/* Clear ETH and CLK25 resets */
+#define RZN1_SYSCTRL_PWRCTRL_SWITCH 0x188
+	regmap_update_bits(plat->syscon, RZN1_SYSCTRL_PWRCTRL_SWITCH,
+			   BIT(4) | BIT(3), BIT(4) | BIT(3));
+
+	/* Reset all PHYs */
+	struct gpio_desc phy_reset_gpio;
+	u32 phy_reset_delay;
+
+	ret = gpio_request_by_name(dev, "phy-reset-gpios", 0,
+				   &phy_reset_gpio, GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
+	if (ret) {
+		dev_err(dev, "failed to get phy-reset-gpios: %d\n", ret);
+		return ret;
+	}
+
+	phy_reset_delay = dev_read_u32_default(dev, "phy-reset-duration", 15);
+
+	dm_gpio_set_value(&phy_reset_gpio, 1);
+	mdelay(phy_reset_delay);
+	dm_gpio_set_value(&phy_reset_gpio, 0);
+
+	ret = rzn1_a5psw_probe_mdio(dev);
+	if (ret) {
+		dev_warn(dev, "mdio probe failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static const struct udevice_id rzn1_a5psw_ids[] = {
+	{ .compatible = "renesas,rzn1-a5psw" },
+	{ }
+};
+
+U_BOOT_DRIVER(rzn1_a5psw) = {
+	.name		= "rzn1_a5psw",
+	.id		= UCLASS_DSA,
+	.of_match	= rzn1_a5psw_ids,
+	.probe		= rzn1_a5psw_probe,
+	.ops		= &rzn1_a5psw_dsa_ops,
+	.plat_auto	= sizeof(struct rzn1_a5psw_plat),
+};

-- 
2.55.0


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

* [PATCH v2 2/3] net: add r9a06g032 MIIC driver
  2026-08-14 18:30 [PATCH v2 0/3] net: add RZ/N1 ethernet drivers Ralph Siemsen
  2026-08-14 18:30 ` [PATCH v2 1/3] net: add r9a06g032 A5PSW switch driver Ralph Siemsen
@ 2026-08-14 18:30 ` Ralph Siemsen
  2026-08-14 22:18   ` Marek Vasut via U-Boot
  2026-08-14 18:30 ` [PATCH v2 3/3] net: designware: add r9a06g032 compatible Ralph Siemsen
  2 siblings, 1 reply; 7+ messages in thread
From: Ralph Siemsen @ 2026-08-14 18:30 UTC (permalink / raw)
  To: u-boot
  Cc: Tom Rini, Marek Vasut, Jerome Forissier, Quentin Schulz,
	Johan Jonker, Julien Stephan, David Lechner, Ralph Siemsen

Driver for the MII/GMII/RGMII media converter blocks found in the
Renesas RZ/N1 SoC. These converters sit in the Ethernet data path,
and need to be configured with speed/duplex as detected by the PHY.

Signed-off-by: Ralph Siemsen <ralph.siemsen@linaro.org>
---
 drivers/net/Kconfig     |   6 ++
 drivers/net/Makefile    |   1 +
 drivers/net/rzn1_miic.c | 193 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 200 insertions(+)

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index edc4cb29598..659e9fd82d0 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -886,6 +886,12 @@ config RZN1_A5PSW
 	  Support the Advanced 5-Port ethernet switch (A5PSW) found in
 	  the Renesas RZ/N1 SoC.
 
+config RZN1_MIIC
+	bool "Renesas RZ/N1 MIIC ethernet accessory"
+	help
+	  Support the MIIC ethernet accessory found in Renesas RZ/N1 SoC.
+	  These are media converters for MII/GMII/RGMII.
+
 config MPC8XX_FEC
 	bool "Fast Ethernet Controller on MPC8XX"
 	depends on MPC8xx
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index b8f270ae233..049212b1fd2 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -95,6 +95,7 @@ obj-$(CONFIG_PIC32_ETH) += pic32_mdio.o pic32_eth.o
 obj-$(CONFIG_RENESAS_ETHER_SWITCH) += rswitch.o
 obj-$(CONFIG_RENESAS_RAVB) += ravb.o
 obj-$(CONFIG_RZN1_A5PSW) += rzn1_a5psw.o
+obj-$(CONFIG_RZN1_MIIC) += rzn1_miic.o
 obj-$(CONFIG_RTL8139) += rtl8139.o
 obj-$(CONFIG_RTL8169) += rtl8169.o
 obj-$(CONFIG_SH_ETHER) += sh_eth.o
diff --git a/drivers/net/rzn1_miic.c b/drivers/net/rzn1_miic.c
new file mode 100644
index 00000000000..491923d8511
--- /dev/null
+++ b/drivers/net/rzn1_miic.c
@@ -0,0 +1,193 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * MII/GMII/RGMII converter support
+ *
+ * Based loosely on Linux drivers/net/pcs/pcs-rzn1-miic.c
+ * and the older driver in Renesas u-boot.
+ */
+
+#include <clk.h>
+#include <dm/device.h>
+#include <dm/device_compat.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dm/of_extra.h>
+#include <linux/bitfield.h>
+#include <linux/delay.h>
+#include <miiphy.h>
+#include <net/dsa.h>
+#include <regmap.h>
+
+struct rzn1_miic_plat {
+	struct clk_bulk bulk;
+	struct regmap *regmap;
+};
+
+/* RIN Ether Accessory (Switch Control) regs */
+#define PRCMD			0x0		/* Ethernet Protect */
+#define IDCODE			0x4		/* EtherSwitch IDCODE */
+#define MODCTRL			0x8		/* Mode Control */
+#define PTP_MODE_CTRL		0xc		/* PTP Mode Control */
+#define PHY_LINK_MODE		0x14		/* Ethernet PHY Link Mode */
+
+/* RIN RGMII/RMII Converter regs */
+#define CONVCTRL(x)		(0x100 + ((x)) * 4) /* RGMII/RMII Converter */
+#define  CONVCTRL_10_MBPS		0
+#define  CONVCTRL_100_MBPS		BIT(0)
+#define  CONVCTRL_1000_MBPS		BIT(1)
+#define  CONVCTRL_MII			0
+#define  CONVCTRL_RMII			BIT(2)
+#define  CONVCTRL_RGMII			BIT(3)
+#define  CONVCTRL_REF_CLK_OUT		BIT(4)
+#define  CONVCTRL_HALF_DUPLEX		0
+#define  CONVCTRL_FULL_DUPLEX		BIT(8)
+#define CONVRST			0x114		/* RGMII/RMII Converter RST */
+#define  PHYIF_RST(x)			BIT(x)
+
+static void rzn1_rin_prot_writel(struct udevice *dev, u32 reg, u32 val)
+{
+	struct rzn1_miic_plat *plat = dev_get_plat(dev);
+	struct regmap *regmap = plat->regmap;
+
+	/* RIN: Unprotect register writes */
+	regmap_write(regmap, PRCMD, 0x00a5);
+	regmap_write(regmap, PRCMD, 0x0001);
+	regmap_write(regmap, PRCMD, 0xfffe);
+	regmap_write(regmap, PRCMD, 0x0001);
+
+	/* Do the write */
+	regmap_write(regmap, reg, val);
+
+	/* Re-enable protection */
+	regmap_write(regmap, PRCMD, 0x0000);
+}
+
+/*
+ * RIN RGMII/RMII Converter set speed
+ * RGMII/RMII Converter number: 0..4
+ * speed: 10, 100, 1000
+ */
+void rzn1_rgmii_rmii_conv_speed(struct udevice *dev, int phy,
+				int full_duplex, int speed)
+{
+	struct rzn1_miic_plat *plat = dev_get_plat(dev);
+	struct regmap *regmap = plat->regmap;
+	u32 val = 0;
+
+	regmap_read(regmap, CONVCTRL(phy), &val);
+
+	val &= CONVCTRL_MII | CONVCTRL_RMII | CONVCTRL_RGMII |
+		CONVCTRL_REF_CLK_OUT;
+
+	/* The interface type and speed bits are somewhat intertwined */
+	if (val != CONVCTRL_MII) {
+		if (speed == SPEED_1000)
+			val |= CONVCTRL_1000_MBPS;
+		else if (speed == SPEED_100)
+			val |= CONVCTRL_100_MBPS;
+		else if (speed == SPEED_10)
+			val |= CONVCTRL_10_MBPS;
+	}
+
+	if (full_duplex)
+		val |= CONVCTRL_FULL_DUPLEX;
+
+	regmap_write(regmap, CONVCTRL(phy), val);
+}
+
+/*
+ * RIN RGMII/RMII Converter setup one
+ * RGMII/RMII Converter number: 0..4
+ * if_type: Type of PHY interface, see phy_interface_t
+ */
+void rzn1_rgmii_rmii_conv_setup(struct udevice *dev, int phy,
+				u32 if_type, int rmii_ref_clk_out)
+{
+	struct rzn1_miic_plat *plat = dev_get_plat(dev);
+	struct regmap *regmap = plat->regmap;
+	u32 val = 0;
+	int speed = SPEED_100;
+
+	switch (if_type) {
+	case PHY_INTERFACE_MODE_RGMII:
+	case PHY_INTERFACE_MODE_RGMII_ID:
+	case PHY_INTERFACE_MODE_RGMII_RXID:
+	case PHY_INTERFACE_MODE_RGMII_TXID:
+		val |= CONVCTRL_RGMII;
+		speed = SPEED_1000;
+		break;
+	case PHY_INTERFACE_MODE_RMII:
+		val |= CONVCTRL_RMII;
+		break;
+	case PHY_INTERFACE_MODE_MII:
+		val |= CONVCTRL_MII;
+		break;
+	};
+
+	if (if_type == PHY_INTERFACE_MODE_RMII && rmii_ref_clk_out)
+		val |= CONVCTRL_REF_CLK_OUT;
+
+	regmap_write(regmap, CONVCTRL(phy), val);
+
+	rzn1_rgmii_rmii_conv_speed(dev, phy, DUPLEX_FULL, speed);
+
+	/* reset */
+	regmap_read(regmap, CONVRST, &val);
+	val &= ~PHYIF_RST(phy);
+	rzn1_rin_prot_writel(dev, CONVRST, val);
+	udelay(1000);
+	val |= PHYIF_RST(phy);
+	rzn1_rin_prot_writel(dev, CONVRST, val);
+}
+
+static int rzn1_miic_probe(struct udevice *dev)
+{
+	struct rzn1_miic_plat *plat = dev_get_plat(dev);
+	int ret;
+
+	dev_warn(dev, "%s:%d\n", __func__, __LINE__);
+
+	/* Enable clocks */
+	ret = clk_get_bulk(dev, &plat->bulk);
+	if (ret) {
+		dev_err(dev, "Failed to get clocks\n");
+		return ret;
+	}
+	ret = clk_enable_bulk(&plat->bulk);
+	if (ret) {
+		dev_err(dev, "Failed to enable clocks\n");
+		return ret;
+	}
+
+	/* Access the registers */
+	ret = regmap_init_mem(dev_ofnode(dev), &plat->regmap);
+	if (ret) {
+		dev_err(dev, "Failed to get regmap\n");
+		return ret;
+	}
+
+	/* Set PTP to use 125MHz PLL clock */
+	rzn1_rin_prot_writel(dev, PTP_MODE_CTRL, 0x2);
+
+	/* Setup RGMII/RMII Converters */
+	rzn1_rgmii_rmii_conv_setup(dev, 3, PHY_INTERFACE_MODE_RGMII_ID, 0);
+	rzn1_rgmii_rmii_conv_setup(dev, 4, PHY_INTERFACE_MODE_RGMII_ID, 0);
+
+	/* RIN: Mode Control - GMAC1 on all Switch ports */
+	rzn1_rin_prot_writel(dev, MODCTRL, 0x13);
+
+	return 0;
+}
+
+static const struct udevice_id rzn1_miic_ids[] = {
+	{ .compatible = "renesas,rzn1-miic" },
+	{ }
+};
+
+U_BOOT_DRIVER(rzn1_miic) = {
+	.name		= "rzn1_miic",
+	.id		= UCLASS_MISC,
+	.of_match	= rzn1_miic_ids,
+	.probe		= rzn1_miic_probe,
+	.plat_auto	= sizeof(struct rzn1_miic_plat),
+};

-- 
2.55.0


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

* [PATCH v2 3/3] net: designware: add r9a06g032 compatible
  2026-08-14 18:30 [PATCH v2 0/3] net: add RZ/N1 ethernet drivers Ralph Siemsen
  2026-08-14 18:30 ` [PATCH v2 1/3] net: add r9a06g032 A5PSW switch driver Ralph Siemsen
  2026-08-14 18:30 ` [PATCH v2 2/3] net: add r9a06g032 MIIC driver Ralph Siemsen
@ 2026-08-14 18:30 ` Ralph Siemsen
  2026-08-14 22:19   ` Marek Vasut via U-Boot
  2 siblings, 1 reply; 7+ messages in thread
From: Ralph Siemsen @ 2026-08-14 18:30 UTC (permalink / raw)
  To: u-boot
  Cc: Tom Rini, Marek Vasut, Jerome Forissier, Quentin Schulz,
	Johan Jonker, Julien Stephan, David Lechner, Ralph Siemsen

The existing Designware driver can be used on Renesas RZ/N1.
Add the corresponding compatible string to the driver.

See corresponding Linux commit
d7cc14bc9802 ("dt-bindings: net: snps,dwmac: add "renesas,rzn1"
compatible")

Signed-off-by: Ralph Siemsen <ralph.siemsen@linaro.org>
---
 drivers/net/designware.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index 6ed9c6d538a..650d47036aa 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -1059,6 +1059,7 @@ int designware_eth_of_to_plat(struct udevice *dev)
 static const struct udevice_id designware_eth_ids[] = {
 	{ .compatible = "allwinner,sun7i-a20-gmac" },
 	{ .compatible = "amlogic,meson6-dwmac" },
+	{ .compatible = "renesas,r9a06g032-gmac" },
 	{ .compatible = "st,stm32-dwmac" },
 	{ .compatible = "snps,arc-dwmac-3.70a" },
 	{ .compatible = "sophgo,cv1800b-dwmac" },

-- 
2.55.0


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

* Re: [PATCH v2 1/3] net: add r9a06g032 A5PSW switch driver
  2026-08-14 18:30 ` [PATCH v2 1/3] net: add r9a06g032 A5PSW switch driver Ralph Siemsen
@ 2026-08-14 22:14   ` Marek Vasut via U-Boot
  0 siblings, 0 replies; 7+ messages in thread
From: Marek Vasut via U-Boot @ 2026-08-14 22:14 UTC (permalink / raw)
  To: Ralph Siemsen, u-boot
  Cc: Tom Rini, Marek Vasut, Jerome Forissier, Quentin Schulz,
	Johan Jonker, Julien Stephan, David Lechner

On 8/14/26 8:30 PM, Ralph Siemsen wrote:

[...]

> +++ b/drivers/net/Kconfig
> @@ -880,6 +880,12 @@ config RENESAS_RAVB
>   	  This driver implements support for the Ethernet AVB block in
>   	  several Renesas R-Car and RZ SoCs.
>   
> +config RZN1_A5PSW

RENESAS_RZN1_A5PSW to be consistent with the other network hardware 
prefixes used here .

> +	bool "Renesas RZ/N1 A5PSW ethernet switch"
> +	help
> +	  Support the Advanced 5-Port ethernet switch (A5PSW) found in
> +	  the Renesas RZ/N1 SoC.
> +

[...]

> +++ b/drivers/net/rzn1_a5psw.c
> @@ -0,0 +1,377 @@

[...]

> +static int rzn1_phy_wait(struct udevice *dev)
> +{
> +	struct rzn1_a5psw_plat *plat = dev_get_plat(dev->parent);
> +	struct regmap *regmap = plat->regmap;
> +	u32 timeout = 100;
> +	int ret;
> +	u32 val;

regmap_read_poll_timeout()

> +	do {
> +		ret = regmap_read(regmap, MT5PT_MDIO_CFG_STATUS, &val);
> +		if (ret == 0 && (val & BIT(0)) == 0)
> +			return 0;
> +
> +		mdelay(1);
> +	} while (--timeout);
> +
> +	return -ETIMEDOUT;
> +}
> +
> +static int rzn1_a5psw_mdio_read(struct udevice *dev, int addr, int devad, int reg)
> +{
> +	struct rzn1_a5psw_plat *plat = dev_get_plat(dev->parent);
> +	struct regmap *regmap = plat->regmap;
> +	int ret;
> +	u32 val = BIT(15) | ((addr & 0x1f) << 5) | (reg & 0x1f);
> +
> +	/* Clause 22 only */
> +	rzn1_switch_write(regmap, MT5PT_MDIO_COMMAND, val);
> +
> +	ret = rzn1_phy_wait(dev);
> +	if (ret) {
> +		dev_warn(dev, "PHY read timeout\n");
> +		return ret;
> +	}
> +
> +	ret = regmap_read(regmap, MT5PT_MDIO_DATA, &val);
> +	if (ret) {
> +		dev_warn(dev, "PHY read error\n");
> +		return ret;
> +	}
> +	val &= 0xffff;
> +
> +	// TODO: check CFG_STATUS for READERR

This should be addressed it seems ?

> +	dev_dbg(dev, "addr=0x%x reg=0x%x read 0x%04x\n", addr, reg, val);
> +
> +	return val;
> +}
> +
> +static int rzn1_a5psw_mdio_write(struct udevice *dev, int addr, int devad,
> +				 int reg, u16 val)
> +{
> +	struct rzn1_a5psw_plat *plat = dev_get_plat(dev->parent);
> +	struct regmap *regmap = plat->regmap;
> +	int ret;
> +	u32 cmd = ((addr & 0x1f) << 5) | (reg & 0x1f);
> +
> +	dev_dbg(dev, "addr=0x%x reg=0x%x write 0x%04x\n", addr, reg, val);
> +
> +	/* Clause 22 only */
> +	rzn1_switch_write(regmap, MT5PT_MDIO_COMMAND, cmd);
> +	rzn1_switch_write(regmap, MT5PT_MDIO_DATA, val);
> +
> +	ret = rzn1_phy_wait(dev);
> +	if (ret) {
> +		dev_warn(dev, "PHY write timeout\n");

Include the error code in the message, it makes debugging easier.

> +		return ret;
> +	}
> +
> +	return 0;
> +}
> +
> +static const struct mdio_ops rzn1_a5psw_mdio_ops = {
> +	.read = rzn1_a5psw_mdio_read,
> +	.write = rzn1_a5psw_mdio_write,
> +};
> +
> +static int rzn1_a5psw_mdio_bind(struct udevice *dev)
> +{
> +	char name[32];
> +	static int num_devices;

Reverse xmas tree, but don't you have ethernet-ports {} subnode in DT 
node for the switch, from which you could derive the MDIO bus address(es) ?

Example
dts/upstream/src/arm64/freescale/imx8mn-vhip4-evalboard-ksz8794-common.dtsi

15         ksz8794: ethernet-switch@1 {
16                 compatible = "microchip,ksz8794";
...
24                 ethernet-ports {
...
28                         port@0 {
29                                 reg = <0>;
30                                 label = "lan1";
31                         };

> +	sprintf(name, "rzn1-a5psw-mdio-%d", num_devices++);
> +	device_set_name(dev, name);
> +
> +	return 0;
> +}
> +
> +U_BOOT_DRIVER(rzn1_a5psw_mdio) = {
> +	.name		= "rzn1_a5psw_mdio",
> +	.id		= UCLASS_MDIO,
> +	.ops		= &rzn1_a5psw_mdio_ops,
> +	.bind		= rzn1_a5psw_mdio_bind,
> +	.plat_auto	= sizeof(struct mdio_perdev_priv),
> +};
> +
> +static int rzn1_a5psw_port_probe(struct udevice *dev, int port, struct phy_device *phy)
> +{
> +	/* Called once when switch is probed */
> +	return phy_config(phy);
> +}
> +
> +void rzn1_rgmii_rmii_conv_speed(struct udevice *dev, int phy,
> +				int full_duplex, int speed);
> +
> +static int rzn1_a5psw_port_enable(struct udevice *dev, int port, struct phy_device *phy)
> +{
> +	struct rzn1_a5psw_plat *plat = dev_get_plat(dev);
> +
> +	/* CPU port is already enabled */
> +	if (port == 4)

4 needs to be a macro, not a magic number directly in the code.

> +		return 0;
> +
> +	/* Get speed/duplex from PHY */
> +	genphy_update_link(phy);
> +	if (!phy->link) {
> +		dev_err(dev, "PHY %s no ethernet link\n", phy->dev->name);
> +		return 0;
> +	}
> +	genphy_parse_link(phy);
> +
> +	/* Program the converter accoringly */
> +	dev_info(dev, "MIIC = %p\n", plat->miic);
> +	rzn1_rgmii_rmii_conv_speed(plat->miic, 4 - port, phy->duplex, phy->speed);
> +
> +	/* Program the switch port accordingly */
> +	dev_info(dev, "%s port=%d using speed=%d\n", __func__, port, phy->speed);
> +	rzn1_switch_port_speed_duplex(dev, port, phy->speed, phy->duplex);
> +	rzn1_switch_port_enable(dev, port);
> +	return 0;
> +}
> +
> +static void rzn1_a5psw_port_disable(struct udevice *dev, int port, struct phy_device *phy)
> +{
> +	/* CPU port is already enabled */
> +	if (port == 4)
> +		return;
> +
> +	rzn1_switch_port_disable(dev, port);
> +}
> +
> +static const struct dsa_ops rzn1_a5psw_dsa_ops = {
> +	.port_probe = rzn1_a5psw_port_probe,
> +	.port_enable = rzn1_a5psw_port_enable,
> +	.port_disable = rzn1_a5psw_port_disable,
> +};
> +
> +static int rzn1_a5psw_probe_mdio(struct udevice *dev)
> +{
> +	struct udevice *mdev;
> +	const char *name;
> +	ofnode node;
> +	int ret;
> +
> +	/* bind phy ports of mdio child node to rzn1_a5psw_mdio device */
> +	node = dev_read_subnode(dev, "mdio");
> +	if (!ofnode_valid(node))
> +		return 0;
> +
> +	name = ofnode_get_name(node);
> +	ret = device_bind_driver_to_node(dev,
> +					 "rzn1_a5psw_mdio",
> +					 name, node, NULL);
> +	if (ret) {
> +		dev_err(dev, "failed to bind %s: %d\n", name, ret);

return ret;
}

> +	} else {

Drop the else {} .

> +		/* need to probe it as there is no compatible to do so */
> +		ret = uclass_get_device_by_ofnode(UCLASS_MDIO, node, &mdev);
> +		if (ret)
> +			dev_err(dev, "failed to probe %s: %d\n", name, ret);
> +	}
> +
> +	return ret;
> +}
> +
> +static int rzn1_a5psw_probe(struct udevice *dev)
> +{
> +	struct rzn1_a5psw_plat *plat = dev_get_plat(dev);
> +	int ret;
> +
> +	dev_dbg(dev, "%s:%d\n", __func__, __LINE__);
> +
> +	/* Enable clocks */
> +	ret = clk_get_bulk(dev, &plat->bulk);
> +	if (ret) {
> +		dev_err(dev, "Failed to get clocks\n");
> +		return ret;
> +	}
> +	ret = clk_enable_bulk(&plat->bulk);
> +	if (ret) {
> +		dev_err(dev, "Failed to enable clocks\n");

"Failed to enable clocks (%d)\n", ret);

Please fix globally.

> +		return ret;
> +	}
> +
> +	/* Access the registers */
> +	ret = regmap_init_mem(dev_ofnode(dev), &plat->regmap);
> +	if (ret) {
> +		dev_err(dev, "Failed to get regmap\n");
> +		return ret;
> +	}
> +
> +	/* Find the MIIC driver */
> +	ret = uclass_get_device_by_name(UCLASS_MISC, "eth-miic@44030000", &plat->miic);
> +	if (ret) {
> +		dev_err(dev, "Failed to get MIIC\n");
> +		return ret;
> +	}
> +	dev_dbg(dev, "got MIIC %p <%s>\n", plat->miic, plat->miic->name);
> +
> +	/* Upstream port is always 1Gbps */
> +	rzn1_switch_port_speed_duplex(dev, 4, SPEED_1000, DUPLEX_FULL);
> +	rzn1_switch_port_enable(dev, 4);
> +
> +	/* Some extra resets are located in system controller */
> +	plat->syscon = syscon_regmap_lookup_by_phandle(dev, "syscon");
> +	if (IS_ERR(plat->syscon)) {
> +		dev_err(dev, "No syscon node found\n");
> +		return PTR_ERR(plat->syscon);
> +	}
> +
> +	/* Clear ETH and CLK25 resets */
> +#define RZN1_SYSCTRL_PWRCTRL_SWITCH 0x188

This goes to the beginning of this file.

> +	regmap_update_bits(plat->syscon, RZN1_SYSCTRL_PWRCTRL_SWITCH,
> +			   BIT(4) | BIT(3), BIT(4) | BIT(3));
> +
> +	/* Reset all PHYs */
> +	struct gpio_desc phy_reset_gpio;
> +	u32 phy_reset_delay;

This goes to the beginning of the function ; didn't the compiler 
complain about this ?

> +	ret = gpio_request_by_name(dev, "phy-reset-gpios", 0,
> +				   &phy_reset_gpio, GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE);
> +	if (ret) {
> +		dev_err(dev, "failed to get phy-reset-gpios: %d\n", ret);
> +		return ret;
> +	}
> +
> +	phy_reset_delay = dev_read_u32_default(dev, "phy-reset-duration", 15);
[...]

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

* Re: [PATCH v2 2/3] net: add r9a06g032 MIIC driver
  2026-08-14 18:30 ` [PATCH v2 2/3] net: add r9a06g032 MIIC driver Ralph Siemsen
@ 2026-08-14 22:18   ` Marek Vasut via U-Boot
  0 siblings, 0 replies; 7+ messages in thread
From: Marek Vasut via U-Boot @ 2026-08-14 22:18 UTC (permalink / raw)
  To: Ralph Siemsen, u-boot
  Cc: Tom Rini, Marek Vasut, Jerome Forissier, Quentin Schulz,
	Johan Jonker, Julien Stephan, David Lechner

On 8/14/26 8:30 PM, Ralph Siemsen wrote:

[...]

> +++ b/drivers/net/Kconfig
> @@ -886,6 +886,12 @@ config RZN1_A5PSW
>   	  Support the Advanced 5-Port ethernet switch (A5PSW) found in
>   	  the Renesas RZ/N1 SoC.
>   
> +config RZN1_MIIC

config RENESAS_RZN1_MIIC

> +	bool "Renesas RZ/N1 MIIC ethernet accessory"
> +	help
> +	  Support the MIIC ethernet accessory found in Renesas RZ/N1 SoC.
> +	  These are media converters for MII/GMII/RGMII.
> +
>   config MPC8XX_FEC
>   	bool "Fast Ethernet Controller on MPC8XX"
>   	depends on MPC8xx
> diff --git a/drivers/net/Makefile b/drivers/net/Makefile
> index b8f270ae233..049212b1fd2 100644
> --- a/drivers/net/Makefile
> +++ b/drivers/net/Makefile
> @@ -95,6 +95,7 @@ obj-$(CONFIG_PIC32_ETH) += pic32_mdio.o pic32_eth.o
>   obj-$(CONFIG_RENESAS_ETHER_SWITCH) += rswitch.o
>   obj-$(CONFIG_RENESAS_RAVB) += ravb.o
>   obj-$(CONFIG_RZN1_A5PSW) += rzn1_a5psw.o
> +obj-$(CONFIG_RZN1_MIIC) += rzn1_miic.o
>   obj-$(CONFIG_RTL8139) += rtl8139.o
>   obj-$(CONFIG_RTL8169) += rtl8169.o
>   obj-$(CONFIG_SH_ETHER) += sh_eth.o
> diff --git a/drivers/net/rzn1_miic.c b/drivers/net/rzn1_miic.c
> new file mode 100644
> index 00000000000..491923d8511
> --- /dev/null
> +++ b/drivers/net/rzn1_miic.c
> @@ -0,0 +1,193 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * MII/GMII/RGMII converter support
> + *
> + * Based loosely on Linux drivers/net/pcs/pcs-rzn1-miic.c
> + * and the older driver in Renesas u-boot.

U-Boot

> + */

[...]

> +static void rzn1_rin_prot_writel(struct udevice *dev, u32 reg, u32 val)
> +{
> +	struct rzn1_miic_plat *plat = dev_get_plat(dev);
> +	struct regmap *regmap = plat->regmap;
> +
> +	/* RIN: Unprotect register writes */

What is "RIN" ?

> +	regmap_write(regmap, PRCMD, 0x00a5);
> +	regmap_write(regmap, PRCMD, 0x0001);
> +	regmap_write(regmap, PRCMD, 0xfffe);
> +	regmap_write(regmap, PRCMD, 0x0001);
> +
> +	/* Do the write */
> +	regmap_write(regmap, reg, val);
> +
> +	/* Re-enable protection */
> +	regmap_write(regmap, PRCMD, 0x0000);
> +}

[...]

> + * RIN RGMII/RMII Converter setup one
> + * RGMII/RMII Converter number: 0..4
> + * if_type: Type of PHY interface, see phy_interface_t
> + */
> +void rzn1_rgmii_rmii_conv_setup(struct udevice *dev, int phy,
> +				u32 if_type, int rmii_ref_clk_out)
> +{
> +	struct rzn1_miic_plat *plat = dev_get_plat(dev);
> +	struct regmap *regmap = plat->regmap;
> +	u32 val = 0;
> +	int speed = SPEED_100;

Reverse xmas tree.

Also, drop = 0 from val assignment and simply assign it below in the 
switch/case statement ...

> +
> +	switch (if_type) {
> +	case PHY_INTERFACE_MODE_RGMII:
> +	case PHY_INTERFACE_MODE_RGMII_ID:
> +	case PHY_INTERFACE_MODE_RGMII_RXID:
> +	case PHY_INTERFACE_MODE_RGMII_TXID:
> +		val |= CONVCTRL_RGMII;

val = CONVCTRL_RGMII;

> +		speed = SPEED_1000;
> +		break;
> +	case PHY_INTERFACE_MODE_RMII:
> +		val |= CONVCTRL_RMII;
> +		break;
> +	case PHY_INTERFACE_MODE_MII:
> +		val |= CONVCTRL_MII;
> +		break;

default:
  return -EINVAL;

or some such ?

> +	};
> +
> +	if (if_type == PHY_INTERFACE_MODE_RMII && rmii_ref_clk_out)
> +		val |= CONVCTRL_REF_CLK_OUT;
> +
> +	regmap_write(regmap, CONVCTRL(phy), val);
> +
> +	rzn1_rgmii_rmii_conv_speed(dev, phy, DUPLEX_FULL, speed);
> +
> +	/* reset */
> +	regmap_read(regmap, CONVRST, &val);
> +	val &= ~PHYIF_RST(phy);
> +	rzn1_rin_prot_writel(dev, CONVRST, val);
> +	udelay(1000);
> +	val |= PHYIF_RST(phy);
> +	rzn1_rin_prot_writel(dev, CONVRST, val);
> +}
> +
> +static int rzn1_miic_probe(struct udevice *dev)
> +{
> +	struct rzn1_miic_plat *plat = dev_get_plat(dev);
> +	int ret;
> +
> +	dev_warn(dev, "%s:%d\n", __func__, __LINE__);
> +
> +	/* Enable clocks */
> +	ret = clk_get_bulk(dev, &plat->bulk);
> +	if (ret) {
> +		dev_err(dev, "Failed to get clocks\n");

"Failed to get clocks (%d)\n", ret);

Please fix globally.

> +		return ret;
> +	}

Add newline here.

> +	ret = clk_enable_bulk(&plat->bulk);
> +	if (ret) {
> +		dev_err(dev, "Failed to enable clocks\n");
> +		return ret;
> +	}
[...]

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

* Re: [PATCH v2 3/3] net: designware: add r9a06g032 compatible
  2026-08-14 18:30 ` [PATCH v2 3/3] net: designware: add r9a06g032 compatible Ralph Siemsen
@ 2026-08-14 22:19   ` Marek Vasut via U-Boot
  0 siblings, 0 replies; 7+ messages in thread
From: Marek Vasut via U-Boot @ 2026-08-14 22:19 UTC (permalink / raw)
  To: Ralph Siemsen, u-boot
  Cc: Tom Rini, Marek Vasut, Jerome Forissier, Quentin Schulz,
	Johan Jonker, Julien Stephan, David Lechner

On 8/14/26 8:30 PM, Ralph Siemsen wrote:
> The existing Designware driver can be used on Renesas RZ/N1.
> Add the corresponding compatible string to the driver.
> 
> See corresponding Linux commit
> d7cc14bc9802 ("dt-bindings: net: snps,dwmac: add "renesas,rzn1"
> compatible")
> 
> Signed-off-by: Ralph Siemsen <ralph.siemsen@linaro.org>
Reviewed-by: Marek Vasut <marek.vasut+renesas@mailbox.org>

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

end of thread, other threads:[~2026-08-14 22:44 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-14 18:30 [PATCH v2 0/3] net: add RZ/N1 ethernet drivers Ralph Siemsen
2026-08-14 18:30 ` [PATCH v2 1/3] net: add r9a06g032 A5PSW switch driver Ralph Siemsen
2026-08-14 22:14   ` Marek Vasut via U-Boot
2026-08-14 18:30 ` [PATCH v2 2/3] net: add r9a06g032 MIIC driver Ralph Siemsen
2026-08-14 22:18   ` Marek Vasut via U-Boot
2026-08-14 18:30 ` [PATCH v2 3/3] net: designware: add r9a06g032 compatible Ralph Siemsen
2026-08-14 22:19   ` Marek Vasut via U-Boot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).