public inbox for devicetree@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH v6 0/8] Add generic PHY driver used by MACB/GEM on EyeQ5
@ 2026-01-27 17:09 Théo Lebrun
  2026-01-27 17:09 ` [PATCH v6 1/8] dt-bindings: soc: mobileye: OLB is an Ethernet PHY provider " Théo Lebrun
                   ` (8 more replies)
  0 siblings, 9 replies; 20+ messages in thread
From: Théo Lebrun @ 2026-01-27 17:09 UTC (permalink / raw)
  To: Vladimir Kondratiev, Grégory Clement, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
	Kishon Vijay Abraham I, Michael Turquette, Stephen Boyd,
	Philipp Zabel, Thomas Bogendoerfer, Neil Armstrong
  Cc: linux-mips, devicetree, linux-kernel, linux-phy, linux-clk,
	Benoît Monin, Tawfik Bayouk, Thomas Petazzoni, Luca Ceresoli,
	Théo Lebrun, Conor Dooley, Jerome Brunet, Andrew Lunn

EyeQ5 SoCs integrate two GEM instances. A system-controller register
region named "OLB" has some control over the Ethernet PHY integration.

Past iterations [0] touched those syscon registers directly from MACB.
It was a bad idea. Extend the current OLB ecosystem with a new generic
PHY driver.
 - OLB is carried by one main platform driver: clk-eyeq.
 - It instantiates auxiliary devices: reset-eyeq & pinctrl-eyeq5.
 - We add a new one: phy-eyeq5-eth.

I always find devicetree the simplest way to understand device
interactions, so here is a DT overview:

    olb: system-controller@e00000 {
            compatible = "mobileye,eyeq5-olb", "syscon";
            reg = <0 0xe00000 0x0 0x400>;
            // ...
            #reset-cells = <2>;
            #clock-cells = <1>;
            #phy-cells = <1>; // <- this is new
    };

    macb0: ethernet@2a00000 {
            compatible = "mobileye,eyeq5-gem";
            phys = <&olb 0>; // <- GEM device consumes the PHY
            // ...
    };

    macb1: ethernet@2b00000 {
            compatible = "mobileye,eyeq5-gem";
            phys = <&olb 1>; // <- same thing for the second instance
            // ...
    };

The Linux MACB driver already consumes a generic PHY for some other
compatibles, this is nothing new. The MACB series [1] has been merged
in v6.19-rc1.

--

About merging, Philipp Zabel gave his ACK for [5/7] to go into
linux-clk. The split is:

 - [PATCH 1/7] dt-bindings: soc: mobileye: OLB is an Ethernet PHY provider on EyeQ5
   [PATCH 6/7] MIPS: mobileye: eyeq5: add two Cadence GEM Ethernet controllers
   [PATCH 7/7] MIPS: mobileye: eyeq5-epm: add two Cadence GEM Ethernet PHYs
   => linux-mips

 - [PATCH 2/7] phy: Add driver for EyeQ5 Ethernet PHY wrapper
   => linux-phy

 - [PATCH 3/7] clk: eyeq: use the auxiliary device creation helper
   [PATCH 4/7] clk: eyeq: add EyeQ5 children auxiliary device for generic PHYs
   [PATCH 5/7] reset: eyeq: drop device_set_of_node_from_dev() done by parent
   => linux-clk

Any objections to get it in before the next merge window?
The new PHY driver has only seen tiny changes since V1.

Have a nice day,
Thanks!
Théo

[0]: https://lore.kernel.org/lkml/20250627-macb-v2-15-ff8207d0bb77@bootlin.com/
[1]: https://lore.kernel.org/lkml/20251022-macb-eyeq5-v2-0-7c140abb0581@bootlin.com/

Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
---
Changes in v6:
- Rebase upon v6.19-rc7; nothing to report.
- Add new patch "phy: sort Kconfig and Makefile".
- phy-eyeq5-eth: drop useless explicit __iomem cast to
  dev_get_platdata() return value.
- I did *not* drop the Kconfig `default MACH_EYEQ5` nor driver
  `dev_dbg()`. I think both are useful and should be kept. See
  last revision discussion here:
  https://lore.kernel.org/lkml/DFGSMN8268O0.33TYCQDBVHUHZ@bootlin.com/
- Link to v5: https://lore.kernel.org/r/20251215-macb-phy-v5-0-a9dfea39da34@bootlin.com

Changes in v5:
- phy-eyeq5-eth:
  - fix #includes: add delay, gfp_types, module and drop array_size,
    bug, cleanup, container_of, lockdep, mutex.
  - eq5_phy_xlate(): avoid magic value, use EQ5_PHY_COUNT.
  - use dev_err_probe() in error cases of devm_phy_create() and
    devm_of_phy_provider_register().
- 3x Reviewed-by: Luca Ceresoli.
- Add Neil Armstrong to Cc as new PHY subsystem reviewer.
- Rebase on v6.19-rc1, tested on hardware, no changes.
- Link to v4: https://lore.kernel.org/r/20251124-macb-phy-v4-0-955c625a81a7@bootlin.com

Changes in v4:
- Append my SoB to Jerome's patch:
  [PATCH v4 3/7] clk: eyeq: use the auxiliary device creation helper
- Rebase on net-next & linux-{clk,mips,phy}. Nothing to report.
- Link to v3: https://lore.kernel.org/r/20251119-macb-phy-v3-0-e9a7be186a33@bootlin.com

Changes in v3:
- Take Philipp Zabel's Reviewed-by & Acked-by trailers on reset patch.
- Take Thomas Bogendoerfer's two Acked-by trailers on DT patches.
- Rebase on net-next & test on target. Nothing to report.
- Link to v2: https://lore.kernel.org/r/20251101-macb-phy-v2-0-c1519eef16d3@bootlin.com

Changes in v2:
- Take Acked-by: Conor Dooley on dt-bindings-patch.
- s/%ld/%tu/ for printing ptrdiff_t; warnings on 32-bit archs.
  Reported by NIPA's netdev/build_32bit test.
  https://patchwork.kernel.org/project/netdevbpf/patch/20251021-macb-eyeq5-v1-7-3b0b5a9d2f85@bootlin.com/
  https://netdev.bots.linux.dev/static/nipa/1014126/14277857/build_32bit/stderr
- Link to v1: https://lore.kernel.org/r/20251022-macb-phy-v1-0-f29f28fae721@bootlin.com

Changes since MACB V1:
- Drop the old "mobileye,olb" properties from DT patches; found while
  running dtbs_check and dt_binding_check.
- Drop all patches targeting net-next. That is MACB dt-bindings patch
  and MACB driver code. See there here [1].
- Link to v1: https://lore.kernel.org/lkml/20251021-macb-eyeq5-v1-0-3b0b5a9d2f85@bootlin.com/

Past versions of MACB patches:
 - March 2025: [PATCH net-next 00/13] Support the Cadence MACB/GEM
   instances on Mobileye EyeQ5 SoCs
   https://lore.kernel.org/lkml/20250321-macb-v1-0-537b7e37971d@bootlin.com/
 - June 2025: [PATCH net-next v2 00/18] Support the Cadence MACB/GEM
   instances on Mobileye EyeQ5 SoCs
   https://lore.kernel.org/lkml/20250627-macb-v2-0-ff8207d0bb77@bootlin.com/
 - August 2025: [PATCH net v3 00/16] net: macb: various fixes & cleanup
   https://lore.kernel.org/lkml/20250808-macb-fixes-v3-0-08f1fcb5179f@bootlin.com/

---
Jerome Brunet (1):
      clk: eyeq: use the auxiliary device creation helper

Théo Lebrun (7):
      dt-bindings: soc: mobileye: OLB is an Ethernet PHY provider on EyeQ5
      phy: sort Kconfig and Makefile
      phy: Add driver for EyeQ5 Ethernet PHY wrapper
      clk: eyeq: add EyeQ5 children auxiliary device for generic PHYs
      reset: eyeq: drop device_set_of_node_from_dev() done by parent
      MIPS: mobileye: eyeq5: add two Cadence GEM Ethernet controllers
      MIPS: mobileye: eyeq5-epm: add two Cadence GEM Ethernet PHYs

 .../bindings/soc/mobileye/mobileye,eyeq5-olb.yaml  |   7 +-
 MAINTAINERS                                        |   1 +
 arch/mips/boot/dts/mobileye/eyeq5-epm5.dts         |  26 +++
 arch/mips/boot/dts/mobileye/eyeq5.dtsi             |  45 ++++
 drivers/clk/clk-eyeq.c                             |  60 ++---
 drivers/phy/Kconfig                                |  75 ++++---
 drivers/phy/Makefile                               |   7 +-
 drivers/phy/phy-eyeq5-eth.c                        | 249 +++++++++++++++++++++
 drivers/reset/reset-eyeq.c                         |  24 +-
 9 files changed, 392 insertions(+), 102 deletions(-)
---
base-commit: aaae99475aaae1373d8bbdef6105e8ad2d4c75af
change-id: 20251022-macb-phy-21bc4e1dfbb7

Best regards,
-- 
Théo Lebrun <theo.lebrun@bootlin.com>


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

* [PATCH v6 1/8] dt-bindings: soc: mobileye: OLB is an Ethernet PHY provider on EyeQ5
  2026-01-27 17:09 [PATCH v6 0/8] Add generic PHY driver used by MACB/GEM on EyeQ5 Théo Lebrun
@ 2026-01-27 17:09 ` Théo Lebrun
  2026-01-27 17:09 ` [PATCH v6 2/8] phy: sort Kconfig and Makefile Théo Lebrun
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 20+ messages in thread
From: Théo Lebrun @ 2026-01-27 17:09 UTC (permalink / raw)
  To: Vladimir Kondratiev, Grégory Clement, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
	Kishon Vijay Abraham I, Michael Turquette, Stephen Boyd,
	Philipp Zabel, Thomas Bogendoerfer, Neil Armstrong
  Cc: linux-mips, devicetree, linux-kernel, linux-phy, linux-clk,
	Benoît Monin, Tawfik Bayouk, Thomas Petazzoni, Luca Ceresoli,
	Théo Lebrun, Conor Dooley

OLB on EyeQ5 ("mobileye,eyeq5-olb" compatible) is now declared as a
generic PHY provider. Under the hood, it provides Ethernet RGMII/SGMII
PHY support for both MAC instances.

Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
---
 .../devicetree/bindings/soc/mobileye/mobileye,eyeq5-olb.yaml       | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/soc/mobileye/mobileye,eyeq5-olb.yaml b/Documentation/devicetree/bindings/soc/mobileye/mobileye,eyeq5-olb.yaml
index 6d11472ba5a7..56401d76a9b5 100644
--- a/Documentation/devicetree/bindings/soc/mobileye/mobileye,eyeq5-olb.yaml
+++ b/Documentation/devicetree/bindings/soc/mobileye/mobileye,eyeq5-olb.yaml
@@ -51,6 +51,9 @@ properties:
   clock-names:
     const: ref
 
+  '#phy-cells':
+    const: 1
+
 patternProperties:
   '-pins?$':
     type: object
@@ -310,7 +313,7 @@ allOf:
       properties:
         '#reset-cells': false
 
-    # Only EyeQ5 has pinctrl in OLB.
+    # Only EyeQ5 has pinctrl and PHY in OLB.
   - if:
       not:
         properties:
@@ -320,6 +323,8 @@ allOf:
     then:
       patternProperties:
         '-pins?$': false
+      properties:
+        '#phy-cells': false
 
 examples:
   - |

-- 
2.52.0


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

* [PATCH v6 2/8] phy: sort Kconfig and Makefile
  2026-01-27 17:09 [PATCH v6 0/8] Add generic PHY driver used by MACB/GEM on EyeQ5 Théo Lebrun
  2026-01-27 17:09 ` [PATCH v6 1/8] dt-bindings: soc: mobileye: OLB is an Ethernet PHY provider " Théo Lebrun
@ 2026-01-27 17:09 ` Théo Lebrun
  2026-02-06  8:39   ` Luca Ceresoli
  2026-02-10 19:37   ` Vladimir Oltean
  2026-01-27 17:09 ` [PATCH v6 3/8] phy: Add driver for EyeQ5 Ethernet PHY wrapper Théo Lebrun
                   ` (6 subsequent siblings)
  8 siblings, 2 replies; 20+ messages in thread
From: Théo Lebrun @ 2026-01-27 17:09 UTC (permalink / raw)
  To: Vladimir Kondratiev, Grégory Clement, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
	Kishon Vijay Abraham I, Michael Turquette, Stephen Boyd,
	Philipp Zabel, Thomas Bogendoerfer, Neil Armstrong
  Cc: linux-mips, devicetree, linux-kernel, linux-phy, linux-clk,
	Benoît Monin, Tawfik Bayouk, Thomas Petazzoni, Luca Ceresoli,
	Théo Lebrun

Neither Kconfig nor Makefile are sorted; reorder them.

$ diff -U100 <(grep ^config drivers/phy/Kconfig) \
             <(grep ^config drivers/phy/Kconfig | sort)

$ diff -U100 <(grep ^obj-\\$ drivers/phy/Makefile) \
             <(grep ^obj-\\$ drivers/phy/Makefile | sort)

Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
---
 drivers/phy/Kconfig  | 62 ++++++++++++++++++++++++++--------------------------
 drivers/phy/Makefile |  6 ++---
 2 files changed, 34 insertions(+), 34 deletions(-)

diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 678dd0452f0a..4f1b1d7f5d20 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -25,6 +25,26 @@ config GENERIC_PHY_MIPI_DPHY
 	  Provides a number of helpers a core functions for MIPI D-PHY
 	  drivers to us.
 
+config PHY_AIROHA_PCIE
+	tristate "Airoha PCIe-PHY Driver"
+	depends on ARCH_AIROHA || COMPILE_TEST
+	depends on OF
+	select GENERIC_PHY
+	help
+	  Say Y here to add support for Airoha PCIe PHY driver.
+	  This driver create the basic PHY instance and provides initialize
+	  callback for PCIe GEN3 port.
+
+config PHY_CAN_TRANSCEIVER
+	tristate "CAN transceiver PHY"
+	select GENERIC_PHY
+	select MULTIPLEXER
+	help
+	  This option enables support for CAN transceivers as a PHY. This
+	  driver provides function for putting the transceivers in various
+	  functional modes using gpios and sets the attribute max link
+	  rate, for CAN drivers.
+
 config PHY_LPC18XX_USB_OTG
 	tristate "NXP LPC18xx/43xx SoC USB OTG PHY driver"
 	depends on OF && (ARCH_LPC18XX || COMPILE_TEST)
@@ -36,6 +56,17 @@ config PHY_LPC18XX_USB_OTG
 	  This driver is need for USB0 support on LPC18xx/43xx and takes
 	  care of enabling and clock setup.
 
+config PHY_NXP_PTN3222
+	tristate "NXP PTN3222 1-port eUSB2 to USB2 redriver"
+	depends on I2C
+	depends on OF
+	select GENERIC_PHY
+	help
+	  Enable this to support NXP PTN3222 1-port eUSB2 to USB2 Redriver.
+	  This redriver performs translation between eUSB2 and USB2 signalling
+	  schemes. It supports all three USB 2.0 data rates: Low Speed, Full
+	  Speed and High Speed.
+
 config PHY_PISTACHIO_USB
 	tristate "IMG Pistachio USB2.0 PHY driver"
 	depends on MIPS || COMPILE_TEST
@@ -70,37 +101,6 @@ config USB_LGM_PHY
 	  interface to interact with USB GEN-II and USB 3.x PHY that is part
 	  of the Intel network SOC.
 
-config PHY_CAN_TRANSCEIVER
-	tristate "CAN transceiver PHY"
-	select GENERIC_PHY
-	select MULTIPLEXER
-	help
-	  This option enables support for CAN transceivers as a PHY. This
-	  driver provides function for putting the transceivers in various
-	  functional modes using gpios and sets the attribute max link
-	  rate, for CAN drivers.
-
-config PHY_AIROHA_PCIE
-	tristate "Airoha PCIe-PHY Driver"
-	depends on ARCH_AIROHA || COMPILE_TEST
-	depends on OF
-	select GENERIC_PHY
-	help
-	  Say Y here to add support for Airoha PCIe PHY driver.
-	  This driver create the basic PHY instance and provides initialize
-	  callback for PCIe GEN3 port.
-
-config PHY_NXP_PTN3222
-	tristate "NXP PTN3222 1-port eUSB2 to USB2 redriver"
-	depends on I2C
-	depends on OF
-	select GENERIC_PHY
-	help
-	  Enable this to support NXP PTN3222 1-port eUSB2 to USB2 Redriver.
-	  This redriver performs translation between eUSB2 and USB2 signalling
-	  schemes. It supports all three USB 2.0 data rates: Low Speed, Full
-	  Speed and High Speed.
-
 source "drivers/phy/allwinner/Kconfig"
 source "drivers/phy/amlogic/Kconfig"
 source "drivers/phy/broadcom/Kconfig"
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index bfb27fb5a494..9943d742571d 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -5,14 +5,14 @@
 
 obj-$(CONFIG_GENERIC_PHY)		+= phy-core.o
 obj-$(CONFIG_GENERIC_PHY_MIPI_DPHY)	+= phy-core-mipi-dphy.o
+obj-$(CONFIG_PHY_AIROHA_PCIE)		+= phy-airoha-pcie.o
 obj-$(CONFIG_PHY_CAN_TRANSCEIVER)	+= phy-can-transceiver.o
 obj-$(CONFIG_PHY_LPC18XX_USB_OTG)	+= phy-lpc18xx-usb-otg.o
-obj-$(CONFIG_PHY_XGENE)			+= phy-xgene.o
+obj-$(CONFIG_PHY_NXP_PTN3222)		+= phy-nxp-ptn3222.o
 obj-$(CONFIG_PHY_PISTACHIO_USB)		+= phy-pistachio-usb.o
 obj-$(CONFIG_PHY_SNPS_EUSB2)		+= phy-snps-eusb2.o
+obj-$(CONFIG_PHY_XGENE)			+= phy-xgene.o
 obj-$(CONFIG_USB_LGM_PHY)		+= phy-lgm-usb.o
-obj-$(CONFIG_PHY_AIROHA_PCIE)		+= phy-airoha-pcie.o
-obj-$(CONFIG_PHY_NXP_PTN3222)		+= phy-nxp-ptn3222.o
 obj-y					+= allwinner/	\
 					   amlogic/	\
 					   broadcom/	\

-- 
2.52.0


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

* [PATCH v6 3/8] phy: Add driver for EyeQ5 Ethernet PHY wrapper
  2026-01-27 17:09 [PATCH v6 0/8] Add generic PHY driver used by MACB/GEM on EyeQ5 Théo Lebrun
  2026-01-27 17:09 ` [PATCH v6 1/8] dt-bindings: soc: mobileye: OLB is an Ethernet PHY provider " Théo Lebrun
  2026-01-27 17:09 ` [PATCH v6 2/8] phy: sort Kconfig and Makefile Théo Lebrun
@ 2026-01-27 17:09 ` Théo Lebrun
  2026-02-10 19:35   ` Vladimir Oltean
  2026-02-25 15:00   ` Vinod Koul
  2026-01-27 17:09 ` [PATCH v6 4/8] clk: eyeq: use the auxiliary device creation helper Théo Lebrun
                   ` (5 subsequent siblings)
  8 siblings, 2 replies; 20+ messages in thread
From: Théo Lebrun @ 2026-01-27 17:09 UTC (permalink / raw)
  To: Vladimir Kondratiev, Grégory Clement, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
	Kishon Vijay Abraham I, Michael Turquette, Stephen Boyd,
	Philipp Zabel, Thomas Bogendoerfer, Neil Armstrong
  Cc: linux-mips, devicetree, linux-kernel, linux-phy, linux-clk,
	Benoît Monin, Tawfik Bayouk, Thomas Petazzoni, Luca Ceresoli,
	Théo Lebrun

EyeQ5 embeds a system-controller called OLB. It features many unrelated
registers, and some of those are registers used to configure the
integration of the RGMII/SGMII Cadence PHY used by MACB/GEM instances.

Wrap in a neat generic PHY provider, exposing two PHYs with standard
phy_init() / phy_set_mode() / phy_power_on() operations.

Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
---
 MAINTAINERS                 |   1 +
 drivers/phy/Kconfig         |  13 +++
 drivers/phy/Makefile        |   1 +
 drivers/phy/phy-eyeq5-eth.c | 249 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 264 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 67db88b04537..2f77dc350706 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -17621,6 +17621,7 @@ F:	arch/mips/boot/dts/mobileye/
 F:	arch/mips/configs/eyeq5_defconfig
 F:	arch/mips/mobileye/board-epm5.its.S
 F:	drivers/clk/clk-eyeq.c
+F:	drivers/phy/phy-eyeq5-eth.c
 F:	drivers/pinctrl/pinctrl-eyeq5.c
 F:	drivers/reset/reset-eyeq.c
 F:	include/dt-bindings/clock/mobileye,eyeq5-clk.h
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 4f1b1d7f5d20..b3c11cd0209a 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -45,6 +45,19 @@ config PHY_CAN_TRANSCEIVER
 	  functional modes using gpios and sets the attribute max link
 	  rate, for CAN drivers.
 
+config PHY_EYEQ5_ETH
+	tristate "Ethernet PHY Driver on EyeQ5"
+	depends on OF
+	depends on MACH_EYEQ5 || COMPILE_TEST
+	select AUXILIARY_BUS
+	select GENERIC_PHY
+	default MACH_EYEQ5
+	help
+	  Enable this to support the Ethernet PHY integrated on EyeQ5.
+	  It supports both RGMII and SGMII. Registers are located in a
+	  shared register region called OLB. If M is selected, the
+	  module will be called phy-eyeq5-eth.
+
 config PHY_LPC18XX_USB_OTG
 	tristate "NXP LPC18xx/43xx SoC USB OTG PHY driver"
 	depends on OF && (ARCH_LPC18XX || COMPILE_TEST)
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index 9943d742571d..c81ac7926e6b 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_GENERIC_PHY)		+= phy-core.o
 obj-$(CONFIG_GENERIC_PHY_MIPI_DPHY)	+= phy-core-mipi-dphy.o
 obj-$(CONFIG_PHY_AIROHA_PCIE)		+= phy-airoha-pcie.o
 obj-$(CONFIG_PHY_CAN_TRANSCEIVER)	+= phy-can-transceiver.o
+obj-$(CONFIG_PHY_EYEQ5_ETH)		+= phy-eyeq5-eth.o
 obj-$(CONFIG_PHY_LPC18XX_USB_OTG)	+= phy-lpc18xx-usb-otg.o
 obj-$(CONFIG_PHY_NXP_PTN3222)		+= phy-nxp-ptn3222.o
 obj-$(CONFIG_PHY_PISTACHIO_USB)		+= phy-pistachio-usb.o
diff --git a/drivers/phy/phy-eyeq5-eth.c b/drivers/phy/phy-eyeq5-eth.c
new file mode 100644
index 000000000000..0c46359dad96
--- /dev/null
+++ b/drivers/phy/phy-eyeq5-eth.c
@@ -0,0 +1,249 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/auxiliary_bus.h>
+#include <linux/bitfield.h>
+#include <linux/bits.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/gfp_types.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/phy.h>
+#include <linux/phy/phy.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+
+#define EQ5_PHY_COUNT	2
+
+#define EQ5_PHY0_GP	0x128
+#define EQ5_PHY1_GP	0x12c
+#define EQ5_PHY0_SGMII	0x134
+#define EQ5_PHY1_SGMII	0x138
+
+#define EQ5_GP_TX_SWRST_DIS	BIT(0)		// Tx SW reset
+#define EQ5_GP_TX_M_CLKE	BIT(1)		// Tx M clock enable
+#define EQ5_GP_SYS_SWRST_DIS	BIT(2)		// Sys SW reset
+#define EQ5_GP_SYS_M_CLKE	BIT(3)		// Sys clock enable
+#define EQ5_GP_SGMII_MODE	BIT(4)		// SGMII mode
+#define EQ5_GP_RGMII_DRV	GENMASK(8, 5)	// RGMII drive strength
+
+#define EQ5_SGMII_PWR_EN	BIT(0)
+#define EQ5_SGMII_RST_DIS	BIT(1)
+#define EQ5_SGMII_PLL_EN	BIT(2)
+#define EQ5_SGMII_SIG_DET_SW	BIT(3)
+#define EQ5_SGMII_PWR_STATE	BIT(4)
+#define EQ5_SGMII_PLL_ACK	BIT(18)
+#define EQ5_SGMII_PWR_STATE_ACK	GENMASK(24, 20)
+
+struct eq5_phy_inst {
+	struct eq5_phy_private	*priv;
+	struct phy		*phy;
+	void __iomem		*gp, *sgmii;
+	phy_interface_t		phy_interface;
+};
+
+struct eq5_phy_private {
+	struct device		*dev;
+	struct eq5_phy_inst	phys[EQ5_PHY_COUNT];
+};
+
+static int eq5_phy_init(struct phy *phy)
+{
+	struct eq5_phy_inst *inst = phy_get_drvdata(phy);
+	struct eq5_phy_private *priv = inst->priv;
+	struct device *dev = priv->dev;
+	u32 reg;
+
+	dev_dbg(dev, "phy_init(inst=%td)\n", inst - priv->phys);
+
+	writel(0, inst->gp);
+	writel(0, inst->sgmii);
+
+	udelay(5);
+
+	reg = readl(inst->gp) | EQ5_GP_TX_SWRST_DIS | EQ5_GP_TX_M_CLKE |
+	      EQ5_GP_SYS_SWRST_DIS | EQ5_GP_SYS_M_CLKE |
+	      FIELD_PREP(EQ5_GP_RGMII_DRV, 0x9);
+	writel(reg, inst->gp);
+
+	return 0;
+}
+
+static int eq5_phy_exit(struct phy *phy)
+{
+	struct eq5_phy_inst *inst = phy_get_drvdata(phy);
+	struct eq5_phy_private *priv = inst->priv;
+	struct device *dev = priv->dev;
+
+	dev_dbg(dev, "phy_exit(inst=%td)\n", inst - priv->phys);
+
+	writel(0, inst->gp);
+	writel(0, inst->sgmii);
+	udelay(5);
+
+	return 0;
+}
+
+static int eq5_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
+{
+	struct eq5_phy_inst *inst = phy_get_drvdata(phy);
+	struct eq5_phy_private *priv = inst->priv;
+	struct device *dev = priv->dev;
+
+	dev_dbg(dev, "phy_set_mode(inst=%td, mode=%d, submode=%d)\n",
+		inst - priv->phys, mode, submode);
+
+	if (mode != PHY_MODE_ETHERNET)
+		return -EOPNOTSUPP;
+
+	if (!phy_interface_mode_is_rgmii(submode) &&
+	    submode != PHY_INTERFACE_MODE_SGMII)
+		return -EOPNOTSUPP;
+
+	inst->phy_interface = submode;
+	return 0;
+}
+
+static int eq5_phy_power_on(struct phy *phy)
+{
+	struct eq5_phy_inst *inst = phy_get_drvdata(phy);
+	struct eq5_phy_private *priv = inst->priv;
+	struct device *dev = priv->dev;
+	u32 reg;
+
+	dev_dbg(dev, "phy_power_on(inst=%td)\n", inst - priv->phys);
+
+	if (inst->phy_interface == PHY_INTERFACE_MODE_SGMII) {
+		writel(readl(inst->gp) | EQ5_GP_SGMII_MODE, inst->gp);
+
+		reg = EQ5_SGMII_PWR_EN | EQ5_SGMII_RST_DIS | EQ5_SGMII_PLL_EN;
+		writel(reg, inst->sgmii);
+
+		if (readl_poll_timeout(inst->sgmii, reg,
+				       reg & EQ5_SGMII_PLL_ACK, 1, 100)) {
+			dev_err(dev, "PLL timeout\n");
+			return -ETIMEDOUT;
+		}
+
+		reg = readl(inst->sgmii);
+		reg |= EQ5_SGMII_PWR_STATE | EQ5_SGMII_SIG_DET_SW;
+		writel(reg, inst->sgmii);
+	} else {
+		writel(readl(inst->gp) & ~EQ5_GP_SGMII_MODE, inst->gp);
+		writel(0, inst->sgmii);
+	}
+
+	return 0;
+}
+
+static int eq5_phy_power_off(struct phy *phy)
+{
+	struct eq5_phy_inst *inst = phy_get_drvdata(phy);
+	struct eq5_phy_private *priv = inst->priv;
+	struct device *dev = priv->dev;
+
+	dev_dbg(dev, "phy_power_off(inst=%td)\n", inst - priv->phys);
+
+	writel(readl(inst->gp) & ~EQ5_GP_SGMII_MODE, inst->gp);
+	writel(0, inst->sgmii);
+
+	return 0;
+}
+
+static const struct phy_ops eq5_phy_ops = {
+	.init		= eq5_phy_init,
+	.exit		= eq5_phy_exit,
+	.set_mode	= eq5_phy_set_mode,
+	.power_on	= eq5_phy_power_on,
+	.power_off	= eq5_phy_power_off,
+};
+
+static struct phy *eq5_phy_xlate(struct device *dev,
+				 const struct of_phandle_args *args)
+{
+	struct eq5_phy_private *priv = dev_get_drvdata(dev);
+
+	if (args->args_count != 1 || args->args[0] >= EQ5_PHY_COUNT)
+		return ERR_PTR(-EINVAL);
+
+	return priv->phys[args->args[0]].phy;
+}
+
+static int eq5_phy_probe_phy(struct eq5_phy_private *priv, unsigned int index,
+			     void __iomem *base, unsigned int gp,
+			     unsigned int sgmii)
+{
+	struct eq5_phy_inst *inst = &priv->phys[index];
+	struct device *dev = priv->dev;
+	struct phy *phy;
+
+	phy = devm_phy_create(dev, dev->of_node, &eq5_phy_ops);
+	if (IS_ERR(phy))
+		return dev_err_probe(dev, PTR_ERR(phy),
+				     "failed to create PHY %u\n", index);
+
+	inst->priv = priv;
+	inst->phy = phy;
+	inst->gp = base + gp;
+	inst->sgmii = base + sgmii;
+	inst->phy_interface = PHY_INTERFACE_MODE_NA;
+	phy_set_drvdata(phy, inst);
+
+	return 0;
+}
+
+static int eq5_phy_probe(struct auxiliary_device *adev,
+			 const struct auxiliary_device_id *id)
+{
+	struct device *dev = &adev->dev;
+	struct phy_provider *provider;
+	struct eq5_phy_private *priv;
+	void __iomem *base;
+	int ret;
+
+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	priv->dev = dev;
+	dev_set_drvdata(dev, priv);
+
+	base = dev_get_platdata(dev);
+
+	ret = eq5_phy_probe_phy(priv, 0, base, EQ5_PHY0_GP, EQ5_PHY0_SGMII);
+	if (ret)
+		return ret;
+
+	ret = eq5_phy_probe_phy(priv, 1, base, EQ5_PHY1_GP, EQ5_PHY1_SGMII);
+	if (ret)
+		return ret;
+
+	provider = devm_of_phy_provider_register(dev, eq5_phy_xlate);
+	if (IS_ERR(provider))
+		return dev_err_probe(dev, PTR_ERR(provider),
+				     "registering provider failed\n");
+
+	return 0;
+}
+
+static const struct auxiliary_device_id eq5_phy_id_table[] = {
+	{ .name = "clk_eyeq.phy" },
+	{}
+};
+MODULE_DEVICE_TABLE(auxiliary, eq5_phy_id_table);
+
+static struct auxiliary_driver eq5_phy_driver = {
+	.probe = eq5_phy_probe,
+	.id_table = eq5_phy_id_table,
+};
+module_auxiliary_driver(eq5_phy_driver);
+
+MODULE_DESCRIPTION("EyeQ5 Ethernet PHY driver");
+MODULE_AUTHOR("Théo Lebrun <theo.lebrun@bootlin.com>");
+MODULE_LICENSE("GPL");

-- 
2.52.0


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

* [PATCH v6 4/8] clk: eyeq: use the auxiliary device creation helper
  2026-01-27 17:09 [PATCH v6 0/8] Add generic PHY driver used by MACB/GEM on EyeQ5 Théo Lebrun
                   ` (2 preceding siblings ...)
  2026-01-27 17:09 ` [PATCH v6 3/8] phy: Add driver for EyeQ5 Ethernet PHY wrapper Théo Lebrun
@ 2026-01-27 17:09 ` Théo Lebrun
  2026-01-27 17:09 ` [PATCH v6 5/8] clk: eyeq: add EyeQ5 children auxiliary device for generic PHYs Théo Lebrun
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 20+ messages in thread
From: Théo Lebrun @ 2026-01-27 17:09 UTC (permalink / raw)
  To: Vladimir Kondratiev, Grégory Clement, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
	Kishon Vijay Abraham I, Michael Turquette, Stephen Boyd,
	Philipp Zabel, Thomas Bogendoerfer, Neil Armstrong
  Cc: linux-mips, devicetree, linux-kernel, linux-phy, linux-clk,
	Benoît Monin, Tawfik Bayouk, Thomas Petazzoni, Luca Ceresoli,
	Théo Lebrun, Jerome Brunet

From: Jerome Brunet <jbrunet@baylibre.com>

The auxiliary device creation of this driver is simple enough to
use the available auxiliary device creation helper.

Use it and remove some boilerplate code.

Tested-by: Théo Lebrun <theo.lebrun@bootlin.com>  # On Mobileye EyeQ5
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
---
 drivers/clk/clk-eyeq.c | 57 +++++++++++---------------------------------------
 1 file changed, 12 insertions(+), 45 deletions(-)

diff --git a/drivers/clk/clk-eyeq.c b/drivers/clk/clk-eyeq.c
index ea1c3d78e7cd..664ce7d7868d 100644
--- a/drivers/clk/clk-eyeq.c
+++ b/drivers/clk/clk-eyeq.c
@@ -322,38 +322,18 @@ static void eqc_probe_init_fixed_factors(struct device *dev,
 	}
 }
 
-static void eqc_auxdev_release(struct device *dev)
-{
-	struct auxiliary_device *adev = to_auxiliary_dev(dev);
-
-	kfree(adev);
-}
-
-static int eqc_auxdev_create(struct device *dev, void __iomem *base,
-			     const char *name, u32 id)
+static void eqc_auxdev_create_optional(struct device *dev, void __iomem *base,
+				       const char *name)
 {
 	struct auxiliary_device *adev;
-	int ret;
 
-	adev = kzalloc(sizeof(*adev), GFP_KERNEL);
-	if (!adev)
-		return -ENOMEM;
-
-	adev->name = name;
-	adev->dev.parent = dev;
-	adev->dev.platform_data = (void __force *)base;
-	adev->dev.release = eqc_auxdev_release;
-	adev->id = id;
-
-	ret = auxiliary_device_init(adev);
-	if (ret)
-		return ret;
-
-	ret = auxiliary_device_add(adev);
-	if (ret)
-		auxiliary_device_uninit(adev);
-
-	return ret;
+	if (name) {
+		adev = devm_auxiliary_device_create(dev, name,
+						    (void __force *)base);
+		if (!adev)
+			dev_warn(dev, "failed creating auxiliary device %s.%s\n",
+				 KBUILD_MODNAME, name);
+	}
 }
 
 static int eqc_probe(struct platform_device *pdev)
@@ -365,7 +345,6 @@ static int eqc_probe(struct platform_device *pdev)
 	unsigned int i, clk_count;
 	struct resource *res;
 	void __iomem *base;
-	int ret;
 
 	data = device_get_match_data(dev);
 	if (!data)
@@ -379,21 +358,9 @@ static int eqc_probe(struct platform_device *pdev)
 	if (!base)
 		return -ENOMEM;
 
-	/* Init optional reset auxiliary device. */
-	if (data->reset_auxdev_name) {
-		ret = eqc_auxdev_create(dev, base, data->reset_auxdev_name, 0);
-		if (ret)
-			dev_warn(dev, "failed creating auxiliary device %s.%s: %d\n",
-				 KBUILD_MODNAME, data->reset_auxdev_name, ret);
-	}
-
-	/* Init optional pinctrl auxiliary device. */
-	if (data->pinctrl_auxdev_name) {
-		ret = eqc_auxdev_create(dev, base, data->pinctrl_auxdev_name, 0);
-		if (ret)
-			dev_warn(dev, "failed creating auxiliary device %s.%s: %d\n",
-				 KBUILD_MODNAME, data->pinctrl_auxdev_name, ret);
-	}
+	/* Init optional auxiliary devices. */
+	eqc_auxdev_create_optional(dev, base, data->reset_auxdev_name);
+	eqc_auxdev_create_optional(dev, base, data->pinctrl_auxdev_name);
 
 	if (data->pll_count + data->div_count + data->fixed_factor_count == 0)
 		return 0; /* Zero clocks, we are done. */

-- 
2.52.0


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

* [PATCH v6 5/8] clk: eyeq: add EyeQ5 children auxiliary device for generic PHYs
  2026-01-27 17:09 [PATCH v6 0/8] Add generic PHY driver used by MACB/GEM on EyeQ5 Théo Lebrun
                   ` (3 preceding siblings ...)
  2026-01-27 17:09 ` [PATCH v6 4/8] clk: eyeq: use the auxiliary device creation helper Théo Lebrun
@ 2026-01-27 17:09 ` Théo Lebrun
  2026-01-27 17:09 ` [PATCH v6 6/8] reset: eyeq: drop device_set_of_node_from_dev() done by parent Théo Lebrun
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 20+ messages in thread
From: Théo Lebrun @ 2026-01-27 17:09 UTC (permalink / raw)
  To: Vladimir Kondratiev, Grégory Clement, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
	Kishon Vijay Abraham I, Michael Turquette, Stephen Boyd,
	Philipp Zabel, Thomas Bogendoerfer, Neil Armstrong
  Cc: linux-mips, devicetree, linux-kernel, linux-phy, linux-clk,
	Benoît Monin, Tawfik Bayouk, Thomas Petazzoni, Luca Ceresoli,
	Théo Lebrun

Grow our clk-eyeq family; it knows how to spawn reset provider and pin
controller children. Expand with a generic PHY driver on EyeQ5.

Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
---
 drivers/clk/clk-eyeq.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/clk/clk-eyeq.c b/drivers/clk/clk-eyeq.c
index 664ce7d7868d..a9de57315e48 100644
--- a/drivers/clk/clk-eyeq.c
+++ b/drivers/clk/clk-eyeq.c
@@ -109,6 +109,7 @@ struct eqc_match_data {
 
 	const char		*reset_auxdev_name;
 	const char		*pinctrl_auxdev_name;
+	const char		*eth_phy_auxdev_name;
 
 	unsigned int		early_clk_count;
 };
@@ -361,6 +362,7 @@ static int eqc_probe(struct platform_device *pdev)
 	/* Init optional auxiliary devices. */
 	eqc_auxdev_create_optional(dev, base, data->reset_auxdev_name);
 	eqc_auxdev_create_optional(dev, base, data->pinctrl_auxdev_name);
+	eqc_auxdev_create_optional(dev, base, data->eth_phy_auxdev_name);
 
 	if (data->pll_count + data->div_count + data->fixed_factor_count == 0)
 		return 0; /* Zero clocks, we are done. */
@@ -521,6 +523,7 @@ static const struct eqc_match_data eqc_eyeq5_match_data = {
 
 	.reset_auxdev_name = "reset",
 	.pinctrl_auxdev_name = "pinctrl",
+	.eth_phy_auxdev_name = "phy",
 
 	.early_clk_count = ARRAY_SIZE(eqc_eyeq5_early_plls) +
 			   ARRAY_SIZE(eqc_eyeq5_early_fixed_factors),

-- 
2.52.0


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

* [PATCH v6 6/8] reset: eyeq: drop device_set_of_node_from_dev() done by parent
  2026-01-27 17:09 [PATCH v6 0/8] Add generic PHY driver used by MACB/GEM on EyeQ5 Théo Lebrun
                   ` (4 preceding siblings ...)
  2026-01-27 17:09 ` [PATCH v6 5/8] clk: eyeq: add EyeQ5 children auxiliary device for generic PHYs Théo Lebrun
@ 2026-01-27 17:09 ` Théo Lebrun
  2026-01-27 17:09 ` [PATCH v6 7/8] MIPS: mobileye: eyeq5: add two Cadence GEM Ethernet controllers Théo Lebrun
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 20+ messages in thread
From: Théo Lebrun @ 2026-01-27 17:09 UTC (permalink / raw)
  To: Vladimir Kondratiev, Grégory Clement, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
	Kishon Vijay Abraham I, Michael Turquette, Stephen Boyd,
	Philipp Zabel, Thomas Bogendoerfer, Neil Armstrong
  Cc: linux-mips, devicetree, linux-kernel, linux-phy, linux-clk,
	Benoît Monin, Tawfik Bayouk, Thomas Petazzoni, Luca Ceresoli,
	Théo Lebrun, Jerome Brunet

Our parent driver (clk-eyeq) now does the
	device_set_of_node_from_dev(dev, dev->parent)
call through the newly introduced devm_auxiliary_device_create() helper.

Doing it again in the reset-eyeq probe would be redundant.
Drop both the WARN_ON() and the device_set_of_node_from_dev() call.
Also fix the following comment that talks about "our newfound OF node".

Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Reviewed-by: Philipp Zabel <p.zabel@pengutronix.de>
Acked-by: Philipp Zabel <p.zabel@pengutronix.de>
Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
---
 drivers/reset/reset-eyeq.c | 24 ++----------------------
 1 file changed, 2 insertions(+), 22 deletions(-)

diff --git a/drivers/reset/reset-eyeq.c b/drivers/reset/reset-eyeq.c
index 2d3998368a1c..8018fa895427 100644
--- a/drivers/reset/reset-eyeq.c
+++ b/drivers/reset/reset-eyeq.c
@@ -410,13 +410,6 @@ static int eqr_of_xlate_twocells(struct reset_controller_dev *rcdev,
 	return eqr_of_xlate_internal(rcdev, reset_spec->args[0], reset_spec->args[1]);
 }
 
-static void eqr_of_node_put(void *_dev)
-{
-	struct device *dev = _dev;
-
-	of_node_put(dev->of_node);
-}
-
 static int eqr_probe(struct auxiliary_device *adev,
 		     const struct auxiliary_device_id *id)
 {
@@ -427,21 +420,8 @@ static int eqr_probe(struct auxiliary_device *adev,
 	int ret;
 
 	/*
-	 * We are an auxiliary device of clk-eyeq. We do not have an OF node by
-	 * default; let's reuse our parent's OF node.
-	 */
-	WARN_ON(dev->of_node);
-	device_set_of_node_from_dev(dev, dev->parent);
-	if (!dev->of_node)
-		return -ENODEV;
-
-	ret = devm_add_action_or_reset(dev, eqr_of_node_put, dev);
-	if (ret)
-		return ret;
-
-	/*
-	 * Using our newfound OF node, we can get match data. We cannot use
-	 * device_get_match_data() because it does not match reused OF nodes.
+	 * Get match data. We cannot use device_get_match_data() because it does
+	 * not accept reused OF nodes; see device_set_of_node_from_dev().
 	 */
 	match = of_match_node(dev->driver->of_match_table, dev->of_node);
 	if (!match || !match->data)

-- 
2.52.0


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

* [PATCH v6 7/8] MIPS: mobileye: eyeq5: add two Cadence GEM Ethernet controllers
  2026-01-27 17:09 [PATCH v6 0/8] Add generic PHY driver used by MACB/GEM on EyeQ5 Théo Lebrun
                   ` (5 preceding siblings ...)
  2026-01-27 17:09 ` [PATCH v6 6/8] reset: eyeq: drop device_set_of_node_from_dev() done by parent Théo Lebrun
@ 2026-01-27 17:09 ` Théo Lebrun
  2026-01-27 17:09 ` [PATCH v6 8/8] MIPS: mobileye: eyeq5-epm: add two Cadence GEM Ethernet PHYs Théo Lebrun
  2026-02-04  9:35 ` [PATCH v6 0/8] Add generic PHY driver used by MACB/GEM on EyeQ5 Théo Lebrun
  8 siblings, 0 replies; 20+ messages in thread
From: Théo Lebrun @ 2026-01-27 17:09 UTC (permalink / raw)
  To: Vladimir Kondratiev, Grégory Clement, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
	Kishon Vijay Abraham I, Michael Turquette, Stephen Boyd,
	Philipp Zabel, Thomas Bogendoerfer, Neil Armstrong
  Cc: linux-mips, devicetree, linux-kernel, linux-phy, linux-clk,
	Benoît Monin, Tawfik Bayouk, Thomas Petazzoni, Luca Ceresoli,
	Théo Lebrun

Add both MACB/GEM instances found in the Mobileye EyeQ5 SoC.

Acked-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
---
 arch/mips/boot/dts/mobileye/eyeq5.dtsi | 45 ++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/arch/mips/boot/dts/mobileye/eyeq5.dtsi b/arch/mips/boot/dts/mobileye/eyeq5.dtsi
index 36a73e8a63a1..cec5ad875228 100644
--- a/arch/mips/boot/dts/mobileye/eyeq5.dtsi
+++ b/arch/mips/boot/dts/mobileye/eyeq5.dtsi
@@ -77,6 +77,8 @@ aliases {
 		serial0 = &uart0;
 		serial1 = &uart1;
 		serial2 = &uart2;
+		ethernet0 = &macb0;
+		ethernet1 = &macb1;
 	};
 
 	cpu_intc: interrupt-controller {
@@ -231,6 +233,7 @@ olb: system-controller@e00000 {
 			#clock-cells = <1>;
 			clocks = <&xtal>;
 			clock-names = "ref";
+			#phy-cells = <1>;
 		};
 
 		gic: interrupt-controller@140000 {
@@ -305,6 +308,48 @@ gpio1: gpio@1500000 {
 			#interrupt-cells = <2>;
 			resets = <&olb 0 26>;
 		};
+
+		iocu-bus {
+			compatible = "simple-bus";
+			#address-cells = <2>;
+			#size-cells = <2>;
+			ranges;
+			dma-coherent;
+			dma-ranges = <0x10 0x00000000 0x0 0x0 0x10 0>;
+
+			macb0: ethernet@2a00000 {
+				compatible = "mobileye,eyeq5-gem";
+				reg = <0x0 0x02a00000 0x0 0x4000>;
+				interrupt-parent = <&gic>;
+				/* One interrupt per queue */
+				interrupts = <GIC_SHARED 23 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SHARED 23 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SHARED 23 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SHARED 23 IRQ_TYPE_LEVEL_HIGH>;
+				clock-names = "pclk", "hclk", "tsu_clk";
+				clocks = <&pclk>, <&pclk>, <&tsu_clk>;
+				nvmem-cells = <&eth0_mac>;
+				nvmem-cell-names = "mac-address";
+				phys = <&olb 0>;
+			};
+
+			macb1: ethernet@2b00000 {
+				compatible = "mobileye,eyeq5-gem";
+				reg = <0x0 0x02b00000 0x0 0x4000>;
+				interrupt-parent = <&gic>;
+				/* One interrupt per queue */
+				interrupts = <GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH>,
+					     <GIC_SHARED 24 IRQ_TYPE_LEVEL_HIGH>;
+				clock-names = "pclk", "hclk", "tsu_clk";
+				clocks = <&pclk>, <&pclk>, <&tsu_clk>;
+				nvmem-cells = <&eth1_mac>;
+				nvmem-cell-names = "mac-address";
+				phys = <&olb 1>;
+			};
+		};
+
 	};
 };
 

-- 
2.52.0


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

* [PATCH v6 8/8] MIPS: mobileye: eyeq5-epm: add two Cadence GEM Ethernet PHYs
  2026-01-27 17:09 [PATCH v6 0/8] Add generic PHY driver used by MACB/GEM on EyeQ5 Théo Lebrun
                   ` (6 preceding siblings ...)
  2026-01-27 17:09 ` [PATCH v6 7/8] MIPS: mobileye: eyeq5: add two Cadence GEM Ethernet controllers Théo Lebrun
@ 2026-01-27 17:09 ` Théo Lebrun
  2026-02-04  9:35 ` [PATCH v6 0/8] Add generic PHY driver used by MACB/GEM on EyeQ5 Théo Lebrun
  8 siblings, 0 replies; 20+ messages in thread
From: Théo Lebrun @ 2026-01-27 17:09 UTC (permalink / raw)
  To: Vladimir Kondratiev, Grégory Clement, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
	Kishon Vijay Abraham I, Michael Turquette, Stephen Boyd,
	Philipp Zabel, Thomas Bogendoerfer, Neil Armstrong
  Cc: linux-mips, devicetree, linux-kernel, linux-phy, linux-clk,
	Benoît Monin, Tawfik Bayouk, Thomas Petazzoni, Luca Ceresoli,
	Théo Lebrun, Andrew Lunn

The Mobileye EyeQ5 eval board (EPM) embeds two MDIO PHYs.

Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Acked-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
---
 arch/mips/boot/dts/mobileye/eyeq5-epm5.dts | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/mips/boot/dts/mobileye/eyeq5-epm5.dts b/arch/mips/boot/dts/mobileye/eyeq5-epm5.dts
index 9fc1a1b0a81b..babf52731ea6 100644
--- a/arch/mips/boot/dts/mobileye/eyeq5-epm5.dts
+++ b/arch/mips/boot/dts/mobileye/eyeq5-epm5.dts
@@ -29,3 +29,29 @@ temperature-sensor@48 {
 		label = "U60";
 	};
 };
+
+&macb0 {
+	phy-mode = "sgmii";
+	phy-handle = <&macb0_phy>;
+
+	mdio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		macb0_phy: ethernet-phy@e {
+			reg = <0xe>;
+		};
+	};
+};
+
+&macb1 {
+	phy-mode = "rgmii-id";
+	phy-handle = <&macb1_phy>;
+
+	mdio {
+		#address-cells = <1>;
+		#size-cells = <0>;
+		macb1_phy: ethernet-phy@e {
+			reg = <0xe>;
+		};
+	};
+};

-- 
2.52.0


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

* Re: [PATCH v6 0/8] Add generic PHY driver used by MACB/GEM on EyeQ5
  2026-01-27 17:09 [PATCH v6 0/8] Add generic PHY driver used by MACB/GEM on EyeQ5 Théo Lebrun
                   ` (7 preceding siblings ...)
  2026-01-27 17:09 ` [PATCH v6 8/8] MIPS: mobileye: eyeq5-epm: add two Cadence GEM Ethernet PHYs Théo Lebrun
@ 2026-02-04  9:35 ` Théo Lebrun
  8 siblings, 0 replies; 20+ messages in thread
From: Théo Lebrun @ 2026-02-04  9:35 UTC (permalink / raw)
  To: Théo Lebrun, Vladimir Kondratiev, Grégory Clement,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
	Kishon Vijay Abraham I, Michael Turquette, Stephen Boyd,
	Philipp Zabel, Thomas Bogendoerfer, Neil Armstrong
  Cc: linux-mips, devicetree, linux-kernel, linux-phy, linux-clk,
	Benoît Monin, Tawfik Bayouk, Thomas Petazzoni, Luca Ceresoli,
	Conor Dooley, Jerome Brunet, Andrew Lunn

On Tue Jan 27, 2026 at 6:09 PM CET, Théo Lebrun wrote:
> EyeQ5 SoCs integrate two GEM instances. A system-controller register
> region named "OLB" has some control over the Ethernet PHY integration.

Is the plan to take this for the v6.20 merge window or await v7.0?
The driver has seldom changed since its first revision 3 months ago.

Thanks!
Have a nice day,

--
Théo Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


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

* Re: [PATCH v6 2/8] phy: sort Kconfig and Makefile
  2026-01-27 17:09 ` [PATCH v6 2/8] phy: sort Kconfig and Makefile Théo Lebrun
@ 2026-02-06  8:39   ` Luca Ceresoli
  2026-02-10 19:37   ` Vladimir Oltean
  1 sibling, 0 replies; 20+ messages in thread
From: Luca Ceresoli @ 2026-02-06  8:39 UTC (permalink / raw)
  To: Théo Lebrun, Vladimir Kondratiev, Grégory Clement,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
	Kishon Vijay Abraham I, Michael Turquette, Stephen Boyd,
	Philipp Zabel, Thomas Bogendoerfer, Neil Armstrong
  Cc: linux-mips, devicetree, linux-kernel, linux-phy, linux-clk,
	Benoît Monin, Tawfik Bayouk, Thomas Petazzoni

On Tue Jan 27, 2026 at 6:09 PM CET, Théo Lebrun wrote:
> Neither Kconfig nor Makefile are sorted; reorder them.
>
> $ diff -U100 <(grep ^config drivers/phy/Kconfig) \
>              <(grep ^config drivers/phy/Kconfig | sort)
>
> $ diff -U100 <(grep ^obj-\\$ drivers/phy/Makefile) \
>              <(grep ^obj-\\$ drivers/phy/Makefile | sort)
>
> Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>

Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>

--
Luca Ceresoli, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

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

* Re: [PATCH v6 3/8] phy: Add driver for EyeQ5 Ethernet PHY wrapper
  2026-01-27 17:09 ` [PATCH v6 3/8] phy: Add driver for EyeQ5 Ethernet PHY wrapper Théo Lebrun
@ 2026-02-10 19:35   ` Vladimir Oltean
  2026-02-24 17:20     ` Théo Lebrun
  2026-02-25 15:00   ` Vinod Koul
  1 sibling, 1 reply; 20+ messages in thread
From: Vladimir Oltean @ 2026-02-10 19:35 UTC (permalink / raw)
  To: Théo Lebrun
  Cc: Vladimir Kondratiev, Grégory Clement, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
	Kishon Vijay Abraham I, Michael Turquette, Stephen Boyd,
	Philipp Zabel, Thomas Bogendoerfer, Neil Armstrong, linux-mips,
	devicetree, linux-kernel, linux-phy, linux-clk, Benoît Monin,
	Tawfik Bayouk, Thomas Petazzoni, Luca Ceresoli

Hi Theo,

On Tue, Jan 27, 2026 at 06:09:31PM +0100, Théo Lebrun wrote:
> +static int eq5_phy_init(struct phy *phy)
> +{
> +	struct eq5_phy_inst *inst = phy_get_drvdata(phy);
> +	struct eq5_phy_private *priv = inst->priv;
> +	struct device *dev = priv->dev;
> +	u32 reg;
> +
> +	dev_dbg(dev, "phy_init(inst=%td)\n", inst - priv->phys);

Nitpick: can you please remove the debugging prints and maybe add some
trace points to the PHY core if you feel strongly about having some
introspection?

> +
> +	writel(0, inst->gp);
> +	writel(0, inst->sgmii);
> +
> +	udelay(5);

Could you please add a macro or comment hinting at the origin of the
magic number 5 here? You could also place these 3 lines in a common
helper, also called from eq5_phy_exit(), to avoid minor code
duplication.

> +
> +	reg = readl(inst->gp) | EQ5_GP_TX_SWRST_DIS | EQ5_GP_TX_M_CLKE |

When you write 0 to inst->gp and then read it back, do you expect to
(a) get back 0 or
(b) are some fields non-resetting?

I see both as inconsistent, since if (a), you can remove the
readl(inst->gp) and expect the same result. And if (b), it also
shouldn't matter if you write zeroes a second time, if it was fine the
first time?

Shortly said, is readl(inst->gp) really needed?

> +	      EQ5_GP_SYS_SWRST_DIS | EQ5_GP_SYS_M_CLKE |
> +	      FIELD_PREP(EQ5_GP_RGMII_DRV, 0x9);

Quick sanity check on your proposal to use #phy-cells = <1>. This is not
a request to change anything.

What if you need to customize the RGMII drive strength (or some other
setting, maybe SGMII polarity if that is available) per lane, for a
particular board? How would you do that if each PHY does not have its
own OF node?

> +	writel(reg, inst->gp);
> +
> +	return 0;
> +}
> +
> +static int eq5_phy_exit(struct phy *phy)
> +{
> +	struct eq5_phy_inst *inst = phy_get_drvdata(phy);
> +	struct eq5_phy_private *priv = inst->priv;
> +	struct device *dev = priv->dev;
> +
> +	dev_dbg(dev, "phy_exit(inst=%td)\n", inst - priv->phys);
> +
> +	writel(0, inst->gp);
> +	writel(0, inst->sgmii);
> +	udelay(5);
> +
> +	return 0;
> +}
> +
> +static int eq5_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
> +{
> +	struct eq5_phy_inst *inst = phy_get_drvdata(phy);
> +	struct eq5_phy_private *priv = inst->priv;
> +	struct device *dev = priv->dev;
> +
> +	dev_dbg(dev, "phy_set_mode(inst=%td, mode=%d, submode=%d)\n",
> +		inst - priv->phys, mode, submode);
> +
> +	if (mode != PHY_MODE_ETHERNET)
> +		return -EOPNOTSUPP;
> +
> +	if (!phy_interface_mode_is_rgmii(submode) &&
> +	    submode != PHY_INTERFACE_MODE_SGMII)
> +		return -EOPNOTSUPP;

Both PHYs are equal in capabilities, and support both RGMII and SGMII,
correct? I see the driver is implemented as if they were, but it doesn't
hurt to ask.

> +
> +	inst->phy_interface = submode;

Short story: don't rely on the phy_set_mode_ext() -> phy_power_on() order.
Implement the driver so that it works the other way around too.

Long story:
https://lore.kernel.org/netdev/aXzFH09AeIRawCwU@shell.armlinux.org.uk/

> +	return 0;
> +}

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

* Re: [PATCH v6 2/8] phy: sort Kconfig and Makefile
  2026-01-27 17:09 ` [PATCH v6 2/8] phy: sort Kconfig and Makefile Théo Lebrun
  2026-02-06  8:39   ` Luca Ceresoli
@ 2026-02-10 19:37   ` Vladimir Oltean
  1 sibling, 0 replies; 20+ messages in thread
From: Vladimir Oltean @ 2026-02-10 19:37 UTC (permalink / raw)
  To: Théo Lebrun
  Cc: Grégory Clement, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Vinod Koul, Kishon Vijay Abraham I,
	Michael Turquette, Stephen Boyd, Philipp Zabel,
	Thomas Bogendoerfer, Neil Armstrong, linux-mips, devicetree,
	linux-kernel, linux-phy, linux-clk, Benoît Monin,
	Tawfik Bayouk, Thomas Petazzoni, Luca Ceresoli

Hi Theo,

On Tue, Jan 27, 2026 at 06:09:30PM +0100, Théo Lebrun wrote:
> Neither Kconfig nor Makefile are sorted; reorder them.
> 
> $ diff -U100 <(grep ^config drivers/phy/Kconfig) \
>              <(grep ^config drivers/phy/Kconfig | sort)
> 
> $ diff -U100 <(grep ^obj-\\$ drivers/phy/Makefile) \
>              <(grep ^obj-\\$ drivers/phy/Makefile | sort)
> 
> Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
> ---

This patch is appreciated, however it no longer applies on top of
current linux-phy/next.

Since we are in the merge window currently, would you mind reposting in
2 weeks (or as RFC in the meantime)?

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

* Re: [PATCH v6 3/8] phy: Add driver for EyeQ5 Ethernet PHY wrapper
  2026-02-10 19:35   ` Vladimir Oltean
@ 2026-02-24 17:20     ` Théo Lebrun
  2026-02-25 12:29       ` Vladimir Oltean
  2026-02-25 13:56       ` Théo Lebrun
  0 siblings, 2 replies; 20+ messages in thread
From: Théo Lebrun @ 2026-02-24 17:20 UTC (permalink / raw)
  To: Vladimir Oltean, Théo Lebrun
  Cc: Vladimir Kondratiev, Grégory Clement, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
	Kishon Vijay Abraham I, Michael Turquette, Stephen Boyd,
	Philipp Zabel, Thomas Bogendoerfer, Neil Armstrong, linux-mips,
	devicetree, linux-kernel, linux-phy, linux-clk, Benoît Monin,
	Tawfik Bayouk, Thomas Petazzoni, Luca Ceresoli

Hello Vladimir,

On Tue Feb 10, 2026 at 8:35 PM CET, Vladimir Oltean wrote:
> On Tue, Jan 27, 2026 at 06:09:31PM +0100, Théo Lebrun wrote:
>> +static int eq5_phy_init(struct phy *phy)
>> +{
>> +	struct eq5_phy_inst *inst = phy_get_drvdata(phy);
>> +	struct eq5_phy_private *priv = inst->priv;
>> +	struct device *dev = priv->dev;
>> +	u32 reg;
>> +
>> +	dev_dbg(dev, "phy_init(inst=%td)\n", inst - priv->phys);
>
> Nitpick: can you please remove the debugging prints and maybe add some
> trace points to the PHY core if you feel strongly about having some
> introspection?

Ack!

>> +
>> +	writel(0, inst->gp);
>> +	writel(0, inst->sgmii);
>> +
>> +	udelay(5);
>
> Could you please add a macro or comment hinting at the origin of the
> magic number 5 here? You could also place these 3 lines in a common
> helper, also called from eq5_phy_exit(), to avoid minor code
> duplication.

ACK, something named `eq5_phy_reinit()`.

I don't have precise explanation for the 5µs value; I only know it is
time to let the PHY settle before further register config writes.
Is this enough?

   udelay(5); /* settling time */

>> +
>> +	reg = readl(inst->gp) | EQ5_GP_TX_SWRST_DIS | EQ5_GP_TX_M_CLKE |
>
> When you write 0 to inst->gp and then read it back, do you expect to
> (a) get back 0 or
> (b) are some fields non-resetting?
>
> I see both as inconsistent, since if (a), you can remove the
> readl(inst->gp) and expect the same result. And if (b), it also
> shouldn't matter if you write zeroes a second time, if it was fine the
> first time?
>
> Shortly said, is readl(inst->gp) really needed?

Some fields are non-resetting (BIT 30).
Will drop. I was trying to play it safe for no good reason.

>
>> +	      EQ5_GP_SYS_SWRST_DIS | EQ5_GP_SYS_M_CLKE |
>> +	      FIELD_PREP(EQ5_GP_RGMII_DRV, 0x9);
>
> Quick sanity check on your proposal to use #phy-cells = <1>. This is not
> a request to change anything.
>
> What if you need to customize the RGMII drive strength (or some other
> setting, maybe SGMII polarity if that is available) per lane, for a
> particular board? How would you do that if each PHY does not have its
> own OF node?

I have no knowledge of what that 0x9 stands for, I didn't see the point
exposing it to devicetree. We could plan for the future and add a cell
or create subnodes, but here I kept it simple stupid. Is it OK?

>> +	writel(reg, inst->gp);
>> +
>> +	return 0;
>> +}
>> +
>> +static int eq5_phy_exit(struct phy *phy)
>> +{
>> +	struct eq5_phy_inst *inst = phy_get_drvdata(phy);
>> +	struct eq5_phy_private *priv = inst->priv;
>> +	struct device *dev = priv->dev;
>> +
>> +	dev_dbg(dev, "phy_exit(inst=%td)\n", inst - priv->phys);
>> +
>> +	writel(0, inst->gp);
>> +	writel(0, inst->sgmii);
>> +	udelay(5);
>> +
>> +	return 0;
>> +}
>> +
>> +static int eq5_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
>> +{
>> +	struct eq5_phy_inst *inst = phy_get_drvdata(phy);
>> +	struct eq5_phy_private *priv = inst->priv;
>> +	struct device *dev = priv->dev;
>> +
>> +	dev_dbg(dev, "phy_set_mode(inst=%td, mode=%d, submode=%d)\n",
>> +		inst - priv->phys, mode, submode);
>> +
>> +	if (mode != PHY_MODE_ETHERNET)
>> +		return -EOPNOTSUPP;
>> +
>> +	if (!phy_interface_mode_is_rgmii(submode) &&
>> +	    submode != PHY_INTERFACE_MODE_SGMII)
>> +		return -EOPNOTSUPP;
>
> Both PHYs are equal in capabilities, and support both RGMII and SGMII,
> correct? I see the driver is implemented as if they were, but it doesn't
> hurt to ask.

Datasheet indicates 0 can do SGMII/RGMII and 1 can do only RGMII.
Did you imply that the driver code should reject SGMII on PHY 1
if it ever gets asked for?

>> +
>> +	inst->phy_interface = submode;
>
> Short story: don't rely on the phy_set_mode_ext() -> phy_power_on() order.
> Implement the driver so that it works the other way around too.
>
> Long story:
> https://lore.kernel.org/netdev/aXzFH09AeIRawCwU@shell.armlinux.org.uk/

I wouldn't mind, but what should phy_power_on() do if no submode has
been provided through phy_set_mode_ext() yet? Guess one? Fail?

Also our PHY will need to be reset to change its mode if we do
power_on() followed by set_mode(), which in practice is never something
we want. Maybe there is a flag to indicate that we require a submode to
power on?

Thanks for the extensive review Vladimir,

--
Théo Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


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

* Re: [PATCH v6 3/8] phy: Add driver for EyeQ5 Ethernet PHY wrapper
  2026-02-24 17:20     ` Théo Lebrun
@ 2026-02-25 12:29       ` Vladimir Oltean
  2026-02-25 14:54         ` Théo Lebrun
  2026-02-25 13:56       ` Théo Lebrun
  1 sibling, 1 reply; 20+ messages in thread
From: Vladimir Oltean @ 2026-02-25 12:29 UTC (permalink / raw)
  To: Théo Lebrun
  Cc: Vladimir Kondratiev, Grégory Clement, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
	Kishon Vijay Abraham I, Michael Turquette, Stephen Boyd,
	Philipp Zabel, Thomas Bogendoerfer, Neil Armstrong, linux-mips,
	devicetree, linux-kernel, linux-phy, linux-clk, Benoît Monin,
	Tawfik Bayouk, Thomas Petazzoni, Luca Ceresoli

On Tue, Feb 24, 2026 at 06:20:21PM +0100, Théo Lebrun wrote:
> > Could you please add a macro or comment hinting at the origin of the
> > magic number 5 here? You could also place these 3 lines in a common
> > helper, also called from eq5_phy_exit(), to avoid minor code
> > duplication.
> 
> ACK, something named `eq5_phy_reinit()`.
> 
> I don't have precise explanation for the 5µs value; I only know it is
> time to let the PHY settle before further register config writes.
> Is this enough?
> 
>    udelay(5); /* settling time */

If there's a single occurrence and there's a comment, it's fine.

> >> +	      EQ5_GP_SYS_SWRST_DIS | EQ5_GP_SYS_M_CLKE |
> >> +	      FIELD_PREP(EQ5_GP_RGMII_DRV, 0x9);
> >
> > Quick sanity check on your proposal to use #phy-cells = <1>. This is not
> > a request to change anything.
> >
> > What if you need to customize the RGMII drive strength (or some other
> > setting, maybe SGMII polarity if that is available) per lane, for a
> > particular board? How would you do that if each PHY does not have its
> > own OF node?
> 
> I have no knowledge of what that 0x9 stands for, I didn't see the point
> exposing it to devicetree. We could plan for the future and add a cell
> or create subnodes, but here I kept it simple stupid. Is it OK?

If you don't know that you need to customize anything, it's fine the way
it is.

> >> +	writel(reg, inst->gp);
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +static int eq5_phy_exit(struct phy *phy)
> >> +{
> >> +	struct eq5_phy_inst *inst = phy_get_drvdata(phy);
> >> +	struct eq5_phy_private *priv = inst->priv;
> >> +	struct device *dev = priv->dev;
> >> +
> >> +	dev_dbg(dev, "phy_exit(inst=%td)\n", inst - priv->phys);
> >> +
> >> +	writel(0, inst->gp);
> >> +	writel(0, inst->sgmii);
> >> +	udelay(5);
> >> +
> >> +	return 0;
> >> +}
> >> +
> >> +static int eq5_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
> >> +{
> >> +	struct eq5_phy_inst *inst = phy_get_drvdata(phy);
> >> +	struct eq5_phy_private *priv = inst->priv;
> >> +	struct device *dev = priv->dev;
> >> +
> >> +	dev_dbg(dev, "phy_set_mode(inst=%td, mode=%d, submode=%d)\n",
> >> +		inst - priv->phys, mode, submode);
> >> +
> >> +	if (mode != PHY_MODE_ETHERNET)
> >> +		return -EOPNOTSUPP;
> >> +
> >> +	if (!phy_interface_mode_is_rgmii(submode) &&
> >> +	    submode != PHY_INTERFACE_MODE_SGMII)
> >> +		return -EOPNOTSUPP;
> >
> > Both PHYs are equal in capabilities, and support both RGMII and SGMII,
> > correct? I see the driver is implemented as if they were, but it doesn't
> > hurt to ask.
> 
> Datasheet indicates 0 can do SGMII/RGMII and 1 can do only RGMII.
> Did you imply that the driver code should reject SGMII on PHY 1
> if it ever gets asked for?

I didn't imply anything, as I didn't know the facts. But now that I do,
yes, I'm explicitly requesting you to reject the submodes that PHY 1
doesn't support.

I also notice that you haven't implemented support for phy_validate().
Please do so, even if your PHY consumer does not call it (it should, to
detect which modes and submodes are supported).

> >> +
> >> +	inst->phy_interface = submode;
> >
> > Short story: don't rely on the phy_set_mode_ext() -> phy_power_on() order.
> > Implement the driver so that it works the other way around too.
> >
> > Long story:
> > https://lore.kernel.org/netdev/aXzFH09AeIRawCwU@shell.armlinux.org.uk/
> 
> I wouldn't mind, but what should phy_power_on() do if no submode has
> been provided through phy_set_mode_ext() yet? Guess one? Fail?

Assume a default initial submode, and power on using the rules of that
submode. In your case you don't even have to assume, you can read
EQ5_GP_SGMII_MODE to figure out what the submode is at probe time.

> Also our PHY will need to be reset to change its mode if we do
> power_on() followed by set_mode(), which in practice is never something
> we want. Maybe there is a flag to indicate that we require a submode to
> power on?

Such flag doesn't exist, nor do I think it is desirable. It would
unnecessarily complicate consumer drivers, which would have to support
two code paths if they were to follow the "generic" PHY API model.

Feel free to reset the PHY if requested to change the submode while it
is powered on. For example, lynx_28g_set_mode() does that.

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

* Re: [PATCH v6 3/8] phy: Add driver for EyeQ5 Ethernet PHY wrapper
  2026-02-24 17:20     ` Théo Lebrun
  2026-02-25 12:29       ` Vladimir Oltean
@ 2026-02-25 13:56       ` Théo Lebrun
  1 sibling, 0 replies; 20+ messages in thread
From: Théo Lebrun @ 2026-02-25 13:56 UTC (permalink / raw)
  To: Théo Lebrun, Vladimir Oltean
  Cc: Vladimir Kondratiev, Grégory Clement, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
	Kishon Vijay Abraham I, Michael Turquette, Stephen Boyd,
	Philipp Zabel, Thomas Bogendoerfer, Neil Armstrong, linux-mips,
	devicetree, linux-kernel, linux-phy, linux-clk, Benoît Monin,
	Tawfik Bayouk, Thomas Petazzoni, Luca Ceresoli

Hello Théo,

On Tue Feb 24, 2026 at 6:20 PM CET, Théo Lebrun wrote:
> Hello Vladimir,
>
> On Tue Feb 10, 2026 at 8:35 PM CET, Vladimir Oltean wrote:
>> On Tue, Jan 27, 2026 at 06:09:31PM +0100, Théo Lebrun wrote:
>>> +static int eq5_phy_init(struct phy *phy)
>>> +{
>>> +	struct eq5_phy_inst *inst = phy_get_drvdata(phy);
>>> +	struct eq5_phy_private *priv = inst->priv;
>>> +	struct device *dev = priv->dev;
>>> +	u32 reg;
>>> +
>>> +	dev_dbg(dev, "phy_init(inst=%td)\n", inst - priv->phys);
>>
>> Nitpick: can you please remove the debugging prints and maybe add some
>> trace points to the PHY core if you feel strongly about having some
>> introspection?
>
> Ack!
>
>>> +
>>> +	writel(0, inst->gp);
>>> +	writel(0, inst->sgmii);
>>> +
>>> +	udelay(5);
>>
>> Could you please add a macro or comment hinting at the origin of the
>> magic number 5 here? You could also place these 3 lines in a common
>> helper, also called from eq5_phy_exit(), to avoid minor code
>> duplication.
>
> ACK, something named `eq5_phy_reinit()`.
>
> I don't have precise explanation for the 5µs value; I only know it is
> time to let the PHY settle before further register config writes.
> Is this enough?
>
>    udelay(5); /* settling time */
>
>>> +
>>> +	reg = readl(inst->gp) | EQ5_GP_TX_SWRST_DIS | EQ5_GP_TX_M_CLKE |
>>
>> When you write 0 to inst->gp and then read it back, do you expect to
>> (a) get back 0 or
>> (b) are some fields non-resetting?
>>
>> I see both as inconsistent, since if (a), you can remove the
>> readl(inst->gp) and expect the same result. And if (b), it also
>> shouldn't matter if you write zeroes a second time, if it was fine the
>> first time?
>>
>> Shortly said, is readl(inst->gp) really needed?
>
> Some fields are non-resetting (BIT 30).
> Will drop. I was trying to play it safe for no good reason.
>
>>
>>> +	      EQ5_GP_SYS_SWRST_DIS | EQ5_GP_SYS_M_CLKE |
>>> +	      FIELD_PREP(EQ5_GP_RGMII_DRV, 0x9);
>>
>> Quick sanity check on your proposal to use #phy-cells = <1>. This is not
>> a request to change anything.
>>
>> What if you need to customize the RGMII drive strength (or some other
>> setting, maybe SGMII polarity if that is available) per lane, for a
>> particular board? How would you do that if each PHY does not have its
>> own OF node?
>
> I have no knowledge of what that 0x9 stands for, I didn't see the point
> exposing it to devicetree. We could plan for the future and add a cell
> or create subnodes, but here I kept it simple stupid. Is it OK?
>
>>> +	writel(reg, inst->gp);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int eq5_phy_exit(struct phy *phy)
>>> +{
>>> +	struct eq5_phy_inst *inst = phy_get_drvdata(phy);
>>> +	struct eq5_phy_private *priv = inst->priv;
>>> +	struct device *dev = priv->dev;
>>> +
>>> +	dev_dbg(dev, "phy_exit(inst=%td)\n", inst - priv->phys);
>>> +
>>> +	writel(0, inst->gp);
>>> +	writel(0, inst->sgmii);
>>> +	udelay(5);
>>> +
>>> +	return 0;
>>> +}
>>> +
>>> +static int eq5_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
>>> +{
>>> +	struct eq5_phy_inst *inst = phy_get_drvdata(phy);
>>> +	struct eq5_phy_private *priv = inst->priv;
>>> +	struct device *dev = priv->dev;
>>> +
>>> +	dev_dbg(dev, "phy_set_mode(inst=%td, mode=%d, submode=%d)\n",
>>> +		inst - priv->phys, mode, submode);
>>> +
>>> +	if (mode != PHY_MODE_ETHERNET)
>>> +		return -EOPNOTSUPP;
>>> +
>>> +	if (!phy_interface_mode_is_rgmii(submode) &&
>>> +	    submode != PHY_INTERFACE_MODE_SGMII)
>>> +		return -EOPNOTSUPP;
>>
>> Both PHYs are equal in capabilities, and support both RGMII and SGMII,
>> correct? I see the driver is implemented as if they were, but it doesn't
>> hurt to ask.
>
> Datasheet indicates 0 can do SGMII/RGMII and 1 can do only RGMII.
> Did you imply that the driver code should reject SGMII on PHY 1
> if it ever gets asked for?
>
>>> +
>>> +	inst->phy_interface = submode;
>>
>> Short story: don't rely on the phy_set_mode_ext() -> phy_power_on() order.
>> Implement the driver so that it works the other way around too.
>>
>> Long story:
>> https://lore.kernel.org/netdev/aXzFH09AeIRawCwU@shell.armlinux.org.uk/
>
> I wouldn't mind, but what should phy_power_on() do if no submode has
> been provided through phy_set_mode_ext() yet? Guess one? Fail?
>
> Also our PHY will need to be reset to change its mode if we do
> power_on() followed by set_mode(), which in practice is never something
> we want. Maybe there is a flag to indicate that we require a submode to
> power on?

To give something concrete, here is what it could look like.
 - We refuse phy_power_on() if we haven't been given a mode (we probe
   with `inst->phy_interface == PHY_INTERFACE_MODE_NA`).
 - We finish phy_set_mode() by restarting if `phy->power_count`.

I am not convinced. I would prefer to refuse phy_set_mode() with EBUSY
if `phy->power_count == 0`.



static void eq5_phy_reinit(struct phy *phy)
{
	struct eq5_phy_inst *inst = phy_get_drvdata(phy);

	writel(0, inst->gp);
	writel(0, inst->sgmii);
	udelay(5); /* settling time */
}

static int eq5_phy_init(struct phy *phy)
{
	struct eq5_phy_inst *inst = phy_get_drvdata(phy);
	u32 reg;

	eq5_phy_reinit(phy);

	reg = EQ5_GP_TX_SWRST_DIS | EQ5_GP_TX_M_CLKE |
	      EQ5_GP_SYS_SWRST_DIS | EQ5_GP_SYS_M_CLKE |
	      FIELD_PREP(EQ5_GP_RGMII_DRV, 0x9);
	writel(reg, inst->gp);

	return 0;
}

static int eq5_phy_exit(struct phy *phy)
{
	eq5_phy_reinit(phy);
	return 0;
}

static int eq5_phy_power_on(struct phy *phy)
{
	struct eq5_phy_inst *inst = phy_get_drvdata(phy);
	struct eq5_phy_private *priv = inst->priv;
	struct device *dev = priv->dev;
	u32 reg;

	if (inst->phy_interface == PHY_INTERFACE_MODE_NA)
		return -ENOMEDIUM;

	if (inst->phy_interface == PHY_INTERFACE_MODE_SGMII) {
		writel(readl(inst->gp) | EQ5_GP_SGMII_MODE, inst->gp);

		reg = EQ5_SGMII_PWR_EN | EQ5_SGMII_RST_DIS | EQ5_SGMII_PLL_EN;
		writel(reg, inst->sgmii);

		if (readl_poll_timeout(inst->sgmii, reg,
				       reg & EQ5_SGMII_PLL_ACK, 1, 100)) {
			dev_err(dev, "PLL timeout\n");
			return -ETIMEDOUT;
		}

		reg = readl(inst->sgmii);
		reg |= EQ5_SGMII_PWR_STATE | EQ5_SGMII_SIG_DET_SW;
		writel(reg, inst->sgmii);
	} else {
		writel(readl(inst->gp) & ~EQ5_GP_SGMII_MODE, inst->gp);
		writel(0, inst->sgmii);
	}

	return 0;
}

static int eq5_phy_set_mode(struct phy *phy, enum phy_mode mode, int submode)
{
	struct eq5_phy_inst *inst = phy_get_drvdata(phy);

	if (mode != PHY_MODE_ETHERNET)
		return -EOPNOTSUPP;

	if (!phy_interface_mode_is_rgmii(submode) &&
	    submode != PHY_INTERFACE_MODE_SGMII)
		return -EOPNOTSUPP;

	if (submode != inst->phy_interface) {
		inst->phy_interface = submode;

		if (phy->power_count) {
			eq5_phy_reinit(phy);
			return eq5_phy_power_on(phy);
		}
	}

	return 0;
}

static int eq5_phy_power_off(struct phy *phy)
{
	struct eq5_phy_inst *inst = phy_get_drvdata(phy);

	writel(readl(inst->gp) & ~EQ5_GP_SGMII_MODE, inst->gp);
	writel(0, inst->sgmii);

	return 0;
}

Thanks,

--
Théo Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


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

* Re: [PATCH v6 3/8] phy: Add driver for EyeQ5 Ethernet PHY wrapper
  2026-02-25 12:29       ` Vladimir Oltean
@ 2026-02-25 14:54         ` Théo Lebrun
  0 siblings, 0 replies; 20+ messages in thread
From: Théo Lebrun @ 2026-02-25 14:54 UTC (permalink / raw)
  To: Vladimir Oltean, Théo Lebrun
  Cc: Vladimir Kondratiev, Grégory Clement, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Vinod Koul,
	Kishon Vijay Abraham I, Michael Turquette, Stephen Boyd,
	Philipp Zabel, Thomas Bogendoerfer, Neil Armstrong, linux-mips,
	devicetree, linux-kernel, linux-phy, linux-clk, Benoît Monin,
	Tawfik Bayouk, Thomas Petazzoni, Luca Ceresoli

You can ignore my email from an hour ago, I don't often fetch emails.
I have everything needed for a new revision that is coming shortly.

Thanks for all the clarification,

--
Théo Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


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

* Re: [PATCH v6 3/8] phy: Add driver for EyeQ5 Ethernet PHY wrapper
  2026-01-27 17:09 ` [PATCH v6 3/8] phy: Add driver for EyeQ5 Ethernet PHY wrapper Théo Lebrun
  2026-02-10 19:35   ` Vladimir Oltean
@ 2026-02-25 15:00   ` Vinod Koul
  2026-02-25 15:54     ` Théo Lebrun
  1 sibling, 1 reply; 20+ messages in thread
From: Vinod Koul @ 2026-02-25 15:00 UTC (permalink / raw)
  To: Théo Lebrun
  Cc: Vladimir Kondratiev, Grégory Clement, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Kishon Vijay Abraham I,
	Michael Turquette, Stephen Boyd, Philipp Zabel,
	Thomas Bogendoerfer, Neil Armstrong, linux-mips, devicetree,
	linux-kernel, linux-phy, linux-clk, Benoît Monin,
	Tawfik Bayouk, Thomas Petazzoni, Luca Ceresoli

On 27-01-26, 18:09, Théo Lebrun wrote:
> EyeQ5 embeds a system-controller called OLB. It features many unrelated
> registers, and some of those are registers used to configure the
> integration of the RGMII/SGMII Cadence PHY used by MACB/GEM instances.
> 
> Wrap in a neat generic PHY provider, exposing two PHYs with standard
> phy_init() / phy_set_mode() / phy_power_on() operations.

Is there a dependency of this patch with rest of the series. If not
please post different series for subsystems.

> +static int eq5_phy_init(struct phy *phy)
> +{
> +	struct eq5_phy_inst *inst = phy_get_drvdata(phy);
> +	struct eq5_phy_private *priv = inst->priv;
> +	struct device *dev = priv->dev;
> +	u32 reg;
> +
> +	dev_dbg(dev, "phy_init(inst=%td)\n", inst - priv->phys);
> +
> +	writel(0, inst->gp);
> +	writel(0, inst->sgmii);
> +
> +	udelay(5);

This is _same_ as exit. Why not call that routine here and document
why...
-- 
~Vinod

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

* Re: [PATCH v6 3/8] phy: Add driver for EyeQ5 Ethernet PHY wrapper
  2026-02-25 15:00   ` Vinod Koul
@ 2026-02-25 15:54     ` Théo Lebrun
  2026-02-27 14:08       ` Vinod Koul
  0 siblings, 1 reply; 20+ messages in thread
From: Théo Lebrun @ 2026-02-25 15:54 UTC (permalink / raw)
  To: Vinod Koul, Théo Lebrun
  Cc: Vladimir Kondratiev, Grégory Clement, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Kishon Vijay Abraham I,
	Michael Turquette, Stephen Boyd, Philipp Zabel,
	Thomas Bogendoerfer, Neil Armstrong, linux-mips, devicetree,
	linux-kernel, linux-phy, linux-clk, Benoît Monin,
	Tawfik Bayouk, Thomas Petazzoni, Luca Ceresoli

On Wed Feb 25, 2026 at 4:00 PM CET, Vinod Koul wrote:
> On 27-01-26, 18:09, Théo Lebrun wrote:
>> EyeQ5 embeds a system-controller called OLB. It features many unrelated
>> registers, and some of those are registers used to configure the
>> integration of the RGMII/SGMII Cadence PHY used by MACB/GEM instances.
>> 
>> Wrap in a neat generic PHY provider, exposing two PHYs with standard
>> phy_init() / phy_set_mode() / phy_power_on() operations.
>
> Is there a dependency of this patch with rest of the series. If not
> please post different series for subsystems.

ACK. It felt sensible to keep patches close together to understand their
reasoning.
 - clk patches are there because they imply we get a dev->of_node.
   Without them we don't and therefore the driver is useless.
 - DTS/MIPS patches are there because they exploit this new driver.
   They show the first users of this driver.

Will split for next revision.

>> +static int eq5_phy_init(struct phy *phy)
>> +{
>> +	struct eq5_phy_inst *inst = phy_get_drvdata(phy);
>> +	struct eq5_phy_private *priv = inst->priv;
>> +	struct device *dev = priv->dev;
>> +	u32 reg;
>> +
>> +	dev_dbg(dev, "phy_init(inst=%td)\n", inst - priv->phys);
>> +
>> +	writel(0, inst->gp);
>> +	writel(0, inst->sgmii);
>> +
>> +	udelay(5);
>
> This is _same_ as exit. Why not call that routine here and document
> why...

ACK!

Thanks,

--
Théo Lebrun, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com


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

* Re: [PATCH v6 3/8] phy: Add driver for EyeQ5 Ethernet PHY wrapper
  2026-02-25 15:54     ` Théo Lebrun
@ 2026-02-27 14:08       ` Vinod Koul
  0 siblings, 0 replies; 20+ messages in thread
From: Vinod Koul @ 2026-02-27 14:08 UTC (permalink / raw)
  To: Théo Lebrun
  Cc: Vladimir Kondratiev, Grégory Clement, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Kishon Vijay Abraham I,
	Michael Turquette, Stephen Boyd, Philipp Zabel,
	Thomas Bogendoerfer, Neil Armstrong, linux-mips, devicetree,
	linux-kernel, linux-phy, linux-clk, Benoît Monin,
	Tawfik Bayouk, Thomas Petazzoni, Luca Ceresoli

On 25-02-26, 16:54, Théo Lebrun wrote:
> On Wed Feb 25, 2026 at 4:00 PM CET, Vinod Koul wrote:
> > On 27-01-26, 18:09, Théo Lebrun wrote:
> >> EyeQ5 embeds a system-controller called OLB. It features many unrelated
> >> registers, and some of those are registers used to configure the
> >> integration of the RGMII/SGMII Cadence PHY used by MACB/GEM instances.
> >> 
> >> Wrap in a neat generic PHY provider, exposing two PHYs with standard
> >> phy_init() / phy_set_mode() / phy_power_on() operations.
> >
> > Is there a dependency of this patch with rest of the series. If not
> > please post different series for subsystems.
> 
> ACK. It felt sensible to keep patches close together to understand their
> reasoning.
>  - clk patches are there because they imply we get a dev->of_node.
>    Without them we don't and therefore the driver is useless.
>  - DTS/MIPS patches are there because they exploit this new driver.
>    They show the first users of this driver.

You can add that in cover letter for people interested to read. It is
easy for me to pick a series rather than find which patches to review
and apply

> 
> Will split for next revision.

Thanks

-- 
~Vinod

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

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

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-27 17:09 [PATCH v6 0/8] Add generic PHY driver used by MACB/GEM on EyeQ5 Théo Lebrun
2026-01-27 17:09 ` [PATCH v6 1/8] dt-bindings: soc: mobileye: OLB is an Ethernet PHY provider " Théo Lebrun
2026-01-27 17:09 ` [PATCH v6 2/8] phy: sort Kconfig and Makefile Théo Lebrun
2026-02-06  8:39   ` Luca Ceresoli
2026-02-10 19:37   ` Vladimir Oltean
2026-01-27 17:09 ` [PATCH v6 3/8] phy: Add driver for EyeQ5 Ethernet PHY wrapper Théo Lebrun
2026-02-10 19:35   ` Vladimir Oltean
2026-02-24 17:20     ` Théo Lebrun
2026-02-25 12:29       ` Vladimir Oltean
2026-02-25 14:54         ` Théo Lebrun
2026-02-25 13:56       ` Théo Lebrun
2026-02-25 15:00   ` Vinod Koul
2026-02-25 15:54     ` Théo Lebrun
2026-02-27 14:08       ` Vinod Koul
2026-01-27 17:09 ` [PATCH v6 4/8] clk: eyeq: use the auxiliary device creation helper Théo Lebrun
2026-01-27 17:09 ` [PATCH v6 5/8] clk: eyeq: add EyeQ5 children auxiliary device for generic PHYs Théo Lebrun
2026-01-27 17:09 ` [PATCH v6 6/8] reset: eyeq: drop device_set_of_node_from_dev() done by parent Théo Lebrun
2026-01-27 17:09 ` [PATCH v6 7/8] MIPS: mobileye: eyeq5: add two Cadence GEM Ethernet controllers Théo Lebrun
2026-01-27 17:09 ` [PATCH v6 8/8] MIPS: mobileye: eyeq5-epm: add two Cadence GEM Ethernet PHYs Théo Lebrun
2026-02-04  9:35 ` [PATCH v6 0/8] Add generic PHY driver used by MACB/GEM on EyeQ5 Théo Lebrun

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