Devicetree
 help / color / mirror / Atom feed
* [PATCH net-next v4 0/5] net: mdio: realtek-rtl9300: add bus frequency handling
@ 2026-09-12 13:04 Markus Stockhausen
  2026-09-12 13:04 ` [PATCH net-next v4 1/5] dt-bindings: net: realtek,rtl9301-mdio: restrict MDIO buses by family Markus Stockhausen
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Markus Stockhausen @ 2026-09-12 13:04 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
	chris.packham, robh, krzk+dt, conor+dt, devicetree
  Cc: Markus Stockhausen

The Realtek Otto switch platform consists of four different series

- RTL838x aka maple   : 28 port 1G Switches
- RTL839x aka cypress : 52 port 1G Switches
- RTL930x aka longan  : 28 port 1G/2.5G/10G Switches
- RTL931x aka mango   : 56 port 1G/2.5G/10G Switches

All of them support changing the bus frequency of their one to four
Ethernet MDIO buses, although the available settings differ between
the series. Extend the driver to support this feature.

Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
v3 -> v4:
  - Add new devicetree patch to clearly describe the number of
    MDIO buses. (Sashiko)
  - Harden devicetree clock-frequency properties to match the
    driver. (Sashiko)
  - Therefore drop Acked-by for devicetree patch. (Markus)
  - Improve fwnode to of conversion. E.g. drop dev_fwnode or usage
    of unneeded includes. (Sashiko)
  - Reword commit message of frequency commit to better reflect how
    the setup logic works. (Sashiko)
  - Refactor RTL839x frequency setup and comment to be consistent
    with the commit message. (Sashiko)
v3: https://lore.kernel.org/netdev/20260909150107.3602067-1-markus.stockhausen@gmx.de/
v3 Sashiko 1: https://sashiko.dev/#/patchset/20260909150107.3602067-1-markus.stockhausen%40gmx.de
v3 Sashiko 2: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260909150107.3602067-1-markus.stockhausen%40gmx.de

v2 -> v3:
  - Add Acked-by for devicetree patch. (Conor)
  - Andrews Reviewed-by not added because of Sashiko findings. (Markus)
  - Add patch "Reject duplicate MDIO bus" to harden the bus detection
    and as preparation for the RTL839x frequency setup. (Markus)
  - Rework RTL839x frequency setup to better handle missing/default
    frequencies. (Sashiko)
  - Use for_each_available_child_of_node_scoped(). (Sashiko)
v2: https://lore.kernel.org/netdev/20260906081946.3499898-1-markus.stockhausen@gmx.de/
v2 Sashiko 1: https://sashiko.dev/#/patchset/20260906081946.3499898-1-markus.stockhausen%40gmx.de
v2 Sashiko 2: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260906081946.3499898-1-markus.stockhausen%40gmx.de

v1 -> v2:
  - Describe per-device frequencies in devicetree. (Andrew)
  - Add proper per-device frequency checks. (Andrew)
  - Use the initialized parent device for dev_warn(). (Sashiko)
  - Make clear that otto_emdio_probe_one() currently has an
    indentation issue that will be fixed by this series. (Andrew)
  - Throw error if RTL839x devicetree has different speeds set
    for first and second bus.

v1: https://lore.kernel.org/netdev/20260903122119.2638354-1-markus.stockhausen@gmx.de/
v1 Sashiko: https://sashiko.dev/#/patchset/20260903122119.2638354-1-markus.stockhausen%40gmx.de



Markus Stockhausen (5):
  dt-bindings: net: realtek,rtl9301-mdio: restrict MDIO buses by family
  dt-bindings: net: realtek,rtl9301-mdio: add clock-frequency
  net: mdio: realtek-rtl9300: convert "fwnode" left-overs to "of"
  net: mdio: realtek-rtl9300: reject duplicate MDIO bus IDs
  net: mdio: realtek-rtl9300: support non-default clock frequencies

 .../bindings/net/realtek,rtl9301-mdio.yaml    |  65 ++++++++++
 drivers/net/mdio/mdio-realtek-rtl9300.c       | 120 ++++++++++++++++--
 2 files changed, 176 insertions(+), 9 deletions(-)

-- 
2.55.0


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

* [PATCH net-next v4 1/5] dt-bindings: net: realtek,rtl9301-mdio: restrict MDIO buses by family
  2026-09-12 13:04 [PATCH net-next v4 0/5] net: mdio: realtek-rtl9300: add bus frequency handling Markus Stockhausen
@ 2026-09-12 13:04 ` Markus Stockhausen
  2026-09-12 13:04 ` [PATCH net-next v4 2/5] dt-bindings: net: realtek,rtl9301-mdio: add clock-frequency Markus Stockhausen
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Markus Stockhausen @ 2026-09-12 13:04 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
	chris.packham, robh, krzk+dt, conor+dt, devicetree
  Cc: Markus Stockhausen

The Realtek Otto switch family provides different numbers of MDIO
buses. RTL838x has one bus, RTL839x has two buses, and RTL930x/RTL931x
have four buses.

The binding currently accepts mdio-bus@0 through mdio-bus@3 for every
supported compatible, allowing non-existent buses to be described for
RTL838x and RTL839x devices.

Select the permitted bus node names based on the controller compatible.

Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
 .../bindings/net/realtek,rtl9301-mdio.yaml    | 24 +++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/Documentation/devicetree/bindings/net/realtek,rtl9301-mdio.yaml b/Documentation/devicetree/bindings/net/realtek,rtl9301-mdio.yaml
index 67e0b23a8470..7f5b4897487b 100644
--- a/Documentation/devicetree/bindings/net/realtek,rtl9301-mdio.yaml
+++ b/Documentation/devicetree/bindings/net/realtek,rtl9301-mdio.yaml
@@ -67,6 +67,30 @@ patternProperties:
 
     unevaluatedProperties: false
 
+allOf:
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - realtek,rtl8380-mdio
+              - realtek,rtl8381-mdio
+              - realtek,rtl8382-mdio
+    then:
+      patternProperties:
+        '^mdio-bus@[1-3]$': false
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - realtek,rtl8391-mdio
+              - realtek,rtl8392-mdio
+              - realtek,rtl8393-mdio
+    then:
+      patternProperties:
+        '^mdio-bus@[2-3]$': false
+
 required:
   - compatible
   - reg
-- 
2.55.0


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

* [PATCH net-next v4 2/5] dt-bindings: net: realtek,rtl9301-mdio: add clock-frequency
  2026-09-12 13:04 [PATCH net-next v4 0/5] net: mdio: realtek-rtl9300: add bus frequency handling Markus Stockhausen
  2026-09-12 13:04 ` [PATCH net-next v4 1/5] dt-bindings: net: realtek,rtl9301-mdio: restrict MDIO buses by family Markus Stockhausen
@ 2026-09-12 13:04 ` Markus Stockhausen
  2026-09-12 13:04 ` [PATCH net-next v4 3/5] net: mdio: realtek-rtl9300: convert "fwnode" left-overs to "of" Markus Stockhausen
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Markus Stockhausen @ 2026-09-12 13:04 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
	chris.packham, robh, krzk+dt, conor+dt, devicetree
  Cc: Markus Stockhausen

The Ethernet MDIO controllers in Realtek Otto switches support several
MDC frequencies. Document the supported clock-frequency values:

- RTL838x: 2.5 MHz or 10 MHz
- RTL839x, RTL930x and RTL931x: 1.25 MHz, 2.5 MHz or 5 MHz

RTL839x has a single frequency selector shared by both MDIO buses.
Require explicitly specified frequencies to be identical and document
that a bus without clock-frequency inherits the frequency selected by
the other available bus. Use 2.5 MHz if neither bus specifies a
frequency.

There is neither an official documentation nor any obvious registers that
indicate a dependency to one of the hardware clocks. The usable setup bits
are more like hardcoded values than dividers. Without further details do
not add a clock reference.

Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
 .../bindings/net/realtek,rtl9301-mdio.yaml    | 47 +++++++++++++++++--
 1 file changed, 44 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/realtek,rtl9301-mdio.yaml b/Documentation/devicetree/bindings/net/realtek,rtl9301-mdio.yaml
index 7f5b4897487b..c5f2289dc0eb 100644
--- a/Documentation/devicetree/bindings/net/realtek,rtl9301-mdio.yaml
+++ b/Documentation/devicetree/bindings/net/realtek,rtl9301-mdio.yaml
@@ -56,6 +56,9 @@ patternProperties:
       reg:
         maxItems: 1
 
+      clock-frequency:
+        $ref: /schemas/types.yaml#/definitions/uint32
+
     required:
       - reg
 
@@ -67,6 +70,10 @@ patternProperties:
 
     unevaluatedProperties: false
 
+required:
+  - compatible
+  - reg
+
 allOf:
   - if:
       properties:
@@ -77,8 +84,16 @@ allOf:
               - realtek,rtl8381-mdio
               - realtek,rtl8382-mdio
     then:
+      properties:
+        mdio-bus@0:
+          properties:
+            clock-frequency:
+              enum: [2500000, 10000000]
+              default: 2500000
+
       patternProperties:
         '^mdio-bus@[1-3]$': false
+
   - if:
       properties:
         compatible:
@@ -89,11 +104,37 @@ allOf:
               - realtek,rtl8393-mdio
     then:
       patternProperties:
+        '^mdio-bus@[01]$':
+          properties:
+            clock-frequency:
+              enum: [1250000, 2500000, 5000000]
+              description: |
+                RTL839x has one clock selector shared by both MDIO buses. All explicitly
+                specified clock-frequency values must be identical. A bus without this
+                property inherits the shared frequency selected by another available bus.
+                If neither available bus specifies a frequency, 2500000 Hz is used.
+
         '^mdio-bus@[2-3]$': false
 
-required:
-  - compatible
-  - reg
+  - if:
+      properties:
+        compatible:
+          contains:
+            enum:
+              - realtek,rtl9301-mdio
+              - realtek,rtl9302b-mdio
+              - realtek,rtl9302c-mdio
+              - realtek,rtl9303-mdio
+              - realtek,rtl9311-mdio
+              - realtek,rtl9312-mdio
+              - realtek,rtl9313-mdio
+    then:
+      patternProperties:
+        '^mdio-bus@[0-3]$':
+          properties:
+            clock-frequency:
+              enum: [1250000, 2500000, 5000000]
+              default: 2500000
 
 unevaluatedProperties: false
 
-- 
2.55.0


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

* [PATCH net-next v4 3/5] net: mdio: realtek-rtl9300: convert "fwnode" left-overs to "of"
  2026-09-12 13:04 [PATCH net-next v4 0/5] net: mdio: realtek-rtl9300: add bus frequency handling Markus Stockhausen
  2026-09-12 13:04 ` [PATCH net-next v4 1/5] dt-bindings: net: realtek,rtl9301-mdio: restrict MDIO buses by family Markus Stockhausen
  2026-09-12 13:04 ` [PATCH net-next v4 2/5] dt-bindings: net: realtek,rtl9301-mdio: add clock-frequency Markus Stockhausen
@ 2026-09-12 13:04 ` Markus Stockhausen
  2026-09-12 13:04 ` [PATCH net-next v4 4/5] net: mdio: realtek-rtl9300: reject duplicate MDIO bus IDs Markus Stockhausen
  2026-09-12 13:04 ` [PATCH net-next v4 5/5] net: mdio: realtek-rtl9300: support non-default clock frequencies Markus Stockhausen
  4 siblings, 0 replies; 6+ messages in thread
From: Markus Stockhausen @ 2026-09-12 13:04 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
	chris.packham, robh, krzk+dt, conor+dt, devicetree
  Cc: Markus Stockhausen

The latest developments of the MDIO driver consistently used the
"of" API. Convert the remaining "fwnode" left-overs too. Also
align the continuation line of otto_emdio_probe_one() with the
opening parenthesis, as required by the kernel coding style.

Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
 drivers/net/mdio/mdio-realtek-rtl9300.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/net/mdio/mdio-realtek-rtl9300.c b/drivers/net/mdio/mdio-realtek-rtl9300.c
index 11d078ef941c..8ca917d9aea3 100644
--- a/drivers/net/mdio/mdio-realtek-rtl9300.c
+++ b/drivers/net/mdio/mdio-realtek-rtl9300.c
@@ -123,7 +123,6 @@
 #include <linux/of_mdio.h>
 #include <linux/phy.h>
 #include <linux/platform_device.h>
-#include <linux/property.h>
 #include <linux/regmap.h>
 
 #define RTL8380_NUM_BUSES			1
@@ -831,14 +830,14 @@ static void otto_emdio_notify_phy_detach(struct phy_device *phydev)
 }
 
 static int otto_emdio_probe_one(struct device *dev, struct otto_emdio_priv *priv,
-				 struct fwnode_handle *node)
+				struct device_node *node)
 {
 	struct otto_emdio_chan *chan;
 	struct mii_bus *bus;
 	u32 mdio_bus;
 	int err;
 
-	err = fwnode_property_read_u32(node, "reg", &mdio_bus);
+	err = of_property_read_u32(node, "reg", &mdio_bus);
 	if (err)
 		return dev_err_probe(dev, err, "undefined smi bus number\n");
 
@@ -865,7 +864,7 @@ static int otto_emdio_probe_one(struct device *dev, struct otto_emdio_priv *priv
 
 	snprintf(bus->id, MII_BUS_ID_SIZE, "%s-%d", dev_name(dev), mdio_bus);
 
-	err = devm_of_mdiobus_register(dev, bus, to_of_node(node));
+	err = devm_of_mdiobus_register(dev, bus, node);
 	if (err)
 		return dev_err_probe(dev, err, "cannot register MDIO bus\n");
 
@@ -901,8 +900,8 @@ static int otto_emdio_map_ports(struct device *dev)
 
 	ports_dn = of_get_child_by_name(parent->of_node, "ethernet-ports");
 	if (!ports_dn)
-		return dev_err_probe(dev, -EINVAL, "%pfwP missing ethernet-ports\n",
-				     dev_fwnode(parent));
+		return dev_err_probe(dev, -EINVAL, "%pOFP missing ethernet-ports\n",
+				     parent->of_node);
 
 	for_each_available_child_of_node_scoped(ports_dn, port_dn) {
 		ctrl_dn = NULL;
@@ -1002,7 +1001,7 @@ static int otto_emdio_probe(struct platform_device *pdev)
 	if (err)
 		return err;
 
-	priv->info = device_get_match_data(dev);
+	priv->info = of_device_get_match_data(dev);
 	priv->regmap = syscon_node_to_regmap(dev->parent->of_node);
 	if (IS_ERR(priv->regmap))
 		return PTR_ERR(priv->regmap);
@@ -1027,7 +1026,7 @@ static int otto_emdio_probe(struct platform_device *pdev)
 			return dev_err_probe(dev, err, "failed to setup MDIO bus controller\n");
 	}
 
-	device_for_each_child_node_scoped(dev, child) {
+	for_each_available_child_of_node_scoped(dev->of_node, child) {
 		err = otto_emdio_probe_one(dev, priv, child);
 		if (err)
 			return err;
-- 
2.55.0


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

* [PATCH net-next v4 4/5] net: mdio: realtek-rtl9300: reject duplicate MDIO bus IDs
  2026-09-12 13:04 [PATCH net-next v4 0/5] net: mdio: realtek-rtl9300: add bus frequency handling Markus Stockhausen
                   ` (2 preceding siblings ...)
  2026-09-12 13:04 ` [PATCH net-next v4 3/5] net: mdio: realtek-rtl9300: convert "fwnode" left-overs to "of" Markus Stockhausen
@ 2026-09-12 13:04 ` Markus Stockhausen
  2026-09-12 13:04 ` [PATCH net-next v4 5/5] net: mdio: realtek-rtl9300: support non-default clock frequencies Markus Stockhausen
  4 siblings, 0 replies; 6+ messages in thread
From: Markus Stockhausen @ 2026-09-12 13:04 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
	chris.packham, robh, krzk+dt, conor+dt, devicetree
  Cc: Markus Stockhausen

The reg property identifies the hardware MDIO bus and is used as an
index into the per-bus state. However, duplicate bus IDs are currently
not rejected explicitly and only fail later during MDIO bus
registration due to the duplicate bus ID.

Keep track of successfully registered buses and reject a duplicate reg
value before allocating another bus. For this use the already existing
but currently unused priv->bus[] property.

Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
 drivers/net/mdio/mdio-realtek-rtl9300.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/net/mdio/mdio-realtek-rtl9300.c b/drivers/net/mdio/mdio-realtek-rtl9300.c
index 8ca917d9aea3..45cbefc52100 100644
--- a/drivers/net/mdio/mdio-realtek-rtl9300.c
+++ b/drivers/net/mdio/mdio-realtek-rtl9300.c
@@ -845,6 +845,9 @@ static int otto_emdio_probe_one(struct device *dev, struct otto_emdio_priv *priv
 		return dev_err_probe(dev, -EINVAL,
 				     "illegal (dangling) smi bus number %d\n", mdio_bus);
 
+	if (priv->bus[mdio_bus])
+		return dev_err_probe(dev, -EINVAL, "duplicated smi bus number %d\n", mdio_bus);
+
 	bus = devm_mdiobus_alloc_size(dev, sizeof(*chan));
 	if (!bus)
 		return -ENOMEM;
@@ -868,6 +871,8 @@ static int otto_emdio_probe_one(struct device *dev, struct otto_emdio_priv *priv
 	if (err)
 		return dev_err_probe(dev, err, "cannot register MDIO bus\n");
 
+	priv->bus[mdio_bus] = bus;
+
 	return 0;
 }
 
-- 
2.55.0


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

* [PATCH net-next v4 5/5] net: mdio: realtek-rtl9300: support non-default clock frequencies
  2026-09-12 13:04 [PATCH net-next v4 0/5] net: mdio: realtek-rtl9300: add bus frequency handling Markus Stockhausen
                   ` (3 preceding siblings ...)
  2026-09-12 13:04 ` [PATCH net-next v4 4/5] net: mdio: realtek-rtl9300: reject duplicate MDIO bus IDs Markus Stockhausen
@ 2026-09-12 13:04 ` Markus Stockhausen
  4 siblings, 0 replies; 6+ messages in thread
From: Markus Stockhausen @ 2026-09-12 13:04 UTC (permalink / raw)
  To: andrew, hkallweit1, linux, davem, edumazet, kuba, pabeni, netdev,
	chris.packham, robh, krzk+dt, conor+dt, devicetree
  Cc: Markus Stockhausen

The Ethernet MDIO controllers in Realtek Otto switches use an MDC clock
frequency of 2.5 MHz by default. Hardware configuration fields allow the
following frequencies to be selected:

- RTL838x: 2.5 MHz or 10 MHz
- RTL839x, RTL930x and RTL931x: 1.25 MHz, 2.5 MHz or 5 MHz

Add support for configuring the MDC frequency through the
clock-frequency property of each MDIO bus node. Lower frequencies can
simplify protocol analysis with a logic analyzer, while higher
frequencies reduce MDIO transaction times during normal operation.

Program the frequency selector during every probe. If clock-frequency is
absent, select the defined default of 2.5 MHz. This matches the
configuration observed with a protocol analyzer under the stock firmware
or after issuing "rtk network on" in the bootloader.

RTL839x is an exception because both MDIO buses share a single frequency
field. Use an explicitly specified frequency as the shared frequency and
let buses without the property inherit it. Use the 2.5 MHz default if
neither bus specifies a frequency. Reject conflicting explicit
frequencies because the hardware cannot configure them independently.

Signed-off-by: Markus Stockhausen <markus.stockhausen@gmx.de>
---
 drivers/net/mdio/mdio-realtek-rtl9300.c | 100 +++++++++++++++++++++++-
 1 file changed, 99 insertions(+), 1 deletion(-)

diff --git a/drivers/net/mdio/mdio-realtek-rtl9300.c b/drivers/net/mdio/mdio-realtek-rtl9300.c
index 45cbefc52100..bde0cf5e0b79 100644
--- a/drivers/net/mdio/mdio-realtek-rtl9300.c
+++ b/drivers/net/mdio/mdio-realtek-rtl9300.c
@@ -129,6 +129,7 @@
 #define RTL8380_NUM_PAGES			4096
 #define RTL8380_NUM_PORTS			28
 #define RTL8380_SMI_GLB_CTRL			0xa100
+#define   RTL8380_SMI_FREQ_SEL			BIT(1)
 #define   RTL8380_SMI_PHY_PATCH_DONE		BIT(15)
 #define RTL8380_SMI_ACCESS_PHY_CTRL_0		0xa1b8
 #define RTL8380_SMI_ACCESS_PHY_CTRL_1		0xa1bc
@@ -168,12 +169,15 @@
 #define RTL8390_PHYREG_PORT_CTRL_LOW		0x03e4
 #define RTL8390_PHYREG_PORT_CTRL_HIGH		0x03e8
 #define RTL8390_SMI_PORT_POLLING_CTRL		0x03fc
+#define RTL8390_SMI_GLB_CTRL			0x03f8
+#define   RTL8390_SMI_FREQ_SEL			GENMASK(6, 5)
 
 #define RTL9300_NUM_BUSES			4
 #define RTL9300_NUM_PAGES			4096
 #define RTL9300_NUM_PORTS			28
 #define RTL9300_SMI_GLB_CTRL			0xca00
 #define   RTL9300_GLB_CTRL_INTF_SEL(intf)	BIT(16 + (intf))
+#define   RTL9300_SMI_FREQ_SEL(intf)		GENMASK((intf) * 2 + 9, (intf) * 2 + 8)
 #define RTL9300_SMI_PORT0_15_POLLING_SEL	0xca08
 #define RTL9300_SMI_ACCESS_PHY_CTRL_0		0xcb70
 #define RTL9300_SMI_ACCESS_PHY_CTRL_1		0xcb74
@@ -195,6 +199,8 @@
 #define RTL9310_NUM_BUSES			4
 #define RTL9310_NUM_PAGES			8192
 #define RTL9310_NUM_PORTS			56
+#define RTL9310_SMI_GLB_CTRL0			0x0cc0
+#define   RTL9310_SMI_FREQ_SEL(intf)		GENMASK((intf) * 2 + 5, (intf) * 2 + 4)
 #define RTL9310_SMI_GLB_CTRL1			0x0cbc
 #define   RTL9310_SMI_GLB_FMT_SEL_C45(intf)	BIT((intf) * 2 + 1)
 #define RTL9310_SMI_INDRT_ACCESS_CTRL_0		0x0c00
@@ -268,6 +274,7 @@ struct otto_emdio_info {
 	u8 num_ports;
 	u16 num_pages;
 	u32 poll_ctrl;
+	int (*set_bus_frequency)(struct mii_bus *bus, u32 freq);
 	int (*setup_controller)(struct otto_emdio_priv *priv);
 	int (*read_c22)(struct mii_bus *bus, int port, int regnum, u32 *value);
 	int (*read_c45)(struct mii_bus *bus, int port, int dev_addr, int regnum, u32 *value);
@@ -739,6 +746,17 @@ static int otto_emdio_setup_topology(struct otto_emdio_priv *priv)
 	return 0;
 }
 
+static int otto_emdio_8380_set_bus_frequency(struct mii_bus *bus, u32 freq)
+{
+	struct otto_emdio_priv *priv = otto_emdio_bus_to_priv(bus);
+
+	if (freq != 2500000 && freq != 10000000)
+		return -EINVAL;
+
+	return regmap_assign_bits(priv->regmap, RTL8380_SMI_GLB_CTRL,
+				  RTL8380_SMI_FREQ_SEL, freq == 10000000);
+}
+
 static int otto_emdio_8380_setup_controller(struct otto_emdio_priv *priv)
 {
 	/*
@@ -748,6 +766,60 @@ static int otto_emdio_8380_setup_controller(struct otto_emdio_priv *priv)
 	return regmap_set_bits(priv->regmap, RTL8380_SMI_GLB_CTRL, RTL8380_SMI_PHY_PATCH_DONE);
 }
 
+static int otto_emdio_8390_set_bus_frequency(struct mii_bus *bus, u32 freq)
+{
+	struct otto_emdio_priv *priv = otto_emdio_bus_to_priv(bus);
+	u32 mdio_bus, child_freq, val;
+	bool freq_set = false;
+	int err;
+
+	/*
+	 * RTL839x uses one frequency shared by both MDIO buses. Use the frequency passed by the
+	 * caller as fallback, but prefer an explicitly requested frequency from any valid,
+	 * available bus. Reject conflicting explicit requests. Only the first call programs the
+	 * shared frequency.
+	 */
+	if (priv->bus[0] || priv->bus[1])
+		return 0;
+
+	for_each_available_child_of_node_scoped(bus->parent->of_node, child) {
+		err = of_property_read_u32(child, "reg", &mdio_bus);
+		if (err || mdio_bus >= priv->info->num_buses)
+			continue;
+
+		if (of_property_read_u32(child, "clock-frequency", &child_freq))
+			continue;
+
+		if (freq_set && freq != child_freq)
+			return -EINVAL;
+
+		freq = child_freq;
+		freq_set = true;
+	}
+
+	if (freq != 1250000 && freq != 2500000 && freq != 5000000)
+		return -EINVAL;
+
+	val = FIELD_PREP(RTL8390_SMI_FREQ_SEL, freq / 2500000);
+
+	return regmap_update_bits(priv->regmap, RTL8390_SMI_GLB_CTRL, RTL8390_SMI_FREQ_SEL, val);
+}
+
+static int otto_emdio_9300_set_bus_frequency(struct mii_bus *bus, u32 freq)
+{
+	struct otto_emdio_priv *priv = otto_emdio_bus_to_priv(bus);
+	struct otto_emdio_chan *chan = bus->priv;
+	u32 mask, val;
+
+	if (freq != 1250000 && freq != 2500000 && freq != 5000000)
+		return -EINVAL;
+
+	mask = RTL9300_SMI_FREQ_SEL(chan->mdio_bus);
+	val = field_prep(mask, freq / 2500000);
+
+	return regmap_update_bits(priv->regmap, RTL9300_SMI_GLB_CTRL, mask, val);
+}
+
 static int otto_emdio_9300_setup_controller(struct otto_emdio_priv *priv)
 {
 	u32 glb_ctrl_mask = 0, glb_ctrl_val = 0;
@@ -768,6 +840,21 @@ static int otto_emdio_9300_setup_controller(struct otto_emdio_priv *priv)
 	return 0;
 }
 
+static int otto_emdio_9310_set_bus_frequency(struct mii_bus *bus, u32 freq)
+{
+	struct otto_emdio_priv *priv = otto_emdio_bus_to_priv(bus);
+	struct otto_emdio_chan *chan = bus->priv;
+	u32 mask, val;
+
+	if (freq != 1250000 && freq != 2500000 && freq != 5000000)
+		return -EINVAL;
+
+	mask = RTL9310_SMI_FREQ_SEL(chan->mdio_bus);
+	val = field_prep(mask, freq / 2500000);
+
+	return regmap_update_bits(priv->regmap, RTL9310_SMI_GLB_CTRL0, mask, val);
+}
+
 static int otto_emdio_9310_setup_controller(struct otto_emdio_priv *priv)
 {
 	int i, err;
@@ -834,7 +921,7 @@ static int otto_emdio_probe_one(struct device *dev, struct otto_emdio_priv *priv
 {
 	struct otto_emdio_chan *chan;
 	struct mii_bus *bus;
-	u32 mdio_bus;
+	u32 mdio_bus, freq;
 	int err;
 
 	err = of_property_read_u32(node, "reg", &mdio_bus);
@@ -867,6 +954,13 @@ static int otto_emdio_probe_one(struct device *dev, struct otto_emdio_priv *priv
 
 	snprintf(bus->id, MII_BUS_ID_SIZE, "%s-%d", dev_name(dev), mdio_bus);
 
+	if (of_property_read_u32(node, "clock-frequency", &freq))
+		freq = 2500000;
+	err = priv->info->set_bus_frequency(bus, freq);
+	if (err)
+		return dev_err_probe(dev, err, "cannot set frequency %u for MDIO bus %d\n",
+				     freq, mdio_bus);
+
 	err = devm_of_mdiobus_register(dev, bus, node);
 	if (err)
 		return dev_err_probe(dev, err, "cannot register MDIO bus\n");
@@ -1055,6 +1149,7 @@ static const struct otto_emdio_info otto_emdio_8380_info = {
 	.num_pages = RTL8380_NUM_PAGES,
 	.num_ports = RTL8380_NUM_PORTS,
 	.poll_ctrl = RTL8380_SMI_POLL_CTRL,
+	.set_bus_frequency = otto_emdio_8380_set_bus_frequency,
 	.setup_controller = otto_emdio_8380_setup_controller,
 	.read_c22 = otto_emdio_8380_read_c22,
 	.read_c45 = otto_emdio_8380_read_c45,
@@ -1079,6 +1174,7 @@ static const struct otto_emdio_info otto_emdio_8390_info = {
 	.num_pages = RTL8390_NUM_PAGES,
 	.num_ports = RTL8390_NUM_PORTS,
 	.poll_ctrl = RTL8390_SMI_PORT_POLLING_CTRL,
+	.set_bus_frequency = otto_emdio_8390_set_bus_frequency,
 	.read_c22 = otto_emdio_8390_read_c22,
 	.read_c45 = otto_emdio_8390_read_c45,
 	.write_c22 = otto_emdio_8390_write_c22,
@@ -1101,6 +1197,7 @@ static const struct otto_emdio_info otto_emdio_9300_info = {
 	.num_ports = RTL9300_NUM_PORTS,
 	.num_pages = RTL9300_NUM_PAGES,
 	.poll_ctrl = RTL9300_SMI_POLL_CTRL,
+	.set_bus_frequency = otto_emdio_9300_set_bus_frequency,
 	.setup_controller = otto_emdio_9300_setup_controller,
 	.read_c22 = otto_emdio_9300_read_c22,
 	.read_c45 = otto_emdio_9300_read_c45,
@@ -1127,6 +1224,7 @@ static const struct otto_emdio_info otto_emdio_9310_info = {
 	.num_pages = RTL9310_NUM_PAGES,
 	.num_ports = RTL9310_NUM_PORTS,
 	.poll_ctrl = RTL9310_SMI_PORT_POLLING_CTRL,
+	.set_bus_frequency = otto_emdio_9310_set_bus_frequency,
 	.setup_controller = otto_emdio_9310_setup_controller,
 	.read_c22 = otto_emdio_9310_read_c22,
 	.read_c45 = otto_emdio_9310_read_c45,
-- 
2.55.0


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

end of thread, other threads:[~2026-09-12 13:05 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-12 13:04 [PATCH net-next v4 0/5] net: mdio: realtek-rtl9300: add bus frequency handling Markus Stockhausen
2026-09-12 13:04 ` [PATCH net-next v4 1/5] dt-bindings: net: realtek,rtl9301-mdio: restrict MDIO buses by family Markus Stockhausen
2026-09-12 13:04 ` [PATCH net-next v4 2/5] dt-bindings: net: realtek,rtl9301-mdio: add clock-frequency Markus Stockhausen
2026-09-12 13:04 ` [PATCH net-next v4 3/5] net: mdio: realtek-rtl9300: convert "fwnode" left-overs to "of" Markus Stockhausen
2026-09-12 13:04 ` [PATCH net-next v4 4/5] net: mdio: realtek-rtl9300: reject duplicate MDIO bus IDs Markus Stockhausen
2026-09-12 13:04 ` [PATCH net-next v4 5/5] net: mdio: realtek-rtl9300: support non-default clock frequencies Markus Stockhausen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox