All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/8] Add support for 10G Ethernet SerDes on MT7988
@ 2023-11-09 21:50 ` Daniel Golle
  0 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 21:50 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Daniel Golle, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

This series aims to add support for GMAC2 and GMAC3 of the MediaTek MT7988 SoC.
While the vendor SDK stuffs all this into their Ethernet driver, I've tried to
seperate things into a PHY driver, a PCS driver as well as changes to the
existing Ethernet and LynxI PCS driver.

                  +----------------+
+--------------+  |  USXGMII PCS   |   +------------------+
| Ethernet MAC +--+-------------+  +---+ PEXTP SerDes PHY |
+--------------+  |  SGMII PCS  |  |   +------------------+
                  +-------------+--+

Alltogether this allows using GMAC2 and GMAC3 with all possible interface modes,
including in-band-status if needed.

Daniel Golle (8):
  dt-bindings: phy: mediatek,xfi-pextp: add new bindings
  phy: add driver for MediaTek pextp 10GE SerDes PHY
  net: pcs: pcs-mtk-lynxi: use 2500Base-X without AN
  net: pcs: pcs-mtk-lynxi: allow calling with NULL advertising
  dt-bindings: net: pcs: add bindings for MediaTek USXGMII PCS
  net: pcs: add driver for MediaTek USXGMII PCS
  dt-bindings: net: mediatek,net: fix and complete mt7988-eth binding
  net: ethernet: mtk_eth_soc: add paths and SerDes modes for MT7988

 .../devicetree/bindings/net/mediatek,net.yaml | 171 ++++-
 .../bindings/net/pcs/mediatek,usxgmii.yaml    | 105 +++
 .../bindings/phy/mediatek,xfi-pextp.yaml      |  71 ++
 MAINTAINERS                                   |   3 +
 drivers/net/ethernet/mediatek/Kconfig         |  17 +
 drivers/net/ethernet/mediatek/mtk_eth_path.c  | 122 +++-
 drivers/net/ethernet/mediatek/mtk_eth_soc.c   | 178 ++++-
 drivers/net/ethernet/mediatek/mtk_eth_soc.h   | 105 ++-
 drivers/net/pcs/Kconfig                       |  10 +
 drivers/net/pcs/Makefile                      |   1 +
 drivers/net/pcs/pcs-mtk-lynxi.c               |  38 +-
 drivers/net/pcs/pcs-mtk-usxgmii.c             | 688 ++++++++++++++++++
 drivers/phy/mediatek/Kconfig                  |  11 +
 drivers/phy/mediatek/Makefile                 |   1 +
 drivers/phy/mediatek/phy-mtk-pextp.c          | 355 +++++++++
 include/linux/pcs/pcs-mtk-usxgmii.h           |  18 +
 16 files changed, 1813 insertions(+), 81 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
 create mode 100644 Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml
 create mode 100644 drivers/net/pcs/pcs-mtk-usxgmii.c
 create mode 100644 drivers/phy/mediatek/phy-mtk-pextp.c
 create mode 100644 include/linux/pcs/pcs-mtk-usxgmii.h

-- 
2.42.1

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

* [RFC PATCH 0/8] Add support for 10G Ethernet SerDes on MT7988
@ 2023-11-09 21:50 ` Daniel Golle
  0 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 21:50 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Daniel Golle, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

This series aims to add support for GMAC2 and GMAC3 of the MediaTek MT7988 SoC.
While the vendor SDK stuffs all this into their Ethernet driver, I've tried to
seperate things into a PHY driver, a PCS driver as well as changes to the
existing Ethernet and LynxI PCS driver.

                  +----------------+
+--------------+  |  USXGMII PCS   |   +------------------+
| Ethernet MAC +--+-------------+  +---+ PEXTP SerDes PHY |
+--------------+  |  SGMII PCS  |  |   +------------------+
                  +-------------+--+

Alltogether this allows using GMAC2 and GMAC3 with all possible interface modes,
including in-band-status if needed.

Daniel Golle (8):
  dt-bindings: phy: mediatek,xfi-pextp: add new bindings
  phy: add driver for MediaTek pextp 10GE SerDes PHY
  net: pcs: pcs-mtk-lynxi: use 2500Base-X without AN
  net: pcs: pcs-mtk-lynxi: allow calling with NULL advertising
  dt-bindings: net: pcs: add bindings for MediaTek USXGMII PCS
  net: pcs: add driver for MediaTek USXGMII PCS
  dt-bindings: net: mediatek,net: fix and complete mt7988-eth binding
  net: ethernet: mtk_eth_soc: add paths and SerDes modes for MT7988

 .../devicetree/bindings/net/mediatek,net.yaml | 171 ++++-
 .../bindings/net/pcs/mediatek,usxgmii.yaml    | 105 +++
 .../bindings/phy/mediatek,xfi-pextp.yaml      |  71 ++
 MAINTAINERS                                   |   3 +
 drivers/net/ethernet/mediatek/Kconfig         |  17 +
 drivers/net/ethernet/mediatek/mtk_eth_path.c  | 122 +++-
 drivers/net/ethernet/mediatek/mtk_eth_soc.c   | 178 ++++-
 drivers/net/ethernet/mediatek/mtk_eth_soc.h   | 105 ++-
 drivers/net/pcs/Kconfig                       |  10 +
 drivers/net/pcs/Makefile                      |   1 +
 drivers/net/pcs/pcs-mtk-lynxi.c               |  38 +-
 drivers/net/pcs/pcs-mtk-usxgmii.c             | 688 ++++++++++++++++++
 drivers/phy/mediatek/Kconfig                  |  11 +
 drivers/phy/mediatek/Makefile                 |   1 +
 drivers/phy/mediatek/phy-mtk-pextp.c          | 355 +++++++++
 include/linux/pcs/pcs-mtk-usxgmii.h           |  18 +
 16 files changed, 1813 insertions(+), 81 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
 create mode 100644 Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml
 create mode 100644 drivers/net/pcs/pcs-mtk-usxgmii.c
 create mode 100644 drivers/phy/mediatek/phy-mtk-pextp.c
 create mode 100644 include/linux/pcs/pcs-mtk-usxgmii.h

-- 
2.42.1

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [RFC PATCH 0/8] Add support for 10G Ethernet SerDes on MT7988
@ 2023-11-09 21:50 ` Daniel Golle
  0 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 21:50 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Daniel Golle, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

This series aims to add support for GMAC2 and GMAC3 of the MediaTek MT7988 SoC.
While the vendor SDK stuffs all this into their Ethernet driver, I've tried to
seperate things into a PHY driver, a PCS driver as well as changes to the
existing Ethernet and LynxI PCS driver.

                  +----------------+
+--------------+  |  USXGMII PCS   |   +------------------+
| Ethernet MAC +--+-------------+  +---+ PEXTP SerDes PHY |
+--------------+  |  SGMII PCS  |  |   +------------------+
                  +-------------+--+

Alltogether this allows using GMAC2 and GMAC3 with all possible interface modes,
including in-band-status if needed.

Daniel Golle (8):
  dt-bindings: phy: mediatek,xfi-pextp: add new bindings
  phy: add driver for MediaTek pextp 10GE SerDes PHY
  net: pcs: pcs-mtk-lynxi: use 2500Base-X without AN
  net: pcs: pcs-mtk-lynxi: allow calling with NULL advertising
  dt-bindings: net: pcs: add bindings for MediaTek USXGMII PCS
  net: pcs: add driver for MediaTek USXGMII PCS
  dt-bindings: net: mediatek,net: fix and complete mt7988-eth binding
  net: ethernet: mtk_eth_soc: add paths and SerDes modes for MT7988

 .../devicetree/bindings/net/mediatek,net.yaml | 171 ++++-
 .../bindings/net/pcs/mediatek,usxgmii.yaml    | 105 +++
 .../bindings/phy/mediatek,xfi-pextp.yaml      |  71 ++
 MAINTAINERS                                   |   3 +
 drivers/net/ethernet/mediatek/Kconfig         |  17 +
 drivers/net/ethernet/mediatek/mtk_eth_path.c  | 122 +++-
 drivers/net/ethernet/mediatek/mtk_eth_soc.c   | 178 ++++-
 drivers/net/ethernet/mediatek/mtk_eth_soc.h   | 105 ++-
 drivers/net/pcs/Kconfig                       |  10 +
 drivers/net/pcs/Makefile                      |   1 +
 drivers/net/pcs/pcs-mtk-lynxi.c               |  38 +-
 drivers/net/pcs/pcs-mtk-usxgmii.c             | 688 ++++++++++++++++++
 drivers/phy/mediatek/Kconfig                  |  11 +
 drivers/phy/mediatek/Makefile                 |   1 +
 drivers/phy/mediatek/phy-mtk-pextp.c          | 355 +++++++++
 include/linux/pcs/pcs-mtk-usxgmii.h           |  18 +
 16 files changed, 1813 insertions(+), 81 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
 create mode 100644 Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml
 create mode 100644 drivers/net/pcs/pcs-mtk-usxgmii.c
 create mode 100644 drivers/phy/mediatek/phy-mtk-pextp.c
 create mode 100644 include/linux/pcs/pcs-mtk-usxgmii.h

-- 
2.42.1

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* [RFC PATCH 1/8] dt-bindings: phy: mediatek,xfi-pextp: add new bindings
  2023-11-09 21:50 ` Daniel Golle
  (?)
@ 2023-11-09 21:50   ` Daniel Golle
  -1 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 21:50 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Daniel Golle, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

Add bindings for the MediaTek PEXTP Ethernet SerDes PHY found in the
MediaTek MT7988 SoC which can operate at various interfaces modes:

 * USXGMII
 * 10GBase-R
 * 5GBase-R
 * 2500Base-X
 * 1000Base-X
 * Cisco SGMII (MAC side)

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 .../bindings/phy/mediatek,xfi-pextp.yaml      | 71 +++++++++++++++++++
 1 file changed, 71 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml

diff --git a/Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml b/Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml
new file mode 100644
index 0000000000000..948d5031af1e3
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/mediatek,xfi-pextp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek XFI PEXTP SerDes PHY
+
+maintainers:
+  - Daniel Golle <daniel@makrotopia.org>
+
+description: |
+  The MediaTek XFI PEXTP SerDes PHY provides the physical SerDes lanes
+  used by the MediaTek USXGMII PCS.
+
+properties:
+  $nodename:
+    pattern: "^phy@[0-9a-f]+$"
+
+  compatible:
+    const: mediatek,mt7988-xfi-pextp
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: XFI PHY clock
+
+  resets:
+    items:
+      - description: PEXTP reset
+
+  mediatek,usxgmii-performance-errata:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      USXGMII0 on MT7988 suffers from a performance problem in 10GBase-R
+      mode which needs a work-around in the driver. The work-around is
+      enabled using this flag.
+
+  "#phy-cells":
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - resets
+  - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mediatek,mt7988-clk.h>
+    #include <dt-bindings/reset/mediatek,mt7988-resets.h>
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      xfi_pextp0: phy@11f20000 {
+        compatible = "mediatek,mt7988-xfi-pextp";
+        reg = <0 0x11f20000 0 0x10000>;
+        clocks = <&topckgen CLK_TOP_XFI_PHY_0_XTAL_SEL>;
+        resets = <&watchdog MT7988_TOPRGU_XFI_PEXTP0_GRST>;
+        mediatek,usxgmii-performance-errata;
+        #phy-cells = <0>;
+      };
+    };
+
+...
-- 
2.42.1

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

* [RFC PATCH 1/8] dt-bindings: phy: mediatek,xfi-pextp: add new bindings
@ 2023-11-09 21:50   ` Daniel Golle
  0 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 21:50 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Daniel Golle, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

Add bindings for the MediaTek PEXTP Ethernet SerDes PHY found in the
MediaTek MT7988 SoC which can operate at various interfaces modes:

 * USXGMII
 * 10GBase-R
 * 5GBase-R
 * 2500Base-X
 * 1000Base-X
 * Cisco SGMII (MAC side)

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 .../bindings/phy/mediatek,xfi-pextp.yaml      | 71 +++++++++++++++++++
 1 file changed, 71 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml

diff --git a/Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml b/Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml
new file mode 100644
index 0000000000000..948d5031af1e3
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/mediatek,xfi-pextp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek XFI PEXTP SerDes PHY
+
+maintainers:
+  - Daniel Golle <daniel@makrotopia.org>
+
+description: |
+  The MediaTek XFI PEXTP SerDes PHY provides the physical SerDes lanes
+  used by the MediaTek USXGMII PCS.
+
+properties:
+  $nodename:
+    pattern: "^phy@[0-9a-f]+$"
+
+  compatible:
+    const: mediatek,mt7988-xfi-pextp
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: XFI PHY clock
+
+  resets:
+    items:
+      - description: PEXTP reset
+
+  mediatek,usxgmii-performance-errata:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      USXGMII0 on MT7988 suffers from a performance problem in 10GBase-R
+      mode which needs a work-around in the driver. The work-around is
+      enabled using this flag.
+
+  "#phy-cells":
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - resets
+  - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mediatek,mt7988-clk.h>
+    #include <dt-bindings/reset/mediatek,mt7988-resets.h>
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      xfi_pextp0: phy@11f20000 {
+        compatible = "mediatek,mt7988-xfi-pextp";
+        reg = <0 0x11f20000 0 0x10000>;
+        clocks = <&topckgen CLK_TOP_XFI_PHY_0_XTAL_SEL>;
+        resets = <&watchdog MT7988_TOPRGU_XFI_PEXTP0_GRST>;
+        mediatek,usxgmii-performance-errata;
+        #phy-cells = <0>;
+      };
+    };
+
+...
-- 
2.42.1

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [RFC PATCH 1/8] dt-bindings: phy: mediatek,xfi-pextp: add new bindings
@ 2023-11-09 21:50   ` Daniel Golle
  0 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 21:50 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Daniel Golle, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

Add bindings for the MediaTek PEXTP Ethernet SerDes PHY found in the
MediaTek MT7988 SoC which can operate at various interfaces modes:

 * USXGMII
 * 10GBase-R
 * 5GBase-R
 * 2500Base-X
 * 1000Base-X
 * Cisco SGMII (MAC side)

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 .../bindings/phy/mediatek,xfi-pextp.yaml      | 71 +++++++++++++++++++
 1 file changed, 71 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml

diff --git a/Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml b/Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml
new file mode 100644
index 0000000000000..948d5031af1e3
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml
@@ -0,0 +1,71 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/mediatek,xfi-pextp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek XFI PEXTP SerDes PHY
+
+maintainers:
+  - Daniel Golle <daniel@makrotopia.org>
+
+description: |
+  The MediaTek XFI PEXTP SerDes PHY provides the physical SerDes lanes
+  used by the MediaTek USXGMII PCS.
+
+properties:
+  $nodename:
+    pattern: "^phy@[0-9a-f]+$"
+
+  compatible:
+    const: mediatek,mt7988-xfi-pextp
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: XFI PHY clock
+
+  resets:
+    items:
+      - description: PEXTP reset
+
+  mediatek,usxgmii-performance-errata:
+    $ref: /schemas/types.yaml#/definitions/flag
+    description:
+      USXGMII0 on MT7988 suffers from a performance problem in 10GBase-R
+      mode which needs a work-around in the driver. The work-around is
+      enabled using this flag.
+
+  "#phy-cells":
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - resets
+  - "#phy-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mediatek,mt7988-clk.h>
+    #include <dt-bindings/reset/mediatek,mt7988-resets.h>
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      xfi_pextp0: phy@11f20000 {
+        compatible = "mediatek,mt7988-xfi-pextp";
+        reg = <0 0x11f20000 0 0x10000>;
+        clocks = <&topckgen CLK_TOP_XFI_PHY_0_XTAL_SEL>;
+        resets = <&watchdog MT7988_TOPRGU_XFI_PEXTP0_GRST>;
+        mediatek,usxgmii-performance-errata;
+        #phy-cells = <0>;
+      };
+    };
+
+...
-- 
2.42.1

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* [RFC PATCH 2/8] phy: add driver for MediaTek pextp 10GE SerDes PHY
  2023-11-09 21:50 ` Daniel Golle
  (?)
@ 2023-11-09 21:51   ` Daniel Golle
  -1 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 21:51 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Daniel Golle, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

Add driver for MediaTek's pextp 10 Gigabit/s Ethernet SerDes PHY which
can be found in the MT7988 SoC.

The PHY can operates only in PHY_MODE_ETHERNET, the submode is one of
PHY_INTERFACE_MODE_* corresponding to the supported modes:

 * USXGMII
 * 10GBase-R
 * 5GBase-R
 * 2500Base-X
 * 1000Base-X
 * Cisco SGMII (MAC side)

In order to work-around a performance issue present on the first of
two PEXTP present in MT7988 special tuning is applied which can be
selected by adding the mediatek,usxgmii-performance-errata property to
the device tree node.

There is no documentation what-so-ever for the pextp registers and
this driver is based on a GPL licensed implementation found in
MediaTek's SDK.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 MAINTAINERS                          |   1 +
 drivers/phy/mediatek/Kconfig         |  11 +
 drivers/phy/mediatek/Makefile        |   1 +
 drivers/phy/mediatek/phy-mtk-pextp.c | 355 +++++++++++++++++++++++++++
 4 files changed, 368 insertions(+)
 create mode 100644 drivers/phy/mediatek/phy-mtk-pextp.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 7b151710e8c58..6499acd8f3874 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13527,6 +13527,7 @@ L:	netdev@vger.kernel.org
 S:	Maintained
 F:	drivers/net/phy/mediatek-ge-soc.c
 F:	drivers/net/phy/mediatek-ge.c
+F:	drivers/phy/mediatek/phy-mediatek-pextp.c
 
 MEDIATEK I2C CONTROLLER DRIVER
 M:	Qii Wang <qii.wang@mediatek.com>
diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig
index 3125ecb5d119f..a7749a6d96541 100644
--- a/drivers/phy/mediatek/Kconfig
+++ b/drivers/phy/mediatek/Kconfig
@@ -13,6 +13,17 @@ config PHY_MTK_PCIE
 	  callback for PCIe GEN3 port, it supports software efuse
 	  initialization.
 
+config PHY_MTK_PEXTP
+	tristate "MediaTek PEXTP Driver"
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	depends on OF && OF_ADDRESS
+	depends on HAS_IOMEM
+	select GENERIC_PHY
+	help
+	  Say 'Y' here to add support for MediaTek pextp PHY driver.
+	  The driver provides access to the Ethernet SerDes PHY supporting
+	  various 1GE, 2.5GE, 5GE and 10GE modes.
+
 config PHY_MTK_TPHY
 	tristate "MediaTek T-PHY Driver"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
index c9a50395533eb..ca60c7b9b02ac 100644
--- a/drivers/phy/mediatek/Makefile
+++ b/drivers/phy/mediatek/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_MTK_PCIE)		+= phy-mtk-pcie.o
 obj-$(CONFIG_PHY_MTK_TPHY)		+= phy-mtk-tphy.o
 obj-$(CONFIG_PHY_MTK_UFS)		+= phy-mtk-ufs.o
 obj-$(CONFIG_PHY_MTK_XSPHY)		+= phy-mtk-xsphy.o
+obj-$(CONFIG_PHY_MTK_PEXTP)		+= phy-mtk-pextp.o
 
 phy-mtk-hdmi-drv-y			:= phy-mtk-hdmi.o
 phy-mtk-hdmi-drv-y			+= phy-mtk-hdmi-mt2701.o
diff --git a/drivers/phy/mediatek/phy-mtk-pextp.c b/drivers/phy/mediatek/phy-mtk-pextp.c
new file mode 100644
index 0000000000000..272bff4f37a96
--- /dev/null
+++ b/drivers/phy/mediatek/phy-mtk-pextp.c
@@ -0,0 +1,355 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* MediaTek 10GE SerDes PHY driver
+ *
+ * Copyright (c) 2023 Daniel Golle <daniel@makrotopia.org>
+ * based on mtk_usxgmii.c found in MediaTek's SDK released under GPL-2.0
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Henry Yen <henry.yen@mediatek.com>
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/netdevice.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/reset.h>
+#include <linux/phy.h>
+#include <linux/phy/phy.h>
+
+struct mtk_pextp_phy {
+	void __iomem		*base;
+	struct device		*dev;
+	struct reset_control	*reset;
+	struct clk		*clk;
+	bool			da_war;
+};
+
+static inline bool mtk_interface_mode_is_xgmii(phy_interface_t interface)
+{
+	switch (interface) {
+	case PHY_INTERFACE_MODE_INTERNAL:
+	case PHY_INTERFACE_MODE_USXGMII:
+	case PHY_INTERFACE_MODE_10GBASER:
+	case PHY_INTERFACE_MODE_5GBASER:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static void mtk_pextp_setup(struct mtk_pextp_phy *pextp, phy_interface_t interface)
+{
+	bool is_10g = (interface == PHY_INTERFACE_MODE_10GBASER ||
+		       interface == PHY_INTERFACE_MODE_USXGMII);
+	bool is_2p5g = (interface == PHY_INTERFACE_MODE_2500BASEX);
+	bool is_5g = (interface == PHY_INTERFACE_MODE_5GBASER);
+
+	dev_dbg(pextp->dev, "setting up for mode %s\n", phy_modes(interface));
+
+	/* Setup operation mode */
+	if (is_10g)
+		iowrite32(0x00C9071C, pextp->base + 0x9024);
+	else
+		iowrite32(0x00D9071C, pextp->base + 0x9024);
+
+	if (is_5g)
+		iowrite32(0xAAA5A5AA, pextp->base + 0x2020);
+	else
+		iowrite32(0xAA8585AA, pextp->base + 0x2020);
+
+	if (is_2p5g || is_5g || is_10g) {
+		iowrite32(0x0C020707, pextp->base + 0x2030);
+		iowrite32(0x0E050F0F, pextp->base + 0x2034);
+		iowrite32(0x00140032, pextp->base + 0x2040);
+	} else {
+		iowrite32(0x0C020207, pextp->base + 0x2030);
+		iowrite32(0x0E05050F, pextp->base + 0x2034);
+		iowrite32(0x00200032, pextp->base + 0x2040);
+	}
+
+	if (is_2p5g || is_10g)
+		iowrite32(0x00C014AA, pextp->base + 0x50F0);
+	else if (is_5g)
+		iowrite32(0x00C018AA, pextp->base + 0x50F0);
+	else
+		iowrite32(0x00C014BA, pextp->base + 0x50F0);
+
+	if (is_5g) {
+		iowrite32(0x3777812B, pextp->base + 0x50E0);
+		iowrite32(0x005C9CFF, pextp->base + 0x506C);
+		iowrite32(0x9DFAFAFA, pextp->base + 0x5070);
+		iowrite32(0x273F3F3F, pextp->base + 0x5074);
+		iowrite32(0xA8883868, pextp->base + 0x5078);
+		iowrite32(0x14661466, pextp->base + 0x507C);
+	} else {
+		iowrite32(0x3777C12B, pextp->base + 0x50E0);
+		iowrite32(0x005F9CFF, pextp->base + 0x506C);
+		iowrite32(0x9D9DFAFA, pextp->base + 0x5070);
+		iowrite32(0x27273F3F, pextp->base + 0x5074);
+		iowrite32(0xA7883C68, pextp->base + 0x5078);
+		iowrite32(0x11661166, pextp->base + 0x507C);
+	}
+
+	if (is_2p5g || is_10g) {
+		iowrite32(0x0E000AAF, pextp->base + 0x5080);
+		iowrite32(0x08080D0D, pextp->base + 0x5084);
+		iowrite32(0x02030909, pextp->base + 0x5088);
+	} else if (is_5g) {
+		iowrite32(0x0E001ABF, pextp->base + 0x5080);
+		iowrite32(0x080B0D0D, pextp->base + 0x5084);
+		iowrite32(0x02050909, pextp->base + 0x5088);
+	} else {
+		iowrite32(0x0E000EAF, pextp->base + 0x5080);
+		iowrite32(0x08080E0D, pextp->base + 0x5084);
+		iowrite32(0x02030B09, pextp->base + 0x5088);
+	}
+
+	if (is_5g) {
+		iowrite32(0x0C000000, pextp->base + 0x50E4);
+		iowrite32(0x04000000, pextp->base + 0x50E8);
+	} else {
+		iowrite32(0x0C0C0000, pextp->base + 0x50E4);
+		iowrite32(0x04040000, pextp->base + 0x50E8);
+	}
+
+	if (is_2p5g || mtk_interface_mode_is_xgmii(interface))
+		iowrite32(0x0F0F0C06, pextp->base + 0x50EC);
+	else
+		iowrite32(0x0F0F0606, pextp->base + 0x50EC);
+
+	if (is_5g) {
+		iowrite32(0x50808C8C, pextp->base + 0x50A8);
+		iowrite32(0x18000000, pextp->base + 0x6004);
+	} else {
+		iowrite32(0x506E8C8C, pextp->base + 0x50A8);
+		iowrite32(0x18190000, pextp->base + 0x6004);
+	}
+
+	if (is_10g)
+		iowrite32(0x01423342, pextp->base + 0x00F8);
+	else if (is_5g)
+		iowrite32(0x00A132A1, pextp->base + 0x00F8);
+	else if (is_2p5g)
+		iowrite32(0x009C329C, pextp->base + 0x00F8);
+	else
+		iowrite32(0x00FA32FA, pextp->base + 0x00F8);
+
+	/* Force SGDT_OUT off and select PCS */
+	if (mtk_interface_mode_is_xgmii(interface))
+		iowrite32(0x80201F20, pextp->base + 0x00F4);
+	else
+		iowrite32(0x80201F21, pextp->base + 0x00F4);
+
+	/* Force GLB_CKDET_OUT */
+	iowrite32(0x00050C00, pextp->base + 0x0030);
+
+	/* Force AEQ on */
+	iowrite32(0x02002800, pextp->base + 0x0070);
+	ndelay(1020);
+
+	/* Setup DA default value */
+	iowrite32(0x00000020, pextp->base + 0x30B0);
+	iowrite32(0x00008A01, pextp->base + 0x3028);
+	iowrite32(0x0000A884, pextp->base + 0x302C);
+	iowrite32(0x00083002, pextp->base + 0x3024);
+	if (mtk_interface_mode_is_xgmii(interface)) {
+		iowrite32(0x00022220, pextp->base + 0x3010);
+		iowrite32(0x0F020A01, pextp->base + 0x5064);
+		iowrite32(0x06100600, pextp->base + 0x50B4);
+		if (interface == PHY_INTERFACE_MODE_USXGMII)
+			iowrite32(0x40704000, pextp->base + 0x3048);
+		else
+			iowrite32(0x47684100, pextp->base + 0x3048);
+	} else {
+		iowrite32(0x00011110, pextp->base + 0x3010);
+		iowrite32(0x40704000, pextp->base + 0x3048);
+	}
+
+	if (!mtk_interface_mode_is_xgmii(interface) && !is_2p5g)
+		iowrite32(0x0000C000, pextp->base + 0x3064);
+
+	if (interface == PHY_INTERFACE_MODE_USXGMII) {
+		iowrite32(0xA8000000, pextp->base + 0x3050);
+		iowrite32(0x000000AA, pextp->base + 0x3054);
+	} else if (mtk_interface_mode_is_xgmii(interface)) {
+		iowrite32(0x00000000, pextp->base + 0x3050);
+		iowrite32(0x00000000, pextp->base + 0x3054);
+	} else {
+		iowrite32(0xA8000000, pextp->base + 0x3050);
+		iowrite32(0x000000AA, pextp->base + 0x3054);
+	}
+
+	if (mtk_interface_mode_is_xgmii(interface))
+		iowrite32(0x00000F00, pextp->base + 0x306C);
+	else if (is_2p5g)
+		iowrite32(0x22000F00, pextp->base + 0x306C);
+	else
+		iowrite32(0x20200F00, pextp->base + 0x306C);
+
+	if (interface == PHY_INTERFACE_MODE_10GBASER && pextp->da_war)
+		iowrite32(0x0007B400, pextp->base + 0xA008);
+
+	if (mtk_interface_mode_is_xgmii(interface))
+		iowrite32(0x00040000, pextp->base + 0xA060);
+	else
+		iowrite32(0x00050000, pextp->base + 0xA060);
+
+	if (is_10g)
+		iowrite32(0x00000001, pextp->base + 0x90D0);
+	else if (is_5g)
+		iowrite32(0x00000003, pextp->base + 0x90D0);
+	else if (is_2p5g)
+		iowrite32(0x00000005, pextp->base + 0x90D0);
+	else
+		iowrite32(0x00000007, pextp->base + 0x90D0);
+
+	/* Release reset */
+	iowrite32(0x0200E800, pextp->base + 0x0070);
+	usleep_range(150, 500);
+
+	/* Switch to P0 */
+	iowrite32(0x0200C111, pextp->base + 0x0070);
+	ndelay(1020);
+	iowrite32(0x0200C101, pextp->base + 0x0070);
+	usleep_range(15, 50);
+
+	if (mtk_interface_mode_is_xgmii(interface)) {
+		/* Switch to Gen3 */
+		iowrite32(0x0202C111, pextp->base + 0x0070);
+	} else {
+		/* Switch to Gen2 */
+		iowrite32(0x0201C111, pextp->base + 0x0070);
+	}
+	ndelay(1020);
+	if (mtk_interface_mode_is_xgmii(interface))
+		iowrite32(0x0202C101, pextp->base + 0x0070);
+	else
+		iowrite32(0x0201C101, pextp->base + 0x0070);
+	usleep_range(100, 500);
+	iowrite32(0x00000030, pextp->base + 0x30B0);
+	if (mtk_interface_mode_is_xgmii(interface))
+		iowrite32(0x80201F00, pextp->base + 0x00F4);
+	else
+		iowrite32(0x80201F01, pextp->base + 0x00F4);
+
+	iowrite32(0x30000000, pextp->base + 0x3040);
+	usleep_range(400, 1000);
+}
+
+static int mtk_pextp_set_mode(struct phy *phy, enum phy_mode mode, int submode)
+{
+	struct mtk_pextp_phy *pextp = phy_get_drvdata(phy);
+
+	if (mode != PHY_MODE_ETHERNET)
+		return -EINVAL;
+
+	switch (submode) {
+	case PHY_INTERFACE_MODE_1000BASEX:
+	case PHY_INTERFACE_MODE_2500BASEX:
+	case PHY_INTERFACE_MODE_SGMII:
+	case PHY_INTERFACE_MODE_5GBASER:
+	case PHY_INTERFACE_MODE_10GBASER:
+	case PHY_INTERFACE_MODE_USXGMII:
+		mtk_pextp_setup(pextp, submode);
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int mtk_pextp_reset(struct phy *phy)
+{
+	struct mtk_pextp_phy *pextp = phy_get_drvdata(phy);
+
+	reset_control_assert(pextp->reset);
+	usleep_range(100, 500);
+	reset_control_deassert(pextp->reset);
+	mdelay(10);
+
+	return 0;
+}
+
+static int mtk_pextp_power_on(struct phy *phy)
+{
+	struct mtk_pextp_phy *pextp = phy_get_drvdata(phy);
+
+	return clk_prepare_enable(pextp->clk);
+}
+
+static int mtk_pextp_power_off(struct phy *phy)
+{
+	struct mtk_pextp_phy *pextp = phy_get_drvdata(phy);
+
+	clk_disable_unprepare(pextp->clk);
+
+	return 0;
+}
+
+static const struct phy_ops mtk_pextp_ops = {
+	.power_on	= mtk_pextp_power_on,
+	.power_off	= mtk_pextp_power_off,
+	.set_mode	= mtk_pextp_set_mode,
+	.reset		= mtk_pextp_reset,
+	.owner		= THIS_MODULE,
+};
+
+static int mtk_pextp_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct phy_provider *phy_provider;
+	struct mtk_pextp_phy *pextp;
+	struct phy *phy;
+
+	if (!np)
+		return -ENODEV;
+
+	pextp = devm_kzalloc(&pdev->dev, sizeof(*pextp), GFP_KERNEL);
+	if (!pextp)
+		return -ENOMEM;
+
+	pextp->base = devm_of_iomap(&pdev->dev, np, 0, NULL);
+	if (!pextp->base)
+		return -EIO;
+
+	pextp->dev = &pdev->dev;
+	pextp->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(pextp->clk))
+		return PTR_ERR(pextp->clk);
+
+	pextp->reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+	if (IS_ERR(pextp->reset))
+		return PTR_ERR(pextp->reset);
+
+	pextp->da_war = of_property_read_bool(np, "mediatek,usxgmii-performance-errata");
+
+	phy = devm_phy_create(&pdev->dev, NULL, &mtk_pextp_ops);
+	if (IS_ERR(phy))
+		return PTR_ERR(phy);
+
+	phy_set_drvdata(phy, pextp);
+
+	phy_provider = devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate);
+
+	return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct of_device_id mtk_pextp_match[] = {
+	{ .compatible = "mediatek,mt7988-xfi-pextp", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, mtk_pextp_match);
+
+static struct platform_driver mtk_pextp_driver = {
+	.probe = mtk_pextp_probe,
+	.driver = {
+		.name = "mtk-pextp",
+		.of_match_table = mtk_pextp_match,
+	},
+};
+module_platform_driver(mtk_pextp_driver);
+
+MODULE_DESCRIPTION("MediaTek pextp SerDes PHY driver");
+MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
+MODULE_LICENSE("GPL");
-- 
2.42.1

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

* [RFC PATCH 2/8] phy: add driver for MediaTek pextp 10GE SerDes PHY
@ 2023-11-09 21:51   ` Daniel Golle
  0 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 21:51 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Daniel Golle, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

Add driver for MediaTek's pextp 10 Gigabit/s Ethernet SerDes PHY which
can be found in the MT7988 SoC.

The PHY can operates only in PHY_MODE_ETHERNET, the submode is one of
PHY_INTERFACE_MODE_* corresponding to the supported modes:

 * USXGMII
 * 10GBase-R
 * 5GBase-R
 * 2500Base-X
 * 1000Base-X
 * Cisco SGMII (MAC side)

In order to work-around a performance issue present on the first of
two PEXTP present in MT7988 special tuning is applied which can be
selected by adding the mediatek,usxgmii-performance-errata property to
the device tree node.

There is no documentation what-so-ever for the pextp registers and
this driver is based on a GPL licensed implementation found in
MediaTek's SDK.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 MAINTAINERS                          |   1 +
 drivers/phy/mediatek/Kconfig         |  11 +
 drivers/phy/mediatek/Makefile        |   1 +
 drivers/phy/mediatek/phy-mtk-pextp.c | 355 +++++++++++++++++++++++++++
 4 files changed, 368 insertions(+)
 create mode 100644 drivers/phy/mediatek/phy-mtk-pextp.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 7b151710e8c58..6499acd8f3874 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13527,6 +13527,7 @@ L:	netdev@vger.kernel.org
 S:	Maintained
 F:	drivers/net/phy/mediatek-ge-soc.c
 F:	drivers/net/phy/mediatek-ge.c
+F:	drivers/phy/mediatek/phy-mediatek-pextp.c
 
 MEDIATEK I2C CONTROLLER DRIVER
 M:	Qii Wang <qii.wang@mediatek.com>
diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig
index 3125ecb5d119f..a7749a6d96541 100644
--- a/drivers/phy/mediatek/Kconfig
+++ b/drivers/phy/mediatek/Kconfig
@@ -13,6 +13,17 @@ config PHY_MTK_PCIE
 	  callback for PCIe GEN3 port, it supports software efuse
 	  initialization.
 
+config PHY_MTK_PEXTP
+	tristate "MediaTek PEXTP Driver"
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	depends on OF && OF_ADDRESS
+	depends on HAS_IOMEM
+	select GENERIC_PHY
+	help
+	  Say 'Y' here to add support for MediaTek pextp PHY driver.
+	  The driver provides access to the Ethernet SerDes PHY supporting
+	  various 1GE, 2.5GE, 5GE and 10GE modes.
+
 config PHY_MTK_TPHY
 	tristate "MediaTek T-PHY Driver"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
index c9a50395533eb..ca60c7b9b02ac 100644
--- a/drivers/phy/mediatek/Makefile
+++ b/drivers/phy/mediatek/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_MTK_PCIE)		+= phy-mtk-pcie.o
 obj-$(CONFIG_PHY_MTK_TPHY)		+= phy-mtk-tphy.o
 obj-$(CONFIG_PHY_MTK_UFS)		+= phy-mtk-ufs.o
 obj-$(CONFIG_PHY_MTK_XSPHY)		+= phy-mtk-xsphy.o
+obj-$(CONFIG_PHY_MTK_PEXTP)		+= phy-mtk-pextp.o
 
 phy-mtk-hdmi-drv-y			:= phy-mtk-hdmi.o
 phy-mtk-hdmi-drv-y			+= phy-mtk-hdmi-mt2701.o
diff --git a/drivers/phy/mediatek/phy-mtk-pextp.c b/drivers/phy/mediatek/phy-mtk-pextp.c
new file mode 100644
index 0000000000000..272bff4f37a96
--- /dev/null
+++ b/drivers/phy/mediatek/phy-mtk-pextp.c
@@ -0,0 +1,355 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* MediaTek 10GE SerDes PHY driver
+ *
+ * Copyright (c) 2023 Daniel Golle <daniel@makrotopia.org>
+ * based on mtk_usxgmii.c found in MediaTek's SDK released under GPL-2.0
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Henry Yen <henry.yen@mediatek.com>
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/netdevice.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/reset.h>
+#include <linux/phy.h>
+#include <linux/phy/phy.h>
+
+struct mtk_pextp_phy {
+	void __iomem		*base;
+	struct device		*dev;
+	struct reset_control	*reset;
+	struct clk		*clk;
+	bool			da_war;
+};
+
+static inline bool mtk_interface_mode_is_xgmii(phy_interface_t interface)
+{
+	switch (interface) {
+	case PHY_INTERFACE_MODE_INTERNAL:
+	case PHY_INTERFACE_MODE_USXGMII:
+	case PHY_INTERFACE_MODE_10GBASER:
+	case PHY_INTERFACE_MODE_5GBASER:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static void mtk_pextp_setup(struct mtk_pextp_phy *pextp, phy_interface_t interface)
+{
+	bool is_10g = (interface == PHY_INTERFACE_MODE_10GBASER ||
+		       interface == PHY_INTERFACE_MODE_USXGMII);
+	bool is_2p5g = (interface == PHY_INTERFACE_MODE_2500BASEX);
+	bool is_5g = (interface == PHY_INTERFACE_MODE_5GBASER);
+
+	dev_dbg(pextp->dev, "setting up for mode %s\n", phy_modes(interface));
+
+	/* Setup operation mode */
+	if (is_10g)
+		iowrite32(0x00C9071C, pextp->base + 0x9024);
+	else
+		iowrite32(0x00D9071C, pextp->base + 0x9024);
+
+	if (is_5g)
+		iowrite32(0xAAA5A5AA, pextp->base + 0x2020);
+	else
+		iowrite32(0xAA8585AA, pextp->base + 0x2020);
+
+	if (is_2p5g || is_5g || is_10g) {
+		iowrite32(0x0C020707, pextp->base + 0x2030);
+		iowrite32(0x0E050F0F, pextp->base + 0x2034);
+		iowrite32(0x00140032, pextp->base + 0x2040);
+	} else {
+		iowrite32(0x0C020207, pextp->base + 0x2030);
+		iowrite32(0x0E05050F, pextp->base + 0x2034);
+		iowrite32(0x00200032, pextp->base + 0x2040);
+	}
+
+	if (is_2p5g || is_10g)
+		iowrite32(0x00C014AA, pextp->base + 0x50F0);
+	else if (is_5g)
+		iowrite32(0x00C018AA, pextp->base + 0x50F0);
+	else
+		iowrite32(0x00C014BA, pextp->base + 0x50F0);
+
+	if (is_5g) {
+		iowrite32(0x3777812B, pextp->base + 0x50E0);
+		iowrite32(0x005C9CFF, pextp->base + 0x506C);
+		iowrite32(0x9DFAFAFA, pextp->base + 0x5070);
+		iowrite32(0x273F3F3F, pextp->base + 0x5074);
+		iowrite32(0xA8883868, pextp->base + 0x5078);
+		iowrite32(0x14661466, pextp->base + 0x507C);
+	} else {
+		iowrite32(0x3777C12B, pextp->base + 0x50E0);
+		iowrite32(0x005F9CFF, pextp->base + 0x506C);
+		iowrite32(0x9D9DFAFA, pextp->base + 0x5070);
+		iowrite32(0x27273F3F, pextp->base + 0x5074);
+		iowrite32(0xA7883C68, pextp->base + 0x5078);
+		iowrite32(0x11661166, pextp->base + 0x507C);
+	}
+
+	if (is_2p5g || is_10g) {
+		iowrite32(0x0E000AAF, pextp->base + 0x5080);
+		iowrite32(0x08080D0D, pextp->base + 0x5084);
+		iowrite32(0x02030909, pextp->base + 0x5088);
+	} else if (is_5g) {
+		iowrite32(0x0E001ABF, pextp->base + 0x5080);
+		iowrite32(0x080B0D0D, pextp->base + 0x5084);
+		iowrite32(0x02050909, pextp->base + 0x5088);
+	} else {
+		iowrite32(0x0E000EAF, pextp->base + 0x5080);
+		iowrite32(0x08080E0D, pextp->base + 0x5084);
+		iowrite32(0x02030B09, pextp->base + 0x5088);
+	}
+
+	if (is_5g) {
+		iowrite32(0x0C000000, pextp->base + 0x50E4);
+		iowrite32(0x04000000, pextp->base + 0x50E8);
+	} else {
+		iowrite32(0x0C0C0000, pextp->base + 0x50E4);
+		iowrite32(0x04040000, pextp->base + 0x50E8);
+	}
+
+	if (is_2p5g || mtk_interface_mode_is_xgmii(interface))
+		iowrite32(0x0F0F0C06, pextp->base + 0x50EC);
+	else
+		iowrite32(0x0F0F0606, pextp->base + 0x50EC);
+
+	if (is_5g) {
+		iowrite32(0x50808C8C, pextp->base + 0x50A8);
+		iowrite32(0x18000000, pextp->base + 0x6004);
+	} else {
+		iowrite32(0x506E8C8C, pextp->base + 0x50A8);
+		iowrite32(0x18190000, pextp->base + 0x6004);
+	}
+
+	if (is_10g)
+		iowrite32(0x01423342, pextp->base + 0x00F8);
+	else if (is_5g)
+		iowrite32(0x00A132A1, pextp->base + 0x00F8);
+	else if (is_2p5g)
+		iowrite32(0x009C329C, pextp->base + 0x00F8);
+	else
+		iowrite32(0x00FA32FA, pextp->base + 0x00F8);
+
+	/* Force SGDT_OUT off and select PCS */
+	if (mtk_interface_mode_is_xgmii(interface))
+		iowrite32(0x80201F20, pextp->base + 0x00F4);
+	else
+		iowrite32(0x80201F21, pextp->base + 0x00F4);
+
+	/* Force GLB_CKDET_OUT */
+	iowrite32(0x00050C00, pextp->base + 0x0030);
+
+	/* Force AEQ on */
+	iowrite32(0x02002800, pextp->base + 0x0070);
+	ndelay(1020);
+
+	/* Setup DA default value */
+	iowrite32(0x00000020, pextp->base + 0x30B0);
+	iowrite32(0x00008A01, pextp->base + 0x3028);
+	iowrite32(0x0000A884, pextp->base + 0x302C);
+	iowrite32(0x00083002, pextp->base + 0x3024);
+	if (mtk_interface_mode_is_xgmii(interface)) {
+		iowrite32(0x00022220, pextp->base + 0x3010);
+		iowrite32(0x0F020A01, pextp->base + 0x5064);
+		iowrite32(0x06100600, pextp->base + 0x50B4);
+		if (interface == PHY_INTERFACE_MODE_USXGMII)
+			iowrite32(0x40704000, pextp->base + 0x3048);
+		else
+			iowrite32(0x47684100, pextp->base + 0x3048);
+	} else {
+		iowrite32(0x00011110, pextp->base + 0x3010);
+		iowrite32(0x40704000, pextp->base + 0x3048);
+	}
+
+	if (!mtk_interface_mode_is_xgmii(interface) && !is_2p5g)
+		iowrite32(0x0000C000, pextp->base + 0x3064);
+
+	if (interface == PHY_INTERFACE_MODE_USXGMII) {
+		iowrite32(0xA8000000, pextp->base + 0x3050);
+		iowrite32(0x000000AA, pextp->base + 0x3054);
+	} else if (mtk_interface_mode_is_xgmii(interface)) {
+		iowrite32(0x00000000, pextp->base + 0x3050);
+		iowrite32(0x00000000, pextp->base + 0x3054);
+	} else {
+		iowrite32(0xA8000000, pextp->base + 0x3050);
+		iowrite32(0x000000AA, pextp->base + 0x3054);
+	}
+
+	if (mtk_interface_mode_is_xgmii(interface))
+		iowrite32(0x00000F00, pextp->base + 0x306C);
+	else if (is_2p5g)
+		iowrite32(0x22000F00, pextp->base + 0x306C);
+	else
+		iowrite32(0x20200F00, pextp->base + 0x306C);
+
+	if (interface == PHY_INTERFACE_MODE_10GBASER && pextp->da_war)
+		iowrite32(0x0007B400, pextp->base + 0xA008);
+
+	if (mtk_interface_mode_is_xgmii(interface))
+		iowrite32(0x00040000, pextp->base + 0xA060);
+	else
+		iowrite32(0x00050000, pextp->base + 0xA060);
+
+	if (is_10g)
+		iowrite32(0x00000001, pextp->base + 0x90D0);
+	else if (is_5g)
+		iowrite32(0x00000003, pextp->base + 0x90D0);
+	else if (is_2p5g)
+		iowrite32(0x00000005, pextp->base + 0x90D0);
+	else
+		iowrite32(0x00000007, pextp->base + 0x90D0);
+
+	/* Release reset */
+	iowrite32(0x0200E800, pextp->base + 0x0070);
+	usleep_range(150, 500);
+
+	/* Switch to P0 */
+	iowrite32(0x0200C111, pextp->base + 0x0070);
+	ndelay(1020);
+	iowrite32(0x0200C101, pextp->base + 0x0070);
+	usleep_range(15, 50);
+
+	if (mtk_interface_mode_is_xgmii(interface)) {
+		/* Switch to Gen3 */
+		iowrite32(0x0202C111, pextp->base + 0x0070);
+	} else {
+		/* Switch to Gen2 */
+		iowrite32(0x0201C111, pextp->base + 0x0070);
+	}
+	ndelay(1020);
+	if (mtk_interface_mode_is_xgmii(interface))
+		iowrite32(0x0202C101, pextp->base + 0x0070);
+	else
+		iowrite32(0x0201C101, pextp->base + 0x0070);
+	usleep_range(100, 500);
+	iowrite32(0x00000030, pextp->base + 0x30B0);
+	if (mtk_interface_mode_is_xgmii(interface))
+		iowrite32(0x80201F00, pextp->base + 0x00F4);
+	else
+		iowrite32(0x80201F01, pextp->base + 0x00F4);
+
+	iowrite32(0x30000000, pextp->base + 0x3040);
+	usleep_range(400, 1000);
+}
+
+static int mtk_pextp_set_mode(struct phy *phy, enum phy_mode mode, int submode)
+{
+	struct mtk_pextp_phy *pextp = phy_get_drvdata(phy);
+
+	if (mode != PHY_MODE_ETHERNET)
+		return -EINVAL;
+
+	switch (submode) {
+	case PHY_INTERFACE_MODE_1000BASEX:
+	case PHY_INTERFACE_MODE_2500BASEX:
+	case PHY_INTERFACE_MODE_SGMII:
+	case PHY_INTERFACE_MODE_5GBASER:
+	case PHY_INTERFACE_MODE_10GBASER:
+	case PHY_INTERFACE_MODE_USXGMII:
+		mtk_pextp_setup(pextp, submode);
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int mtk_pextp_reset(struct phy *phy)
+{
+	struct mtk_pextp_phy *pextp = phy_get_drvdata(phy);
+
+	reset_control_assert(pextp->reset);
+	usleep_range(100, 500);
+	reset_control_deassert(pextp->reset);
+	mdelay(10);
+
+	return 0;
+}
+
+static int mtk_pextp_power_on(struct phy *phy)
+{
+	struct mtk_pextp_phy *pextp = phy_get_drvdata(phy);
+
+	return clk_prepare_enable(pextp->clk);
+}
+
+static int mtk_pextp_power_off(struct phy *phy)
+{
+	struct mtk_pextp_phy *pextp = phy_get_drvdata(phy);
+
+	clk_disable_unprepare(pextp->clk);
+
+	return 0;
+}
+
+static const struct phy_ops mtk_pextp_ops = {
+	.power_on	= mtk_pextp_power_on,
+	.power_off	= mtk_pextp_power_off,
+	.set_mode	= mtk_pextp_set_mode,
+	.reset		= mtk_pextp_reset,
+	.owner		= THIS_MODULE,
+};
+
+static int mtk_pextp_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct phy_provider *phy_provider;
+	struct mtk_pextp_phy *pextp;
+	struct phy *phy;
+
+	if (!np)
+		return -ENODEV;
+
+	pextp = devm_kzalloc(&pdev->dev, sizeof(*pextp), GFP_KERNEL);
+	if (!pextp)
+		return -ENOMEM;
+
+	pextp->base = devm_of_iomap(&pdev->dev, np, 0, NULL);
+	if (!pextp->base)
+		return -EIO;
+
+	pextp->dev = &pdev->dev;
+	pextp->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(pextp->clk))
+		return PTR_ERR(pextp->clk);
+
+	pextp->reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+	if (IS_ERR(pextp->reset))
+		return PTR_ERR(pextp->reset);
+
+	pextp->da_war = of_property_read_bool(np, "mediatek,usxgmii-performance-errata");
+
+	phy = devm_phy_create(&pdev->dev, NULL, &mtk_pextp_ops);
+	if (IS_ERR(phy))
+		return PTR_ERR(phy);
+
+	phy_set_drvdata(phy, pextp);
+
+	phy_provider = devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate);
+
+	return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct of_device_id mtk_pextp_match[] = {
+	{ .compatible = "mediatek,mt7988-xfi-pextp", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, mtk_pextp_match);
+
+static struct platform_driver mtk_pextp_driver = {
+	.probe = mtk_pextp_probe,
+	.driver = {
+		.name = "mtk-pextp",
+		.of_match_table = mtk_pextp_match,
+	},
+};
+module_platform_driver(mtk_pextp_driver);
+
+MODULE_DESCRIPTION("MediaTek pextp SerDes PHY driver");
+MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
+MODULE_LICENSE("GPL");
-- 
2.42.1

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [RFC PATCH 2/8] phy: add driver for MediaTek pextp 10GE SerDes PHY
@ 2023-11-09 21:51   ` Daniel Golle
  0 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 21:51 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Daniel Golle, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

Add driver for MediaTek's pextp 10 Gigabit/s Ethernet SerDes PHY which
can be found in the MT7988 SoC.

The PHY can operates only in PHY_MODE_ETHERNET, the submode is one of
PHY_INTERFACE_MODE_* corresponding to the supported modes:

 * USXGMII
 * 10GBase-R
 * 5GBase-R
 * 2500Base-X
 * 1000Base-X
 * Cisco SGMII (MAC side)

In order to work-around a performance issue present on the first of
two PEXTP present in MT7988 special tuning is applied which can be
selected by adding the mediatek,usxgmii-performance-errata property to
the device tree node.

There is no documentation what-so-ever for the pextp registers and
this driver is based on a GPL licensed implementation found in
MediaTek's SDK.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 MAINTAINERS                          |   1 +
 drivers/phy/mediatek/Kconfig         |  11 +
 drivers/phy/mediatek/Makefile        |   1 +
 drivers/phy/mediatek/phy-mtk-pextp.c | 355 +++++++++++++++++++++++++++
 4 files changed, 368 insertions(+)
 create mode 100644 drivers/phy/mediatek/phy-mtk-pextp.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 7b151710e8c58..6499acd8f3874 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13527,6 +13527,7 @@ L:	netdev@vger.kernel.org
 S:	Maintained
 F:	drivers/net/phy/mediatek-ge-soc.c
 F:	drivers/net/phy/mediatek-ge.c
+F:	drivers/phy/mediatek/phy-mediatek-pextp.c
 
 MEDIATEK I2C CONTROLLER DRIVER
 M:	Qii Wang <qii.wang@mediatek.com>
diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig
index 3125ecb5d119f..a7749a6d96541 100644
--- a/drivers/phy/mediatek/Kconfig
+++ b/drivers/phy/mediatek/Kconfig
@@ -13,6 +13,17 @@ config PHY_MTK_PCIE
 	  callback for PCIe GEN3 port, it supports software efuse
 	  initialization.
 
+config PHY_MTK_PEXTP
+	tristate "MediaTek PEXTP Driver"
+	depends on ARCH_MEDIATEK || COMPILE_TEST
+	depends on OF && OF_ADDRESS
+	depends on HAS_IOMEM
+	select GENERIC_PHY
+	help
+	  Say 'Y' here to add support for MediaTek pextp PHY driver.
+	  The driver provides access to the Ethernet SerDes PHY supporting
+	  various 1GE, 2.5GE, 5GE and 10GE modes.
+
 config PHY_MTK_TPHY
 	tristate "MediaTek T-PHY Driver"
 	depends on ARCH_MEDIATEK || COMPILE_TEST
diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
index c9a50395533eb..ca60c7b9b02ac 100644
--- a/drivers/phy/mediatek/Makefile
+++ b/drivers/phy/mediatek/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_MTK_PCIE)		+= phy-mtk-pcie.o
 obj-$(CONFIG_PHY_MTK_TPHY)		+= phy-mtk-tphy.o
 obj-$(CONFIG_PHY_MTK_UFS)		+= phy-mtk-ufs.o
 obj-$(CONFIG_PHY_MTK_XSPHY)		+= phy-mtk-xsphy.o
+obj-$(CONFIG_PHY_MTK_PEXTP)		+= phy-mtk-pextp.o
 
 phy-mtk-hdmi-drv-y			:= phy-mtk-hdmi.o
 phy-mtk-hdmi-drv-y			+= phy-mtk-hdmi-mt2701.o
diff --git a/drivers/phy/mediatek/phy-mtk-pextp.c b/drivers/phy/mediatek/phy-mtk-pextp.c
new file mode 100644
index 0000000000000..272bff4f37a96
--- /dev/null
+++ b/drivers/phy/mediatek/phy-mtk-pextp.c
@@ -0,0 +1,355 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/* MediaTek 10GE SerDes PHY driver
+ *
+ * Copyright (c) 2023 Daniel Golle <daniel@makrotopia.org>
+ * based on mtk_usxgmii.c found in MediaTek's SDK released under GPL-2.0
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Henry Yen <henry.yen@mediatek.com>
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/netdevice.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <linux/reset.h>
+#include <linux/phy.h>
+#include <linux/phy/phy.h>
+
+struct mtk_pextp_phy {
+	void __iomem		*base;
+	struct device		*dev;
+	struct reset_control	*reset;
+	struct clk		*clk;
+	bool			da_war;
+};
+
+static inline bool mtk_interface_mode_is_xgmii(phy_interface_t interface)
+{
+	switch (interface) {
+	case PHY_INTERFACE_MODE_INTERNAL:
+	case PHY_INTERFACE_MODE_USXGMII:
+	case PHY_INTERFACE_MODE_10GBASER:
+	case PHY_INTERFACE_MODE_5GBASER:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static void mtk_pextp_setup(struct mtk_pextp_phy *pextp, phy_interface_t interface)
+{
+	bool is_10g = (interface == PHY_INTERFACE_MODE_10GBASER ||
+		       interface == PHY_INTERFACE_MODE_USXGMII);
+	bool is_2p5g = (interface == PHY_INTERFACE_MODE_2500BASEX);
+	bool is_5g = (interface == PHY_INTERFACE_MODE_5GBASER);
+
+	dev_dbg(pextp->dev, "setting up for mode %s\n", phy_modes(interface));
+
+	/* Setup operation mode */
+	if (is_10g)
+		iowrite32(0x00C9071C, pextp->base + 0x9024);
+	else
+		iowrite32(0x00D9071C, pextp->base + 0x9024);
+
+	if (is_5g)
+		iowrite32(0xAAA5A5AA, pextp->base + 0x2020);
+	else
+		iowrite32(0xAA8585AA, pextp->base + 0x2020);
+
+	if (is_2p5g || is_5g || is_10g) {
+		iowrite32(0x0C020707, pextp->base + 0x2030);
+		iowrite32(0x0E050F0F, pextp->base + 0x2034);
+		iowrite32(0x00140032, pextp->base + 0x2040);
+	} else {
+		iowrite32(0x0C020207, pextp->base + 0x2030);
+		iowrite32(0x0E05050F, pextp->base + 0x2034);
+		iowrite32(0x00200032, pextp->base + 0x2040);
+	}
+
+	if (is_2p5g || is_10g)
+		iowrite32(0x00C014AA, pextp->base + 0x50F0);
+	else if (is_5g)
+		iowrite32(0x00C018AA, pextp->base + 0x50F0);
+	else
+		iowrite32(0x00C014BA, pextp->base + 0x50F0);
+
+	if (is_5g) {
+		iowrite32(0x3777812B, pextp->base + 0x50E0);
+		iowrite32(0x005C9CFF, pextp->base + 0x506C);
+		iowrite32(0x9DFAFAFA, pextp->base + 0x5070);
+		iowrite32(0x273F3F3F, pextp->base + 0x5074);
+		iowrite32(0xA8883868, pextp->base + 0x5078);
+		iowrite32(0x14661466, pextp->base + 0x507C);
+	} else {
+		iowrite32(0x3777C12B, pextp->base + 0x50E0);
+		iowrite32(0x005F9CFF, pextp->base + 0x506C);
+		iowrite32(0x9D9DFAFA, pextp->base + 0x5070);
+		iowrite32(0x27273F3F, pextp->base + 0x5074);
+		iowrite32(0xA7883C68, pextp->base + 0x5078);
+		iowrite32(0x11661166, pextp->base + 0x507C);
+	}
+
+	if (is_2p5g || is_10g) {
+		iowrite32(0x0E000AAF, pextp->base + 0x5080);
+		iowrite32(0x08080D0D, pextp->base + 0x5084);
+		iowrite32(0x02030909, pextp->base + 0x5088);
+	} else if (is_5g) {
+		iowrite32(0x0E001ABF, pextp->base + 0x5080);
+		iowrite32(0x080B0D0D, pextp->base + 0x5084);
+		iowrite32(0x02050909, pextp->base + 0x5088);
+	} else {
+		iowrite32(0x0E000EAF, pextp->base + 0x5080);
+		iowrite32(0x08080E0D, pextp->base + 0x5084);
+		iowrite32(0x02030B09, pextp->base + 0x5088);
+	}
+
+	if (is_5g) {
+		iowrite32(0x0C000000, pextp->base + 0x50E4);
+		iowrite32(0x04000000, pextp->base + 0x50E8);
+	} else {
+		iowrite32(0x0C0C0000, pextp->base + 0x50E4);
+		iowrite32(0x04040000, pextp->base + 0x50E8);
+	}
+
+	if (is_2p5g || mtk_interface_mode_is_xgmii(interface))
+		iowrite32(0x0F0F0C06, pextp->base + 0x50EC);
+	else
+		iowrite32(0x0F0F0606, pextp->base + 0x50EC);
+
+	if (is_5g) {
+		iowrite32(0x50808C8C, pextp->base + 0x50A8);
+		iowrite32(0x18000000, pextp->base + 0x6004);
+	} else {
+		iowrite32(0x506E8C8C, pextp->base + 0x50A8);
+		iowrite32(0x18190000, pextp->base + 0x6004);
+	}
+
+	if (is_10g)
+		iowrite32(0x01423342, pextp->base + 0x00F8);
+	else if (is_5g)
+		iowrite32(0x00A132A1, pextp->base + 0x00F8);
+	else if (is_2p5g)
+		iowrite32(0x009C329C, pextp->base + 0x00F8);
+	else
+		iowrite32(0x00FA32FA, pextp->base + 0x00F8);
+
+	/* Force SGDT_OUT off and select PCS */
+	if (mtk_interface_mode_is_xgmii(interface))
+		iowrite32(0x80201F20, pextp->base + 0x00F4);
+	else
+		iowrite32(0x80201F21, pextp->base + 0x00F4);
+
+	/* Force GLB_CKDET_OUT */
+	iowrite32(0x00050C00, pextp->base + 0x0030);
+
+	/* Force AEQ on */
+	iowrite32(0x02002800, pextp->base + 0x0070);
+	ndelay(1020);
+
+	/* Setup DA default value */
+	iowrite32(0x00000020, pextp->base + 0x30B0);
+	iowrite32(0x00008A01, pextp->base + 0x3028);
+	iowrite32(0x0000A884, pextp->base + 0x302C);
+	iowrite32(0x00083002, pextp->base + 0x3024);
+	if (mtk_interface_mode_is_xgmii(interface)) {
+		iowrite32(0x00022220, pextp->base + 0x3010);
+		iowrite32(0x0F020A01, pextp->base + 0x5064);
+		iowrite32(0x06100600, pextp->base + 0x50B4);
+		if (interface == PHY_INTERFACE_MODE_USXGMII)
+			iowrite32(0x40704000, pextp->base + 0x3048);
+		else
+			iowrite32(0x47684100, pextp->base + 0x3048);
+	} else {
+		iowrite32(0x00011110, pextp->base + 0x3010);
+		iowrite32(0x40704000, pextp->base + 0x3048);
+	}
+
+	if (!mtk_interface_mode_is_xgmii(interface) && !is_2p5g)
+		iowrite32(0x0000C000, pextp->base + 0x3064);
+
+	if (interface == PHY_INTERFACE_MODE_USXGMII) {
+		iowrite32(0xA8000000, pextp->base + 0x3050);
+		iowrite32(0x000000AA, pextp->base + 0x3054);
+	} else if (mtk_interface_mode_is_xgmii(interface)) {
+		iowrite32(0x00000000, pextp->base + 0x3050);
+		iowrite32(0x00000000, pextp->base + 0x3054);
+	} else {
+		iowrite32(0xA8000000, pextp->base + 0x3050);
+		iowrite32(0x000000AA, pextp->base + 0x3054);
+	}
+
+	if (mtk_interface_mode_is_xgmii(interface))
+		iowrite32(0x00000F00, pextp->base + 0x306C);
+	else if (is_2p5g)
+		iowrite32(0x22000F00, pextp->base + 0x306C);
+	else
+		iowrite32(0x20200F00, pextp->base + 0x306C);
+
+	if (interface == PHY_INTERFACE_MODE_10GBASER && pextp->da_war)
+		iowrite32(0x0007B400, pextp->base + 0xA008);
+
+	if (mtk_interface_mode_is_xgmii(interface))
+		iowrite32(0x00040000, pextp->base + 0xA060);
+	else
+		iowrite32(0x00050000, pextp->base + 0xA060);
+
+	if (is_10g)
+		iowrite32(0x00000001, pextp->base + 0x90D0);
+	else if (is_5g)
+		iowrite32(0x00000003, pextp->base + 0x90D0);
+	else if (is_2p5g)
+		iowrite32(0x00000005, pextp->base + 0x90D0);
+	else
+		iowrite32(0x00000007, pextp->base + 0x90D0);
+
+	/* Release reset */
+	iowrite32(0x0200E800, pextp->base + 0x0070);
+	usleep_range(150, 500);
+
+	/* Switch to P0 */
+	iowrite32(0x0200C111, pextp->base + 0x0070);
+	ndelay(1020);
+	iowrite32(0x0200C101, pextp->base + 0x0070);
+	usleep_range(15, 50);
+
+	if (mtk_interface_mode_is_xgmii(interface)) {
+		/* Switch to Gen3 */
+		iowrite32(0x0202C111, pextp->base + 0x0070);
+	} else {
+		/* Switch to Gen2 */
+		iowrite32(0x0201C111, pextp->base + 0x0070);
+	}
+	ndelay(1020);
+	if (mtk_interface_mode_is_xgmii(interface))
+		iowrite32(0x0202C101, pextp->base + 0x0070);
+	else
+		iowrite32(0x0201C101, pextp->base + 0x0070);
+	usleep_range(100, 500);
+	iowrite32(0x00000030, pextp->base + 0x30B0);
+	if (mtk_interface_mode_is_xgmii(interface))
+		iowrite32(0x80201F00, pextp->base + 0x00F4);
+	else
+		iowrite32(0x80201F01, pextp->base + 0x00F4);
+
+	iowrite32(0x30000000, pextp->base + 0x3040);
+	usleep_range(400, 1000);
+}
+
+static int mtk_pextp_set_mode(struct phy *phy, enum phy_mode mode, int submode)
+{
+	struct mtk_pextp_phy *pextp = phy_get_drvdata(phy);
+
+	if (mode != PHY_MODE_ETHERNET)
+		return -EINVAL;
+
+	switch (submode) {
+	case PHY_INTERFACE_MODE_1000BASEX:
+	case PHY_INTERFACE_MODE_2500BASEX:
+	case PHY_INTERFACE_MODE_SGMII:
+	case PHY_INTERFACE_MODE_5GBASER:
+	case PHY_INTERFACE_MODE_10GBASER:
+	case PHY_INTERFACE_MODE_USXGMII:
+		mtk_pextp_setup(pextp, submode);
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+static int mtk_pextp_reset(struct phy *phy)
+{
+	struct mtk_pextp_phy *pextp = phy_get_drvdata(phy);
+
+	reset_control_assert(pextp->reset);
+	usleep_range(100, 500);
+	reset_control_deassert(pextp->reset);
+	mdelay(10);
+
+	return 0;
+}
+
+static int mtk_pextp_power_on(struct phy *phy)
+{
+	struct mtk_pextp_phy *pextp = phy_get_drvdata(phy);
+
+	return clk_prepare_enable(pextp->clk);
+}
+
+static int mtk_pextp_power_off(struct phy *phy)
+{
+	struct mtk_pextp_phy *pextp = phy_get_drvdata(phy);
+
+	clk_disable_unprepare(pextp->clk);
+
+	return 0;
+}
+
+static const struct phy_ops mtk_pextp_ops = {
+	.power_on	= mtk_pextp_power_on,
+	.power_off	= mtk_pextp_power_off,
+	.set_mode	= mtk_pextp_set_mode,
+	.reset		= mtk_pextp_reset,
+	.owner		= THIS_MODULE,
+};
+
+static int mtk_pextp_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct phy_provider *phy_provider;
+	struct mtk_pextp_phy *pextp;
+	struct phy *phy;
+
+	if (!np)
+		return -ENODEV;
+
+	pextp = devm_kzalloc(&pdev->dev, sizeof(*pextp), GFP_KERNEL);
+	if (!pextp)
+		return -ENOMEM;
+
+	pextp->base = devm_of_iomap(&pdev->dev, np, 0, NULL);
+	if (!pextp->base)
+		return -EIO;
+
+	pextp->dev = &pdev->dev;
+	pextp->clk = devm_clk_get(&pdev->dev, NULL);
+	if (IS_ERR(pextp->clk))
+		return PTR_ERR(pextp->clk);
+
+	pextp->reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
+	if (IS_ERR(pextp->reset))
+		return PTR_ERR(pextp->reset);
+
+	pextp->da_war = of_property_read_bool(np, "mediatek,usxgmii-performance-errata");
+
+	phy = devm_phy_create(&pdev->dev, NULL, &mtk_pextp_ops);
+	if (IS_ERR(phy))
+		return PTR_ERR(phy);
+
+	phy_set_drvdata(phy, pextp);
+
+	phy_provider = devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate);
+
+	return PTR_ERR_OR_ZERO(phy_provider);
+}
+
+static const struct of_device_id mtk_pextp_match[] = {
+	{ .compatible = "mediatek,mt7988-xfi-pextp", },
+	{ }
+};
+MODULE_DEVICE_TABLE(of, mtk_pextp_match);
+
+static struct platform_driver mtk_pextp_driver = {
+	.probe = mtk_pextp_probe,
+	.driver = {
+		.name = "mtk-pextp",
+		.of_match_table = mtk_pextp_match,
+	},
+};
+module_platform_driver(mtk_pextp_driver);
+
+MODULE_DESCRIPTION("MediaTek pextp SerDes PHY driver");
+MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
+MODULE_LICENSE("GPL");
-- 
2.42.1

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* [RFC PATCH 3/8] net: pcs: pcs-mtk-lynxi: use 2500Base-X without AN
  2023-11-09 21:50 ` Daniel Golle
  (?)
@ 2023-11-09 21:51   ` Daniel Golle
  -1 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 21:51 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Daniel Golle, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

Using 2500Base-T SFP modules e.g. on the BananaPi R3 requires manually
disabling auto-negotiation, e.g. using ethtool. While a proper fix
using SFP quirks is being discussed upstream, bring a work-around to
restore user experience to what it was before the switch to the
dedicated SGMII PCS driver.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 drivers/net/pcs/pcs-mtk-lynxi.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/net/pcs/pcs-mtk-lynxi.c b/drivers/net/pcs/pcs-mtk-lynxi.c
index 8501dd365279b..6204448d8eac6 100644
--- a/drivers/net/pcs/pcs-mtk-lynxi.c
+++ b/drivers/net/pcs/pcs-mtk-lynxi.c
@@ -92,14 +92,23 @@ static void mtk_pcs_lynxi_get_state(struct phylink_pcs *pcs,
 				    struct phylink_link_state *state)
 {
 	struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
-	unsigned int bm, adv;
+	unsigned int bm, bmsr, adv;
 
 	/* Read the BMSR and LPA */
 	regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm);
-	regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
+	bmsr = FIELD_GET(SGMII_BMSR, bm);
+
+	if (state->interface == PHY_INTERFACE_MODE_2500BASEX) {
+		state->link = !!(bmsr & BMSR_LSTATUS);
+		state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);
+		state->speed = SPEED_2500;
+		state->duplex = DUPLEX_FULL;
+
+		return;
+	}
 
-	phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm),
-					 FIELD_GET(SGMII_LPA, adv));
+	regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
+	phylink_mii_c22_pcs_decode_state(state, bmsr, FIELD_GET(SGMII_LPA, adv));
 }
 
 static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode,
@@ -129,7 +138,8 @@ static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode,
 	if (neg_mode & PHYLINK_PCS_NEG_INBAND)
 		sgm_mode |= SGMII_REMOTE_FAULT_DIS;
 
-	if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
+	if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED &&
+	    interface != PHY_INTERFACE_MODE_2500BASEX) {
 		if (interface == PHY_INTERFACE_MODE_SGMII)
 			sgm_mode |= SGMII_SPEED_DUPLEX_AN;
 		bmcr = BMCR_ANENABLE;
-- 
2.42.1

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

* [RFC PATCH 3/8] net: pcs: pcs-mtk-lynxi: use 2500Base-X without AN
@ 2023-11-09 21:51   ` Daniel Golle
  0 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 21:51 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Daniel Golle, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

Using 2500Base-T SFP modules e.g. on the BananaPi R3 requires manually
disabling auto-negotiation, e.g. using ethtool. While a proper fix
using SFP quirks is being discussed upstream, bring a work-around to
restore user experience to what it was before the switch to the
dedicated SGMII PCS driver.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 drivers/net/pcs/pcs-mtk-lynxi.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/net/pcs/pcs-mtk-lynxi.c b/drivers/net/pcs/pcs-mtk-lynxi.c
index 8501dd365279b..6204448d8eac6 100644
--- a/drivers/net/pcs/pcs-mtk-lynxi.c
+++ b/drivers/net/pcs/pcs-mtk-lynxi.c
@@ -92,14 +92,23 @@ static void mtk_pcs_lynxi_get_state(struct phylink_pcs *pcs,
 				    struct phylink_link_state *state)
 {
 	struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
-	unsigned int bm, adv;
+	unsigned int bm, bmsr, adv;
 
 	/* Read the BMSR and LPA */
 	regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm);
-	regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
+	bmsr = FIELD_GET(SGMII_BMSR, bm);
+
+	if (state->interface == PHY_INTERFACE_MODE_2500BASEX) {
+		state->link = !!(bmsr & BMSR_LSTATUS);
+		state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);
+		state->speed = SPEED_2500;
+		state->duplex = DUPLEX_FULL;
+
+		return;
+	}
 
-	phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm),
-					 FIELD_GET(SGMII_LPA, adv));
+	regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
+	phylink_mii_c22_pcs_decode_state(state, bmsr, FIELD_GET(SGMII_LPA, adv));
 }
 
 static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode,
@@ -129,7 +138,8 @@ static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode,
 	if (neg_mode & PHYLINK_PCS_NEG_INBAND)
 		sgm_mode |= SGMII_REMOTE_FAULT_DIS;
 
-	if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
+	if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED &&
+	    interface != PHY_INTERFACE_MODE_2500BASEX) {
 		if (interface == PHY_INTERFACE_MODE_SGMII)
 			sgm_mode |= SGMII_SPEED_DUPLEX_AN;
 		bmcr = BMCR_ANENABLE;
-- 
2.42.1

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [RFC PATCH 3/8] net: pcs: pcs-mtk-lynxi: use 2500Base-X without AN
@ 2023-11-09 21:51   ` Daniel Golle
  0 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 21:51 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Daniel Golle, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

Using 2500Base-T SFP modules e.g. on the BananaPi R3 requires manually
disabling auto-negotiation, e.g. using ethtool. While a proper fix
using SFP quirks is being discussed upstream, bring a work-around to
restore user experience to what it was before the switch to the
dedicated SGMII PCS driver.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 drivers/net/pcs/pcs-mtk-lynxi.c | 20 +++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/drivers/net/pcs/pcs-mtk-lynxi.c b/drivers/net/pcs/pcs-mtk-lynxi.c
index 8501dd365279b..6204448d8eac6 100644
--- a/drivers/net/pcs/pcs-mtk-lynxi.c
+++ b/drivers/net/pcs/pcs-mtk-lynxi.c
@@ -92,14 +92,23 @@ static void mtk_pcs_lynxi_get_state(struct phylink_pcs *pcs,
 				    struct phylink_link_state *state)
 {
 	struct mtk_pcs_lynxi *mpcs = pcs_to_mtk_pcs_lynxi(pcs);
-	unsigned int bm, adv;
+	unsigned int bm, bmsr, adv;
 
 	/* Read the BMSR and LPA */
 	regmap_read(mpcs->regmap, SGMSYS_PCS_CONTROL_1, &bm);
-	regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
+	bmsr = FIELD_GET(SGMII_BMSR, bm);
+
+	if (state->interface == PHY_INTERFACE_MODE_2500BASEX) {
+		state->link = !!(bmsr & BMSR_LSTATUS);
+		state->an_complete = !!(bmsr & BMSR_ANEGCOMPLETE);
+		state->speed = SPEED_2500;
+		state->duplex = DUPLEX_FULL;
+
+		return;
+	}
 
-	phylink_mii_c22_pcs_decode_state(state, FIELD_GET(SGMII_BMSR, bm),
-					 FIELD_GET(SGMII_LPA, adv));
+	regmap_read(mpcs->regmap, SGMSYS_PCS_ADVERTISE, &adv);
+	phylink_mii_c22_pcs_decode_state(state, bmsr, FIELD_GET(SGMII_LPA, adv));
 }
 
 static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode,
@@ -129,7 +138,8 @@ static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode,
 	if (neg_mode & PHYLINK_PCS_NEG_INBAND)
 		sgm_mode |= SGMII_REMOTE_FAULT_DIS;
 
-	if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
+	if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED &&
+	    interface != PHY_INTERFACE_MODE_2500BASEX) {
 		if (interface == PHY_INTERFACE_MODE_SGMII)
 			sgm_mode |= SGMII_SPEED_DUPLEX_AN;
 		bmcr = BMCR_ANENABLE;
-- 
2.42.1

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* [RFC PATCH 4/8] net: pcs: pcs-mtk-lynxi: allow calling with NULL advertising
  2023-11-09 21:50 ` Daniel Golle
  (?)
@ 2023-11-09 21:51   ` Daniel Golle
  -1 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 21:51 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Daniel Golle, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

Allow calling pcs_config with advertising set to NULL and in this case
keep the previously assigned advertisement.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 drivers/net/pcs/pcs-mtk-lynxi.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/net/pcs/pcs-mtk-lynxi.c b/drivers/net/pcs/pcs-mtk-lynxi.c
index 6204448d8eac6..1372653c3d422 100644
--- a/drivers/net/pcs/pcs-mtk-lynxi.c
+++ b/drivers/net/pcs/pcs-mtk-lynxi.c
@@ -81,6 +81,7 @@ struct mtk_pcs_lynxi {
 	phy_interface_t		interface;
 	struct			phylink_pcs pcs;
 	u32			flags;
+	int			advertise;
 };
 
 static struct mtk_pcs_lynxi *pcs_to_mtk_pcs_lynxi(struct phylink_pcs *pcs)
@@ -121,11 +122,19 @@ static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode,
 	unsigned int rgc3, sgm_mode, bmcr;
 	int advertise, link_timer;
 
-	advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
-							     advertising);
-	if (advertise < 0)
-		return advertise;
+	if (advertising) {
+		advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
+								     advertising);
+		if (advertise < 0)
+			return advertise;
 
+		mpcs->advertise = advertise;
+	} else {
+		if (mpcs->advertise < 0)
+			return -EINVAL;
+
+		advertise = mpcs->advertise;
+	}
 	/* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and
 	 * we assume that fixes it's speed at bitrate = line rate (in
 	 * other words, 1000Mbps or 2500Mbps).
@@ -299,6 +308,7 @@ struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev,
 	mpcs->pcs.neg_mode = true;
 	mpcs->pcs.poll = true;
 	mpcs->interface = PHY_INTERFACE_MODE_NA;
+	mpcs->advertise = -1;
 
 	return &mpcs->pcs;
 }
-- 
2.42.1

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

* [RFC PATCH 4/8] net: pcs: pcs-mtk-lynxi: allow calling with NULL advertising
@ 2023-11-09 21:51   ` Daniel Golle
  0 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 21:51 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Daniel Golle, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

Allow calling pcs_config with advertising set to NULL and in this case
keep the previously assigned advertisement.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 drivers/net/pcs/pcs-mtk-lynxi.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/net/pcs/pcs-mtk-lynxi.c b/drivers/net/pcs/pcs-mtk-lynxi.c
index 6204448d8eac6..1372653c3d422 100644
--- a/drivers/net/pcs/pcs-mtk-lynxi.c
+++ b/drivers/net/pcs/pcs-mtk-lynxi.c
@@ -81,6 +81,7 @@ struct mtk_pcs_lynxi {
 	phy_interface_t		interface;
 	struct			phylink_pcs pcs;
 	u32			flags;
+	int			advertise;
 };
 
 static struct mtk_pcs_lynxi *pcs_to_mtk_pcs_lynxi(struct phylink_pcs *pcs)
@@ -121,11 +122,19 @@ static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode,
 	unsigned int rgc3, sgm_mode, bmcr;
 	int advertise, link_timer;
 
-	advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
-							     advertising);
-	if (advertise < 0)
-		return advertise;
+	if (advertising) {
+		advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
+								     advertising);
+		if (advertise < 0)
+			return advertise;
 
+		mpcs->advertise = advertise;
+	} else {
+		if (mpcs->advertise < 0)
+			return -EINVAL;
+
+		advertise = mpcs->advertise;
+	}
 	/* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and
 	 * we assume that fixes it's speed at bitrate = line rate (in
 	 * other words, 1000Mbps or 2500Mbps).
@@ -299,6 +308,7 @@ struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev,
 	mpcs->pcs.neg_mode = true;
 	mpcs->pcs.poll = true;
 	mpcs->interface = PHY_INTERFACE_MODE_NA;
+	mpcs->advertise = -1;
 
 	return &mpcs->pcs;
 }
-- 
2.42.1

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [RFC PATCH 4/8] net: pcs: pcs-mtk-lynxi: allow calling with NULL advertising
@ 2023-11-09 21:51   ` Daniel Golle
  0 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 21:51 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Daniel Golle, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

Allow calling pcs_config with advertising set to NULL and in this case
keep the previously assigned advertisement.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 drivers/net/pcs/pcs-mtk-lynxi.c | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/net/pcs/pcs-mtk-lynxi.c b/drivers/net/pcs/pcs-mtk-lynxi.c
index 6204448d8eac6..1372653c3d422 100644
--- a/drivers/net/pcs/pcs-mtk-lynxi.c
+++ b/drivers/net/pcs/pcs-mtk-lynxi.c
@@ -81,6 +81,7 @@ struct mtk_pcs_lynxi {
 	phy_interface_t		interface;
 	struct			phylink_pcs pcs;
 	u32			flags;
+	int			advertise;
 };
 
 static struct mtk_pcs_lynxi *pcs_to_mtk_pcs_lynxi(struct phylink_pcs *pcs)
@@ -121,11 +122,19 @@ static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode,
 	unsigned int rgc3, sgm_mode, bmcr;
 	int advertise, link_timer;
 
-	advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
-							     advertising);
-	if (advertise < 0)
-		return advertise;
+	if (advertising) {
+		advertise = phylink_mii_c22_pcs_encode_advertisement(interface,
+								     advertising);
+		if (advertise < 0)
+			return advertise;
 
+		mpcs->advertise = advertise;
+	} else {
+		if (mpcs->advertise < 0)
+			return -EINVAL;
+
+		advertise = mpcs->advertise;
+	}
 	/* Clearing IF_MODE_BIT0 switches the PCS to BASE-X mode, and
 	 * we assume that fixes it's speed at bitrate = line rate (in
 	 * other words, 1000Mbps or 2500Mbps).
@@ -299,6 +308,7 @@ struct phylink_pcs *mtk_pcs_lynxi_create(struct device *dev,
 	mpcs->pcs.neg_mode = true;
 	mpcs->pcs.poll = true;
 	mpcs->interface = PHY_INTERFACE_MODE_NA;
+	mpcs->advertise = -1;
 
 	return &mpcs->pcs;
 }
-- 
2.42.1

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* [RFC PATCH 5/8] dt-bindings: net: pcs: add bindings for MediaTek USXGMII PCS
  2023-11-09 21:50 ` Daniel Golle
  (?)
@ 2023-11-09 21:51   ` Daniel Golle
  -1 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 21:51 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Daniel Golle, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

MediaTek's USXGMII can be found in the MT7988 SoC. We need to access
it in order to configure and monitor the Ethernet SerDes link in
USXGMII, 10GBase-R and 5GBase-R mode. By including a wrapped
legacy 1000Base-X/2500Base-X/Cisco SGMII LynxI PCS as well, those
interface modes are also available.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 .../bindings/net/pcs/mediatek,usxgmii.yaml    | 105 ++++++++++++++++++
 1 file changed, 105 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml

diff --git a/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml b/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
new file mode 100644
index 0000000000000..199cf47859e31
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
@@ -0,0 +1,105 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/pcs/mediatek,usxgmii.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek USXGMII PCS
+
+maintainers:
+  - Daniel Golle <daniel@makrotopia.org>
+
+description:
+  The MediaTek USXGMII PCS provides physical link control and status
+  for USXGMII, 10GBase-R and 5GBase-R links on the SerDes interfaces
+  provided by the PEXTP PHY.
+  In order to also support legacy 2500Base-X, 1000Base-X and Cisco
+  SGMII an existing mediatek,*-sgmiisys LynxI PCS is wrapped to
+  provide those interfaces modes on the same SerDes interfaces shared
+  with the USXGMII PCS.
+
+properties:
+  $nodename:
+    pattern: "^pcs@[0-9a-f]+$"
+
+  compatible:
+    const: mediatek,mt7988-usxgmiisys
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: USXGMII top-level clock
+      - description: SGMII top-level clock
+      - description: SGMII subsystem TX clock
+      - description: SGMII subsystem RX clock
+      - description: XFI PLL clock
+
+  clock-names:
+    items:
+      - const: usxgmii
+      - const: sgmii_sel
+      - const: sgmii_tx
+      - const: sgmii_rx
+      - const: xfi_pll
+
+  phys:
+    items:
+      - description: PEXTP SerDes PHY
+
+  mediatek,sgmiisys:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to the syscon node of the corresponding SGMII LynxI PCS.
+
+  resets:
+    items:
+      - description: XFI reset
+      - description: SGMII reset
+
+  reset-names:
+    items:
+      - const: xfi
+      - const: sgmii
+
+  "#pcs-cells":
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - phys
+  - mediatek,sgmiisys
+  - resets
+  - reset-names
+  - "#pcs-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mediatek,mt7988-clk.h>
+    #include <dt-bindings/reset/mediatek,mt7988-resets.h>
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+        usxgmiisys0: pcs@10080000 {
+          compatible = "mediatek,mt7988-usxgmiisys";
+          reg = <0 0x10080000 0 0x1000>;
+          clocks = <&topckgen CLK_TOP_USXGMII_SBUS_0_SEL>,
+                   <&topckgen CLK_TOP_SGM_0_SEL>,
+                   <&sgmiisys0 CLK_SGM0_TX_EN>,
+                   <&sgmiisys0 CLK_SGM0_RX_EN>,
+                   <&xfi_pll CLK_XFIPLL_PLL_EN>;
+          clock-names = "usxgmii", "sgmii_sel", "sgmii_tx", "sgmii_rx", "xfi_pll";
+          resets = <&watchdog MT7988_TOPRGU_XFI0_GRST>,
+                   <&watchdog MT7988_TOPRGU_SGMII0_GRST>;
+          reset-names = "xfi", "sgmii";
+          phys = <&xfi_pextp0>;
+          mediatek,sgmiisys = <&sgmiisys0>;
+          #pcs-cells = <0>;
+        };
+    };
-- 
2.42.1

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

* [RFC PATCH 5/8] dt-bindings: net: pcs: add bindings for MediaTek USXGMII PCS
@ 2023-11-09 21:51   ` Daniel Golle
  0 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 21:51 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Daniel Golle, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

MediaTek's USXGMII can be found in the MT7988 SoC. We need to access
it in order to configure and monitor the Ethernet SerDes link in
USXGMII, 10GBase-R and 5GBase-R mode. By including a wrapped
legacy 1000Base-X/2500Base-X/Cisco SGMII LynxI PCS as well, those
interface modes are also available.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 .../bindings/net/pcs/mediatek,usxgmii.yaml    | 105 ++++++++++++++++++
 1 file changed, 105 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml

diff --git a/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml b/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
new file mode 100644
index 0000000000000..199cf47859e31
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
@@ -0,0 +1,105 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/pcs/mediatek,usxgmii.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek USXGMII PCS
+
+maintainers:
+  - Daniel Golle <daniel@makrotopia.org>
+
+description:
+  The MediaTek USXGMII PCS provides physical link control and status
+  for USXGMII, 10GBase-R and 5GBase-R links on the SerDes interfaces
+  provided by the PEXTP PHY.
+  In order to also support legacy 2500Base-X, 1000Base-X and Cisco
+  SGMII an existing mediatek,*-sgmiisys LynxI PCS is wrapped to
+  provide those interfaces modes on the same SerDes interfaces shared
+  with the USXGMII PCS.
+
+properties:
+  $nodename:
+    pattern: "^pcs@[0-9a-f]+$"
+
+  compatible:
+    const: mediatek,mt7988-usxgmiisys
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: USXGMII top-level clock
+      - description: SGMII top-level clock
+      - description: SGMII subsystem TX clock
+      - description: SGMII subsystem RX clock
+      - description: XFI PLL clock
+
+  clock-names:
+    items:
+      - const: usxgmii
+      - const: sgmii_sel
+      - const: sgmii_tx
+      - const: sgmii_rx
+      - const: xfi_pll
+
+  phys:
+    items:
+      - description: PEXTP SerDes PHY
+
+  mediatek,sgmiisys:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to the syscon node of the corresponding SGMII LynxI PCS.
+
+  resets:
+    items:
+      - description: XFI reset
+      - description: SGMII reset
+
+  reset-names:
+    items:
+      - const: xfi
+      - const: sgmii
+
+  "#pcs-cells":
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - phys
+  - mediatek,sgmiisys
+  - resets
+  - reset-names
+  - "#pcs-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mediatek,mt7988-clk.h>
+    #include <dt-bindings/reset/mediatek,mt7988-resets.h>
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+        usxgmiisys0: pcs@10080000 {
+          compatible = "mediatek,mt7988-usxgmiisys";
+          reg = <0 0x10080000 0 0x1000>;
+          clocks = <&topckgen CLK_TOP_USXGMII_SBUS_0_SEL>,
+                   <&topckgen CLK_TOP_SGM_0_SEL>,
+                   <&sgmiisys0 CLK_SGM0_TX_EN>,
+                   <&sgmiisys0 CLK_SGM0_RX_EN>,
+                   <&xfi_pll CLK_XFIPLL_PLL_EN>;
+          clock-names = "usxgmii", "sgmii_sel", "sgmii_tx", "sgmii_rx", "xfi_pll";
+          resets = <&watchdog MT7988_TOPRGU_XFI0_GRST>,
+                   <&watchdog MT7988_TOPRGU_SGMII0_GRST>;
+          reset-names = "xfi", "sgmii";
+          phys = <&xfi_pextp0>;
+          mediatek,sgmiisys = <&sgmiisys0>;
+          #pcs-cells = <0>;
+        };
+    };
-- 
2.42.1

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [RFC PATCH 5/8] dt-bindings: net: pcs: add bindings for MediaTek USXGMII PCS
@ 2023-11-09 21:51   ` Daniel Golle
  0 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 21:51 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Daniel Golle, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

MediaTek's USXGMII can be found in the MT7988 SoC. We need to access
it in order to configure and monitor the Ethernet SerDes link in
USXGMII, 10GBase-R and 5GBase-R mode. By including a wrapped
legacy 1000Base-X/2500Base-X/Cisco SGMII LynxI PCS as well, those
interface modes are also available.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 .../bindings/net/pcs/mediatek,usxgmii.yaml    | 105 ++++++++++++++++++
 1 file changed, 105 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml

diff --git a/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml b/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
new file mode 100644
index 0000000000000..199cf47859e31
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
@@ -0,0 +1,105 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/pcs/mediatek,usxgmii.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek USXGMII PCS
+
+maintainers:
+  - Daniel Golle <daniel@makrotopia.org>
+
+description:
+  The MediaTek USXGMII PCS provides physical link control and status
+  for USXGMII, 10GBase-R and 5GBase-R links on the SerDes interfaces
+  provided by the PEXTP PHY.
+  In order to also support legacy 2500Base-X, 1000Base-X and Cisco
+  SGMII an existing mediatek,*-sgmiisys LynxI PCS is wrapped to
+  provide those interfaces modes on the same SerDes interfaces shared
+  with the USXGMII PCS.
+
+properties:
+  $nodename:
+    pattern: "^pcs@[0-9a-f]+$"
+
+  compatible:
+    const: mediatek,mt7988-usxgmiisys
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: USXGMII top-level clock
+      - description: SGMII top-level clock
+      - description: SGMII subsystem TX clock
+      - description: SGMII subsystem RX clock
+      - description: XFI PLL clock
+
+  clock-names:
+    items:
+      - const: usxgmii
+      - const: sgmii_sel
+      - const: sgmii_tx
+      - const: sgmii_rx
+      - const: xfi_pll
+
+  phys:
+    items:
+      - description: PEXTP SerDes PHY
+
+  mediatek,sgmiisys:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to the syscon node of the corresponding SGMII LynxI PCS.
+
+  resets:
+    items:
+      - description: XFI reset
+      - description: SGMII reset
+
+  reset-names:
+    items:
+      - const: xfi
+      - const: sgmii
+
+  "#pcs-cells":
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - phys
+  - mediatek,sgmiisys
+  - resets
+  - reset-names
+  - "#pcs-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/mediatek,mt7988-clk.h>
+    #include <dt-bindings/reset/mediatek,mt7988-resets.h>
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+        usxgmiisys0: pcs@10080000 {
+          compatible = "mediatek,mt7988-usxgmiisys";
+          reg = <0 0x10080000 0 0x1000>;
+          clocks = <&topckgen CLK_TOP_USXGMII_SBUS_0_SEL>,
+                   <&topckgen CLK_TOP_SGM_0_SEL>,
+                   <&sgmiisys0 CLK_SGM0_TX_EN>,
+                   <&sgmiisys0 CLK_SGM0_RX_EN>,
+                   <&xfi_pll CLK_XFIPLL_PLL_EN>;
+          clock-names = "usxgmii", "sgmii_sel", "sgmii_tx", "sgmii_rx", "xfi_pll";
+          resets = <&watchdog MT7988_TOPRGU_XFI0_GRST>,
+                   <&watchdog MT7988_TOPRGU_SGMII0_GRST>;
+          reset-names = "xfi", "sgmii";
+          phys = <&xfi_pextp0>;
+          mediatek,sgmiisys = <&sgmiisys0>;
+          #pcs-cells = <0>;
+        };
+    };
-- 
2.42.1

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* [RFC PATCH 6/8] net: pcs: add driver for MediaTek USXGMII PCS
  2023-11-09 21:50 ` Daniel Golle
  (?)
@ 2023-11-09 21:51   ` Daniel Golle
  -1 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 21:51 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Daniel Golle, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

Add driver for USXGMII PCS found in the MediaTek MT7988 SoC and supporting
USXGMII, 10GBase-R and 5GBase-R interface modes. In order to support
Cisco SGMII, 1000Base-X and 2500Base-X via the also present LynxI PCS
create a wrapped PCS taking care of the components shared between the
new USXGMII PCS and the legacy LynxI PCS.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 MAINTAINERS                         |   2 +
 drivers/net/pcs/Kconfig             |  10 +
 drivers/net/pcs/Makefile            |   1 +
 drivers/net/pcs/pcs-mtk-usxgmii.c   | 688 ++++++++++++++++++++++++++++
 include/linux/pcs/pcs-mtk-usxgmii.h |  18 +
 5 files changed, 719 insertions(+)
 create mode 100644 drivers/net/pcs/pcs-mtk-usxgmii.c
 create mode 100644 include/linux/pcs/pcs-mtk-usxgmii.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 6499acd8f3874..026f62243f595 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13517,7 +13517,9 @@ M:	Daniel Golle <daniel@makrotopia.org>
 L:	netdev@vger.kernel.org
 S:	Maintained
 F:	drivers/net/pcs/pcs-mtk-lynxi.c
+F:	drivers/net/pcs/pcs-mtk-usxgmii.c
 F:	include/linux/pcs/pcs-mtk-lynxi.h
+F:	include/linux/pcs/pcs-mtk-usxgmii.h
 
 MEDIATEK ETHERNET PHY DRIVERS
 M:	Daniel Golle <daniel@makrotopia.org>
diff --git a/drivers/net/pcs/Kconfig b/drivers/net/pcs/Kconfig
index 87cf308fc6d8b..5df5b19c4eb93 100644
--- a/drivers/net/pcs/Kconfig
+++ b/drivers/net/pcs/Kconfig
@@ -25,6 +25,16 @@ config PCS_MTK_LYNXI
 	  This module provides helpers to phylink for managing the LynxI PCS
 	  which is part of MediaTek's SoC and Ethernet switch ICs.
 
+config PCS_MTK_USXGMII
+	tristate "MediaTek USXGMII PCS"
+	select PCS_MTK_LYNXI
+	select PHY_MTK_PEXTP
+	help
+	  This module provides a driver for MediaTek's USXGMII PCS supporting
+	  10GBase-R, 5GBase-R and USXGMII interface modes.
+	  1000Base-X, 2500Base-X and Cisco SGMII are supported on the same
+	  differential pairs via an embedded LynxI PHY.
+
 config PCS_RZN1_MIIC
 	tristate "Renesas RZ/N1 MII converter"
 	depends on OF && (ARCH_RZN1 || COMPILE_TEST)
diff --git a/drivers/net/pcs/Makefile b/drivers/net/pcs/Makefile
index fb1694192ae63..cc355152ca1ca 100644
--- a/drivers/net/pcs/Makefile
+++ b/drivers/net/pcs/Makefile
@@ -6,4 +6,5 @@ pcs_xpcs-$(CONFIG_PCS_XPCS)	:= pcs-xpcs.o pcs-xpcs-nxp.o pcs-xpcs-wx.o
 obj-$(CONFIG_PCS_XPCS)		+= pcs_xpcs.o
 obj-$(CONFIG_PCS_LYNX)		+= pcs-lynx.o
 obj-$(CONFIG_PCS_MTK_LYNXI)	+= pcs-mtk-lynxi.o
+obj-$(CONFIG_PCS_MTK_USXGMII)	+= pcs-mtk-usxgmii.o
 obj-$(CONFIG_PCS_RZN1_MIIC)	+= pcs-rzn1-miic.o
diff --git a/drivers/net/pcs/pcs-mtk-usxgmii.c b/drivers/net/pcs/pcs-mtk-usxgmii.c
new file mode 100644
index 0000000000000..b3ca66c9df2a9
--- /dev/null
+++ b/drivers/net/pcs/pcs-mtk-usxgmii.c
@@ -0,0 +1,688 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023 MediaTek Inc.
+ * Author: Henry Yen <henry.yen@mediatek.com>
+ *         Daniel Golle <daniel@makrotopia.org>
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mdio.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/pcs/pcs-mtk-lynxi.h>
+#include <linux/pcs/pcs-mtk-usxgmii.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+
+/* USXGMII subsystem config registers */
+/* Register to control speed */
+#define RG_PHY_TOP_SPEED_CTRL1			0x80c
+#define USXGMII_RATE_UPDATE_MODE		BIT(31)
+#define USXGMII_MAC_CK_GATED			BIT(29)
+#define USXGMII_IF_FORCE_EN			BIT(28)
+#define USXGMII_RATE_ADAPT_MODE			GENMASK(10, 8)
+#define USXGMII_RATE_ADAPT_MODE_X1		0
+#define USXGMII_RATE_ADAPT_MODE_X2		1
+#define USXGMII_RATE_ADAPT_MODE_X4		2
+#define USXGMII_RATE_ADAPT_MODE_X10		3
+#define USXGMII_RATE_ADAPT_MODE_X100		4
+#define USXGMII_RATE_ADAPT_MODE_X5		5
+#define USXGMII_RATE_ADAPT_MODE_X50		6
+#define USXGMII_XFI_RX_MODE			GENMASK(6, 4)
+#define USXGMII_XFI_TX_MODE			GENMASK(2, 0)
+#define USXGMII_XFI_MODE_10G			0
+#define USXGMII_XFI_MODE_5G			1
+#define USXGMII_XFI_MODE_2P5G			3
+
+/* Register to control PCS AN */
+#define RG_PCS_AN_CTRL0				0x810
+#define USXGMII_AN_RESTART			BIT(31)
+#define USXGMII_AN_SYNC_CNT			GENMASK(30, 11)
+#define USXGMII_AN_ENABLE			BIT(0)
+
+#define RG_PCS_AN_CTRL2				0x818
+#define USXGMII_LINK_TIMER_IDLE_DETECT		GENMASK(29, 20)
+#define USXGMII_LINK_TIMER_COMP_ACK_DETECT	GENMASK(19, 10)
+#define USXGMII_LINK_TIMER_AN_RESTART		GENMASK(9, 0)
+
+/* Register to read PCS AN status */
+#define RG_PCS_AN_STS0				0x81c
+#define USXGMII_LPA				GENMASK(15, 0)
+#define USXGMII_LPA_LATCH			BIT(31)
+
+/* Register to read PCS link status */
+#define RG_PCS_RX_STATUS0			0x904
+#define RG_PCS_RX_STATUS_UPDATE			BIT(16)
+#define RG_PCS_RX_LINK_STATUS			BIT(2)
+
+#define MTK_NETSYS_V3_AMA_RGC3			0x128
+
+/* struct mtk_usxgmii_pcs - This structure holds each usxgmii PCS
+ * @pcs:		Phylink PCS structure
+ * @dev:		Pointer to device structure
+ * @base:		IO memory to access PCS hardware
+ * @clk:		Pointer to USXGMII clk
+ * @xfi_pll:		Pointer to XFI PLL clk
+ * @pextp:		The PHYA instance attached to the PCS
+ * @reset:		Pointer to USXGMII reset control
+ * @interface:		Currently selected interface mode
+ * @neg_mode:		Currently used phylink neg_mode
+ */
+struct mtk_usxgmii_pcs {
+	struct phylink_pcs		pcs;
+	struct phylink_pcs		*sgmii_pcs;
+	struct device			*dev;
+	void __iomem			*base;
+	struct clk			*clk;
+	struct clk			*xfi_pll;
+	struct phy			*pextp;
+	struct reset_control		*reset;
+	struct regmap			*regmap_pll;
+	phy_interface_t			interface;
+	unsigned int			neg_mode;
+};
+
+/* struct mtk_sgmii_wrapper_pcs - Structure holding wrapped SGMII PCS
+ * @usxgmii_pcs		Pointer to owning mtk_usxgmii_pcs structure
+ * @pcs			Phylink PCS structure
+ * @clks:		Pointers to 3 SGMII clks
+ * @reset:		Pointer to SGMII reset control
+ * @interface:		Currently selected interface mode
+ * @neg_mode:		Currently used phylink neg_mode
+ */
+struct mtk_sgmii_wrapper_pcs {
+	struct mtk_usxgmii_pcs		*usxgmii_pcs;
+	struct phylink_pcs		*lynxi_pcs;
+	struct phylink_pcs		pcs;
+	struct clk			*clks[3];
+	struct reset_control		*reset;
+	phy_interface_t			interface;
+	unsigned int			neg_mode;
+	bool				permit_pause_to_mac;
+};
+
+static u32 mtk_r32(struct mtk_usxgmii_pcs *mpcs, unsigned int reg)
+{
+	return ioread32(mpcs->base + reg);
+}
+
+static void mtk_m32(struct mtk_usxgmii_pcs *mpcs, unsigned int reg, u32 mask, u32 set)
+{
+	u32 val;
+
+	val = ioread32(mpcs->base + reg);
+	val &= ~mask;
+	val |= set;
+	iowrite32(val, mpcs->base + reg);
+}
+
+static struct mtk_usxgmii_pcs *pcs_to_mtk_usxgmii_pcs(struct phylink_pcs *pcs)
+{
+	return container_of(pcs, struct mtk_usxgmii_pcs, pcs);
+}
+
+static int mtk_xfi_pextp_init(struct mtk_usxgmii_pcs *mpcs)
+{
+	struct device *dev = mpcs->dev;
+
+	mpcs->pextp = devm_phy_get(dev, NULL);
+	if (IS_ERR(mpcs->pextp))
+		return dev_err_probe(dev, PTR_ERR(mpcs->pextp), "cannot acquire PHYA\n");
+
+	if (!mpcs->pextp)
+		return dev_err_probe(dev, -ENODEV, "PHYA not found\n");
+
+	return 0;
+}
+
+static void mtk_usxgmii_reset(struct mtk_usxgmii_pcs *mpcs)
+{
+	if (!mpcs->pextp)
+		return;
+
+	phy_reset(mpcs->pextp);
+
+	reset_control_assert(mpcs->reset);
+	usleep_range(100, 500);
+	reset_control_deassert(mpcs->reset);
+
+	mdelay(10);
+}
+
+static void mtk_sgmii_reset(struct mtk_sgmii_wrapper_pcs *wp)
+{
+	if (!wp->usxgmii_pcs->pextp)
+		return;
+
+	phy_reset(wp->usxgmii_pcs->pextp);
+
+	reset_control_assert(wp->reset);
+	usleep_range(100, 500);
+	reset_control_deassert(wp->reset);
+
+	mdelay(10);
+}
+
+static int mtk_sgmii_wrapped_pcs_config(struct phylink_pcs *pcs,
+					unsigned int neg_mode,
+					phy_interface_t interface,
+					const unsigned long *advertising,
+					bool permit_pause_to_mac)
+{
+	struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
+	bool full_reconf;
+	int ret;
+
+	phy_power_on(wp->usxgmii_pcs->pextp);
+
+	full_reconf = (interface != wp->interface);
+	if (full_reconf)
+		mtk_sgmii_reset(wp);
+
+	ret = wp->lynxi_pcs->ops->pcs_config(wp->lynxi_pcs, neg_mode, interface, advertising,
+					     permit_pause_to_mac);
+
+	if (full_reconf)
+		phy_set_mode_ext(wp->usxgmii_pcs->pextp, PHY_MODE_ETHERNET, interface);
+
+	wp->interface = interface;
+	wp->neg_mode = neg_mode;
+	wp->permit_pause_to_mac = permit_pause_to_mac;
+
+	return ret;
+}
+
+static void mtk_sgmii_wrapped_pcs_get_state(struct phylink_pcs *pcs,
+					    struct phylink_link_state *state)
+{
+	struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
+
+	wp->lynxi_pcs->ops->pcs_get_state(wp->lynxi_pcs, state);
+
+	/* Continuously repeat re-configuration sequence until link comes up */
+	if (!state->link)
+		mtk_sgmii_wrapped_pcs_config(pcs, wp->neg_mode, state->interface,
+					     NULL, wp->permit_pause_to_mac);
+}
+
+static void mtk_sgmii_wrapped_pcs_an_restart(struct phylink_pcs *pcs)
+{
+	struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
+
+	wp->lynxi_pcs->ops->pcs_an_restart(wp->lynxi_pcs);
+}
+
+static void mtk_sgmii_wrapped_pcs_link_up(struct phylink_pcs *pcs,
+					  unsigned int neg_mode,
+					  phy_interface_t interface, int speed,
+					  int duplex)
+{
+	struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
+
+	wp->lynxi_pcs->ops->pcs_link_up(wp->lynxi_pcs, neg_mode, interface, speed, duplex);
+}
+
+static void mtk_sgmii_wrapped_pcs_disable(struct phylink_pcs *pcs)
+{
+	struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
+
+	wp->lynxi_pcs->ops->pcs_disable(wp->lynxi_pcs);
+	wp->interface = PHY_INTERFACE_MODE_NA;
+	wp->neg_mode = -1;
+}
+
+static int mtk_sgmii_wrapped_pcs_enable(struct phylink_pcs *pcs)
+{
+	struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
+
+	if (wp->lynxi_pcs->ops->pcs_enable)
+		wp->lynxi_pcs->ops->pcs_enable(wp->lynxi_pcs);
+
+	wp->interface = PHY_INTERFACE_MODE_NA;
+	wp->neg_mode = -1;
+
+	phy_power_on(wp->usxgmii_pcs->pextp);
+
+	return 0;
+}
+
+static const struct phylink_pcs_ops mtk_sgmii_wrapped_pcs_ops = {
+	.pcs_get_state = mtk_sgmii_wrapped_pcs_get_state,
+	.pcs_config = mtk_sgmii_wrapped_pcs_config,
+	.pcs_an_restart = mtk_sgmii_wrapped_pcs_an_restart,
+	.pcs_link_up = mtk_sgmii_wrapped_pcs_link_up,
+	.pcs_disable = mtk_sgmii_wrapped_pcs_disable,
+	.pcs_enable = mtk_sgmii_wrapped_pcs_enable,
+};
+
+static int mtk_sgmii_wrapper_init(struct mtk_usxgmii_pcs *mpcs)
+{
+	struct device_node *r = mpcs->dev->of_node, *np;
+	struct mtk_sgmii_wrapper_pcs *wp;
+	struct phylink_pcs *lynxi_pcs;
+	struct reset_control *rstc;
+	struct regmap *regmap;
+	struct clk *sgmii_sel, *sgmii_rx, *sgmii_tx;
+
+	np = of_parse_phandle(r, "mediatek,sgmiisys", 0);
+	if (!np)
+		return -ENODEV;
+
+	regmap = syscon_node_to_regmap(np);
+	of_node_put(np);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	rstc = of_reset_control_get_shared(r, "sgmii");
+
+	if (IS_ERR(rstc))
+		return PTR_ERR(rstc);
+
+	sgmii_sel = devm_clk_get_enabled(mpcs->dev, "sgmii_sel");
+	if (IS_ERR(sgmii_sel))
+		return PTR_ERR(sgmii_sel);
+
+	sgmii_rx = devm_clk_get_enabled(mpcs->dev, "sgmii_rx");
+	if (IS_ERR(sgmii_rx))
+		return PTR_ERR(sgmii_rx);
+
+	sgmii_tx = devm_clk_get_enabled(mpcs->dev, "sgmii_tx");
+	if (IS_ERR(sgmii_tx))
+		return PTR_ERR(sgmii_tx);
+
+	lynxi_pcs = mtk_pcs_lynxi_create(mpcs->dev, regmap, MTK_NETSYS_V3_AMA_RGC3, 0);
+
+	if (IS_ERR(lynxi_pcs))
+		return PTR_ERR(lynxi_pcs);
+
+	if (!lynxi_pcs)
+		return -ENODEV;
+
+	/* Make sure all PCS ops are supported by wrapped PCS */
+	if (!lynxi_pcs->ops->pcs_get_state ||
+	    !lynxi_pcs->ops->pcs_config ||
+	    !lynxi_pcs->ops->pcs_an_restart ||
+	    !lynxi_pcs->ops->pcs_link_up ||
+	    !lynxi_pcs->ops->pcs_disable)
+		return -EOPNOTSUPP;
+
+	wp = devm_kzalloc(mpcs->dev, sizeof(*wp), GFP_KERNEL);
+	if (!wp)
+		return -ENOMEM;
+
+	wp->pcs.neg_mode = lynxi_pcs->neg_mode;
+	wp->pcs.ops = &mtk_sgmii_wrapped_pcs_ops;
+	wp->pcs.poll = true;
+	wp->lynxi_pcs = lynxi_pcs;
+	wp->usxgmii_pcs = mpcs;
+	wp->clks[0] = sgmii_sel;
+	wp->clks[1] = sgmii_rx;
+	wp->clks[2] = sgmii_tx;
+	wp->reset = rstc;
+	wp->interface = PHY_INTERFACE_MODE_NA;
+	wp->neg_mode = -1;
+
+	if (IS_ERR(wp->reset))
+		return PTR_ERR(wp->reset);
+
+	reset_control_deassert(wp->reset);
+
+	mpcs->sgmii_pcs = &wp->pcs;
+
+	return 0;
+}
+
+static void mtk_sgmii_wrapper_destroy(struct mtk_usxgmii_pcs *mpcs)
+{
+	struct mtk_sgmii_wrapper_pcs *wp = container_of(mpcs->sgmii_pcs,
+							struct mtk_sgmii_wrapper_pcs,
+							pcs);
+
+	mtk_pcs_lynxi_destroy(wp->lynxi_pcs);
+	reset_control_put(wp->reset);
+}
+
+static int mtk_usxgmii_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
+				  phy_interface_t interface,
+				  const unsigned long *advertising,
+				  bool permit_pause_to_mac)
+{
+	struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
+	unsigned int an_ctrl = 0, link_timer = 0, xfi_mode = 0, adapt_mode = 0;
+	bool mode_changed = false;
+
+	if (interface == PHY_INTERFACE_MODE_USXGMII) {
+		an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF) | USXGMII_AN_ENABLE;
+		link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) |
+			     FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) |
+			     FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B);
+		xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_MODE_10G) |
+			   FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_MODE_10G);
+	} else if (interface == PHY_INTERFACE_MODE_10GBASER) {
+		an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF);
+		link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) |
+			     FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) |
+			     FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B);
+		xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_MODE_10G) |
+			   FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_MODE_10G);
+		adapt_mode = USXGMII_RATE_UPDATE_MODE;
+	} else if (interface == PHY_INTERFACE_MODE_5GBASER) {
+		an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0xFF);
+		link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x3D) |
+			     FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x3D) |
+			     FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x3D);
+		xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_MODE_5G) |
+			   FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_MODE_5G);
+		adapt_mode = USXGMII_RATE_UPDATE_MODE;
+	} else {
+		return -EINVAL;
+	}
+
+	adapt_mode |= FIELD_PREP(USXGMII_RATE_ADAPT_MODE, USXGMII_RATE_ADAPT_MODE_X1);
+
+	if (mpcs->interface != interface) {
+		mpcs->interface = interface;
+		mode_changed = true;
+	}
+
+	phy_power_on(mpcs->pextp);
+	mtk_usxgmii_reset(mpcs);
+
+	/* Setup USXGMII AN ctrl */
+	mtk_m32(mpcs, RG_PCS_AN_CTRL0,
+		USXGMII_AN_SYNC_CNT | USXGMII_AN_ENABLE,
+		an_ctrl);
+
+	mtk_m32(mpcs, RG_PCS_AN_CTRL2,
+		USXGMII_LINK_TIMER_IDLE_DETECT |
+		USXGMII_LINK_TIMER_COMP_ACK_DETECT |
+		USXGMII_LINK_TIMER_AN_RESTART,
+		link_timer);
+
+	mpcs->neg_mode = neg_mode;
+
+	/* Gated MAC CK */
+	mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1,
+		USXGMII_MAC_CK_GATED, USXGMII_MAC_CK_GATED);
+
+	/* Enable interface force mode */
+	mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1,
+		USXGMII_IF_FORCE_EN, USXGMII_IF_FORCE_EN);
+
+	/* Setup USXGMII adapt mode */
+	mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1,
+		USXGMII_RATE_UPDATE_MODE | USXGMII_RATE_ADAPT_MODE,
+		adapt_mode);
+
+	/* Setup USXGMII speed */
+	mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1,
+		USXGMII_XFI_RX_MODE | USXGMII_XFI_TX_MODE,
+		xfi_mode);
+
+	usleep_range(1, 10);
+
+	/* Un-gated MAC CK */
+	mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1, USXGMII_MAC_CK_GATED, 0);
+
+	usleep_range(1, 10);
+
+	/* Disable interface force mode for the AN mode */
+	if (an_ctrl & USXGMII_AN_ENABLE)
+		mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1, USXGMII_IF_FORCE_EN, 0);
+
+	/* Setup PHY for interface mode */
+	phy_set_mode_ext(mpcs->pextp, PHY_MODE_ETHERNET, interface);
+
+	return mode_changed;
+}
+
+static void mtk_usxgmii_pcs_get_fixed_speed(struct mtk_usxgmii_pcs *mpcs,
+					    struct phylink_link_state *state)
+{
+	u32 val = mtk_r32(mpcs, RG_PHY_TOP_SPEED_CTRL1);
+	int speed;
+
+	/* Calculate speed from interface speed and rate adapt mode */
+	switch (FIELD_GET(USXGMII_XFI_RX_MODE, val)) {
+	case USXGMII_XFI_MODE_10G:
+		speed = 10000;
+		break;
+	case USXGMII_XFI_MODE_5G:
+		speed = 5000;
+		break;
+	case USXGMII_XFI_MODE_2P5G:
+		speed = 2500;
+		break;
+	default:
+		state->speed = SPEED_UNKNOWN;
+		return;
+	}
+
+	switch (FIELD_GET(USXGMII_RATE_ADAPT_MODE, val)) {
+	case USXGMII_RATE_ADAPT_MODE_X100:
+		speed /= 100;
+		break;
+	case USXGMII_RATE_ADAPT_MODE_X50:
+		speed /= 50;
+		break;
+	case USXGMII_RATE_ADAPT_MODE_X10:
+		speed /= 10;
+		break;
+	case USXGMII_RATE_ADAPT_MODE_X5:
+		speed /= 5;
+		break;
+	case USXGMII_RATE_ADAPT_MODE_X4:
+		speed /= 4;
+		break;
+	case USXGMII_RATE_ADAPT_MODE_X2:
+		speed /= 2;
+		break;
+	case USXGMII_RATE_ADAPT_MODE_X1:
+		break;
+	default:
+		state->speed = SPEED_UNKNOWN;
+		return;
+	}
+
+	state->speed = speed;
+	state->duplex = DUPLEX_FULL;
+}
+
+static void mtk_usxgmii_pcs_get_an_state(struct mtk_usxgmii_pcs *mpcs,
+					 struct phylink_link_state *state)
+{
+	u16 lpa;
+
+	/* Refresh LPA by toggling LPA_LATCH */
+	mtk_m32(mpcs, RG_PCS_AN_STS0, USXGMII_LPA_LATCH, USXGMII_LPA_LATCH);
+	ndelay(1020);
+	mtk_m32(mpcs, RG_PCS_AN_STS0, USXGMII_LPA_LATCH, 0);
+	ndelay(1020);
+	lpa = FIELD_GET(USXGMII_LPA, mtk_r32(mpcs, RG_PCS_AN_STS0));
+
+	phylink_decode_usxgmii_word(state, lpa);
+}
+
+static void mtk_usxgmii_pcs_get_state(struct phylink_pcs *pcs,
+				      struct phylink_link_state *state)
+{
+	struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
+
+	/* Refresh USXGMII link status by toggling RG_PCS_AN_STATUS_UPDATE */
+	mtk_m32(mpcs, RG_PCS_RX_STATUS0, RG_PCS_RX_STATUS_UPDATE,
+		RG_PCS_RX_STATUS_UPDATE);
+	ndelay(1020);
+	mtk_m32(mpcs, RG_PCS_RX_STATUS0, RG_PCS_RX_STATUS_UPDATE, 0);
+	ndelay(1020);
+
+	/* Read USXGMII link status */
+	state->link = FIELD_GET(RG_PCS_RX_LINK_STATUS,
+				mtk_r32(mpcs, RG_PCS_RX_STATUS0));
+
+	/* Continuously repeat re-configuration sequence until link comes up */
+	if (!state->link) {
+		mtk_usxgmii_pcs_config(pcs, mpcs->neg_mode,
+				       state->interface, NULL, false);
+		return;
+	}
+
+	if (FIELD_GET(USXGMII_AN_ENABLE, mtk_r32(mpcs, RG_PCS_AN_CTRL0)))
+		mtk_usxgmii_pcs_get_an_state(mpcs, state);
+	else
+		mtk_usxgmii_pcs_get_fixed_speed(mpcs, state);
+}
+
+static void mtk_usxgmii_pcs_restart_an(struct phylink_pcs *pcs)
+{
+	struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
+
+	mtk_m32(mpcs, RG_PCS_AN_CTRL0, USXGMII_AN_RESTART, USXGMII_AN_RESTART);
+}
+
+static void mtk_usxgmii_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode,
+				    phy_interface_t interface,
+				    int speed, int duplex)
+{
+	/* Reconfiguring USXGMII to ensure the quality of the RX signal
+	 * after the line side link up.
+	 */
+	mtk_usxgmii_pcs_config(pcs, neg_mode, interface, NULL, false);
+}
+
+static void mtk_usxgmii_pcs_disable(struct phylink_pcs *pcs)
+{
+	struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
+
+	mpcs->interface = PHY_INTERFACE_MODE_NA;
+	mpcs->neg_mode = -1;
+}
+
+static const struct phylink_pcs_ops mtk_usxgmii_pcs_ops = {
+	.pcs_config = mtk_usxgmii_pcs_config,
+	.pcs_get_state = mtk_usxgmii_pcs_get_state,
+	.pcs_an_restart = mtk_usxgmii_pcs_restart_an,
+	.pcs_link_up = mtk_usxgmii_pcs_link_up,
+	.pcs_disable = mtk_usxgmii_pcs_disable,
+};
+
+static int mtk_usxgmii_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_usxgmii_pcs *mpcs;
+	int ret;
+
+	mpcs = devm_kzalloc(dev, sizeof(*mpcs), GFP_KERNEL);
+	if (!mpcs)
+		return -ENOMEM;
+
+	mpcs->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(mpcs->base))
+		return PTR_ERR(mpcs->base);
+
+	mpcs->dev = dev;
+	mpcs->pcs.ops = &mtk_usxgmii_pcs_ops;
+	mpcs->pcs.poll = true;
+	mpcs->pcs.neg_mode = true;
+	mpcs->interface = PHY_INTERFACE_MODE_NA;
+	mpcs->neg_mode = -1;
+
+	mpcs->clk = devm_clk_get_enabled(mpcs->dev, "usxgmii");
+	if (IS_ERR(mpcs->clk))
+		return PTR_ERR(mpcs->clk);
+
+	mpcs->xfi_pll = devm_clk_get_enabled(mpcs->dev, "xfi_pll");
+	if (IS_ERR(mpcs->xfi_pll))
+		return PTR_ERR(mpcs->xfi_pll);
+
+	mpcs->reset = devm_reset_control_get_shared(dev, "xfi");
+	if (IS_ERR(mpcs->reset))
+		return PTR_ERR(mpcs->reset);
+
+	reset_control_deassert(mpcs->reset);
+
+	ret = mtk_xfi_pextp_init(mpcs);
+	if (ret)
+		return ret;
+
+	ret = mtk_sgmii_wrapper_init(mpcs);
+	if (ret)
+		return ret;
+
+	platform_set_drvdata(pdev, mpcs);
+
+	return 0;
+}
+
+static int mtk_usxgmii_remove(struct platform_device *pdev)
+{
+	struct mtk_usxgmii_pcs *mpcs = platform_get_drvdata(pdev);
+
+	mtk_sgmii_wrapper_destroy(mpcs);
+	phy_power_off(mpcs->pextp);
+
+	return 0;
+}
+
+static const struct of_device_id mtk_usxgmii_of_mtable[] = {
+	{ .compatible = "mediatek,mt7988-usxgmiisys" },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mtk_usxgmii_of_mtable);
+
+struct phylink_pcs *mtk_usxgmii_select_pcs(struct device_node *np, phy_interface_t mode)
+{
+	struct platform_device *pdev;
+	struct mtk_usxgmii_pcs *mpcs;
+
+	if (!np)
+		return NULL;
+
+	if (!of_device_is_available(np))
+		return ERR_PTR(-ENODEV);
+
+	if (!of_match_node(mtk_usxgmii_of_mtable, np))
+		return ERR_PTR(-EINVAL);
+
+	pdev = of_find_device_by_node(np);
+	if (!pdev || !platform_get_drvdata(pdev)) {
+		if (pdev)
+			put_device(&pdev->dev);
+		return ERR_PTR(-EPROBE_DEFER);
+	}
+
+	mpcs = platform_get_drvdata(pdev);
+	put_device(&pdev->dev);
+
+	switch (mode) {
+	case PHY_INTERFACE_MODE_1000BASEX:
+	case PHY_INTERFACE_MODE_2500BASEX:
+	case PHY_INTERFACE_MODE_SGMII:
+		return mpcs->sgmii_pcs;
+	case PHY_INTERFACE_MODE_5GBASER:
+	case PHY_INTERFACE_MODE_10GBASER:
+	case PHY_INTERFACE_MODE_USXGMII:
+		return &mpcs->pcs;
+	default:
+		return NULL;
+	}
+}
+EXPORT_SYMBOL(mtk_usxgmii_select_pcs);
+
+static struct platform_driver mtk_usxgmii_driver = {
+	.driver = {
+		.name			= "mtk_usxgmii",
+		.suppress_bind_attrs	= true,
+		.of_match_table		= mtk_usxgmii_of_mtable,
+	},
+	.probe = mtk_usxgmii_probe,
+	.remove = mtk_usxgmii_remove,
+};
+module_platform_driver(mtk_usxgmii_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MediaTek USXGMII PCS driver");
+MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
diff --git a/include/linux/pcs/pcs-mtk-usxgmii.h b/include/linux/pcs/pcs-mtk-usxgmii.h
new file mode 100644
index 0000000000000..7a3c49760ffa6
--- /dev/null
+++ b/include/linux/pcs/pcs-mtk-usxgmii.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LINUX_PCS_MTK_USXGMII_H
+#define __LINUX_PCS_MTK_USXGMII_H
+
+#include <linux/phylink.h>
+
+/**
+ * mtk_usxgmii_select_pcs
+ * Return PCS indentified by a device node and the PHY interface mode in use
+ *
+ * @param np	Pointer to device node indentifying a MediaTek USXGMII PCS
+ * @param mode	Ethernet PHY interface mode
+ *
+ * @return	Pointer to phylink PCS instance of NULL
+ */
+struct phylink_pcs *mtk_usxgmii_select_pcs(struct device_node *np, phy_interface_t mode);
+
+#endif /* __LINUX_PCS_MTK_USXGMII_H */
-- 
2.42.1

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

* [RFC PATCH 6/8] net: pcs: add driver for MediaTek USXGMII PCS
@ 2023-11-09 21:51   ` Daniel Golle
  0 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 21:51 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Daniel Golle, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

Add driver for USXGMII PCS found in the MediaTek MT7988 SoC and supporting
USXGMII, 10GBase-R and 5GBase-R interface modes. In order to support
Cisco SGMII, 1000Base-X and 2500Base-X via the also present LynxI PCS
create a wrapped PCS taking care of the components shared between the
new USXGMII PCS and the legacy LynxI PCS.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 MAINTAINERS                         |   2 +
 drivers/net/pcs/Kconfig             |  10 +
 drivers/net/pcs/Makefile            |   1 +
 drivers/net/pcs/pcs-mtk-usxgmii.c   | 688 ++++++++++++++++++++++++++++
 include/linux/pcs/pcs-mtk-usxgmii.h |  18 +
 5 files changed, 719 insertions(+)
 create mode 100644 drivers/net/pcs/pcs-mtk-usxgmii.c
 create mode 100644 include/linux/pcs/pcs-mtk-usxgmii.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 6499acd8f3874..026f62243f595 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13517,7 +13517,9 @@ M:	Daniel Golle <daniel@makrotopia.org>
 L:	netdev@vger.kernel.org
 S:	Maintained
 F:	drivers/net/pcs/pcs-mtk-lynxi.c
+F:	drivers/net/pcs/pcs-mtk-usxgmii.c
 F:	include/linux/pcs/pcs-mtk-lynxi.h
+F:	include/linux/pcs/pcs-mtk-usxgmii.h
 
 MEDIATEK ETHERNET PHY DRIVERS
 M:	Daniel Golle <daniel@makrotopia.org>
diff --git a/drivers/net/pcs/Kconfig b/drivers/net/pcs/Kconfig
index 87cf308fc6d8b..5df5b19c4eb93 100644
--- a/drivers/net/pcs/Kconfig
+++ b/drivers/net/pcs/Kconfig
@@ -25,6 +25,16 @@ config PCS_MTK_LYNXI
 	  This module provides helpers to phylink for managing the LynxI PCS
 	  which is part of MediaTek's SoC and Ethernet switch ICs.
 
+config PCS_MTK_USXGMII
+	tristate "MediaTek USXGMII PCS"
+	select PCS_MTK_LYNXI
+	select PHY_MTK_PEXTP
+	help
+	  This module provides a driver for MediaTek's USXGMII PCS supporting
+	  10GBase-R, 5GBase-R and USXGMII interface modes.
+	  1000Base-X, 2500Base-X and Cisco SGMII are supported on the same
+	  differential pairs via an embedded LynxI PHY.
+
 config PCS_RZN1_MIIC
 	tristate "Renesas RZ/N1 MII converter"
 	depends on OF && (ARCH_RZN1 || COMPILE_TEST)
diff --git a/drivers/net/pcs/Makefile b/drivers/net/pcs/Makefile
index fb1694192ae63..cc355152ca1ca 100644
--- a/drivers/net/pcs/Makefile
+++ b/drivers/net/pcs/Makefile
@@ -6,4 +6,5 @@ pcs_xpcs-$(CONFIG_PCS_XPCS)	:= pcs-xpcs.o pcs-xpcs-nxp.o pcs-xpcs-wx.o
 obj-$(CONFIG_PCS_XPCS)		+= pcs_xpcs.o
 obj-$(CONFIG_PCS_LYNX)		+= pcs-lynx.o
 obj-$(CONFIG_PCS_MTK_LYNXI)	+= pcs-mtk-lynxi.o
+obj-$(CONFIG_PCS_MTK_USXGMII)	+= pcs-mtk-usxgmii.o
 obj-$(CONFIG_PCS_RZN1_MIIC)	+= pcs-rzn1-miic.o
diff --git a/drivers/net/pcs/pcs-mtk-usxgmii.c b/drivers/net/pcs/pcs-mtk-usxgmii.c
new file mode 100644
index 0000000000000..b3ca66c9df2a9
--- /dev/null
+++ b/drivers/net/pcs/pcs-mtk-usxgmii.c
@@ -0,0 +1,688 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023 MediaTek Inc.
+ * Author: Henry Yen <henry.yen@mediatek.com>
+ *         Daniel Golle <daniel@makrotopia.org>
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mdio.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/pcs/pcs-mtk-lynxi.h>
+#include <linux/pcs/pcs-mtk-usxgmii.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+
+/* USXGMII subsystem config registers */
+/* Register to control speed */
+#define RG_PHY_TOP_SPEED_CTRL1			0x80c
+#define USXGMII_RATE_UPDATE_MODE		BIT(31)
+#define USXGMII_MAC_CK_GATED			BIT(29)
+#define USXGMII_IF_FORCE_EN			BIT(28)
+#define USXGMII_RATE_ADAPT_MODE			GENMASK(10, 8)
+#define USXGMII_RATE_ADAPT_MODE_X1		0
+#define USXGMII_RATE_ADAPT_MODE_X2		1
+#define USXGMII_RATE_ADAPT_MODE_X4		2
+#define USXGMII_RATE_ADAPT_MODE_X10		3
+#define USXGMII_RATE_ADAPT_MODE_X100		4
+#define USXGMII_RATE_ADAPT_MODE_X5		5
+#define USXGMII_RATE_ADAPT_MODE_X50		6
+#define USXGMII_XFI_RX_MODE			GENMASK(6, 4)
+#define USXGMII_XFI_TX_MODE			GENMASK(2, 0)
+#define USXGMII_XFI_MODE_10G			0
+#define USXGMII_XFI_MODE_5G			1
+#define USXGMII_XFI_MODE_2P5G			3
+
+/* Register to control PCS AN */
+#define RG_PCS_AN_CTRL0				0x810
+#define USXGMII_AN_RESTART			BIT(31)
+#define USXGMII_AN_SYNC_CNT			GENMASK(30, 11)
+#define USXGMII_AN_ENABLE			BIT(0)
+
+#define RG_PCS_AN_CTRL2				0x818
+#define USXGMII_LINK_TIMER_IDLE_DETECT		GENMASK(29, 20)
+#define USXGMII_LINK_TIMER_COMP_ACK_DETECT	GENMASK(19, 10)
+#define USXGMII_LINK_TIMER_AN_RESTART		GENMASK(9, 0)
+
+/* Register to read PCS AN status */
+#define RG_PCS_AN_STS0				0x81c
+#define USXGMII_LPA				GENMASK(15, 0)
+#define USXGMII_LPA_LATCH			BIT(31)
+
+/* Register to read PCS link status */
+#define RG_PCS_RX_STATUS0			0x904
+#define RG_PCS_RX_STATUS_UPDATE			BIT(16)
+#define RG_PCS_RX_LINK_STATUS			BIT(2)
+
+#define MTK_NETSYS_V3_AMA_RGC3			0x128
+
+/* struct mtk_usxgmii_pcs - This structure holds each usxgmii PCS
+ * @pcs:		Phylink PCS structure
+ * @dev:		Pointer to device structure
+ * @base:		IO memory to access PCS hardware
+ * @clk:		Pointer to USXGMII clk
+ * @xfi_pll:		Pointer to XFI PLL clk
+ * @pextp:		The PHYA instance attached to the PCS
+ * @reset:		Pointer to USXGMII reset control
+ * @interface:		Currently selected interface mode
+ * @neg_mode:		Currently used phylink neg_mode
+ */
+struct mtk_usxgmii_pcs {
+	struct phylink_pcs		pcs;
+	struct phylink_pcs		*sgmii_pcs;
+	struct device			*dev;
+	void __iomem			*base;
+	struct clk			*clk;
+	struct clk			*xfi_pll;
+	struct phy			*pextp;
+	struct reset_control		*reset;
+	struct regmap			*regmap_pll;
+	phy_interface_t			interface;
+	unsigned int			neg_mode;
+};
+
+/* struct mtk_sgmii_wrapper_pcs - Structure holding wrapped SGMII PCS
+ * @usxgmii_pcs		Pointer to owning mtk_usxgmii_pcs structure
+ * @pcs			Phylink PCS structure
+ * @clks:		Pointers to 3 SGMII clks
+ * @reset:		Pointer to SGMII reset control
+ * @interface:		Currently selected interface mode
+ * @neg_mode:		Currently used phylink neg_mode
+ */
+struct mtk_sgmii_wrapper_pcs {
+	struct mtk_usxgmii_pcs		*usxgmii_pcs;
+	struct phylink_pcs		*lynxi_pcs;
+	struct phylink_pcs		pcs;
+	struct clk			*clks[3];
+	struct reset_control		*reset;
+	phy_interface_t			interface;
+	unsigned int			neg_mode;
+	bool				permit_pause_to_mac;
+};
+
+static u32 mtk_r32(struct mtk_usxgmii_pcs *mpcs, unsigned int reg)
+{
+	return ioread32(mpcs->base + reg);
+}
+
+static void mtk_m32(struct mtk_usxgmii_pcs *mpcs, unsigned int reg, u32 mask, u32 set)
+{
+	u32 val;
+
+	val = ioread32(mpcs->base + reg);
+	val &= ~mask;
+	val |= set;
+	iowrite32(val, mpcs->base + reg);
+}
+
+static struct mtk_usxgmii_pcs *pcs_to_mtk_usxgmii_pcs(struct phylink_pcs *pcs)
+{
+	return container_of(pcs, struct mtk_usxgmii_pcs, pcs);
+}
+
+static int mtk_xfi_pextp_init(struct mtk_usxgmii_pcs *mpcs)
+{
+	struct device *dev = mpcs->dev;
+
+	mpcs->pextp = devm_phy_get(dev, NULL);
+	if (IS_ERR(mpcs->pextp))
+		return dev_err_probe(dev, PTR_ERR(mpcs->pextp), "cannot acquire PHYA\n");
+
+	if (!mpcs->pextp)
+		return dev_err_probe(dev, -ENODEV, "PHYA not found\n");
+
+	return 0;
+}
+
+static void mtk_usxgmii_reset(struct mtk_usxgmii_pcs *mpcs)
+{
+	if (!mpcs->pextp)
+		return;
+
+	phy_reset(mpcs->pextp);
+
+	reset_control_assert(mpcs->reset);
+	usleep_range(100, 500);
+	reset_control_deassert(mpcs->reset);
+
+	mdelay(10);
+}
+
+static void mtk_sgmii_reset(struct mtk_sgmii_wrapper_pcs *wp)
+{
+	if (!wp->usxgmii_pcs->pextp)
+		return;
+
+	phy_reset(wp->usxgmii_pcs->pextp);
+
+	reset_control_assert(wp->reset);
+	usleep_range(100, 500);
+	reset_control_deassert(wp->reset);
+
+	mdelay(10);
+}
+
+static int mtk_sgmii_wrapped_pcs_config(struct phylink_pcs *pcs,
+					unsigned int neg_mode,
+					phy_interface_t interface,
+					const unsigned long *advertising,
+					bool permit_pause_to_mac)
+{
+	struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
+	bool full_reconf;
+	int ret;
+
+	phy_power_on(wp->usxgmii_pcs->pextp);
+
+	full_reconf = (interface != wp->interface);
+	if (full_reconf)
+		mtk_sgmii_reset(wp);
+
+	ret = wp->lynxi_pcs->ops->pcs_config(wp->lynxi_pcs, neg_mode, interface, advertising,
+					     permit_pause_to_mac);
+
+	if (full_reconf)
+		phy_set_mode_ext(wp->usxgmii_pcs->pextp, PHY_MODE_ETHERNET, interface);
+
+	wp->interface = interface;
+	wp->neg_mode = neg_mode;
+	wp->permit_pause_to_mac = permit_pause_to_mac;
+
+	return ret;
+}
+
+static void mtk_sgmii_wrapped_pcs_get_state(struct phylink_pcs *pcs,
+					    struct phylink_link_state *state)
+{
+	struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
+
+	wp->lynxi_pcs->ops->pcs_get_state(wp->lynxi_pcs, state);
+
+	/* Continuously repeat re-configuration sequence until link comes up */
+	if (!state->link)
+		mtk_sgmii_wrapped_pcs_config(pcs, wp->neg_mode, state->interface,
+					     NULL, wp->permit_pause_to_mac);
+}
+
+static void mtk_sgmii_wrapped_pcs_an_restart(struct phylink_pcs *pcs)
+{
+	struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
+
+	wp->lynxi_pcs->ops->pcs_an_restart(wp->lynxi_pcs);
+}
+
+static void mtk_sgmii_wrapped_pcs_link_up(struct phylink_pcs *pcs,
+					  unsigned int neg_mode,
+					  phy_interface_t interface, int speed,
+					  int duplex)
+{
+	struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
+
+	wp->lynxi_pcs->ops->pcs_link_up(wp->lynxi_pcs, neg_mode, interface, speed, duplex);
+}
+
+static void mtk_sgmii_wrapped_pcs_disable(struct phylink_pcs *pcs)
+{
+	struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
+
+	wp->lynxi_pcs->ops->pcs_disable(wp->lynxi_pcs);
+	wp->interface = PHY_INTERFACE_MODE_NA;
+	wp->neg_mode = -1;
+}
+
+static int mtk_sgmii_wrapped_pcs_enable(struct phylink_pcs *pcs)
+{
+	struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
+
+	if (wp->lynxi_pcs->ops->pcs_enable)
+		wp->lynxi_pcs->ops->pcs_enable(wp->lynxi_pcs);
+
+	wp->interface = PHY_INTERFACE_MODE_NA;
+	wp->neg_mode = -1;
+
+	phy_power_on(wp->usxgmii_pcs->pextp);
+
+	return 0;
+}
+
+static const struct phylink_pcs_ops mtk_sgmii_wrapped_pcs_ops = {
+	.pcs_get_state = mtk_sgmii_wrapped_pcs_get_state,
+	.pcs_config = mtk_sgmii_wrapped_pcs_config,
+	.pcs_an_restart = mtk_sgmii_wrapped_pcs_an_restart,
+	.pcs_link_up = mtk_sgmii_wrapped_pcs_link_up,
+	.pcs_disable = mtk_sgmii_wrapped_pcs_disable,
+	.pcs_enable = mtk_sgmii_wrapped_pcs_enable,
+};
+
+static int mtk_sgmii_wrapper_init(struct mtk_usxgmii_pcs *mpcs)
+{
+	struct device_node *r = mpcs->dev->of_node, *np;
+	struct mtk_sgmii_wrapper_pcs *wp;
+	struct phylink_pcs *lynxi_pcs;
+	struct reset_control *rstc;
+	struct regmap *regmap;
+	struct clk *sgmii_sel, *sgmii_rx, *sgmii_tx;
+
+	np = of_parse_phandle(r, "mediatek,sgmiisys", 0);
+	if (!np)
+		return -ENODEV;
+
+	regmap = syscon_node_to_regmap(np);
+	of_node_put(np);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	rstc = of_reset_control_get_shared(r, "sgmii");
+
+	if (IS_ERR(rstc))
+		return PTR_ERR(rstc);
+
+	sgmii_sel = devm_clk_get_enabled(mpcs->dev, "sgmii_sel");
+	if (IS_ERR(sgmii_sel))
+		return PTR_ERR(sgmii_sel);
+
+	sgmii_rx = devm_clk_get_enabled(mpcs->dev, "sgmii_rx");
+	if (IS_ERR(sgmii_rx))
+		return PTR_ERR(sgmii_rx);
+
+	sgmii_tx = devm_clk_get_enabled(mpcs->dev, "sgmii_tx");
+	if (IS_ERR(sgmii_tx))
+		return PTR_ERR(sgmii_tx);
+
+	lynxi_pcs = mtk_pcs_lynxi_create(mpcs->dev, regmap, MTK_NETSYS_V3_AMA_RGC3, 0);
+
+	if (IS_ERR(lynxi_pcs))
+		return PTR_ERR(lynxi_pcs);
+
+	if (!lynxi_pcs)
+		return -ENODEV;
+
+	/* Make sure all PCS ops are supported by wrapped PCS */
+	if (!lynxi_pcs->ops->pcs_get_state ||
+	    !lynxi_pcs->ops->pcs_config ||
+	    !lynxi_pcs->ops->pcs_an_restart ||
+	    !lynxi_pcs->ops->pcs_link_up ||
+	    !lynxi_pcs->ops->pcs_disable)
+		return -EOPNOTSUPP;
+
+	wp = devm_kzalloc(mpcs->dev, sizeof(*wp), GFP_KERNEL);
+	if (!wp)
+		return -ENOMEM;
+
+	wp->pcs.neg_mode = lynxi_pcs->neg_mode;
+	wp->pcs.ops = &mtk_sgmii_wrapped_pcs_ops;
+	wp->pcs.poll = true;
+	wp->lynxi_pcs = lynxi_pcs;
+	wp->usxgmii_pcs = mpcs;
+	wp->clks[0] = sgmii_sel;
+	wp->clks[1] = sgmii_rx;
+	wp->clks[2] = sgmii_tx;
+	wp->reset = rstc;
+	wp->interface = PHY_INTERFACE_MODE_NA;
+	wp->neg_mode = -1;
+
+	if (IS_ERR(wp->reset))
+		return PTR_ERR(wp->reset);
+
+	reset_control_deassert(wp->reset);
+
+	mpcs->sgmii_pcs = &wp->pcs;
+
+	return 0;
+}
+
+static void mtk_sgmii_wrapper_destroy(struct mtk_usxgmii_pcs *mpcs)
+{
+	struct mtk_sgmii_wrapper_pcs *wp = container_of(mpcs->sgmii_pcs,
+							struct mtk_sgmii_wrapper_pcs,
+							pcs);
+
+	mtk_pcs_lynxi_destroy(wp->lynxi_pcs);
+	reset_control_put(wp->reset);
+}
+
+static int mtk_usxgmii_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
+				  phy_interface_t interface,
+				  const unsigned long *advertising,
+				  bool permit_pause_to_mac)
+{
+	struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
+	unsigned int an_ctrl = 0, link_timer = 0, xfi_mode = 0, adapt_mode = 0;
+	bool mode_changed = false;
+
+	if (interface == PHY_INTERFACE_MODE_USXGMII) {
+		an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF) | USXGMII_AN_ENABLE;
+		link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) |
+			     FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) |
+			     FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B);
+		xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_MODE_10G) |
+			   FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_MODE_10G);
+	} else if (interface == PHY_INTERFACE_MODE_10GBASER) {
+		an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF);
+		link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) |
+			     FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) |
+			     FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B);
+		xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_MODE_10G) |
+			   FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_MODE_10G);
+		adapt_mode = USXGMII_RATE_UPDATE_MODE;
+	} else if (interface == PHY_INTERFACE_MODE_5GBASER) {
+		an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0xFF);
+		link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x3D) |
+			     FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x3D) |
+			     FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x3D);
+		xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_MODE_5G) |
+			   FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_MODE_5G);
+		adapt_mode = USXGMII_RATE_UPDATE_MODE;
+	} else {
+		return -EINVAL;
+	}
+
+	adapt_mode |= FIELD_PREP(USXGMII_RATE_ADAPT_MODE, USXGMII_RATE_ADAPT_MODE_X1);
+
+	if (mpcs->interface != interface) {
+		mpcs->interface = interface;
+		mode_changed = true;
+	}
+
+	phy_power_on(mpcs->pextp);
+	mtk_usxgmii_reset(mpcs);
+
+	/* Setup USXGMII AN ctrl */
+	mtk_m32(mpcs, RG_PCS_AN_CTRL0,
+		USXGMII_AN_SYNC_CNT | USXGMII_AN_ENABLE,
+		an_ctrl);
+
+	mtk_m32(mpcs, RG_PCS_AN_CTRL2,
+		USXGMII_LINK_TIMER_IDLE_DETECT |
+		USXGMII_LINK_TIMER_COMP_ACK_DETECT |
+		USXGMII_LINK_TIMER_AN_RESTART,
+		link_timer);
+
+	mpcs->neg_mode = neg_mode;
+
+	/* Gated MAC CK */
+	mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1,
+		USXGMII_MAC_CK_GATED, USXGMII_MAC_CK_GATED);
+
+	/* Enable interface force mode */
+	mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1,
+		USXGMII_IF_FORCE_EN, USXGMII_IF_FORCE_EN);
+
+	/* Setup USXGMII adapt mode */
+	mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1,
+		USXGMII_RATE_UPDATE_MODE | USXGMII_RATE_ADAPT_MODE,
+		adapt_mode);
+
+	/* Setup USXGMII speed */
+	mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1,
+		USXGMII_XFI_RX_MODE | USXGMII_XFI_TX_MODE,
+		xfi_mode);
+
+	usleep_range(1, 10);
+
+	/* Un-gated MAC CK */
+	mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1, USXGMII_MAC_CK_GATED, 0);
+
+	usleep_range(1, 10);
+
+	/* Disable interface force mode for the AN mode */
+	if (an_ctrl & USXGMII_AN_ENABLE)
+		mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1, USXGMII_IF_FORCE_EN, 0);
+
+	/* Setup PHY for interface mode */
+	phy_set_mode_ext(mpcs->pextp, PHY_MODE_ETHERNET, interface);
+
+	return mode_changed;
+}
+
+static void mtk_usxgmii_pcs_get_fixed_speed(struct mtk_usxgmii_pcs *mpcs,
+					    struct phylink_link_state *state)
+{
+	u32 val = mtk_r32(mpcs, RG_PHY_TOP_SPEED_CTRL1);
+	int speed;
+
+	/* Calculate speed from interface speed and rate adapt mode */
+	switch (FIELD_GET(USXGMII_XFI_RX_MODE, val)) {
+	case USXGMII_XFI_MODE_10G:
+		speed = 10000;
+		break;
+	case USXGMII_XFI_MODE_5G:
+		speed = 5000;
+		break;
+	case USXGMII_XFI_MODE_2P5G:
+		speed = 2500;
+		break;
+	default:
+		state->speed = SPEED_UNKNOWN;
+		return;
+	}
+
+	switch (FIELD_GET(USXGMII_RATE_ADAPT_MODE, val)) {
+	case USXGMII_RATE_ADAPT_MODE_X100:
+		speed /= 100;
+		break;
+	case USXGMII_RATE_ADAPT_MODE_X50:
+		speed /= 50;
+		break;
+	case USXGMII_RATE_ADAPT_MODE_X10:
+		speed /= 10;
+		break;
+	case USXGMII_RATE_ADAPT_MODE_X5:
+		speed /= 5;
+		break;
+	case USXGMII_RATE_ADAPT_MODE_X4:
+		speed /= 4;
+		break;
+	case USXGMII_RATE_ADAPT_MODE_X2:
+		speed /= 2;
+		break;
+	case USXGMII_RATE_ADAPT_MODE_X1:
+		break;
+	default:
+		state->speed = SPEED_UNKNOWN;
+		return;
+	}
+
+	state->speed = speed;
+	state->duplex = DUPLEX_FULL;
+}
+
+static void mtk_usxgmii_pcs_get_an_state(struct mtk_usxgmii_pcs *mpcs,
+					 struct phylink_link_state *state)
+{
+	u16 lpa;
+
+	/* Refresh LPA by toggling LPA_LATCH */
+	mtk_m32(mpcs, RG_PCS_AN_STS0, USXGMII_LPA_LATCH, USXGMII_LPA_LATCH);
+	ndelay(1020);
+	mtk_m32(mpcs, RG_PCS_AN_STS0, USXGMII_LPA_LATCH, 0);
+	ndelay(1020);
+	lpa = FIELD_GET(USXGMII_LPA, mtk_r32(mpcs, RG_PCS_AN_STS0));
+
+	phylink_decode_usxgmii_word(state, lpa);
+}
+
+static void mtk_usxgmii_pcs_get_state(struct phylink_pcs *pcs,
+				      struct phylink_link_state *state)
+{
+	struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
+
+	/* Refresh USXGMII link status by toggling RG_PCS_AN_STATUS_UPDATE */
+	mtk_m32(mpcs, RG_PCS_RX_STATUS0, RG_PCS_RX_STATUS_UPDATE,
+		RG_PCS_RX_STATUS_UPDATE);
+	ndelay(1020);
+	mtk_m32(mpcs, RG_PCS_RX_STATUS0, RG_PCS_RX_STATUS_UPDATE, 0);
+	ndelay(1020);
+
+	/* Read USXGMII link status */
+	state->link = FIELD_GET(RG_PCS_RX_LINK_STATUS,
+				mtk_r32(mpcs, RG_PCS_RX_STATUS0));
+
+	/* Continuously repeat re-configuration sequence until link comes up */
+	if (!state->link) {
+		mtk_usxgmii_pcs_config(pcs, mpcs->neg_mode,
+				       state->interface, NULL, false);
+		return;
+	}
+
+	if (FIELD_GET(USXGMII_AN_ENABLE, mtk_r32(mpcs, RG_PCS_AN_CTRL0)))
+		mtk_usxgmii_pcs_get_an_state(mpcs, state);
+	else
+		mtk_usxgmii_pcs_get_fixed_speed(mpcs, state);
+}
+
+static void mtk_usxgmii_pcs_restart_an(struct phylink_pcs *pcs)
+{
+	struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
+
+	mtk_m32(mpcs, RG_PCS_AN_CTRL0, USXGMII_AN_RESTART, USXGMII_AN_RESTART);
+}
+
+static void mtk_usxgmii_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode,
+				    phy_interface_t interface,
+				    int speed, int duplex)
+{
+	/* Reconfiguring USXGMII to ensure the quality of the RX signal
+	 * after the line side link up.
+	 */
+	mtk_usxgmii_pcs_config(pcs, neg_mode, interface, NULL, false);
+}
+
+static void mtk_usxgmii_pcs_disable(struct phylink_pcs *pcs)
+{
+	struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
+
+	mpcs->interface = PHY_INTERFACE_MODE_NA;
+	mpcs->neg_mode = -1;
+}
+
+static const struct phylink_pcs_ops mtk_usxgmii_pcs_ops = {
+	.pcs_config = mtk_usxgmii_pcs_config,
+	.pcs_get_state = mtk_usxgmii_pcs_get_state,
+	.pcs_an_restart = mtk_usxgmii_pcs_restart_an,
+	.pcs_link_up = mtk_usxgmii_pcs_link_up,
+	.pcs_disable = mtk_usxgmii_pcs_disable,
+};
+
+static int mtk_usxgmii_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_usxgmii_pcs *mpcs;
+	int ret;
+
+	mpcs = devm_kzalloc(dev, sizeof(*mpcs), GFP_KERNEL);
+	if (!mpcs)
+		return -ENOMEM;
+
+	mpcs->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(mpcs->base))
+		return PTR_ERR(mpcs->base);
+
+	mpcs->dev = dev;
+	mpcs->pcs.ops = &mtk_usxgmii_pcs_ops;
+	mpcs->pcs.poll = true;
+	mpcs->pcs.neg_mode = true;
+	mpcs->interface = PHY_INTERFACE_MODE_NA;
+	mpcs->neg_mode = -1;
+
+	mpcs->clk = devm_clk_get_enabled(mpcs->dev, "usxgmii");
+	if (IS_ERR(mpcs->clk))
+		return PTR_ERR(mpcs->clk);
+
+	mpcs->xfi_pll = devm_clk_get_enabled(mpcs->dev, "xfi_pll");
+	if (IS_ERR(mpcs->xfi_pll))
+		return PTR_ERR(mpcs->xfi_pll);
+
+	mpcs->reset = devm_reset_control_get_shared(dev, "xfi");
+	if (IS_ERR(mpcs->reset))
+		return PTR_ERR(mpcs->reset);
+
+	reset_control_deassert(mpcs->reset);
+
+	ret = mtk_xfi_pextp_init(mpcs);
+	if (ret)
+		return ret;
+
+	ret = mtk_sgmii_wrapper_init(mpcs);
+	if (ret)
+		return ret;
+
+	platform_set_drvdata(pdev, mpcs);
+
+	return 0;
+}
+
+static int mtk_usxgmii_remove(struct platform_device *pdev)
+{
+	struct mtk_usxgmii_pcs *mpcs = platform_get_drvdata(pdev);
+
+	mtk_sgmii_wrapper_destroy(mpcs);
+	phy_power_off(mpcs->pextp);
+
+	return 0;
+}
+
+static const struct of_device_id mtk_usxgmii_of_mtable[] = {
+	{ .compatible = "mediatek,mt7988-usxgmiisys" },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mtk_usxgmii_of_mtable);
+
+struct phylink_pcs *mtk_usxgmii_select_pcs(struct device_node *np, phy_interface_t mode)
+{
+	struct platform_device *pdev;
+	struct mtk_usxgmii_pcs *mpcs;
+
+	if (!np)
+		return NULL;
+
+	if (!of_device_is_available(np))
+		return ERR_PTR(-ENODEV);
+
+	if (!of_match_node(mtk_usxgmii_of_mtable, np))
+		return ERR_PTR(-EINVAL);
+
+	pdev = of_find_device_by_node(np);
+	if (!pdev || !platform_get_drvdata(pdev)) {
+		if (pdev)
+			put_device(&pdev->dev);
+		return ERR_PTR(-EPROBE_DEFER);
+	}
+
+	mpcs = platform_get_drvdata(pdev);
+	put_device(&pdev->dev);
+
+	switch (mode) {
+	case PHY_INTERFACE_MODE_1000BASEX:
+	case PHY_INTERFACE_MODE_2500BASEX:
+	case PHY_INTERFACE_MODE_SGMII:
+		return mpcs->sgmii_pcs;
+	case PHY_INTERFACE_MODE_5GBASER:
+	case PHY_INTERFACE_MODE_10GBASER:
+	case PHY_INTERFACE_MODE_USXGMII:
+		return &mpcs->pcs;
+	default:
+		return NULL;
+	}
+}
+EXPORT_SYMBOL(mtk_usxgmii_select_pcs);
+
+static struct platform_driver mtk_usxgmii_driver = {
+	.driver = {
+		.name			= "mtk_usxgmii",
+		.suppress_bind_attrs	= true,
+		.of_match_table		= mtk_usxgmii_of_mtable,
+	},
+	.probe = mtk_usxgmii_probe,
+	.remove = mtk_usxgmii_remove,
+};
+module_platform_driver(mtk_usxgmii_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MediaTek USXGMII PCS driver");
+MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
diff --git a/include/linux/pcs/pcs-mtk-usxgmii.h b/include/linux/pcs/pcs-mtk-usxgmii.h
new file mode 100644
index 0000000000000..7a3c49760ffa6
--- /dev/null
+++ b/include/linux/pcs/pcs-mtk-usxgmii.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LINUX_PCS_MTK_USXGMII_H
+#define __LINUX_PCS_MTK_USXGMII_H
+
+#include <linux/phylink.h>
+
+/**
+ * mtk_usxgmii_select_pcs
+ * Return PCS indentified by a device node and the PHY interface mode in use
+ *
+ * @param np	Pointer to device node indentifying a MediaTek USXGMII PCS
+ * @param mode	Ethernet PHY interface mode
+ *
+ * @return	Pointer to phylink PCS instance of NULL
+ */
+struct phylink_pcs *mtk_usxgmii_select_pcs(struct device_node *np, phy_interface_t mode);
+
+#endif /* __LINUX_PCS_MTK_USXGMII_H */
-- 
2.42.1

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [RFC PATCH 6/8] net: pcs: add driver for MediaTek USXGMII PCS
@ 2023-11-09 21:51   ` Daniel Golle
  0 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 21:51 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Daniel Golle, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

Add driver for USXGMII PCS found in the MediaTek MT7988 SoC and supporting
USXGMII, 10GBase-R and 5GBase-R interface modes. In order to support
Cisco SGMII, 1000Base-X and 2500Base-X via the also present LynxI PCS
create a wrapped PCS taking care of the components shared between the
new USXGMII PCS and the legacy LynxI PCS.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 MAINTAINERS                         |   2 +
 drivers/net/pcs/Kconfig             |  10 +
 drivers/net/pcs/Makefile            |   1 +
 drivers/net/pcs/pcs-mtk-usxgmii.c   | 688 ++++++++++++++++++++++++++++
 include/linux/pcs/pcs-mtk-usxgmii.h |  18 +
 5 files changed, 719 insertions(+)
 create mode 100644 drivers/net/pcs/pcs-mtk-usxgmii.c
 create mode 100644 include/linux/pcs/pcs-mtk-usxgmii.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 6499acd8f3874..026f62243f595 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -13517,7 +13517,9 @@ M:	Daniel Golle <daniel@makrotopia.org>
 L:	netdev@vger.kernel.org
 S:	Maintained
 F:	drivers/net/pcs/pcs-mtk-lynxi.c
+F:	drivers/net/pcs/pcs-mtk-usxgmii.c
 F:	include/linux/pcs/pcs-mtk-lynxi.h
+F:	include/linux/pcs/pcs-mtk-usxgmii.h
 
 MEDIATEK ETHERNET PHY DRIVERS
 M:	Daniel Golle <daniel@makrotopia.org>
diff --git a/drivers/net/pcs/Kconfig b/drivers/net/pcs/Kconfig
index 87cf308fc6d8b..5df5b19c4eb93 100644
--- a/drivers/net/pcs/Kconfig
+++ b/drivers/net/pcs/Kconfig
@@ -25,6 +25,16 @@ config PCS_MTK_LYNXI
 	  This module provides helpers to phylink for managing the LynxI PCS
 	  which is part of MediaTek's SoC and Ethernet switch ICs.
 
+config PCS_MTK_USXGMII
+	tristate "MediaTek USXGMII PCS"
+	select PCS_MTK_LYNXI
+	select PHY_MTK_PEXTP
+	help
+	  This module provides a driver for MediaTek's USXGMII PCS supporting
+	  10GBase-R, 5GBase-R and USXGMII interface modes.
+	  1000Base-X, 2500Base-X and Cisco SGMII are supported on the same
+	  differential pairs via an embedded LynxI PHY.
+
 config PCS_RZN1_MIIC
 	tristate "Renesas RZ/N1 MII converter"
 	depends on OF && (ARCH_RZN1 || COMPILE_TEST)
diff --git a/drivers/net/pcs/Makefile b/drivers/net/pcs/Makefile
index fb1694192ae63..cc355152ca1ca 100644
--- a/drivers/net/pcs/Makefile
+++ b/drivers/net/pcs/Makefile
@@ -6,4 +6,5 @@ pcs_xpcs-$(CONFIG_PCS_XPCS)	:= pcs-xpcs.o pcs-xpcs-nxp.o pcs-xpcs-wx.o
 obj-$(CONFIG_PCS_XPCS)		+= pcs_xpcs.o
 obj-$(CONFIG_PCS_LYNX)		+= pcs-lynx.o
 obj-$(CONFIG_PCS_MTK_LYNXI)	+= pcs-mtk-lynxi.o
+obj-$(CONFIG_PCS_MTK_USXGMII)	+= pcs-mtk-usxgmii.o
 obj-$(CONFIG_PCS_RZN1_MIIC)	+= pcs-rzn1-miic.o
diff --git a/drivers/net/pcs/pcs-mtk-usxgmii.c b/drivers/net/pcs/pcs-mtk-usxgmii.c
new file mode 100644
index 0000000000000..b3ca66c9df2a9
--- /dev/null
+++ b/drivers/net/pcs/pcs-mtk-usxgmii.c
@@ -0,0 +1,688 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2023 MediaTek Inc.
+ * Author: Henry Yen <henry.yen@mediatek.com>
+ *         Daniel Golle <daniel@makrotopia.org>
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/mfd/syscon.h>
+#include <linux/mdio.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <linux/reset.h>
+#include <linux/pcs/pcs-mtk-lynxi.h>
+#include <linux/pcs/pcs-mtk-usxgmii.h>
+#include <linux/phy/phy.h>
+#include <linux/platform_device.h>
+
+/* USXGMII subsystem config registers */
+/* Register to control speed */
+#define RG_PHY_TOP_SPEED_CTRL1			0x80c
+#define USXGMII_RATE_UPDATE_MODE		BIT(31)
+#define USXGMII_MAC_CK_GATED			BIT(29)
+#define USXGMII_IF_FORCE_EN			BIT(28)
+#define USXGMII_RATE_ADAPT_MODE			GENMASK(10, 8)
+#define USXGMII_RATE_ADAPT_MODE_X1		0
+#define USXGMII_RATE_ADAPT_MODE_X2		1
+#define USXGMII_RATE_ADAPT_MODE_X4		2
+#define USXGMII_RATE_ADAPT_MODE_X10		3
+#define USXGMII_RATE_ADAPT_MODE_X100		4
+#define USXGMII_RATE_ADAPT_MODE_X5		5
+#define USXGMII_RATE_ADAPT_MODE_X50		6
+#define USXGMII_XFI_RX_MODE			GENMASK(6, 4)
+#define USXGMII_XFI_TX_MODE			GENMASK(2, 0)
+#define USXGMII_XFI_MODE_10G			0
+#define USXGMII_XFI_MODE_5G			1
+#define USXGMII_XFI_MODE_2P5G			3
+
+/* Register to control PCS AN */
+#define RG_PCS_AN_CTRL0				0x810
+#define USXGMII_AN_RESTART			BIT(31)
+#define USXGMII_AN_SYNC_CNT			GENMASK(30, 11)
+#define USXGMII_AN_ENABLE			BIT(0)
+
+#define RG_PCS_AN_CTRL2				0x818
+#define USXGMII_LINK_TIMER_IDLE_DETECT		GENMASK(29, 20)
+#define USXGMII_LINK_TIMER_COMP_ACK_DETECT	GENMASK(19, 10)
+#define USXGMII_LINK_TIMER_AN_RESTART		GENMASK(9, 0)
+
+/* Register to read PCS AN status */
+#define RG_PCS_AN_STS0				0x81c
+#define USXGMII_LPA				GENMASK(15, 0)
+#define USXGMII_LPA_LATCH			BIT(31)
+
+/* Register to read PCS link status */
+#define RG_PCS_RX_STATUS0			0x904
+#define RG_PCS_RX_STATUS_UPDATE			BIT(16)
+#define RG_PCS_RX_LINK_STATUS			BIT(2)
+
+#define MTK_NETSYS_V3_AMA_RGC3			0x128
+
+/* struct mtk_usxgmii_pcs - This structure holds each usxgmii PCS
+ * @pcs:		Phylink PCS structure
+ * @dev:		Pointer to device structure
+ * @base:		IO memory to access PCS hardware
+ * @clk:		Pointer to USXGMII clk
+ * @xfi_pll:		Pointer to XFI PLL clk
+ * @pextp:		The PHYA instance attached to the PCS
+ * @reset:		Pointer to USXGMII reset control
+ * @interface:		Currently selected interface mode
+ * @neg_mode:		Currently used phylink neg_mode
+ */
+struct mtk_usxgmii_pcs {
+	struct phylink_pcs		pcs;
+	struct phylink_pcs		*sgmii_pcs;
+	struct device			*dev;
+	void __iomem			*base;
+	struct clk			*clk;
+	struct clk			*xfi_pll;
+	struct phy			*pextp;
+	struct reset_control		*reset;
+	struct regmap			*regmap_pll;
+	phy_interface_t			interface;
+	unsigned int			neg_mode;
+};
+
+/* struct mtk_sgmii_wrapper_pcs - Structure holding wrapped SGMII PCS
+ * @usxgmii_pcs		Pointer to owning mtk_usxgmii_pcs structure
+ * @pcs			Phylink PCS structure
+ * @clks:		Pointers to 3 SGMII clks
+ * @reset:		Pointer to SGMII reset control
+ * @interface:		Currently selected interface mode
+ * @neg_mode:		Currently used phylink neg_mode
+ */
+struct mtk_sgmii_wrapper_pcs {
+	struct mtk_usxgmii_pcs		*usxgmii_pcs;
+	struct phylink_pcs		*lynxi_pcs;
+	struct phylink_pcs		pcs;
+	struct clk			*clks[3];
+	struct reset_control		*reset;
+	phy_interface_t			interface;
+	unsigned int			neg_mode;
+	bool				permit_pause_to_mac;
+};
+
+static u32 mtk_r32(struct mtk_usxgmii_pcs *mpcs, unsigned int reg)
+{
+	return ioread32(mpcs->base + reg);
+}
+
+static void mtk_m32(struct mtk_usxgmii_pcs *mpcs, unsigned int reg, u32 mask, u32 set)
+{
+	u32 val;
+
+	val = ioread32(mpcs->base + reg);
+	val &= ~mask;
+	val |= set;
+	iowrite32(val, mpcs->base + reg);
+}
+
+static struct mtk_usxgmii_pcs *pcs_to_mtk_usxgmii_pcs(struct phylink_pcs *pcs)
+{
+	return container_of(pcs, struct mtk_usxgmii_pcs, pcs);
+}
+
+static int mtk_xfi_pextp_init(struct mtk_usxgmii_pcs *mpcs)
+{
+	struct device *dev = mpcs->dev;
+
+	mpcs->pextp = devm_phy_get(dev, NULL);
+	if (IS_ERR(mpcs->pextp))
+		return dev_err_probe(dev, PTR_ERR(mpcs->pextp), "cannot acquire PHYA\n");
+
+	if (!mpcs->pextp)
+		return dev_err_probe(dev, -ENODEV, "PHYA not found\n");
+
+	return 0;
+}
+
+static void mtk_usxgmii_reset(struct mtk_usxgmii_pcs *mpcs)
+{
+	if (!mpcs->pextp)
+		return;
+
+	phy_reset(mpcs->pextp);
+
+	reset_control_assert(mpcs->reset);
+	usleep_range(100, 500);
+	reset_control_deassert(mpcs->reset);
+
+	mdelay(10);
+}
+
+static void mtk_sgmii_reset(struct mtk_sgmii_wrapper_pcs *wp)
+{
+	if (!wp->usxgmii_pcs->pextp)
+		return;
+
+	phy_reset(wp->usxgmii_pcs->pextp);
+
+	reset_control_assert(wp->reset);
+	usleep_range(100, 500);
+	reset_control_deassert(wp->reset);
+
+	mdelay(10);
+}
+
+static int mtk_sgmii_wrapped_pcs_config(struct phylink_pcs *pcs,
+					unsigned int neg_mode,
+					phy_interface_t interface,
+					const unsigned long *advertising,
+					bool permit_pause_to_mac)
+{
+	struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
+	bool full_reconf;
+	int ret;
+
+	phy_power_on(wp->usxgmii_pcs->pextp);
+
+	full_reconf = (interface != wp->interface);
+	if (full_reconf)
+		mtk_sgmii_reset(wp);
+
+	ret = wp->lynxi_pcs->ops->pcs_config(wp->lynxi_pcs, neg_mode, interface, advertising,
+					     permit_pause_to_mac);
+
+	if (full_reconf)
+		phy_set_mode_ext(wp->usxgmii_pcs->pextp, PHY_MODE_ETHERNET, interface);
+
+	wp->interface = interface;
+	wp->neg_mode = neg_mode;
+	wp->permit_pause_to_mac = permit_pause_to_mac;
+
+	return ret;
+}
+
+static void mtk_sgmii_wrapped_pcs_get_state(struct phylink_pcs *pcs,
+					    struct phylink_link_state *state)
+{
+	struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
+
+	wp->lynxi_pcs->ops->pcs_get_state(wp->lynxi_pcs, state);
+
+	/* Continuously repeat re-configuration sequence until link comes up */
+	if (!state->link)
+		mtk_sgmii_wrapped_pcs_config(pcs, wp->neg_mode, state->interface,
+					     NULL, wp->permit_pause_to_mac);
+}
+
+static void mtk_sgmii_wrapped_pcs_an_restart(struct phylink_pcs *pcs)
+{
+	struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
+
+	wp->lynxi_pcs->ops->pcs_an_restart(wp->lynxi_pcs);
+}
+
+static void mtk_sgmii_wrapped_pcs_link_up(struct phylink_pcs *pcs,
+					  unsigned int neg_mode,
+					  phy_interface_t interface, int speed,
+					  int duplex)
+{
+	struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
+
+	wp->lynxi_pcs->ops->pcs_link_up(wp->lynxi_pcs, neg_mode, interface, speed, duplex);
+}
+
+static void mtk_sgmii_wrapped_pcs_disable(struct phylink_pcs *pcs)
+{
+	struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
+
+	wp->lynxi_pcs->ops->pcs_disable(wp->lynxi_pcs);
+	wp->interface = PHY_INTERFACE_MODE_NA;
+	wp->neg_mode = -1;
+}
+
+static int mtk_sgmii_wrapped_pcs_enable(struct phylink_pcs *pcs)
+{
+	struct mtk_sgmii_wrapper_pcs *wp = container_of(pcs, struct mtk_sgmii_wrapper_pcs, pcs);
+
+	if (wp->lynxi_pcs->ops->pcs_enable)
+		wp->lynxi_pcs->ops->pcs_enable(wp->lynxi_pcs);
+
+	wp->interface = PHY_INTERFACE_MODE_NA;
+	wp->neg_mode = -1;
+
+	phy_power_on(wp->usxgmii_pcs->pextp);
+
+	return 0;
+}
+
+static const struct phylink_pcs_ops mtk_sgmii_wrapped_pcs_ops = {
+	.pcs_get_state = mtk_sgmii_wrapped_pcs_get_state,
+	.pcs_config = mtk_sgmii_wrapped_pcs_config,
+	.pcs_an_restart = mtk_sgmii_wrapped_pcs_an_restart,
+	.pcs_link_up = mtk_sgmii_wrapped_pcs_link_up,
+	.pcs_disable = mtk_sgmii_wrapped_pcs_disable,
+	.pcs_enable = mtk_sgmii_wrapped_pcs_enable,
+};
+
+static int mtk_sgmii_wrapper_init(struct mtk_usxgmii_pcs *mpcs)
+{
+	struct device_node *r = mpcs->dev->of_node, *np;
+	struct mtk_sgmii_wrapper_pcs *wp;
+	struct phylink_pcs *lynxi_pcs;
+	struct reset_control *rstc;
+	struct regmap *regmap;
+	struct clk *sgmii_sel, *sgmii_rx, *sgmii_tx;
+
+	np = of_parse_phandle(r, "mediatek,sgmiisys", 0);
+	if (!np)
+		return -ENODEV;
+
+	regmap = syscon_node_to_regmap(np);
+	of_node_put(np);
+	if (IS_ERR(regmap))
+		return PTR_ERR(regmap);
+
+	rstc = of_reset_control_get_shared(r, "sgmii");
+
+	if (IS_ERR(rstc))
+		return PTR_ERR(rstc);
+
+	sgmii_sel = devm_clk_get_enabled(mpcs->dev, "sgmii_sel");
+	if (IS_ERR(sgmii_sel))
+		return PTR_ERR(sgmii_sel);
+
+	sgmii_rx = devm_clk_get_enabled(mpcs->dev, "sgmii_rx");
+	if (IS_ERR(sgmii_rx))
+		return PTR_ERR(sgmii_rx);
+
+	sgmii_tx = devm_clk_get_enabled(mpcs->dev, "sgmii_tx");
+	if (IS_ERR(sgmii_tx))
+		return PTR_ERR(sgmii_tx);
+
+	lynxi_pcs = mtk_pcs_lynxi_create(mpcs->dev, regmap, MTK_NETSYS_V3_AMA_RGC3, 0);
+
+	if (IS_ERR(lynxi_pcs))
+		return PTR_ERR(lynxi_pcs);
+
+	if (!lynxi_pcs)
+		return -ENODEV;
+
+	/* Make sure all PCS ops are supported by wrapped PCS */
+	if (!lynxi_pcs->ops->pcs_get_state ||
+	    !lynxi_pcs->ops->pcs_config ||
+	    !lynxi_pcs->ops->pcs_an_restart ||
+	    !lynxi_pcs->ops->pcs_link_up ||
+	    !lynxi_pcs->ops->pcs_disable)
+		return -EOPNOTSUPP;
+
+	wp = devm_kzalloc(mpcs->dev, sizeof(*wp), GFP_KERNEL);
+	if (!wp)
+		return -ENOMEM;
+
+	wp->pcs.neg_mode = lynxi_pcs->neg_mode;
+	wp->pcs.ops = &mtk_sgmii_wrapped_pcs_ops;
+	wp->pcs.poll = true;
+	wp->lynxi_pcs = lynxi_pcs;
+	wp->usxgmii_pcs = mpcs;
+	wp->clks[0] = sgmii_sel;
+	wp->clks[1] = sgmii_rx;
+	wp->clks[2] = sgmii_tx;
+	wp->reset = rstc;
+	wp->interface = PHY_INTERFACE_MODE_NA;
+	wp->neg_mode = -1;
+
+	if (IS_ERR(wp->reset))
+		return PTR_ERR(wp->reset);
+
+	reset_control_deassert(wp->reset);
+
+	mpcs->sgmii_pcs = &wp->pcs;
+
+	return 0;
+}
+
+static void mtk_sgmii_wrapper_destroy(struct mtk_usxgmii_pcs *mpcs)
+{
+	struct mtk_sgmii_wrapper_pcs *wp = container_of(mpcs->sgmii_pcs,
+							struct mtk_sgmii_wrapper_pcs,
+							pcs);
+
+	mtk_pcs_lynxi_destroy(wp->lynxi_pcs);
+	reset_control_put(wp->reset);
+}
+
+static int mtk_usxgmii_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,
+				  phy_interface_t interface,
+				  const unsigned long *advertising,
+				  bool permit_pause_to_mac)
+{
+	struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
+	unsigned int an_ctrl = 0, link_timer = 0, xfi_mode = 0, adapt_mode = 0;
+	bool mode_changed = false;
+
+	if (interface == PHY_INTERFACE_MODE_USXGMII) {
+		an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF) | USXGMII_AN_ENABLE;
+		link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) |
+			     FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) |
+			     FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B);
+		xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_MODE_10G) |
+			   FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_MODE_10G);
+	} else if (interface == PHY_INTERFACE_MODE_10GBASER) {
+		an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0x1FF);
+		link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x7B) |
+			     FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x7B) |
+			     FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x7B);
+		xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_MODE_10G) |
+			   FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_MODE_10G);
+		adapt_mode = USXGMII_RATE_UPDATE_MODE;
+	} else if (interface == PHY_INTERFACE_MODE_5GBASER) {
+		an_ctrl = FIELD_PREP(USXGMII_AN_SYNC_CNT, 0xFF);
+		link_timer = FIELD_PREP(USXGMII_LINK_TIMER_IDLE_DETECT, 0x3D) |
+			     FIELD_PREP(USXGMII_LINK_TIMER_COMP_ACK_DETECT, 0x3D) |
+			     FIELD_PREP(USXGMII_LINK_TIMER_AN_RESTART, 0x3D);
+		xfi_mode = FIELD_PREP(USXGMII_XFI_RX_MODE, USXGMII_XFI_MODE_5G) |
+			   FIELD_PREP(USXGMII_XFI_TX_MODE, USXGMII_XFI_MODE_5G);
+		adapt_mode = USXGMII_RATE_UPDATE_MODE;
+	} else {
+		return -EINVAL;
+	}
+
+	adapt_mode |= FIELD_PREP(USXGMII_RATE_ADAPT_MODE, USXGMII_RATE_ADAPT_MODE_X1);
+
+	if (mpcs->interface != interface) {
+		mpcs->interface = interface;
+		mode_changed = true;
+	}
+
+	phy_power_on(mpcs->pextp);
+	mtk_usxgmii_reset(mpcs);
+
+	/* Setup USXGMII AN ctrl */
+	mtk_m32(mpcs, RG_PCS_AN_CTRL0,
+		USXGMII_AN_SYNC_CNT | USXGMII_AN_ENABLE,
+		an_ctrl);
+
+	mtk_m32(mpcs, RG_PCS_AN_CTRL2,
+		USXGMII_LINK_TIMER_IDLE_DETECT |
+		USXGMII_LINK_TIMER_COMP_ACK_DETECT |
+		USXGMII_LINK_TIMER_AN_RESTART,
+		link_timer);
+
+	mpcs->neg_mode = neg_mode;
+
+	/* Gated MAC CK */
+	mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1,
+		USXGMII_MAC_CK_GATED, USXGMII_MAC_CK_GATED);
+
+	/* Enable interface force mode */
+	mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1,
+		USXGMII_IF_FORCE_EN, USXGMII_IF_FORCE_EN);
+
+	/* Setup USXGMII adapt mode */
+	mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1,
+		USXGMII_RATE_UPDATE_MODE | USXGMII_RATE_ADAPT_MODE,
+		adapt_mode);
+
+	/* Setup USXGMII speed */
+	mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1,
+		USXGMII_XFI_RX_MODE | USXGMII_XFI_TX_MODE,
+		xfi_mode);
+
+	usleep_range(1, 10);
+
+	/* Un-gated MAC CK */
+	mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1, USXGMII_MAC_CK_GATED, 0);
+
+	usleep_range(1, 10);
+
+	/* Disable interface force mode for the AN mode */
+	if (an_ctrl & USXGMII_AN_ENABLE)
+		mtk_m32(mpcs, RG_PHY_TOP_SPEED_CTRL1, USXGMII_IF_FORCE_EN, 0);
+
+	/* Setup PHY for interface mode */
+	phy_set_mode_ext(mpcs->pextp, PHY_MODE_ETHERNET, interface);
+
+	return mode_changed;
+}
+
+static void mtk_usxgmii_pcs_get_fixed_speed(struct mtk_usxgmii_pcs *mpcs,
+					    struct phylink_link_state *state)
+{
+	u32 val = mtk_r32(mpcs, RG_PHY_TOP_SPEED_CTRL1);
+	int speed;
+
+	/* Calculate speed from interface speed and rate adapt mode */
+	switch (FIELD_GET(USXGMII_XFI_RX_MODE, val)) {
+	case USXGMII_XFI_MODE_10G:
+		speed = 10000;
+		break;
+	case USXGMII_XFI_MODE_5G:
+		speed = 5000;
+		break;
+	case USXGMII_XFI_MODE_2P5G:
+		speed = 2500;
+		break;
+	default:
+		state->speed = SPEED_UNKNOWN;
+		return;
+	}
+
+	switch (FIELD_GET(USXGMII_RATE_ADAPT_MODE, val)) {
+	case USXGMII_RATE_ADAPT_MODE_X100:
+		speed /= 100;
+		break;
+	case USXGMII_RATE_ADAPT_MODE_X50:
+		speed /= 50;
+		break;
+	case USXGMII_RATE_ADAPT_MODE_X10:
+		speed /= 10;
+		break;
+	case USXGMII_RATE_ADAPT_MODE_X5:
+		speed /= 5;
+		break;
+	case USXGMII_RATE_ADAPT_MODE_X4:
+		speed /= 4;
+		break;
+	case USXGMII_RATE_ADAPT_MODE_X2:
+		speed /= 2;
+		break;
+	case USXGMII_RATE_ADAPT_MODE_X1:
+		break;
+	default:
+		state->speed = SPEED_UNKNOWN;
+		return;
+	}
+
+	state->speed = speed;
+	state->duplex = DUPLEX_FULL;
+}
+
+static void mtk_usxgmii_pcs_get_an_state(struct mtk_usxgmii_pcs *mpcs,
+					 struct phylink_link_state *state)
+{
+	u16 lpa;
+
+	/* Refresh LPA by toggling LPA_LATCH */
+	mtk_m32(mpcs, RG_PCS_AN_STS0, USXGMII_LPA_LATCH, USXGMII_LPA_LATCH);
+	ndelay(1020);
+	mtk_m32(mpcs, RG_PCS_AN_STS0, USXGMII_LPA_LATCH, 0);
+	ndelay(1020);
+	lpa = FIELD_GET(USXGMII_LPA, mtk_r32(mpcs, RG_PCS_AN_STS0));
+
+	phylink_decode_usxgmii_word(state, lpa);
+}
+
+static void mtk_usxgmii_pcs_get_state(struct phylink_pcs *pcs,
+				      struct phylink_link_state *state)
+{
+	struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
+
+	/* Refresh USXGMII link status by toggling RG_PCS_AN_STATUS_UPDATE */
+	mtk_m32(mpcs, RG_PCS_RX_STATUS0, RG_PCS_RX_STATUS_UPDATE,
+		RG_PCS_RX_STATUS_UPDATE);
+	ndelay(1020);
+	mtk_m32(mpcs, RG_PCS_RX_STATUS0, RG_PCS_RX_STATUS_UPDATE, 0);
+	ndelay(1020);
+
+	/* Read USXGMII link status */
+	state->link = FIELD_GET(RG_PCS_RX_LINK_STATUS,
+				mtk_r32(mpcs, RG_PCS_RX_STATUS0));
+
+	/* Continuously repeat re-configuration sequence until link comes up */
+	if (!state->link) {
+		mtk_usxgmii_pcs_config(pcs, mpcs->neg_mode,
+				       state->interface, NULL, false);
+		return;
+	}
+
+	if (FIELD_GET(USXGMII_AN_ENABLE, mtk_r32(mpcs, RG_PCS_AN_CTRL0)))
+		mtk_usxgmii_pcs_get_an_state(mpcs, state);
+	else
+		mtk_usxgmii_pcs_get_fixed_speed(mpcs, state);
+}
+
+static void mtk_usxgmii_pcs_restart_an(struct phylink_pcs *pcs)
+{
+	struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
+
+	mtk_m32(mpcs, RG_PCS_AN_CTRL0, USXGMII_AN_RESTART, USXGMII_AN_RESTART);
+}
+
+static void mtk_usxgmii_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode,
+				    phy_interface_t interface,
+				    int speed, int duplex)
+{
+	/* Reconfiguring USXGMII to ensure the quality of the RX signal
+	 * after the line side link up.
+	 */
+	mtk_usxgmii_pcs_config(pcs, neg_mode, interface, NULL, false);
+}
+
+static void mtk_usxgmii_pcs_disable(struct phylink_pcs *pcs)
+{
+	struct mtk_usxgmii_pcs *mpcs = pcs_to_mtk_usxgmii_pcs(pcs);
+
+	mpcs->interface = PHY_INTERFACE_MODE_NA;
+	mpcs->neg_mode = -1;
+}
+
+static const struct phylink_pcs_ops mtk_usxgmii_pcs_ops = {
+	.pcs_config = mtk_usxgmii_pcs_config,
+	.pcs_get_state = mtk_usxgmii_pcs_get_state,
+	.pcs_an_restart = mtk_usxgmii_pcs_restart_an,
+	.pcs_link_up = mtk_usxgmii_pcs_link_up,
+	.pcs_disable = mtk_usxgmii_pcs_disable,
+};
+
+static int mtk_usxgmii_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct mtk_usxgmii_pcs *mpcs;
+	int ret;
+
+	mpcs = devm_kzalloc(dev, sizeof(*mpcs), GFP_KERNEL);
+	if (!mpcs)
+		return -ENOMEM;
+
+	mpcs->base = devm_platform_ioremap_resource(pdev, 0);
+	if (IS_ERR(mpcs->base))
+		return PTR_ERR(mpcs->base);
+
+	mpcs->dev = dev;
+	mpcs->pcs.ops = &mtk_usxgmii_pcs_ops;
+	mpcs->pcs.poll = true;
+	mpcs->pcs.neg_mode = true;
+	mpcs->interface = PHY_INTERFACE_MODE_NA;
+	mpcs->neg_mode = -1;
+
+	mpcs->clk = devm_clk_get_enabled(mpcs->dev, "usxgmii");
+	if (IS_ERR(mpcs->clk))
+		return PTR_ERR(mpcs->clk);
+
+	mpcs->xfi_pll = devm_clk_get_enabled(mpcs->dev, "xfi_pll");
+	if (IS_ERR(mpcs->xfi_pll))
+		return PTR_ERR(mpcs->xfi_pll);
+
+	mpcs->reset = devm_reset_control_get_shared(dev, "xfi");
+	if (IS_ERR(mpcs->reset))
+		return PTR_ERR(mpcs->reset);
+
+	reset_control_deassert(mpcs->reset);
+
+	ret = mtk_xfi_pextp_init(mpcs);
+	if (ret)
+		return ret;
+
+	ret = mtk_sgmii_wrapper_init(mpcs);
+	if (ret)
+		return ret;
+
+	platform_set_drvdata(pdev, mpcs);
+
+	return 0;
+}
+
+static int mtk_usxgmii_remove(struct platform_device *pdev)
+{
+	struct mtk_usxgmii_pcs *mpcs = platform_get_drvdata(pdev);
+
+	mtk_sgmii_wrapper_destroy(mpcs);
+	phy_power_off(mpcs->pextp);
+
+	return 0;
+}
+
+static const struct of_device_id mtk_usxgmii_of_mtable[] = {
+	{ .compatible = "mediatek,mt7988-usxgmiisys" },
+	{ /* sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, mtk_usxgmii_of_mtable);
+
+struct phylink_pcs *mtk_usxgmii_select_pcs(struct device_node *np, phy_interface_t mode)
+{
+	struct platform_device *pdev;
+	struct mtk_usxgmii_pcs *mpcs;
+
+	if (!np)
+		return NULL;
+
+	if (!of_device_is_available(np))
+		return ERR_PTR(-ENODEV);
+
+	if (!of_match_node(mtk_usxgmii_of_mtable, np))
+		return ERR_PTR(-EINVAL);
+
+	pdev = of_find_device_by_node(np);
+	if (!pdev || !platform_get_drvdata(pdev)) {
+		if (pdev)
+			put_device(&pdev->dev);
+		return ERR_PTR(-EPROBE_DEFER);
+	}
+
+	mpcs = platform_get_drvdata(pdev);
+	put_device(&pdev->dev);
+
+	switch (mode) {
+	case PHY_INTERFACE_MODE_1000BASEX:
+	case PHY_INTERFACE_MODE_2500BASEX:
+	case PHY_INTERFACE_MODE_SGMII:
+		return mpcs->sgmii_pcs;
+	case PHY_INTERFACE_MODE_5GBASER:
+	case PHY_INTERFACE_MODE_10GBASER:
+	case PHY_INTERFACE_MODE_USXGMII:
+		return &mpcs->pcs;
+	default:
+		return NULL;
+	}
+}
+EXPORT_SYMBOL(mtk_usxgmii_select_pcs);
+
+static struct platform_driver mtk_usxgmii_driver = {
+	.driver = {
+		.name			= "mtk_usxgmii",
+		.suppress_bind_attrs	= true,
+		.of_match_table		= mtk_usxgmii_of_mtable,
+	},
+	.probe = mtk_usxgmii_probe,
+	.remove = mtk_usxgmii_remove,
+};
+module_platform_driver(mtk_usxgmii_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("MediaTek USXGMII PCS driver");
+MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
diff --git a/include/linux/pcs/pcs-mtk-usxgmii.h b/include/linux/pcs/pcs-mtk-usxgmii.h
new file mode 100644
index 0000000000000..7a3c49760ffa6
--- /dev/null
+++ b/include/linux/pcs/pcs-mtk-usxgmii.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __LINUX_PCS_MTK_USXGMII_H
+#define __LINUX_PCS_MTK_USXGMII_H
+
+#include <linux/phylink.h>
+
+/**
+ * mtk_usxgmii_select_pcs
+ * Return PCS indentified by a device node and the PHY interface mode in use
+ *
+ * @param np	Pointer to device node indentifying a MediaTek USXGMII PCS
+ * @param mode	Ethernet PHY interface mode
+ *
+ * @return	Pointer to phylink PCS instance of NULL
+ */
+struct phylink_pcs *mtk_usxgmii_select_pcs(struct device_node *np, phy_interface_t mode);
+
+#endif /* __LINUX_PCS_MTK_USXGMII_H */
-- 
2.42.1

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* [RFC PATCH 7/8] dt-bindings: net: mediatek,net: fix and complete mt7988-eth binding
  2023-11-09 21:50 ` Daniel Golle
  (?)
@ 2023-11-09 21:52   ` Daniel Golle
  -1 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 21:52 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Daniel Golle, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

Remove clocks which were copied from the vendor driver but are now taken
care of by dedicated drivers for PCS and PHY in the upstream driver.
Also remove mediatek,sgmiisys phandle which isn't required on MT7988
because we use pcs-handle on the MAC nodes instead.
Last but not least, add an example for MT7988.

Fixes: c94a9aabec36 ("dt-bindings: net: mediatek,net: add mt7988-eth binding")
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 .../devicetree/bindings/net/mediatek,net.yaml | 171 +++++++++++++++---
 1 file changed, 142 insertions(+), 29 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/mediatek,net.yaml b/Documentation/devicetree/bindings/net/mediatek,net.yaml
index e74502a0afe86..c0f7bb6f3ef8d 100644
--- a/Documentation/devicetree/bindings/net/mediatek,net.yaml
+++ b/Documentation/devicetree/bindings/net/mediatek,net.yaml
@@ -27,9 +27,6 @@ properties:
       - mediatek,mt7988-eth
       - ralink,rt5350-eth
 
-  reg:
-    maxItems: 1
-
   clocks: true
   clock-names: true
 
@@ -115,6 +112,9 @@ allOf:
               - mediatek,mt7623-eth
     then:
       properties:
+        reg:
+          maxItems: 1
+
         interrupts:
           maxItems: 3
 
@@ -149,6 +149,9 @@ allOf:
               - mediatek,mt7621-eth
     then:
       properties:
+        reg:
+          maxItems: 1
+
         interrupts:
           maxItems: 1
 
@@ -174,6 +177,9 @@ allOf:
             const: mediatek,mt7622-eth
     then:
       properties:
+        reg:
+          maxItems: 1
+
         interrupts:
           maxItems: 3
 
@@ -215,6 +221,9 @@ allOf:
             const: mediatek,mt7629-eth
     then:
       properties:
+        reg:
+          maxItems: 1
+
         interrupts:
           maxItems: 3
 
@@ -257,6 +266,9 @@ allOf:
             const: mediatek,mt7981-eth
     then:
       properties:
+        reg:
+          maxItems: 1
+
         interrupts:
           minItems: 4
 
@@ -295,6 +307,9 @@ allOf:
             const: mediatek,mt7986-eth
     then:
       properties:
+        reg:
+          maxItems: 1
+
         interrupts:
           minItems: 4
 
@@ -333,36 +348,32 @@ allOf:
             const: mediatek,mt7988-eth
     then:
       properties:
+        reg:
+          maxItems: 2
+          minItems: 2
+
         interrupts:
           minItems: 4
+          maxItems: 4
 
         clocks:
-          minItems: 34
-          maxItems: 34
+          minItems: 24
+          maxItems: 24
 
         clock-names:
           items:
-            - const: crypto
+            - const: xgp1
+            - const: xgp2
+            - const: xgp3
             - const: fe
             - const: gp2
             - const: gp1
             - const: gp3
+            - const: esw
+            - const: crypto
             - const: ethwarp_wocpu2
             - const: ethwarp_wocpu1
             - const: ethwarp_wocpu0
-            - const: esw
-            - const: netsys0
-            - const: netsys1
-            - const: sgmii_tx250m
-            - const: sgmii_rx250m
-            - const: sgmii2_tx250m
-            - const: sgmii2_rx250m
-            - const: top_usxgmii0_sel
-            - const: top_usxgmii1_sel
-            - const: top_sgm0_sel
-            - const: top_sgm1_sel
-            - const: top_xfi_phy0_xtal_sel
-            - const: top_xfi_phy1_xtal_sel
             - const: top_eth_gmii_sel
             - const: top_eth_refck_50m_sel
             - const: top_eth_sys_200m_sel
@@ -375,18 +386,9 @@ allOf:
             - const: top_netsys_sync_250m_sel
             - const: top_netsys_ppefb_250m_sel
             - const: top_netsys_warp_sel
-            - const: wocpu1
-            - const: wocpu0
-            - const: xgp1
-            - const: xgp2
-            - const: xgp3
-
-        mediatek,sgmiisys:
-          minItems: 2
-          maxItems: 2
 
 patternProperties:
-  "^mac@[0-1]$":
+  "^mac@[0-2]$":
     type: object
     unevaluatedProperties: false
     allOf:
@@ -577,3 +579,114 @@ examples:
         };
       };
     };
+
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/clock/mediatek,mt7988-clk.h>
+
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      ethernet@15100000 {
+        compatible = "mediatek,mt7988-eth";
+        reg = <0 0x15100000 0 0x80000>, <0 0x15400000 0 0x380000>;
+        interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
+
+        clocks = <&ethsys CLK_ETHDMA_XGP1_EN>,
+                 <&ethsys CLK_ETHDMA_XGP2_EN>,
+                 <&ethsys CLK_ETHDMA_XGP3_EN>,
+                 <&ethsys CLK_ETHDMA_FE_EN>,
+                 <&ethsys CLK_ETHDMA_GP2_EN>,
+                 <&ethsys CLK_ETHDMA_GP1_EN>,
+                 <&ethsys CLK_ETHDMA_GP3_EN>,
+                 <&ethsys CLK_ETHDMA_ESW_EN>,
+                 <&ethsys CLK_ETHDMA_CRYPT0_EN>,
+                 <&ethwarp CLK_ETHWARP_WOCPU2_EN>,
+                 <&ethwarp CLK_ETHWARP_WOCPU1_EN>,
+                 <&ethwarp CLK_ETHWARP_WOCPU0_EN>,
+                 <&topckgen CLK_TOP_ETH_GMII_SEL>,
+                 <&topckgen CLK_TOP_ETH_REFCK_50M_SEL>,
+                 <&topckgen CLK_TOP_ETH_SYS_200M_SEL>,
+                 <&topckgen CLK_TOP_ETH_SYS_SEL>,
+                 <&topckgen CLK_TOP_ETH_XGMII_SEL>,
+                 <&topckgen CLK_TOP_ETH_MII_SEL>,
+                 <&topckgen CLK_TOP_NETSYS_SEL>,
+                 <&topckgen CLK_TOP_NETSYS_500M_SEL>,
+                 <&topckgen CLK_TOP_NETSYS_PAO_2X_SEL>,
+                 <&topckgen CLK_TOP_NETSYS_SYNC_250M_SEL>,
+                 <&topckgen CLK_TOP_NETSYS_PPEFB_250M_SEL>,
+                 <&topckgen CLK_TOP_NETSYS_WARP_SEL>;
+
+        clock-names = "xgp1", "xgp2", "xgp3", "fe", "gp2", "gp1",
+                      "gp3", "esw", "crypto",
+                      "ethwarp_wocpu2", "ethwarp_wocpu1",
+                      "ethwarp_wocpu0", "top_eth_gmii_sel",
+                      "top_eth_refck_50m_sel", "top_eth_sys_200m_sel",
+                      "top_eth_sys_sel", "top_eth_xgmii_sel",
+                      "top_eth_mii_sel", "top_netsys_sel",
+                      "top_netsys_500m_sel", "top_netsys_pao_2x_sel",
+                      "top_netsys_sync_250m_sel",
+                      "top_netsys_ppefb_250m_sel",
+                      "top_netsys_warp_sel";
+        assigned-clocks = <&topckgen CLK_TOP_NETSYS_2X_SEL>,
+                          <&topckgen CLK_TOP_NETSYS_GSW_SEL>,
+                          <&topckgen CLK_TOP_USXGMII_SBUS_0_SEL>,
+                          <&topckgen CLK_TOP_USXGMII_SBUS_1_SEL>,
+                          <&topckgen CLK_TOP_SGM_0_SEL>,
+                          <&topckgen CLK_TOP_SGM_1_SEL>;
+        assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>,
+                                 <&topckgen CLK_TOP_NET1PLL_D4>,
+                                 <&topckgen CLK_TOP_NET1PLL_D8_D4>,
+                                 <&topckgen CLK_TOP_NET1PLL_D8_D4>,
+                                 <&apmixedsys CLK_APMIXED_SGMPLL>,
+                                 <&apmixedsys CLK_APMIXED_SGMPLL>;
+        mediatek,ethsys = <&ethsys>;
+        mediatek,infracfg = <&topmisc>;
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        mac@0 {
+          compatible = "mediatek,eth-mac";
+          reg = <0>;
+          phy-mode = "internal";
+          status = "disabled";
+
+          fixed-link {
+            speed = <10000>;
+            full-duplex;
+            pause;
+          };
+        };
+
+        mac@1 {
+          compatible = "mediatek,eth-mac";
+          reg = <1>;
+          status = "disabled";
+          pcs-handle = <&usxgmiisys1>;
+        };
+
+        mac@2 {
+          compatible = "mediatek,eth-mac";
+          reg = <2>;
+          status = "disabled";
+          pcs-handle = <&usxgmiisys0>;
+        };
+
+        mdio_bus: mdio-bus {
+          #address-cells = <1>;
+          #size-cells = <0>;
+
+          /* internal 2.5G PHY */
+          int_2p5g_phy: ethernet-phy@15 {
+            reg = <15>;
+            compatible = "ethernet-phy-ieee802.3-c45";
+            phy-mode = "internal";
+          };
+        };
+      };
+    };
-- 
2.42.1

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

* [RFC PATCH 7/8] dt-bindings: net: mediatek,net: fix and complete mt7988-eth binding
@ 2023-11-09 21:52   ` Daniel Golle
  0 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 21:52 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Daniel Golle, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

Remove clocks which were copied from the vendor driver but are now taken
care of by dedicated drivers for PCS and PHY in the upstream driver.
Also remove mediatek,sgmiisys phandle which isn't required on MT7988
because we use pcs-handle on the MAC nodes instead.
Last but not least, add an example for MT7988.

Fixes: c94a9aabec36 ("dt-bindings: net: mediatek,net: add mt7988-eth binding")
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 .../devicetree/bindings/net/mediatek,net.yaml | 171 +++++++++++++++---
 1 file changed, 142 insertions(+), 29 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/mediatek,net.yaml b/Documentation/devicetree/bindings/net/mediatek,net.yaml
index e74502a0afe86..c0f7bb6f3ef8d 100644
--- a/Documentation/devicetree/bindings/net/mediatek,net.yaml
+++ b/Documentation/devicetree/bindings/net/mediatek,net.yaml
@@ -27,9 +27,6 @@ properties:
       - mediatek,mt7988-eth
       - ralink,rt5350-eth
 
-  reg:
-    maxItems: 1
-
   clocks: true
   clock-names: true
 
@@ -115,6 +112,9 @@ allOf:
               - mediatek,mt7623-eth
     then:
       properties:
+        reg:
+          maxItems: 1
+
         interrupts:
           maxItems: 3
 
@@ -149,6 +149,9 @@ allOf:
               - mediatek,mt7621-eth
     then:
       properties:
+        reg:
+          maxItems: 1
+
         interrupts:
           maxItems: 1
 
@@ -174,6 +177,9 @@ allOf:
             const: mediatek,mt7622-eth
     then:
       properties:
+        reg:
+          maxItems: 1
+
         interrupts:
           maxItems: 3
 
@@ -215,6 +221,9 @@ allOf:
             const: mediatek,mt7629-eth
     then:
       properties:
+        reg:
+          maxItems: 1
+
         interrupts:
           maxItems: 3
 
@@ -257,6 +266,9 @@ allOf:
             const: mediatek,mt7981-eth
     then:
       properties:
+        reg:
+          maxItems: 1
+
         interrupts:
           minItems: 4
 
@@ -295,6 +307,9 @@ allOf:
             const: mediatek,mt7986-eth
     then:
       properties:
+        reg:
+          maxItems: 1
+
         interrupts:
           minItems: 4
 
@@ -333,36 +348,32 @@ allOf:
             const: mediatek,mt7988-eth
     then:
       properties:
+        reg:
+          maxItems: 2
+          minItems: 2
+
         interrupts:
           minItems: 4
+          maxItems: 4
 
         clocks:
-          minItems: 34
-          maxItems: 34
+          minItems: 24
+          maxItems: 24
 
         clock-names:
           items:
-            - const: crypto
+            - const: xgp1
+            - const: xgp2
+            - const: xgp3
             - const: fe
             - const: gp2
             - const: gp1
             - const: gp3
+            - const: esw
+            - const: crypto
             - const: ethwarp_wocpu2
             - const: ethwarp_wocpu1
             - const: ethwarp_wocpu0
-            - const: esw
-            - const: netsys0
-            - const: netsys1
-            - const: sgmii_tx250m
-            - const: sgmii_rx250m
-            - const: sgmii2_tx250m
-            - const: sgmii2_rx250m
-            - const: top_usxgmii0_sel
-            - const: top_usxgmii1_sel
-            - const: top_sgm0_sel
-            - const: top_sgm1_sel
-            - const: top_xfi_phy0_xtal_sel
-            - const: top_xfi_phy1_xtal_sel
             - const: top_eth_gmii_sel
             - const: top_eth_refck_50m_sel
             - const: top_eth_sys_200m_sel
@@ -375,18 +386,9 @@ allOf:
             - const: top_netsys_sync_250m_sel
             - const: top_netsys_ppefb_250m_sel
             - const: top_netsys_warp_sel
-            - const: wocpu1
-            - const: wocpu0
-            - const: xgp1
-            - const: xgp2
-            - const: xgp3
-
-        mediatek,sgmiisys:
-          minItems: 2
-          maxItems: 2
 
 patternProperties:
-  "^mac@[0-1]$":
+  "^mac@[0-2]$":
     type: object
     unevaluatedProperties: false
     allOf:
@@ -577,3 +579,114 @@ examples:
         };
       };
     };
+
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/clock/mediatek,mt7988-clk.h>
+
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      ethernet@15100000 {
+        compatible = "mediatek,mt7988-eth";
+        reg = <0 0x15100000 0 0x80000>, <0 0x15400000 0 0x380000>;
+        interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
+
+        clocks = <&ethsys CLK_ETHDMA_XGP1_EN>,
+                 <&ethsys CLK_ETHDMA_XGP2_EN>,
+                 <&ethsys CLK_ETHDMA_XGP3_EN>,
+                 <&ethsys CLK_ETHDMA_FE_EN>,
+                 <&ethsys CLK_ETHDMA_GP2_EN>,
+                 <&ethsys CLK_ETHDMA_GP1_EN>,
+                 <&ethsys CLK_ETHDMA_GP3_EN>,
+                 <&ethsys CLK_ETHDMA_ESW_EN>,
+                 <&ethsys CLK_ETHDMA_CRYPT0_EN>,
+                 <&ethwarp CLK_ETHWARP_WOCPU2_EN>,
+                 <&ethwarp CLK_ETHWARP_WOCPU1_EN>,
+                 <&ethwarp CLK_ETHWARP_WOCPU0_EN>,
+                 <&topckgen CLK_TOP_ETH_GMII_SEL>,
+                 <&topckgen CLK_TOP_ETH_REFCK_50M_SEL>,
+                 <&topckgen CLK_TOP_ETH_SYS_200M_SEL>,
+                 <&topckgen CLK_TOP_ETH_SYS_SEL>,
+                 <&topckgen CLK_TOP_ETH_XGMII_SEL>,
+                 <&topckgen CLK_TOP_ETH_MII_SEL>,
+                 <&topckgen CLK_TOP_NETSYS_SEL>,
+                 <&topckgen CLK_TOP_NETSYS_500M_SEL>,
+                 <&topckgen CLK_TOP_NETSYS_PAO_2X_SEL>,
+                 <&topckgen CLK_TOP_NETSYS_SYNC_250M_SEL>,
+                 <&topckgen CLK_TOP_NETSYS_PPEFB_250M_SEL>,
+                 <&topckgen CLK_TOP_NETSYS_WARP_SEL>;
+
+        clock-names = "xgp1", "xgp2", "xgp3", "fe", "gp2", "gp1",
+                      "gp3", "esw", "crypto",
+                      "ethwarp_wocpu2", "ethwarp_wocpu1",
+                      "ethwarp_wocpu0", "top_eth_gmii_sel",
+                      "top_eth_refck_50m_sel", "top_eth_sys_200m_sel",
+                      "top_eth_sys_sel", "top_eth_xgmii_sel",
+                      "top_eth_mii_sel", "top_netsys_sel",
+                      "top_netsys_500m_sel", "top_netsys_pao_2x_sel",
+                      "top_netsys_sync_250m_sel",
+                      "top_netsys_ppefb_250m_sel",
+                      "top_netsys_warp_sel";
+        assigned-clocks = <&topckgen CLK_TOP_NETSYS_2X_SEL>,
+                          <&topckgen CLK_TOP_NETSYS_GSW_SEL>,
+                          <&topckgen CLK_TOP_USXGMII_SBUS_0_SEL>,
+                          <&topckgen CLK_TOP_USXGMII_SBUS_1_SEL>,
+                          <&topckgen CLK_TOP_SGM_0_SEL>,
+                          <&topckgen CLK_TOP_SGM_1_SEL>;
+        assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>,
+                                 <&topckgen CLK_TOP_NET1PLL_D4>,
+                                 <&topckgen CLK_TOP_NET1PLL_D8_D4>,
+                                 <&topckgen CLK_TOP_NET1PLL_D8_D4>,
+                                 <&apmixedsys CLK_APMIXED_SGMPLL>,
+                                 <&apmixedsys CLK_APMIXED_SGMPLL>;
+        mediatek,ethsys = <&ethsys>;
+        mediatek,infracfg = <&topmisc>;
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        mac@0 {
+          compatible = "mediatek,eth-mac";
+          reg = <0>;
+          phy-mode = "internal";
+          status = "disabled";
+
+          fixed-link {
+            speed = <10000>;
+            full-duplex;
+            pause;
+          };
+        };
+
+        mac@1 {
+          compatible = "mediatek,eth-mac";
+          reg = <1>;
+          status = "disabled";
+          pcs-handle = <&usxgmiisys1>;
+        };
+
+        mac@2 {
+          compatible = "mediatek,eth-mac";
+          reg = <2>;
+          status = "disabled";
+          pcs-handle = <&usxgmiisys0>;
+        };
+
+        mdio_bus: mdio-bus {
+          #address-cells = <1>;
+          #size-cells = <0>;
+
+          /* internal 2.5G PHY */
+          int_2p5g_phy: ethernet-phy@15 {
+            reg = <15>;
+            compatible = "ethernet-phy-ieee802.3-c45";
+            phy-mode = "internal";
+          };
+        };
+      };
+    };
-- 
2.42.1

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [RFC PATCH 7/8] dt-bindings: net: mediatek,net: fix and complete mt7988-eth binding
@ 2023-11-09 21:52   ` Daniel Golle
  0 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 21:52 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Daniel Golle, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

Remove clocks which were copied from the vendor driver but are now taken
care of by dedicated drivers for PCS and PHY in the upstream driver.
Also remove mediatek,sgmiisys phandle which isn't required on MT7988
because we use pcs-handle on the MAC nodes instead.
Last but not least, add an example for MT7988.

Fixes: c94a9aabec36 ("dt-bindings: net: mediatek,net: add mt7988-eth binding")
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 .../devicetree/bindings/net/mediatek,net.yaml | 171 +++++++++++++++---
 1 file changed, 142 insertions(+), 29 deletions(-)

diff --git a/Documentation/devicetree/bindings/net/mediatek,net.yaml b/Documentation/devicetree/bindings/net/mediatek,net.yaml
index e74502a0afe86..c0f7bb6f3ef8d 100644
--- a/Documentation/devicetree/bindings/net/mediatek,net.yaml
+++ b/Documentation/devicetree/bindings/net/mediatek,net.yaml
@@ -27,9 +27,6 @@ properties:
       - mediatek,mt7988-eth
       - ralink,rt5350-eth
 
-  reg:
-    maxItems: 1
-
   clocks: true
   clock-names: true
 
@@ -115,6 +112,9 @@ allOf:
               - mediatek,mt7623-eth
     then:
       properties:
+        reg:
+          maxItems: 1
+
         interrupts:
           maxItems: 3
 
@@ -149,6 +149,9 @@ allOf:
               - mediatek,mt7621-eth
     then:
       properties:
+        reg:
+          maxItems: 1
+
         interrupts:
           maxItems: 1
 
@@ -174,6 +177,9 @@ allOf:
             const: mediatek,mt7622-eth
     then:
       properties:
+        reg:
+          maxItems: 1
+
         interrupts:
           maxItems: 3
 
@@ -215,6 +221,9 @@ allOf:
             const: mediatek,mt7629-eth
     then:
       properties:
+        reg:
+          maxItems: 1
+
         interrupts:
           maxItems: 3
 
@@ -257,6 +266,9 @@ allOf:
             const: mediatek,mt7981-eth
     then:
       properties:
+        reg:
+          maxItems: 1
+
         interrupts:
           minItems: 4
 
@@ -295,6 +307,9 @@ allOf:
             const: mediatek,mt7986-eth
     then:
       properties:
+        reg:
+          maxItems: 1
+
         interrupts:
           minItems: 4
 
@@ -333,36 +348,32 @@ allOf:
             const: mediatek,mt7988-eth
     then:
       properties:
+        reg:
+          maxItems: 2
+          minItems: 2
+
         interrupts:
           minItems: 4
+          maxItems: 4
 
         clocks:
-          minItems: 34
-          maxItems: 34
+          minItems: 24
+          maxItems: 24
 
         clock-names:
           items:
-            - const: crypto
+            - const: xgp1
+            - const: xgp2
+            - const: xgp3
             - const: fe
             - const: gp2
             - const: gp1
             - const: gp3
+            - const: esw
+            - const: crypto
             - const: ethwarp_wocpu2
             - const: ethwarp_wocpu1
             - const: ethwarp_wocpu0
-            - const: esw
-            - const: netsys0
-            - const: netsys1
-            - const: sgmii_tx250m
-            - const: sgmii_rx250m
-            - const: sgmii2_tx250m
-            - const: sgmii2_rx250m
-            - const: top_usxgmii0_sel
-            - const: top_usxgmii1_sel
-            - const: top_sgm0_sel
-            - const: top_sgm1_sel
-            - const: top_xfi_phy0_xtal_sel
-            - const: top_xfi_phy1_xtal_sel
             - const: top_eth_gmii_sel
             - const: top_eth_refck_50m_sel
             - const: top_eth_sys_200m_sel
@@ -375,18 +386,9 @@ allOf:
             - const: top_netsys_sync_250m_sel
             - const: top_netsys_ppefb_250m_sel
             - const: top_netsys_warp_sel
-            - const: wocpu1
-            - const: wocpu0
-            - const: xgp1
-            - const: xgp2
-            - const: xgp3
-
-        mediatek,sgmiisys:
-          minItems: 2
-          maxItems: 2
 
 patternProperties:
-  "^mac@[0-1]$":
+  "^mac@[0-2]$":
     type: object
     unevaluatedProperties: false
     allOf:
@@ -577,3 +579,114 @@ examples:
         };
       };
     };
+
+  - |
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/clock/mediatek,mt7988-clk.h>
+
+    soc {
+      #address-cells = <2>;
+      #size-cells = <2>;
+
+      ethernet@15100000 {
+        compatible = "mediatek,mt7988-eth";
+        reg = <0 0x15100000 0 0x80000>, <0 0x15400000 0 0x380000>;
+        interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
+                     <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
+
+        clocks = <&ethsys CLK_ETHDMA_XGP1_EN>,
+                 <&ethsys CLK_ETHDMA_XGP2_EN>,
+                 <&ethsys CLK_ETHDMA_XGP3_EN>,
+                 <&ethsys CLK_ETHDMA_FE_EN>,
+                 <&ethsys CLK_ETHDMA_GP2_EN>,
+                 <&ethsys CLK_ETHDMA_GP1_EN>,
+                 <&ethsys CLK_ETHDMA_GP3_EN>,
+                 <&ethsys CLK_ETHDMA_ESW_EN>,
+                 <&ethsys CLK_ETHDMA_CRYPT0_EN>,
+                 <&ethwarp CLK_ETHWARP_WOCPU2_EN>,
+                 <&ethwarp CLK_ETHWARP_WOCPU1_EN>,
+                 <&ethwarp CLK_ETHWARP_WOCPU0_EN>,
+                 <&topckgen CLK_TOP_ETH_GMII_SEL>,
+                 <&topckgen CLK_TOP_ETH_REFCK_50M_SEL>,
+                 <&topckgen CLK_TOP_ETH_SYS_200M_SEL>,
+                 <&topckgen CLK_TOP_ETH_SYS_SEL>,
+                 <&topckgen CLK_TOP_ETH_XGMII_SEL>,
+                 <&topckgen CLK_TOP_ETH_MII_SEL>,
+                 <&topckgen CLK_TOP_NETSYS_SEL>,
+                 <&topckgen CLK_TOP_NETSYS_500M_SEL>,
+                 <&topckgen CLK_TOP_NETSYS_PAO_2X_SEL>,
+                 <&topckgen CLK_TOP_NETSYS_SYNC_250M_SEL>,
+                 <&topckgen CLK_TOP_NETSYS_PPEFB_250M_SEL>,
+                 <&topckgen CLK_TOP_NETSYS_WARP_SEL>;
+
+        clock-names = "xgp1", "xgp2", "xgp3", "fe", "gp2", "gp1",
+                      "gp3", "esw", "crypto",
+                      "ethwarp_wocpu2", "ethwarp_wocpu1",
+                      "ethwarp_wocpu0", "top_eth_gmii_sel",
+                      "top_eth_refck_50m_sel", "top_eth_sys_200m_sel",
+                      "top_eth_sys_sel", "top_eth_xgmii_sel",
+                      "top_eth_mii_sel", "top_netsys_sel",
+                      "top_netsys_500m_sel", "top_netsys_pao_2x_sel",
+                      "top_netsys_sync_250m_sel",
+                      "top_netsys_ppefb_250m_sel",
+                      "top_netsys_warp_sel";
+        assigned-clocks = <&topckgen CLK_TOP_NETSYS_2X_SEL>,
+                          <&topckgen CLK_TOP_NETSYS_GSW_SEL>,
+                          <&topckgen CLK_TOP_USXGMII_SBUS_0_SEL>,
+                          <&topckgen CLK_TOP_USXGMII_SBUS_1_SEL>,
+                          <&topckgen CLK_TOP_SGM_0_SEL>,
+                          <&topckgen CLK_TOP_SGM_1_SEL>;
+        assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>,
+                                 <&topckgen CLK_TOP_NET1PLL_D4>,
+                                 <&topckgen CLK_TOP_NET1PLL_D8_D4>,
+                                 <&topckgen CLK_TOP_NET1PLL_D8_D4>,
+                                 <&apmixedsys CLK_APMIXED_SGMPLL>,
+                                 <&apmixedsys CLK_APMIXED_SGMPLL>;
+        mediatek,ethsys = <&ethsys>;
+        mediatek,infracfg = <&topmisc>;
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        mac@0 {
+          compatible = "mediatek,eth-mac";
+          reg = <0>;
+          phy-mode = "internal";
+          status = "disabled";
+
+          fixed-link {
+            speed = <10000>;
+            full-duplex;
+            pause;
+          };
+        };
+
+        mac@1 {
+          compatible = "mediatek,eth-mac";
+          reg = <1>;
+          status = "disabled";
+          pcs-handle = <&usxgmiisys1>;
+        };
+
+        mac@2 {
+          compatible = "mediatek,eth-mac";
+          reg = <2>;
+          status = "disabled";
+          pcs-handle = <&usxgmiisys0>;
+        };
+
+        mdio_bus: mdio-bus {
+          #address-cells = <1>;
+          #size-cells = <0>;
+
+          /* internal 2.5G PHY */
+          int_2p5g_phy: ethernet-phy@15 {
+            reg = <15>;
+            compatible = "ethernet-phy-ieee802.3-c45";
+            phy-mode = "internal";
+          };
+        };
+      };
+    };
-- 
2.42.1

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* [RFC PATCH 8/8] net: ethernet: mtk_eth_soc: add paths and SerDes modes for MT7988
  2023-11-09 21:50 ` Daniel Golle
  (?)
@ 2023-11-09 21:52   ` Daniel Golle
  -1 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 21:52 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Daniel Golle, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

MT7988 comes with a built-in 2.5G PHY as well as SerDes lanes to
connect external PHYs or transceivers in USXGMII, 10GBase-R, 5GBase-R,
2500Base-X, 1000Base-X and Cisco SGMII interface modes.

Implement support for configuring for the new paths to SerDes interfaces
and the internal 2.5G PHY.

Add USXGMII PCS driver for 10GBase-R, 5GBase-R and USXGMII mode, and
setup the new PHYA on MT7988 to access the also still existing old
LynxI PCS for 1000Base-X, 2500Base-X and Cisco SGMII PCS interface
modes.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 drivers/net/ethernet/mediatek/Kconfig        |  17 ++
 drivers/net/ethernet/mediatek/mtk_eth_path.c | 122 ++++++++++++-
 drivers/net/ethernet/mediatek/mtk_eth_soc.c  | 178 ++++++++++++++++---
 drivers/net/ethernet/mediatek/mtk_eth_soc.h  | 105 +++++++++--
 4 files changed, 379 insertions(+), 43 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/Kconfig b/drivers/net/ethernet/mediatek/Kconfig
index da0db417ab690..b63723b8d1d2c 100644
--- a/drivers/net/ethernet/mediatek/Kconfig
+++ b/drivers/net/ethernet/mediatek/Kconfig
@@ -21,10 +21,27 @@ config NET_MEDIATEK_SOC
 	select PAGE_POOL_STATS
 	select PCS_MTK_LYNXI
 	select REGMAP_MMIO
+	select PCS_MTK_USXGMII if NET_MEDIATEK_SOC_USXGMII
 	help
 	  This driver supports the gigabit ethernet MACs in the
 	  MediaTek SoC family.
 
+config NET_MEDIATEK_SOC_USXGMII
+	bool "Support USXGMII SerDes on MT7988"
+	depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
+	def_bool NET_MEDIATEK_SOC != n
+	help
+	  Include support for 10GE SerDes which can be found on MT7988.
+	  If this kernel should run on SoCs with 10 GBit/s Ethernet you
+	  will need to select this option to use GMAC2 and GMAC3 with
+	  external PHYs, SFP(+) cages in 10GBase-R, 5GBase-R or USXGMII
+	  interface modes.
+
+	  Note that as the 2500Base-X/1000Base-X/Cisco SGMII SerDes PCS
+	  unit (MediaTek LynxI) in MT7988 is connected via the new 10GE
+	  SerDes, you will also need to select this option in case you
+	  want to use any of those SerDes modes.
+
 config NET_MEDIATEK_STAR_EMAC
 	tristate "MediaTek STAR Ethernet MAC support"
 	select PHYLIB
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_path.c b/drivers/net/ethernet/mediatek/mtk_eth_path.c
index 7c27a19c4d8f4..3f4f4cfe6a233 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
@@ -31,10 +31,20 @@ static const char *mtk_eth_path_name(u64 path)
 		return "gmac2_rgmii";
 	case MTK_ETH_PATH_GMAC2_SGMII:
 		return "gmac2_sgmii";
+	case MTK_ETH_PATH_GMAC2_2P5GPHY:
+		return "gmac2_2p5gphy";
 	case MTK_ETH_PATH_GMAC2_GEPHY:
 		return "gmac2_gephy";
+	case MTK_ETH_PATH_GMAC3_SGMII:
+		return "gmac3_sgmii";
 	case MTK_ETH_PATH_GDM1_ESW:
 		return "gdm1_esw";
+	case MTK_ETH_PATH_GMAC1_USXGMII:
+		return "gmac1_usxgmii";
+	case MTK_ETH_PATH_GMAC2_USXGMII:
+		return "gmac2_usxgmii";
+	case MTK_ETH_PATH_GMAC3_USXGMII:
+		return "gmac3_usxgmii";
 	default:
 		return "unknown path";
 	}
@@ -127,6 +137,27 @@ static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, u64 path)
 	return 0;
 }
 
+static int set_mux_gmac2_to_2p5gphy(struct mtk_eth *eth, u64 path)
+{
+	int ret;
+
+	if (path == MTK_ETH_PATH_GMAC2_2P5GPHY) {
+		ret = regmap_clear_bits(eth->ethsys, ETHSYS_SYSCFG0, SYSCFG0_SGMII_GMAC2_V2);
+		if (ret)
+			return ret;
+
+		/* Setup mux to 2p5g PHY */
+		ret = regmap_clear_bits(eth->infra, TOP_MISC_NETSYS_PCS_MUX, MUX_G2_USXGMII_SEL);
+		if (ret)
+			return ret;
+
+		dev_dbg(eth->dev, "path %s in %s updated\n",
+			mtk_eth_path_name(path), __func__);
+	}
+
+	return 0;
+}
+
 static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path)
 {
 	unsigned int val = 0;
@@ -165,7 +196,48 @@ static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path)
 	return 0;
 }
 
-static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
+static int set_mux_gmac123_to_usxgmii(struct mtk_eth *eth, u64 path)
+{
+	unsigned int val = 0;
+	bool updated = true;
+	int mac_id = 0;
+
+	/* Disable SYSCFG1 SGMII */
+	regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val);
+
+	switch (path) {
+	case MTK_ETH_PATH_GMAC1_USXGMII:
+		val &= ~(u32)SYSCFG0_SGMII_GMAC1_V2;
+		mac_id = MTK_GMAC1_ID;
+		break;
+	case MTK_ETH_PATH_GMAC2_USXGMII:
+		val &= ~(u32)SYSCFG0_SGMII_GMAC2_V2;
+		mac_id = MTK_GMAC2_ID;
+		break;
+	case MTK_ETH_PATH_GMAC3_USXGMII:
+		val &= ~(u32)SYSCFG0_SGMII_GMAC3_V2;
+		mac_id = MTK_GMAC3_ID;
+		break;
+	default:
+		updated = false;
+	};
+
+	if (updated) {
+		regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
+				   SYSCFG0_SGMII_MASK, val);
+
+		if (mac_id == MTK_GMAC2_ID)
+			regmap_set_bits(eth->infra, TOP_MISC_NETSYS_PCS_MUX,
+					MUX_G2_USXGMII_SEL);
+	}
+
+	dev_dbg(eth->dev, "path %s in %s updated = %d\n",
+		mtk_eth_path_name(path), __func__, updated);
+
+	return 0;
+}
+
+static int set_mux_gmac123_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
 {
 	unsigned int val = 0;
 	bool updated = true;
@@ -182,6 +254,9 @@ static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
 	case MTK_ETH_PATH_GMAC2_SGMII:
 		val |= SYSCFG0_SGMII_GMAC2_V2;
 		break;
+	case MTK_ETH_PATH_GMAC3_SGMII:
+		val |= SYSCFG0_SGMII_GMAC3_V2;
+		break;
 	default:
 		updated = false;
 	}
@@ -209,6 +284,10 @@ static const struct mtk_eth_muxc mtk_eth_muxc[] = {
 		.name = "mux_u3_gmac2_to_qphy",
 		.cap_bit = MTK_ETH_MUX_U3_GMAC2_TO_QPHY,
 		.set_path = set_mux_u3_gmac2_to_qphy,
+	}, {
+		.name = "mux_gmac2_to_2p5gphy",
+		.cap_bit = MTK_ETH_MUX_GMAC2_TO_2P5GPHY,
+		.set_path = set_mux_gmac2_to_2p5gphy,
 	}, {
 		.name = "mux_gmac1_gmac2_to_sgmii_rgmii",
 		.cap_bit = MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII,
@@ -216,7 +295,15 @@ static const struct mtk_eth_muxc mtk_eth_muxc[] = {
 	}, {
 		.name = "mux_gmac12_to_gephy_sgmii",
 		.cap_bit = MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII,
-		.set_path = set_mux_gmac12_to_gephy_sgmii,
+		.set_path = set_mux_gmac123_to_gephy_sgmii,
+	}, {
+		.name = "mux_gmac123_to_gephy_sgmii",
+		.cap_bit = MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII,
+		.set_path = set_mux_gmac123_to_gephy_sgmii,
+	}, {
+		.name = "mux_gmac123_to_usxgmii",
+		.cap_bit = MTK_ETH_MUX_GMAC123_TO_USXGMII,
+		.set_path = set_mux_gmac123_to_usxgmii,
 	},
 };
 
@@ -249,12 +336,39 @@ static int mtk_eth_mux_setup(struct mtk_eth *eth, u64 path)
 	return err;
 }
 
+int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id)
+{
+	u64 path;
+
+	path = (mac_id == MTK_GMAC1_ID) ?  MTK_ETH_PATH_GMAC1_USXGMII :
+	       (mac_id == MTK_GMAC2_ID) ?  MTK_ETH_PATH_GMAC2_USXGMII :
+					   MTK_ETH_PATH_GMAC3_USXGMII;
+
+	/* Setup proper MUXes along the path */
+	return mtk_eth_mux_setup(eth, path);
+}
+
 int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id)
 {
 	u64 path;
 
-	path = (mac_id == 0) ?  MTK_ETH_PATH_GMAC1_SGMII :
-				MTK_ETH_PATH_GMAC2_SGMII;
+	path = (mac_id == MTK_GMAC1_ID) ? MTK_ETH_PATH_GMAC1_SGMII :
+	       (mac_id == MTK_GMAC2_ID) ? MTK_ETH_PATH_GMAC2_SGMII :
+					  MTK_ETH_PATH_GMAC3_SGMII;
+
+	/* Setup proper MUXes along the path */
+	return mtk_eth_mux_setup(eth, path);
+}
+
+int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id)
+{
+	u64 path = 0;
+
+	if (mac_id == MTK_GMAC2_ID)
+		path = MTK_ETH_PATH_GMAC2_2P5GPHY;
+
+	if (!path)
+		return -EINVAL;
 
 	/* Setup proper MUXes along the path */
 	return mtk_eth_mux_setup(eth, path);
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 3cf6589cfdacf..a550cf7ab0d91 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -22,6 +22,7 @@
 #include <linux/pinctrl/devinfo.h>
 #include <linux/phylink.h>
 #include <linux/pcs/pcs-mtk-lynxi.h>
+#include <linux/pcs/pcs-mtk-usxgmii.h>
 #include <linux/jhash.h>
 #include <linux/bitfield.h>
 #include <net/dsa.h>
@@ -260,12 +261,8 @@ static const char * const mtk_clks_source_name[] = {
 	"ethwarp_wocpu2",
 	"ethwarp_wocpu1",
 	"ethwarp_wocpu0",
-	"top_usxgmii0_sel",
-	"top_usxgmii1_sel",
 	"top_sgm0_sel",
 	"top_sgm1_sel",
-	"top_xfi_phy0_xtal_sel",
-	"top_xfi_phy1_xtal_sel",
 	"top_eth_gmii_sel",
 	"top_eth_refck_50m_sel",
 	"top_eth_sys_200m_sel",
@@ -508,6 +505,30 @@ static void mtk_setup_bridge_switch(struct mtk_eth *eth)
 		MTK_GSW_CFG);
 }
 
+static bool mtk_check_gmac23_idle(struct mtk_mac *mac)
+{
+	u32 mac_fsm, gdm_fsm;
+
+	mac_fsm = mtk_r32(mac->hw, MTK_MAC_FSM(mac->id));
+
+	switch (mac->id) {
+	case MTK_GMAC2_ID:
+		gdm_fsm = mtk_r32(mac->hw, MTK_FE_GDM2_FSM);
+		break;
+	case MTK_GMAC3_ID:
+		gdm_fsm = mtk_r32(mac->hw, MTK_FE_GDM3_FSM);
+		break;
+	default:
+		return true;
+	};
+
+	if ((mac_fsm & 0xFFFF0000) == 0x01010000 &&
+	    (gdm_fsm & 0xFFFF0000) == 0x00000000)
+		return true;
+
+	return false;
+}
+
 static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
 					      phy_interface_t interface)
 {
@@ -516,6 +537,14 @@ static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
 	struct mtk_eth *eth = mac->hw;
 	unsigned int sid;
 
+	if (mtk_is_netsys_v3_or_greater(eth)) {
+#if IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_USXGMII)
+		return mtk_usxgmii_select_pcs(mac->pcs_of_node, interface);
+#else
+		return NULL;
+#endif
+	}
+
 	if (interface == PHY_INTERFACE_MODE_SGMII ||
 	    phy_interface_mode_is_8023z(interface)) {
 		sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
@@ -567,7 +596,22 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode,
 					goto init_err;
 			}
 			break;
+		case PHY_INTERFACE_MODE_USXGMII:
+		case PHY_INTERFACE_MODE_10GBASER:
+		case PHY_INTERFACE_MODE_5GBASER:
+			if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) {
+				err = mtk_gmac_usxgmii_path_setup(eth, mac->id);
+				if (err)
+					goto init_err;
+			}
+			break;
 		case PHY_INTERFACE_MODE_INTERNAL:
+			if (mac->id == MTK_GMAC2_ID &&
+			    MTK_HAS_CAPS(eth->soc->caps, MTK_2P5GPHY)) {
+				err = mtk_gmac_2p5gphy_path_setup(eth, mac->id);
+				if (err)
+					goto init_err;
+			}
 			break;
 		default:
 			goto err_phy;
@@ -614,8 +658,6 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode,
 		val &= ~SYSCFG0_GE_MODE(SYSCFG0_GE_MASK, mac->id);
 		val |= SYSCFG0_GE_MODE(ge_mode, mac->id);
 		regmap_write(eth->ethsys, ETHSYS_SYSCFG0, val);
-
-		mac->interface = state->interface;
 	}
 
 	/* SGMII */
@@ -632,21 +674,40 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode,
 
 		/* Save the syscfg0 value for mac_finish */
 		mac->syscfg0 = val;
-	} else if (phylink_autoneg_inband(mode)) {
+	} else if (state->interface != PHY_INTERFACE_MODE_USXGMII &&
+		   state->interface != PHY_INTERFACE_MODE_10GBASER &&
+		   state->interface != PHY_INTERFACE_MODE_5GBASER &&
+		   phylink_autoneg_inband(mode)) {
 		dev_err(eth->dev,
-			"In-band mode not supported in non SGMII mode!\n");
+			"In-band mode not supported in non-SerDes modes!\n");
 		return;
 	}
 
 	/* Setup gmac */
-	if (mtk_is_netsys_v3_or_greater(eth) &&
-	    mac->interface == PHY_INTERFACE_MODE_INTERNAL) {
-		mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id));
-		mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id));
+	if (mtk_is_netsys_v3_or_greater(eth)) {
+		if (mtk_interface_mode_is_xgmii(state->interface)) {
+			mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id));
+			mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id));
 
-		mtk_setup_bridge_switch(eth);
+			if (mac->id == MTK_GMAC1_ID)
+				mtk_setup_bridge_switch(eth);
+		} else {
+			mtk_w32(eth, 0, MTK_GDMA_EG_CTRL(mac->id));
+
+			/* FIXME: In current hardware design, we have to reset FE
+			 * when swtiching XGDM to GDM. Therefore, here trigger an SER
+			 * to let GDM go back to the initial state.
+			 */
+			if ((mtk_interface_mode_is_xgmii(mac->interface) ||
+			     mac->interface == PHY_INTERFACE_MODE_NA) &&
+			    !mtk_check_gmac23_idle(mac) &&
+			    !test_bit(MTK_RESETTING, &eth->state))
+				schedule_work(&eth->pending_work);
+		}
 	}
 
+	mac->interface = state->interface;
+
 	return;
 
 err_phy:
@@ -692,10 +753,13 @@ static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode,
 {
 	struct mtk_mac *mac = container_of(config, struct mtk_mac,
 					   phylink_config);
-	u32 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
 
-	mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN);
-	mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
+	if (!mtk_interface_mode_is_xgmii(interface)) {
+		mtk_m32(mac->hw, MAC_MCR_TX_EN | MAC_MCR_RX_EN, 0, MTK_MAC_MCR(mac->id));
+		mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), 0, MTK_XGMAC_STS(mac->id));
+	} else if (mac->id != MTK_GMAC1_ID) {
+		mtk_m32(mac->hw, XMAC_MCR_TRX_DISABLE, XMAC_MCR_TRX_DISABLE, MTK_XMAC_MCR(mac->id));
+	}
 }
 
 static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx,
@@ -767,13 +831,11 @@ static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx,
 	mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
 }
 
-static void mtk_mac_link_up(struct phylink_config *config,
-			    struct phy_device *phy,
-			    unsigned int mode, phy_interface_t interface,
-			    int speed, int duplex, bool tx_pause, bool rx_pause)
+static void mtk_gdm_mac_link_up(struct mtk_mac *mac,
+				struct phy_device *phy,
+				unsigned int mode, phy_interface_t interface,
+				int speed, int duplex, bool tx_pause, bool rx_pause)
 {
-	struct mtk_mac *mac = container_of(config, struct mtk_mac,
-					   phylink_config);
 	u32 mcr;
 
 	mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
@@ -807,6 +869,55 @@ static void mtk_mac_link_up(struct phylink_config *config,
 	mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
 }
 
+static void mtk_xgdm_mac_link_up(struct mtk_mac *mac,
+				 struct phy_device *phy,
+				 unsigned int mode, phy_interface_t interface,
+				 int speed, int duplex, bool tx_pause, bool rx_pause)
+{
+	u32 mcr, force_link = 0;
+
+	if (mac->id == MTK_GMAC1_ID)
+		return;
+
+	/* Eliminate the interference(before link-up) caused by PHY noise */
+	mtk_m32(mac->hw, XMAC_LOGIC_RST, 0, MTK_XMAC_LOGIC_RST(mac->id));
+	mdelay(20);
+	mtk_m32(mac->hw, XMAC_GLB_CNTCLR, XMAC_GLB_CNTCLR, MTK_XMAC_CNT_CTRL(mac->id));
+
+	if (mac->interface == PHY_INTERFACE_MODE_INTERNAL || mac->id == MTK_GMAC3_ID)
+		force_link = MTK_XGMAC_FORCE_LINK(mac->id);
+
+	mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), force_link, MTK_XGMAC_STS(mac->id));
+
+	mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id));
+	mcr &= ~(XMAC_MCR_FORCE_TX_FC | XMAC_MCR_FORCE_RX_FC | XMAC_MCR_TRX_DISABLE);
+	/* Configure pause modes -
+	 * phylink will avoid these for half duplex
+	 */
+	if (tx_pause)
+		mcr |= XMAC_MCR_FORCE_TX_FC;
+	if (rx_pause)
+		mcr |= XMAC_MCR_FORCE_RX_FC;
+
+	mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id));
+}
+
+static void mtk_mac_link_up(struct phylink_config *config,
+			    struct phy_device *phy,
+			    unsigned int mode, phy_interface_t interface,
+			    int speed, int duplex, bool tx_pause, bool rx_pause)
+{
+	struct mtk_mac *mac = container_of(config, struct mtk_mac,
+					   phylink_config);
+
+	if (mtk_interface_mode_is_xgmii(interface))
+		mtk_xgdm_mac_link_up(mac, phy, mode, interface, speed, duplex,
+				     tx_pause, rx_pause);
+	else
+		mtk_gdm_mac_link_up(mac, phy, mode, interface, speed, duplex,
+				    tx_pause, rx_pause);
+}
+
 static const struct phylink_mac_ops mtk_phylink_ops = {
 	.mac_select_pcs = mtk_mac_select_pcs,
 	.mac_config = mtk_mac_config,
@@ -4484,6 +4595,7 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
 	const __be32 *_id = of_get_property(np, "reg", NULL);
 	phy_interface_t phy_mode;
 	struct phylink *phylink;
+	struct phylink_pcs *pcs;
 	struct mtk_mac *mac;
 	int id, err;
 	int txqs = 1;
@@ -4518,6 +4630,12 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
 	mac->id = id;
 	mac->hw = eth;
 	mac->of_node = np;
+	mac->pcs_of_node = of_parse_phandle(mac->of_node, "pcs-handle", 0);
+	if (mac->pcs_of_node) {
+		pcs = mtk_usxgmii_select_pcs(mac->pcs_of_node, PHY_INTERFACE_MODE_NA);
+		if (IS_ERR(pcs))
+			return PTR_ERR(pcs);
+	}
 
 	err = of_get_ethdev_address(mac->of_node, eth->netdev[id]);
 	if (err == -EPROBE_DEFER)
@@ -4610,8 +4728,21 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
 		phy_interface_zero(mac->phylink_config.supported_interfaces);
 		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
 			  mac->phylink_config.supported_interfaces);
+	} else if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_USXGMII)) {
+		mac->phylink_config.mac_capabilities |= MAC_5000FD | MAC_10000FD;
+		__set_bit(PHY_INTERFACE_MODE_5GBASER,
+			  mac->phylink_config.supported_interfaces);
+		__set_bit(PHY_INTERFACE_MODE_10GBASER,
+			  mac->phylink_config.supported_interfaces);
+		__set_bit(PHY_INTERFACE_MODE_USXGMII,
+			  mac->phylink_config.supported_interfaces);
 	}
 
+	if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_2P5GPHY) &&
+	    id == MTK_GMAC2_ID)
+		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
+			  mac->phylink_config.supported_interfaces);
+
 	phylink = phylink_create(&mac->phylink_config,
 				 of_fwnode_handle(mac->of_node),
 				 phy_mode, &mtk_phylink_ops);
@@ -4805,7 +4936,8 @@ static int mtk_probe(struct platform_device *pdev)
 			regmap_write(cci, 0, 3);
 	}
 
-	if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) {
+	if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII) &&
+	    !mtk_is_netsys_v3_or_greater(eth)) {
 		err = mtk_sgmii_init(eth);
 
 		if (err)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 9ae3b8a71d0e6..ba5998ef7965e 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -15,6 +15,7 @@
 #include <linux/u64_stats_sync.h>
 #include <linux/refcount.h>
 #include <linux/phylink.h>
+#include <linux/reset.h>
 #include <linux/rhashtable.h>
 #include <linux/dim.h>
 #include <linux/bitfield.h>
@@ -503,6 +504,21 @@
 #define INTF_MODE_RGMII_1000    (TRGMII_MODE | TRGMII_CENTRAL_ALIGNED)
 #define INTF_MODE_RGMII_10_100  0
 
+/* XFI Mac control registers */
+#define MTK_XMAC_BASE(x)	(0x12000 + (((x) - 1) * 0x1000))
+#define MTK_XMAC_MCR(x)		(MTK_XMAC_BASE(x))
+#define XMAC_MCR_TRX_DISABLE	0xf
+#define XMAC_MCR_FORCE_TX_FC	BIT(5)
+#define XMAC_MCR_FORCE_RX_FC	BIT(4)
+
+/* XFI Mac logic reset registers */
+#define MTK_XMAC_LOGIC_RST(x)	(MTK_XMAC_BASE(x) + 0x10)
+#define XMAC_LOGIC_RST		BIT(0)
+
+/* XFI Mac count global control */
+#define MTK_XMAC_CNT_CTRL(x)	(MTK_XMAC_BASE(x) + 0x100)
+#define XMAC_GLB_CNTCLR		BIT(0)
+
 /* GPIO port control registers for GMAC 2*/
 #define GPIO_OD33_CTRL8		0x4c0
 #define GPIO_BIAS_CTRL		0xed0
@@ -528,6 +544,7 @@
 #define SYSCFG0_SGMII_GMAC2    ((3 << 8) & SYSCFG0_SGMII_MASK)
 #define SYSCFG0_SGMII_GMAC1_V2 BIT(9)
 #define SYSCFG0_SGMII_GMAC2_V2 BIT(8)
+#define SYSCFG0_SGMII_GMAC3_V2 BIT(7)
 
 
 /* ethernet subsystem clock register */
@@ -566,6 +583,11 @@
 #define GEPHY_MAC_SEL          BIT(1)
 
 /* Top misc registers */
+#define TOP_MISC_NETSYS_PCS_MUX	0x84
+#define NETSYS_PCS_MUX_MASK	GENMASK(1, 0)
+#define	MUX_G2_USXGMII_SEL	BIT(1)
+#define MUX_HSGMII1_G1_SEL	BIT(0)
+
 #define USB_PHY_SWITCH_REG	0x218
 #define QPHY_SEL_MASK		GENMASK(1, 0)
 #define SGMII_QPHY_SEL		0x2
@@ -590,6 +612,8 @@
 #define MT7628_SDM_RBCNT	(MT7628_SDM_OFFSET + 0x10c)
 #define MT7628_SDM_CS_ERR	(MT7628_SDM_OFFSET + 0x110)
 
+/* Debug Purpose Register */
+#define MTK_PSE_FQFC_CFG	0x100
 #define MTK_FE_CDM1_FSM		0x220
 #define MTK_FE_CDM2_FSM		0x224
 #define MTK_FE_CDM3_FSM		0x238
@@ -598,6 +622,11 @@
 #define MTK_FE_CDM6_FSM		0x328
 #define MTK_FE_GDM1_FSM		0x228
 #define MTK_FE_GDM2_FSM		0x22C
+#define MTK_FE_GDM3_FSM		0x23C
+#define MTK_FE_PSE_FREE		0x240
+#define MTK_FE_DROP_FQ		0x244
+#define MTK_FE_DROP_FC		0x248
+#define MTK_FE_DROP_PPE		0x24C
 
 #define MTK_MAC_FSM(x)		(0x1010C + ((x) * 0x100))
 
@@ -722,12 +751,8 @@ enum mtk_clks_map {
 	MTK_CLK_ETHWARP_WOCPU2,
 	MTK_CLK_ETHWARP_WOCPU1,
 	MTK_CLK_ETHWARP_WOCPU0,
-	MTK_CLK_TOP_USXGMII_SBUS_0_SEL,
-	MTK_CLK_TOP_USXGMII_SBUS_1_SEL,
 	MTK_CLK_TOP_SGM_0_SEL,
 	MTK_CLK_TOP_SGM_1_SEL,
-	MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL,
-	MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL,
 	MTK_CLK_TOP_ETH_GMII_SEL,
 	MTK_CLK_TOP_ETH_REFCK_50M_SEL,
 	MTK_CLK_TOP_ETH_SYS_200M_SEL,
@@ -798,19 +823,9 @@ enum mtk_clks_map {
 				 BIT_ULL(MTK_CLK_GP3) | BIT_ULL(MTK_CLK_XGP1) | \
 				 BIT_ULL(MTK_CLK_XGP2) | BIT_ULL(MTK_CLK_XGP3) | \
 				 BIT_ULL(MTK_CLK_CRYPTO) | \
-				 BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
-				 BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
-				 BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
-				 BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
 				 BIT_ULL(MTK_CLK_ETHWARP_WOCPU2) | \
 				 BIT_ULL(MTK_CLK_ETHWARP_WOCPU1) | \
 				 BIT_ULL(MTK_CLK_ETHWARP_WOCPU0) | \
-				 BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_0_SEL) | \
-				 BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_1_SEL) | \
-				 BIT_ULL(MTK_CLK_TOP_SGM_0_SEL) | \
-				 BIT_ULL(MTK_CLK_TOP_SGM_1_SEL) | \
-				 BIT_ULL(MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL) | \
-				 BIT_ULL(MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL) | \
 				 BIT_ULL(MTK_CLK_TOP_ETH_GMII_SEL) | \
 				 BIT_ULL(MTK_CLK_TOP_ETH_REFCK_50M_SEL) | \
 				 BIT_ULL(MTK_CLK_TOP_ETH_SYS_200M_SEL) | \
@@ -944,6 +959,8 @@ enum mkt_eth_capabilities {
 	MTK_RGMII_BIT = 0,
 	MTK_TRGMII_BIT,
 	MTK_SGMII_BIT,
+	MTK_USXGMII_BIT,
+	MTK_2P5GPHY_BIT,
 	MTK_ESW_BIT,
 	MTK_GEPHY_BIT,
 	MTK_MUX_BIT,
@@ -964,8 +981,11 @@ enum mkt_eth_capabilities {
 	MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
 	MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT,
 	MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT,
+	MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT,
 	MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT,
 	MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT,
+	MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT,
+	MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT,
 
 	/* PATH BITS */
 	MTK_ETH_PATH_GMAC1_RGMII_BIT,
@@ -973,14 +993,21 @@ enum mkt_eth_capabilities {
 	MTK_ETH_PATH_GMAC1_SGMII_BIT,
 	MTK_ETH_PATH_GMAC2_RGMII_BIT,
 	MTK_ETH_PATH_GMAC2_SGMII_BIT,
+	MTK_ETH_PATH_GMAC2_2P5GPHY_BIT,
 	MTK_ETH_PATH_GMAC2_GEPHY_BIT,
+	MTK_ETH_PATH_GMAC3_SGMII_BIT,
 	MTK_ETH_PATH_GDM1_ESW_BIT,
+	MTK_ETH_PATH_GMAC1_USXGMII_BIT,
+	MTK_ETH_PATH_GMAC2_USXGMII_BIT,
+	MTK_ETH_PATH_GMAC3_USXGMII_BIT,
 };
 
 /* Supported hardware group on SoCs */
 #define MTK_RGMII		BIT_ULL(MTK_RGMII_BIT)
 #define MTK_TRGMII		BIT_ULL(MTK_TRGMII_BIT)
 #define MTK_SGMII		BIT_ULL(MTK_SGMII_BIT)
+#define MTK_USXGMII		BIT_ULL(MTK_USXGMII_BIT)
+#define MTK_2P5GPHY		BIT_ULL(MTK_2P5GPHY_BIT)
 #define MTK_ESW			BIT_ULL(MTK_ESW_BIT)
 #define MTK_GEPHY		BIT_ULL(MTK_GEPHY_BIT)
 #define MTK_MUX			BIT_ULL(MTK_MUX_BIT)
@@ -1003,10 +1030,16 @@ enum mkt_eth_capabilities {
 	BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
 #define MTK_ETH_MUX_U3_GMAC2_TO_QPHY		\
 	BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
+#define MTK_ETH_MUX_GMAC2_TO_2P5GPHY		\
+	BIT_ULL(MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT)
 #define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII	\
 	BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
 #define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII	\
 	BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
+#define MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII	\
+	BIT_ULL(MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT)
+#define MTK_ETH_MUX_GMAC123_TO_USXGMII	\
+	BIT_ULL(MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT)
 
 /* Supported path present on SoCs */
 #define MTK_ETH_PATH_GMAC1_RGMII	BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT)
@@ -1014,8 +1047,13 @@ enum mkt_eth_capabilities {
 #define MTK_ETH_PATH_GMAC1_SGMII	BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT)
 #define MTK_ETH_PATH_GMAC2_RGMII	BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT)
 #define MTK_ETH_PATH_GMAC2_SGMII	BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT)
+#define MTK_ETH_PATH_GMAC2_2P5GPHY	BIT_ULL(MTK_ETH_PATH_GMAC2_2P5GPHY_BIT)
 #define MTK_ETH_PATH_GMAC2_GEPHY	BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
+#define MTK_ETH_PATH_GMAC3_SGMII	BIT_ULL(MTK_ETH_PATH_GMAC3_SGMII_BIT)
 #define MTK_ETH_PATH_GDM1_ESW		BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT)
+#define MTK_ETH_PATH_GMAC1_USXGMII	BIT_ULL(MTK_ETH_PATH_GMAC1_USXGMII_BIT)
+#define MTK_ETH_PATH_GMAC2_USXGMII	BIT_ULL(MTK_ETH_PATH_GMAC2_USXGMII_BIT)
+#define MTK_ETH_PATH_GMAC3_USXGMII	BIT_ULL(MTK_ETH_PATH_GMAC3_USXGMII_BIT)
 
 #define MTK_GMAC1_RGMII		(MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII)
 #define MTK_GMAC1_TRGMII	(MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
@@ -1023,7 +1061,12 @@ enum mkt_eth_capabilities {
 #define MTK_GMAC2_RGMII		(MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII)
 #define MTK_GMAC2_SGMII		(MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII)
 #define MTK_GMAC2_GEPHY		(MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY)
+#define MTK_GMAC2_2P5GPHY	(MTK_ETH_PATH_GMAC2_2P5GPHY | MTK_2P5GPHY)
+#define MTK_GMAC3_SGMII		(MTK_ETH_PATH_GMAC3_SGMII | MTK_SGMII)
 #define MTK_GDM1_ESW		(MTK_ETH_PATH_GDM1_ESW | MTK_ESW)
+#define MTK_GMAC1_USXGMII	(MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII)
+#define MTK_GMAC2_USXGMII	(MTK_ETH_PATH_GMAC2_USXGMII | MTK_USXGMII)
+#define MTK_GMAC3_USXGMII	(MTK_ETH_PATH_GMAC3_USXGMII | MTK_USXGMII)
 
 /* MUXes present on SoCs */
 /* 0: GDM1 -> GMAC1, 1: GDM1 -> ESW */
@@ -1042,10 +1085,20 @@ enum mkt_eth_capabilities {
 	(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_MUX | \
 	MTK_SHARED_SGMII)
 
+/* 2: GMAC2 -> XGMII */
+#define MTK_MUX_GMAC2_TO_2P5GPHY      \
+	(MTK_ETH_MUX_GMAC2_TO_2P5GPHY | MTK_MUX | MTK_INFRA)
+
 /* 0: GMACx -> GEPHY, 1: GMACx -> SGMII where x is 1 or 2 */
 #define MTK_MUX_GMAC12_TO_GEPHY_SGMII   \
 	(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX)
 
+#define MTK_MUX_GMAC123_TO_GEPHY_SGMII   \
+	(MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII | MTK_MUX)
+
+#define MTK_MUX_GMAC123_TO_USXGMII   \
+	(MTK_ETH_MUX_GMAC123_TO_USXGMII | MTK_MUX | MTK_INFRA)
+
 #define MTK_HAS_CAPS(caps, _x)		(((caps) & (_x)) == (_x))
 
 #define MT7621_CAPS  (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \
@@ -1077,8 +1130,12 @@ enum mkt_eth_capabilities {
 		      MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
 		      MTK_RSTCTRL_PPE1 | MTK_SRAM)
 
-#define MT7988_CAPS  (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_QDMA | \
-		      MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM)
+#define MT7988_CAPS  (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_GMAC1_SGMII | \
+		      MTK_GMAC2_2P5GPHY | MTK_GMAC2_SGMII | MTK_GMAC2_USXGMII | \
+		      MTK_GMAC3_SGMII | MTK_GMAC3_USXGMII | \
+		      MTK_MUX_GMAC123_TO_GEPHY_SGMII | \
+		      MTK_MUX_GMAC123_TO_USXGMII | MTK_MUX_GMAC2_TO_2P5GPHY | \
+		      MTK_QDMA | MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM)
 
 struct mtk_tx_dma_desc_info {
 	dma_addr_t	addr;
@@ -1313,6 +1370,7 @@ struct mtk_mac {
 	phy_interface_t			interface;
 	int				speed;
 	struct device_node		*of_node;
+	struct device_node		*pcs_of_node;
 	struct phylink			*phylink;
 	struct phylink_config		phylink_config;
 	struct mtk_eth			*hw;
@@ -1421,6 +1479,19 @@ static inline u32 mtk_get_ib2_multicast_mask(struct mtk_eth *eth)
 	return MTK_FOE_IB2_MULTICAST;
 }
 
+static inline bool mtk_interface_mode_is_xgmii(phy_interface_t interface)
+{
+	switch (interface) {
+	case PHY_INTERFACE_MODE_INTERNAL:
+	case PHY_INTERFACE_MODE_USXGMII:
+	case PHY_INTERFACE_MODE_10GBASER:
+	case PHY_INTERFACE_MODE_5GBASER:
+		return true;
+	default:
+		return false;
+	}
+}
+
 /* read the hardware status register */
 void mtk_stats_update_mac(struct mtk_mac *mac);
 
@@ -1429,8 +1500,10 @@ u32 mtk_r32(struct mtk_eth *eth, unsigned reg);
 u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg);
 
 int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
+int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id);
 int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id);
 int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id);
+int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id);
 
 int mtk_eth_offload_init(struct mtk_eth *eth);
 int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
-- 
2.42.1

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

* [RFC PATCH 8/8] net: ethernet: mtk_eth_soc: add paths and SerDes modes for MT7988
@ 2023-11-09 21:52   ` Daniel Golle
  0 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 21:52 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Daniel Golle, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

MT7988 comes with a built-in 2.5G PHY as well as SerDes lanes to
connect external PHYs or transceivers in USXGMII, 10GBase-R, 5GBase-R,
2500Base-X, 1000Base-X and Cisco SGMII interface modes.

Implement support for configuring for the new paths to SerDes interfaces
and the internal 2.5G PHY.

Add USXGMII PCS driver for 10GBase-R, 5GBase-R and USXGMII mode, and
setup the new PHYA on MT7988 to access the also still existing old
LynxI PCS for 1000Base-X, 2500Base-X and Cisco SGMII PCS interface
modes.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 drivers/net/ethernet/mediatek/Kconfig        |  17 ++
 drivers/net/ethernet/mediatek/mtk_eth_path.c | 122 ++++++++++++-
 drivers/net/ethernet/mediatek/mtk_eth_soc.c  | 178 ++++++++++++++++---
 drivers/net/ethernet/mediatek/mtk_eth_soc.h  | 105 +++++++++--
 4 files changed, 379 insertions(+), 43 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/Kconfig b/drivers/net/ethernet/mediatek/Kconfig
index da0db417ab690..b63723b8d1d2c 100644
--- a/drivers/net/ethernet/mediatek/Kconfig
+++ b/drivers/net/ethernet/mediatek/Kconfig
@@ -21,10 +21,27 @@ config NET_MEDIATEK_SOC
 	select PAGE_POOL_STATS
 	select PCS_MTK_LYNXI
 	select REGMAP_MMIO
+	select PCS_MTK_USXGMII if NET_MEDIATEK_SOC_USXGMII
 	help
 	  This driver supports the gigabit ethernet MACs in the
 	  MediaTek SoC family.
 
+config NET_MEDIATEK_SOC_USXGMII
+	bool "Support USXGMII SerDes on MT7988"
+	depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
+	def_bool NET_MEDIATEK_SOC != n
+	help
+	  Include support for 10GE SerDes which can be found on MT7988.
+	  If this kernel should run on SoCs with 10 GBit/s Ethernet you
+	  will need to select this option to use GMAC2 and GMAC3 with
+	  external PHYs, SFP(+) cages in 10GBase-R, 5GBase-R or USXGMII
+	  interface modes.
+
+	  Note that as the 2500Base-X/1000Base-X/Cisco SGMII SerDes PCS
+	  unit (MediaTek LynxI) in MT7988 is connected via the new 10GE
+	  SerDes, you will also need to select this option in case you
+	  want to use any of those SerDes modes.
+
 config NET_MEDIATEK_STAR_EMAC
 	tristate "MediaTek STAR Ethernet MAC support"
 	select PHYLIB
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_path.c b/drivers/net/ethernet/mediatek/mtk_eth_path.c
index 7c27a19c4d8f4..3f4f4cfe6a233 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
@@ -31,10 +31,20 @@ static const char *mtk_eth_path_name(u64 path)
 		return "gmac2_rgmii";
 	case MTK_ETH_PATH_GMAC2_SGMII:
 		return "gmac2_sgmii";
+	case MTK_ETH_PATH_GMAC2_2P5GPHY:
+		return "gmac2_2p5gphy";
 	case MTK_ETH_PATH_GMAC2_GEPHY:
 		return "gmac2_gephy";
+	case MTK_ETH_PATH_GMAC3_SGMII:
+		return "gmac3_sgmii";
 	case MTK_ETH_PATH_GDM1_ESW:
 		return "gdm1_esw";
+	case MTK_ETH_PATH_GMAC1_USXGMII:
+		return "gmac1_usxgmii";
+	case MTK_ETH_PATH_GMAC2_USXGMII:
+		return "gmac2_usxgmii";
+	case MTK_ETH_PATH_GMAC3_USXGMII:
+		return "gmac3_usxgmii";
 	default:
 		return "unknown path";
 	}
@@ -127,6 +137,27 @@ static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, u64 path)
 	return 0;
 }
 
+static int set_mux_gmac2_to_2p5gphy(struct mtk_eth *eth, u64 path)
+{
+	int ret;
+
+	if (path == MTK_ETH_PATH_GMAC2_2P5GPHY) {
+		ret = regmap_clear_bits(eth->ethsys, ETHSYS_SYSCFG0, SYSCFG0_SGMII_GMAC2_V2);
+		if (ret)
+			return ret;
+
+		/* Setup mux to 2p5g PHY */
+		ret = regmap_clear_bits(eth->infra, TOP_MISC_NETSYS_PCS_MUX, MUX_G2_USXGMII_SEL);
+		if (ret)
+			return ret;
+
+		dev_dbg(eth->dev, "path %s in %s updated\n",
+			mtk_eth_path_name(path), __func__);
+	}
+
+	return 0;
+}
+
 static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path)
 {
 	unsigned int val = 0;
@@ -165,7 +196,48 @@ static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path)
 	return 0;
 }
 
-static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
+static int set_mux_gmac123_to_usxgmii(struct mtk_eth *eth, u64 path)
+{
+	unsigned int val = 0;
+	bool updated = true;
+	int mac_id = 0;
+
+	/* Disable SYSCFG1 SGMII */
+	regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val);
+
+	switch (path) {
+	case MTK_ETH_PATH_GMAC1_USXGMII:
+		val &= ~(u32)SYSCFG0_SGMII_GMAC1_V2;
+		mac_id = MTK_GMAC1_ID;
+		break;
+	case MTK_ETH_PATH_GMAC2_USXGMII:
+		val &= ~(u32)SYSCFG0_SGMII_GMAC2_V2;
+		mac_id = MTK_GMAC2_ID;
+		break;
+	case MTK_ETH_PATH_GMAC3_USXGMII:
+		val &= ~(u32)SYSCFG0_SGMII_GMAC3_V2;
+		mac_id = MTK_GMAC3_ID;
+		break;
+	default:
+		updated = false;
+	};
+
+	if (updated) {
+		regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
+				   SYSCFG0_SGMII_MASK, val);
+
+		if (mac_id == MTK_GMAC2_ID)
+			regmap_set_bits(eth->infra, TOP_MISC_NETSYS_PCS_MUX,
+					MUX_G2_USXGMII_SEL);
+	}
+
+	dev_dbg(eth->dev, "path %s in %s updated = %d\n",
+		mtk_eth_path_name(path), __func__, updated);
+
+	return 0;
+}
+
+static int set_mux_gmac123_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
 {
 	unsigned int val = 0;
 	bool updated = true;
@@ -182,6 +254,9 @@ static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
 	case MTK_ETH_PATH_GMAC2_SGMII:
 		val |= SYSCFG0_SGMII_GMAC2_V2;
 		break;
+	case MTK_ETH_PATH_GMAC3_SGMII:
+		val |= SYSCFG0_SGMII_GMAC3_V2;
+		break;
 	default:
 		updated = false;
 	}
@@ -209,6 +284,10 @@ static const struct mtk_eth_muxc mtk_eth_muxc[] = {
 		.name = "mux_u3_gmac2_to_qphy",
 		.cap_bit = MTK_ETH_MUX_U3_GMAC2_TO_QPHY,
 		.set_path = set_mux_u3_gmac2_to_qphy,
+	}, {
+		.name = "mux_gmac2_to_2p5gphy",
+		.cap_bit = MTK_ETH_MUX_GMAC2_TO_2P5GPHY,
+		.set_path = set_mux_gmac2_to_2p5gphy,
 	}, {
 		.name = "mux_gmac1_gmac2_to_sgmii_rgmii",
 		.cap_bit = MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII,
@@ -216,7 +295,15 @@ static const struct mtk_eth_muxc mtk_eth_muxc[] = {
 	}, {
 		.name = "mux_gmac12_to_gephy_sgmii",
 		.cap_bit = MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII,
-		.set_path = set_mux_gmac12_to_gephy_sgmii,
+		.set_path = set_mux_gmac123_to_gephy_sgmii,
+	}, {
+		.name = "mux_gmac123_to_gephy_sgmii",
+		.cap_bit = MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII,
+		.set_path = set_mux_gmac123_to_gephy_sgmii,
+	}, {
+		.name = "mux_gmac123_to_usxgmii",
+		.cap_bit = MTK_ETH_MUX_GMAC123_TO_USXGMII,
+		.set_path = set_mux_gmac123_to_usxgmii,
 	},
 };
 
@@ -249,12 +336,39 @@ static int mtk_eth_mux_setup(struct mtk_eth *eth, u64 path)
 	return err;
 }
 
+int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id)
+{
+	u64 path;
+
+	path = (mac_id == MTK_GMAC1_ID) ?  MTK_ETH_PATH_GMAC1_USXGMII :
+	       (mac_id == MTK_GMAC2_ID) ?  MTK_ETH_PATH_GMAC2_USXGMII :
+					   MTK_ETH_PATH_GMAC3_USXGMII;
+
+	/* Setup proper MUXes along the path */
+	return mtk_eth_mux_setup(eth, path);
+}
+
 int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id)
 {
 	u64 path;
 
-	path = (mac_id == 0) ?  MTK_ETH_PATH_GMAC1_SGMII :
-				MTK_ETH_PATH_GMAC2_SGMII;
+	path = (mac_id == MTK_GMAC1_ID) ? MTK_ETH_PATH_GMAC1_SGMII :
+	       (mac_id == MTK_GMAC2_ID) ? MTK_ETH_PATH_GMAC2_SGMII :
+					  MTK_ETH_PATH_GMAC3_SGMII;
+
+	/* Setup proper MUXes along the path */
+	return mtk_eth_mux_setup(eth, path);
+}
+
+int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id)
+{
+	u64 path = 0;
+
+	if (mac_id == MTK_GMAC2_ID)
+		path = MTK_ETH_PATH_GMAC2_2P5GPHY;
+
+	if (!path)
+		return -EINVAL;
 
 	/* Setup proper MUXes along the path */
 	return mtk_eth_mux_setup(eth, path);
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 3cf6589cfdacf..a550cf7ab0d91 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -22,6 +22,7 @@
 #include <linux/pinctrl/devinfo.h>
 #include <linux/phylink.h>
 #include <linux/pcs/pcs-mtk-lynxi.h>
+#include <linux/pcs/pcs-mtk-usxgmii.h>
 #include <linux/jhash.h>
 #include <linux/bitfield.h>
 #include <net/dsa.h>
@@ -260,12 +261,8 @@ static const char * const mtk_clks_source_name[] = {
 	"ethwarp_wocpu2",
 	"ethwarp_wocpu1",
 	"ethwarp_wocpu0",
-	"top_usxgmii0_sel",
-	"top_usxgmii1_sel",
 	"top_sgm0_sel",
 	"top_sgm1_sel",
-	"top_xfi_phy0_xtal_sel",
-	"top_xfi_phy1_xtal_sel",
 	"top_eth_gmii_sel",
 	"top_eth_refck_50m_sel",
 	"top_eth_sys_200m_sel",
@@ -508,6 +505,30 @@ static void mtk_setup_bridge_switch(struct mtk_eth *eth)
 		MTK_GSW_CFG);
 }
 
+static bool mtk_check_gmac23_idle(struct mtk_mac *mac)
+{
+	u32 mac_fsm, gdm_fsm;
+
+	mac_fsm = mtk_r32(mac->hw, MTK_MAC_FSM(mac->id));
+
+	switch (mac->id) {
+	case MTK_GMAC2_ID:
+		gdm_fsm = mtk_r32(mac->hw, MTK_FE_GDM2_FSM);
+		break;
+	case MTK_GMAC3_ID:
+		gdm_fsm = mtk_r32(mac->hw, MTK_FE_GDM3_FSM);
+		break;
+	default:
+		return true;
+	};
+
+	if ((mac_fsm & 0xFFFF0000) == 0x01010000 &&
+	    (gdm_fsm & 0xFFFF0000) == 0x00000000)
+		return true;
+
+	return false;
+}
+
 static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
 					      phy_interface_t interface)
 {
@@ -516,6 +537,14 @@ static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
 	struct mtk_eth *eth = mac->hw;
 	unsigned int sid;
 
+	if (mtk_is_netsys_v3_or_greater(eth)) {
+#if IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_USXGMII)
+		return mtk_usxgmii_select_pcs(mac->pcs_of_node, interface);
+#else
+		return NULL;
+#endif
+	}
+
 	if (interface == PHY_INTERFACE_MODE_SGMII ||
 	    phy_interface_mode_is_8023z(interface)) {
 		sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
@@ -567,7 +596,22 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode,
 					goto init_err;
 			}
 			break;
+		case PHY_INTERFACE_MODE_USXGMII:
+		case PHY_INTERFACE_MODE_10GBASER:
+		case PHY_INTERFACE_MODE_5GBASER:
+			if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) {
+				err = mtk_gmac_usxgmii_path_setup(eth, mac->id);
+				if (err)
+					goto init_err;
+			}
+			break;
 		case PHY_INTERFACE_MODE_INTERNAL:
+			if (mac->id == MTK_GMAC2_ID &&
+			    MTK_HAS_CAPS(eth->soc->caps, MTK_2P5GPHY)) {
+				err = mtk_gmac_2p5gphy_path_setup(eth, mac->id);
+				if (err)
+					goto init_err;
+			}
 			break;
 		default:
 			goto err_phy;
@@ -614,8 +658,6 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode,
 		val &= ~SYSCFG0_GE_MODE(SYSCFG0_GE_MASK, mac->id);
 		val |= SYSCFG0_GE_MODE(ge_mode, mac->id);
 		regmap_write(eth->ethsys, ETHSYS_SYSCFG0, val);
-
-		mac->interface = state->interface;
 	}
 
 	/* SGMII */
@@ -632,21 +674,40 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode,
 
 		/* Save the syscfg0 value for mac_finish */
 		mac->syscfg0 = val;
-	} else if (phylink_autoneg_inband(mode)) {
+	} else if (state->interface != PHY_INTERFACE_MODE_USXGMII &&
+		   state->interface != PHY_INTERFACE_MODE_10GBASER &&
+		   state->interface != PHY_INTERFACE_MODE_5GBASER &&
+		   phylink_autoneg_inband(mode)) {
 		dev_err(eth->dev,
-			"In-band mode not supported in non SGMII mode!\n");
+			"In-band mode not supported in non-SerDes modes!\n");
 		return;
 	}
 
 	/* Setup gmac */
-	if (mtk_is_netsys_v3_or_greater(eth) &&
-	    mac->interface == PHY_INTERFACE_MODE_INTERNAL) {
-		mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id));
-		mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id));
+	if (mtk_is_netsys_v3_or_greater(eth)) {
+		if (mtk_interface_mode_is_xgmii(state->interface)) {
+			mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id));
+			mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id));
 
-		mtk_setup_bridge_switch(eth);
+			if (mac->id == MTK_GMAC1_ID)
+				mtk_setup_bridge_switch(eth);
+		} else {
+			mtk_w32(eth, 0, MTK_GDMA_EG_CTRL(mac->id));
+
+			/* FIXME: In current hardware design, we have to reset FE
+			 * when swtiching XGDM to GDM. Therefore, here trigger an SER
+			 * to let GDM go back to the initial state.
+			 */
+			if ((mtk_interface_mode_is_xgmii(mac->interface) ||
+			     mac->interface == PHY_INTERFACE_MODE_NA) &&
+			    !mtk_check_gmac23_idle(mac) &&
+			    !test_bit(MTK_RESETTING, &eth->state))
+				schedule_work(&eth->pending_work);
+		}
 	}
 
+	mac->interface = state->interface;
+
 	return;
 
 err_phy:
@@ -692,10 +753,13 @@ static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode,
 {
 	struct mtk_mac *mac = container_of(config, struct mtk_mac,
 					   phylink_config);
-	u32 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
 
-	mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN);
-	mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
+	if (!mtk_interface_mode_is_xgmii(interface)) {
+		mtk_m32(mac->hw, MAC_MCR_TX_EN | MAC_MCR_RX_EN, 0, MTK_MAC_MCR(mac->id));
+		mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), 0, MTK_XGMAC_STS(mac->id));
+	} else if (mac->id != MTK_GMAC1_ID) {
+		mtk_m32(mac->hw, XMAC_MCR_TRX_DISABLE, XMAC_MCR_TRX_DISABLE, MTK_XMAC_MCR(mac->id));
+	}
 }
 
 static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx,
@@ -767,13 +831,11 @@ static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx,
 	mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
 }
 
-static void mtk_mac_link_up(struct phylink_config *config,
-			    struct phy_device *phy,
-			    unsigned int mode, phy_interface_t interface,
-			    int speed, int duplex, bool tx_pause, bool rx_pause)
+static void mtk_gdm_mac_link_up(struct mtk_mac *mac,
+				struct phy_device *phy,
+				unsigned int mode, phy_interface_t interface,
+				int speed, int duplex, bool tx_pause, bool rx_pause)
 {
-	struct mtk_mac *mac = container_of(config, struct mtk_mac,
-					   phylink_config);
 	u32 mcr;
 
 	mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
@@ -807,6 +869,55 @@ static void mtk_mac_link_up(struct phylink_config *config,
 	mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
 }
 
+static void mtk_xgdm_mac_link_up(struct mtk_mac *mac,
+				 struct phy_device *phy,
+				 unsigned int mode, phy_interface_t interface,
+				 int speed, int duplex, bool tx_pause, bool rx_pause)
+{
+	u32 mcr, force_link = 0;
+
+	if (mac->id == MTK_GMAC1_ID)
+		return;
+
+	/* Eliminate the interference(before link-up) caused by PHY noise */
+	mtk_m32(mac->hw, XMAC_LOGIC_RST, 0, MTK_XMAC_LOGIC_RST(mac->id));
+	mdelay(20);
+	mtk_m32(mac->hw, XMAC_GLB_CNTCLR, XMAC_GLB_CNTCLR, MTK_XMAC_CNT_CTRL(mac->id));
+
+	if (mac->interface == PHY_INTERFACE_MODE_INTERNAL || mac->id == MTK_GMAC3_ID)
+		force_link = MTK_XGMAC_FORCE_LINK(mac->id);
+
+	mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), force_link, MTK_XGMAC_STS(mac->id));
+
+	mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id));
+	mcr &= ~(XMAC_MCR_FORCE_TX_FC | XMAC_MCR_FORCE_RX_FC | XMAC_MCR_TRX_DISABLE);
+	/* Configure pause modes -
+	 * phylink will avoid these for half duplex
+	 */
+	if (tx_pause)
+		mcr |= XMAC_MCR_FORCE_TX_FC;
+	if (rx_pause)
+		mcr |= XMAC_MCR_FORCE_RX_FC;
+
+	mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id));
+}
+
+static void mtk_mac_link_up(struct phylink_config *config,
+			    struct phy_device *phy,
+			    unsigned int mode, phy_interface_t interface,
+			    int speed, int duplex, bool tx_pause, bool rx_pause)
+{
+	struct mtk_mac *mac = container_of(config, struct mtk_mac,
+					   phylink_config);
+
+	if (mtk_interface_mode_is_xgmii(interface))
+		mtk_xgdm_mac_link_up(mac, phy, mode, interface, speed, duplex,
+				     tx_pause, rx_pause);
+	else
+		mtk_gdm_mac_link_up(mac, phy, mode, interface, speed, duplex,
+				    tx_pause, rx_pause);
+}
+
 static const struct phylink_mac_ops mtk_phylink_ops = {
 	.mac_select_pcs = mtk_mac_select_pcs,
 	.mac_config = mtk_mac_config,
@@ -4484,6 +4595,7 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
 	const __be32 *_id = of_get_property(np, "reg", NULL);
 	phy_interface_t phy_mode;
 	struct phylink *phylink;
+	struct phylink_pcs *pcs;
 	struct mtk_mac *mac;
 	int id, err;
 	int txqs = 1;
@@ -4518,6 +4630,12 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
 	mac->id = id;
 	mac->hw = eth;
 	mac->of_node = np;
+	mac->pcs_of_node = of_parse_phandle(mac->of_node, "pcs-handle", 0);
+	if (mac->pcs_of_node) {
+		pcs = mtk_usxgmii_select_pcs(mac->pcs_of_node, PHY_INTERFACE_MODE_NA);
+		if (IS_ERR(pcs))
+			return PTR_ERR(pcs);
+	}
 
 	err = of_get_ethdev_address(mac->of_node, eth->netdev[id]);
 	if (err == -EPROBE_DEFER)
@@ -4610,8 +4728,21 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
 		phy_interface_zero(mac->phylink_config.supported_interfaces);
 		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
 			  mac->phylink_config.supported_interfaces);
+	} else if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_USXGMII)) {
+		mac->phylink_config.mac_capabilities |= MAC_5000FD | MAC_10000FD;
+		__set_bit(PHY_INTERFACE_MODE_5GBASER,
+			  mac->phylink_config.supported_interfaces);
+		__set_bit(PHY_INTERFACE_MODE_10GBASER,
+			  mac->phylink_config.supported_interfaces);
+		__set_bit(PHY_INTERFACE_MODE_USXGMII,
+			  mac->phylink_config.supported_interfaces);
 	}
 
+	if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_2P5GPHY) &&
+	    id == MTK_GMAC2_ID)
+		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
+			  mac->phylink_config.supported_interfaces);
+
 	phylink = phylink_create(&mac->phylink_config,
 				 of_fwnode_handle(mac->of_node),
 				 phy_mode, &mtk_phylink_ops);
@@ -4805,7 +4936,8 @@ static int mtk_probe(struct platform_device *pdev)
 			regmap_write(cci, 0, 3);
 	}
 
-	if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) {
+	if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII) &&
+	    !mtk_is_netsys_v3_or_greater(eth)) {
 		err = mtk_sgmii_init(eth);
 
 		if (err)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 9ae3b8a71d0e6..ba5998ef7965e 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -15,6 +15,7 @@
 #include <linux/u64_stats_sync.h>
 #include <linux/refcount.h>
 #include <linux/phylink.h>
+#include <linux/reset.h>
 #include <linux/rhashtable.h>
 #include <linux/dim.h>
 #include <linux/bitfield.h>
@@ -503,6 +504,21 @@
 #define INTF_MODE_RGMII_1000    (TRGMII_MODE | TRGMII_CENTRAL_ALIGNED)
 #define INTF_MODE_RGMII_10_100  0
 
+/* XFI Mac control registers */
+#define MTK_XMAC_BASE(x)	(0x12000 + (((x) - 1) * 0x1000))
+#define MTK_XMAC_MCR(x)		(MTK_XMAC_BASE(x))
+#define XMAC_MCR_TRX_DISABLE	0xf
+#define XMAC_MCR_FORCE_TX_FC	BIT(5)
+#define XMAC_MCR_FORCE_RX_FC	BIT(4)
+
+/* XFI Mac logic reset registers */
+#define MTK_XMAC_LOGIC_RST(x)	(MTK_XMAC_BASE(x) + 0x10)
+#define XMAC_LOGIC_RST		BIT(0)
+
+/* XFI Mac count global control */
+#define MTK_XMAC_CNT_CTRL(x)	(MTK_XMAC_BASE(x) + 0x100)
+#define XMAC_GLB_CNTCLR		BIT(0)
+
 /* GPIO port control registers for GMAC 2*/
 #define GPIO_OD33_CTRL8		0x4c0
 #define GPIO_BIAS_CTRL		0xed0
@@ -528,6 +544,7 @@
 #define SYSCFG0_SGMII_GMAC2    ((3 << 8) & SYSCFG0_SGMII_MASK)
 #define SYSCFG0_SGMII_GMAC1_V2 BIT(9)
 #define SYSCFG0_SGMII_GMAC2_V2 BIT(8)
+#define SYSCFG0_SGMII_GMAC3_V2 BIT(7)
 
 
 /* ethernet subsystem clock register */
@@ -566,6 +583,11 @@
 #define GEPHY_MAC_SEL          BIT(1)
 
 /* Top misc registers */
+#define TOP_MISC_NETSYS_PCS_MUX	0x84
+#define NETSYS_PCS_MUX_MASK	GENMASK(1, 0)
+#define	MUX_G2_USXGMII_SEL	BIT(1)
+#define MUX_HSGMII1_G1_SEL	BIT(0)
+
 #define USB_PHY_SWITCH_REG	0x218
 #define QPHY_SEL_MASK		GENMASK(1, 0)
 #define SGMII_QPHY_SEL		0x2
@@ -590,6 +612,8 @@
 #define MT7628_SDM_RBCNT	(MT7628_SDM_OFFSET + 0x10c)
 #define MT7628_SDM_CS_ERR	(MT7628_SDM_OFFSET + 0x110)
 
+/* Debug Purpose Register */
+#define MTK_PSE_FQFC_CFG	0x100
 #define MTK_FE_CDM1_FSM		0x220
 #define MTK_FE_CDM2_FSM		0x224
 #define MTK_FE_CDM3_FSM		0x238
@@ -598,6 +622,11 @@
 #define MTK_FE_CDM6_FSM		0x328
 #define MTK_FE_GDM1_FSM		0x228
 #define MTK_FE_GDM2_FSM		0x22C
+#define MTK_FE_GDM3_FSM		0x23C
+#define MTK_FE_PSE_FREE		0x240
+#define MTK_FE_DROP_FQ		0x244
+#define MTK_FE_DROP_FC		0x248
+#define MTK_FE_DROP_PPE		0x24C
 
 #define MTK_MAC_FSM(x)		(0x1010C + ((x) * 0x100))
 
@@ -722,12 +751,8 @@ enum mtk_clks_map {
 	MTK_CLK_ETHWARP_WOCPU2,
 	MTK_CLK_ETHWARP_WOCPU1,
 	MTK_CLK_ETHWARP_WOCPU0,
-	MTK_CLK_TOP_USXGMII_SBUS_0_SEL,
-	MTK_CLK_TOP_USXGMII_SBUS_1_SEL,
 	MTK_CLK_TOP_SGM_0_SEL,
 	MTK_CLK_TOP_SGM_1_SEL,
-	MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL,
-	MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL,
 	MTK_CLK_TOP_ETH_GMII_SEL,
 	MTK_CLK_TOP_ETH_REFCK_50M_SEL,
 	MTK_CLK_TOP_ETH_SYS_200M_SEL,
@@ -798,19 +823,9 @@ enum mtk_clks_map {
 				 BIT_ULL(MTK_CLK_GP3) | BIT_ULL(MTK_CLK_XGP1) | \
 				 BIT_ULL(MTK_CLK_XGP2) | BIT_ULL(MTK_CLK_XGP3) | \
 				 BIT_ULL(MTK_CLK_CRYPTO) | \
-				 BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
-				 BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
-				 BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
-				 BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
 				 BIT_ULL(MTK_CLK_ETHWARP_WOCPU2) | \
 				 BIT_ULL(MTK_CLK_ETHWARP_WOCPU1) | \
 				 BIT_ULL(MTK_CLK_ETHWARP_WOCPU0) | \
-				 BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_0_SEL) | \
-				 BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_1_SEL) | \
-				 BIT_ULL(MTK_CLK_TOP_SGM_0_SEL) | \
-				 BIT_ULL(MTK_CLK_TOP_SGM_1_SEL) | \
-				 BIT_ULL(MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL) | \
-				 BIT_ULL(MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL) | \
 				 BIT_ULL(MTK_CLK_TOP_ETH_GMII_SEL) | \
 				 BIT_ULL(MTK_CLK_TOP_ETH_REFCK_50M_SEL) | \
 				 BIT_ULL(MTK_CLK_TOP_ETH_SYS_200M_SEL) | \
@@ -944,6 +959,8 @@ enum mkt_eth_capabilities {
 	MTK_RGMII_BIT = 0,
 	MTK_TRGMII_BIT,
 	MTK_SGMII_BIT,
+	MTK_USXGMII_BIT,
+	MTK_2P5GPHY_BIT,
 	MTK_ESW_BIT,
 	MTK_GEPHY_BIT,
 	MTK_MUX_BIT,
@@ -964,8 +981,11 @@ enum mkt_eth_capabilities {
 	MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
 	MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT,
 	MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT,
+	MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT,
 	MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT,
 	MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT,
+	MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT,
+	MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT,
 
 	/* PATH BITS */
 	MTK_ETH_PATH_GMAC1_RGMII_BIT,
@@ -973,14 +993,21 @@ enum mkt_eth_capabilities {
 	MTK_ETH_PATH_GMAC1_SGMII_BIT,
 	MTK_ETH_PATH_GMAC2_RGMII_BIT,
 	MTK_ETH_PATH_GMAC2_SGMII_BIT,
+	MTK_ETH_PATH_GMAC2_2P5GPHY_BIT,
 	MTK_ETH_PATH_GMAC2_GEPHY_BIT,
+	MTK_ETH_PATH_GMAC3_SGMII_BIT,
 	MTK_ETH_PATH_GDM1_ESW_BIT,
+	MTK_ETH_PATH_GMAC1_USXGMII_BIT,
+	MTK_ETH_PATH_GMAC2_USXGMII_BIT,
+	MTK_ETH_PATH_GMAC3_USXGMII_BIT,
 };
 
 /* Supported hardware group on SoCs */
 #define MTK_RGMII		BIT_ULL(MTK_RGMII_BIT)
 #define MTK_TRGMII		BIT_ULL(MTK_TRGMII_BIT)
 #define MTK_SGMII		BIT_ULL(MTK_SGMII_BIT)
+#define MTK_USXGMII		BIT_ULL(MTK_USXGMII_BIT)
+#define MTK_2P5GPHY		BIT_ULL(MTK_2P5GPHY_BIT)
 #define MTK_ESW			BIT_ULL(MTK_ESW_BIT)
 #define MTK_GEPHY		BIT_ULL(MTK_GEPHY_BIT)
 #define MTK_MUX			BIT_ULL(MTK_MUX_BIT)
@@ -1003,10 +1030,16 @@ enum mkt_eth_capabilities {
 	BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
 #define MTK_ETH_MUX_U3_GMAC2_TO_QPHY		\
 	BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
+#define MTK_ETH_MUX_GMAC2_TO_2P5GPHY		\
+	BIT_ULL(MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT)
 #define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII	\
 	BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
 #define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII	\
 	BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
+#define MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII	\
+	BIT_ULL(MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT)
+#define MTK_ETH_MUX_GMAC123_TO_USXGMII	\
+	BIT_ULL(MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT)
 
 /* Supported path present on SoCs */
 #define MTK_ETH_PATH_GMAC1_RGMII	BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT)
@@ -1014,8 +1047,13 @@ enum mkt_eth_capabilities {
 #define MTK_ETH_PATH_GMAC1_SGMII	BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT)
 #define MTK_ETH_PATH_GMAC2_RGMII	BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT)
 #define MTK_ETH_PATH_GMAC2_SGMII	BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT)
+#define MTK_ETH_PATH_GMAC2_2P5GPHY	BIT_ULL(MTK_ETH_PATH_GMAC2_2P5GPHY_BIT)
 #define MTK_ETH_PATH_GMAC2_GEPHY	BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
+#define MTK_ETH_PATH_GMAC3_SGMII	BIT_ULL(MTK_ETH_PATH_GMAC3_SGMII_BIT)
 #define MTK_ETH_PATH_GDM1_ESW		BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT)
+#define MTK_ETH_PATH_GMAC1_USXGMII	BIT_ULL(MTK_ETH_PATH_GMAC1_USXGMII_BIT)
+#define MTK_ETH_PATH_GMAC2_USXGMII	BIT_ULL(MTK_ETH_PATH_GMAC2_USXGMII_BIT)
+#define MTK_ETH_PATH_GMAC3_USXGMII	BIT_ULL(MTK_ETH_PATH_GMAC3_USXGMII_BIT)
 
 #define MTK_GMAC1_RGMII		(MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII)
 #define MTK_GMAC1_TRGMII	(MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
@@ -1023,7 +1061,12 @@ enum mkt_eth_capabilities {
 #define MTK_GMAC2_RGMII		(MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII)
 #define MTK_GMAC2_SGMII		(MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII)
 #define MTK_GMAC2_GEPHY		(MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY)
+#define MTK_GMAC2_2P5GPHY	(MTK_ETH_PATH_GMAC2_2P5GPHY | MTK_2P5GPHY)
+#define MTK_GMAC3_SGMII		(MTK_ETH_PATH_GMAC3_SGMII | MTK_SGMII)
 #define MTK_GDM1_ESW		(MTK_ETH_PATH_GDM1_ESW | MTK_ESW)
+#define MTK_GMAC1_USXGMII	(MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII)
+#define MTK_GMAC2_USXGMII	(MTK_ETH_PATH_GMAC2_USXGMII | MTK_USXGMII)
+#define MTK_GMAC3_USXGMII	(MTK_ETH_PATH_GMAC3_USXGMII | MTK_USXGMII)
 
 /* MUXes present on SoCs */
 /* 0: GDM1 -> GMAC1, 1: GDM1 -> ESW */
@@ -1042,10 +1085,20 @@ enum mkt_eth_capabilities {
 	(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_MUX | \
 	MTK_SHARED_SGMII)
 
+/* 2: GMAC2 -> XGMII */
+#define MTK_MUX_GMAC2_TO_2P5GPHY      \
+	(MTK_ETH_MUX_GMAC2_TO_2P5GPHY | MTK_MUX | MTK_INFRA)
+
 /* 0: GMACx -> GEPHY, 1: GMACx -> SGMII where x is 1 or 2 */
 #define MTK_MUX_GMAC12_TO_GEPHY_SGMII   \
 	(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX)
 
+#define MTK_MUX_GMAC123_TO_GEPHY_SGMII   \
+	(MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII | MTK_MUX)
+
+#define MTK_MUX_GMAC123_TO_USXGMII   \
+	(MTK_ETH_MUX_GMAC123_TO_USXGMII | MTK_MUX | MTK_INFRA)
+
 #define MTK_HAS_CAPS(caps, _x)		(((caps) & (_x)) == (_x))
 
 #define MT7621_CAPS  (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \
@@ -1077,8 +1130,12 @@ enum mkt_eth_capabilities {
 		      MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
 		      MTK_RSTCTRL_PPE1 | MTK_SRAM)
 
-#define MT7988_CAPS  (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_QDMA | \
-		      MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM)
+#define MT7988_CAPS  (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_GMAC1_SGMII | \
+		      MTK_GMAC2_2P5GPHY | MTK_GMAC2_SGMII | MTK_GMAC2_USXGMII | \
+		      MTK_GMAC3_SGMII | MTK_GMAC3_USXGMII | \
+		      MTK_MUX_GMAC123_TO_GEPHY_SGMII | \
+		      MTK_MUX_GMAC123_TO_USXGMII | MTK_MUX_GMAC2_TO_2P5GPHY | \
+		      MTK_QDMA | MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM)
 
 struct mtk_tx_dma_desc_info {
 	dma_addr_t	addr;
@@ -1313,6 +1370,7 @@ struct mtk_mac {
 	phy_interface_t			interface;
 	int				speed;
 	struct device_node		*of_node;
+	struct device_node		*pcs_of_node;
 	struct phylink			*phylink;
 	struct phylink_config		phylink_config;
 	struct mtk_eth			*hw;
@@ -1421,6 +1479,19 @@ static inline u32 mtk_get_ib2_multicast_mask(struct mtk_eth *eth)
 	return MTK_FOE_IB2_MULTICAST;
 }
 
+static inline bool mtk_interface_mode_is_xgmii(phy_interface_t interface)
+{
+	switch (interface) {
+	case PHY_INTERFACE_MODE_INTERNAL:
+	case PHY_INTERFACE_MODE_USXGMII:
+	case PHY_INTERFACE_MODE_10GBASER:
+	case PHY_INTERFACE_MODE_5GBASER:
+		return true;
+	default:
+		return false;
+	}
+}
+
 /* read the hardware status register */
 void mtk_stats_update_mac(struct mtk_mac *mac);
 
@@ -1429,8 +1500,10 @@ u32 mtk_r32(struct mtk_eth *eth, unsigned reg);
 u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg);
 
 int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
+int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id);
 int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id);
 int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id);
+int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id);
 
 int mtk_eth_offload_init(struct mtk_eth *eth);
 int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
-- 
2.42.1

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* [RFC PATCH 8/8] net: ethernet: mtk_eth_soc: add paths and SerDes modes for MT7988
@ 2023-11-09 21:52   ` Daniel Golle
  0 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 21:52 UTC (permalink / raw)
  To: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Daniel Golle, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

MT7988 comes with a built-in 2.5G PHY as well as SerDes lanes to
connect external PHYs or transceivers in USXGMII, 10GBase-R, 5GBase-R,
2500Base-X, 1000Base-X and Cisco SGMII interface modes.

Implement support for configuring for the new paths to SerDes interfaces
and the internal 2.5G PHY.

Add USXGMII PCS driver for 10GBase-R, 5GBase-R and USXGMII mode, and
setup the new PHYA on MT7988 to access the also still existing old
LynxI PCS for 1000Base-X, 2500Base-X and Cisco SGMII PCS interface
modes.

Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
 drivers/net/ethernet/mediatek/Kconfig        |  17 ++
 drivers/net/ethernet/mediatek/mtk_eth_path.c | 122 ++++++++++++-
 drivers/net/ethernet/mediatek/mtk_eth_soc.c  | 178 ++++++++++++++++---
 drivers/net/ethernet/mediatek/mtk_eth_soc.h  | 105 +++++++++--
 4 files changed, 379 insertions(+), 43 deletions(-)

diff --git a/drivers/net/ethernet/mediatek/Kconfig b/drivers/net/ethernet/mediatek/Kconfig
index da0db417ab690..b63723b8d1d2c 100644
--- a/drivers/net/ethernet/mediatek/Kconfig
+++ b/drivers/net/ethernet/mediatek/Kconfig
@@ -21,10 +21,27 @@ config NET_MEDIATEK_SOC
 	select PAGE_POOL_STATS
 	select PCS_MTK_LYNXI
 	select REGMAP_MMIO
+	select PCS_MTK_USXGMII if NET_MEDIATEK_SOC_USXGMII
 	help
 	  This driver supports the gigabit ethernet MACs in the
 	  MediaTek SoC family.
 
+config NET_MEDIATEK_SOC_USXGMII
+	bool "Support USXGMII SerDes on MT7988"
+	depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
+	def_bool NET_MEDIATEK_SOC != n
+	help
+	  Include support for 10GE SerDes which can be found on MT7988.
+	  If this kernel should run on SoCs with 10 GBit/s Ethernet you
+	  will need to select this option to use GMAC2 and GMAC3 with
+	  external PHYs, SFP(+) cages in 10GBase-R, 5GBase-R or USXGMII
+	  interface modes.
+
+	  Note that as the 2500Base-X/1000Base-X/Cisco SGMII SerDes PCS
+	  unit (MediaTek LynxI) in MT7988 is connected via the new 10GE
+	  SerDes, you will also need to select this option in case you
+	  want to use any of those SerDes modes.
+
 config NET_MEDIATEK_STAR_EMAC
 	tristate "MediaTek STAR Ethernet MAC support"
 	select PHYLIB
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_path.c b/drivers/net/ethernet/mediatek/mtk_eth_path.c
index 7c27a19c4d8f4..3f4f4cfe6a233 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_path.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_path.c
@@ -31,10 +31,20 @@ static const char *mtk_eth_path_name(u64 path)
 		return "gmac2_rgmii";
 	case MTK_ETH_PATH_GMAC2_SGMII:
 		return "gmac2_sgmii";
+	case MTK_ETH_PATH_GMAC2_2P5GPHY:
+		return "gmac2_2p5gphy";
 	case MTK_ETH_PATH_GMAC2_GEPHY:
 		return "gmac2_gephy";
+	case MTK_ETH_PATH_GMAC3_SGMII:
+		return "gmac3_sgmii";
 	case MTK_ETH_PATH_GDM1_ESW:
 		return "gdm1_esw";
+	case MTK_ETH_PATH_GMAC1_USXGMII:
+		return "gmac1_usxgmii";
+	case MTK_ETH_PATH_GMAC2_USXGMII:
+		return "gmac2_usxgmii";
+	case MTK_ETH_PATH_GMAC3_USXGMII:
+		return "gmac3_usxgmii";
 	default:
 		return "unknown path";
 	}
@@ -127,6 +137,27 @@ static int set_mux_u3_gmac2_to_qphy(struct mtk_eth *eth, u64 path)
 	return 0;
 }
 
+static int set_mux_gmac2_to_2p5gphy(struct mtk_eth *eth, u64 path)
+{
+	int ret;
+
+	if (path == MTK_ETH_PATH_GMAC2_2P5GPHY) {
+		ret = regmap_clear_bits(eth->ethsys, ETHSYS_SYSCFG0, SYSCFG0_SGMII_GMAC2_V2);
+		if (ret)
+			return ret;
+
+		/* Setup mux to 2p5g PHY */
+		ret = regmap_clear_bits(eth->infra, TOP_MISC_NETSYS_PCS_MUX, MUX_G2_USXGMII_SEL);
+		if (ret)
+			return ret;
+
+		dev_dbg(eth->dev, "path %s in %s updated\n",
+			mtk_eth_path_name(path), __func__);
+	}
+
+	return 0;
+}
+
 static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path)
 {
 	unsigned int val = 0;
@@ -165,7 +196,48 @@ static int set_mux_gmac1_gmac2_to_sgmii_rgmii(struct mtk_eth *eth, u64 path)
 	return 0;
 }
 
-static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
+static int set_mux_gmac123_to_usxgmii(struct mtk_eth *eth, u64 path)
+{
+	unsigned int val = 0;
+	bool updated = true;
+	int mac_id = 0;
+
+	/* Disable SYSCFG1 SGMII */
+	regmap_read(eth->ethsys, ETHSYS_SYSCFG0, &val);
+
+	switch (path) {
+	case MTK_ETH_PATH_GMAC1_USXGMII:
+		val &= ~(u32)SYSCFG0_SGMII_GMAC1_V2;
+		mac_id = MTK_GMAC1_ID;
+		break;
+	case MTK_ETH_PATH_GMAC2_USXGMII:
+		val &= ~(u32)SYSCFG0_SGMII_GMAC2_V2;
+		mac_id = MTK_GMAC2_ID;
+		break;
+	case MTK_ETH_PATH_GMAC3_USXGMII:
+		val &= ~(u32)SYSCFG0_SGMII_GMAC3_V2;
+		mac_id = MTK_GMAC3_ID;
+		break;
+	default:
+		updated = false;
+	};
+
+	if (updated) {
+		regmap_update_bits(eth->ethsys, ETHSYS_SYSCFG0,
+				   SYSCFG0_SGMII_MASK, val);
+
+		if (mac_id == MTK_GMAC2_ID)
+			regmap_set_bits(eth->infra, TOP_MISC_NETSYS_PCS_MUX,
+					MUX_G2_USXGMII_SEL);
+	}
+
+	dev_dbg(eth->dev, "path %s in %s updated = %d\n",
+		mtk_eth_path_name(path), __func__, updated);
+
+	return 0;
+}
+
+static int set_mux_gmac123_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
 {
 	unsigned int val = 0;
 	bool updated = true;
@@ -182,6 +254,9 @@ static int set_mux_gmac12_to_gephy_sgmii(struct mtk_eth *eth, u64 path)
 	case MTK_ETH_PATH_GMAC2_SGMII:
 		val |= SYSCFG0_SGMII_GMAC2_V2;
 		break;
+	case MTK_ETH_PATH_GMAC3_SGMII:
+		val |= SYSCFG0_SGMII_GMAC3_V2;
+		break;
 	default:
 		updated = false;
 	}
@@ -209,6 +284,10 @@ static const struct mtk_eth_muxc mtk_eth_muxc[] = {
 		.name = "mux_u3_gmac2_to_qphy",
 		.cap_bit = MTK_ETH_MUX_U3_GMAC2_TO_QPHY,
 		.set_path = set_mux_u3_gmac2_to_qphy,
+	}, {
+		.name = "mux_gmac2_to_2p5gphy",
+		.cap_bit = MTK_ETH_MUX_GMAC2_TO_2P5GPHY,
+		.set_path = set_mux_gmac2_to_2p5gphy,
 	}, {
 		.name = "mux_gmac1_gmac2_to_sgmii_rgmii",
 		.cap_bit = MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII,
@@ -216,7 +295,15 @@ static const struct mtk_eth_muxc mtk_eth_muxc[] = {
 	}, {
 		.name = "mux_gmac12_to_gephy_sgmii",
 		.cap_bit = MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII,
-		.set_path = set_mux_gmac12_to_gephy_sgmii,
+		.set_path = set_mux_gmac123_to_gephy_sgmii,
+	}, {
+		.name = "mux_gmac123_to_gephy_sgmii",
+		.cap_bit = MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII,
+		.set_path = set_mux_gmac123_to_gephy_sgmii,
+	}, {
+		.name = "mux_gmac123_to_usxgmii",
+		.cap_bit = MTK_ETH_MUX_GMAC123_TO_USXGMII,
+		.set_path = set_mux_gmac123_to_usxgmii,
 	},
 };
 
@@ -249,12 +336,39 @@ static int mtk_eth_mux_setup(struct mtk_eth *eth, u64 path)
 	return err;
 }
 
+int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id)
+{
+	u64 path;
+
+	path = (mac_id == MTK_GMAC1_ID) ?  MTK_ETH_PATH_GMAC1_USXGMII :
+	       (mac_id == MTK_GMAC2_ID) ?  MTK_ETH_PATH_GMAC2_USXGMII :
+					   MTK_ETH_PATH_GMAC3_USXGMII;
+
+	/* Setup proper MUXes along the path */
+	return mtk_eth_mux_setup(eth, path);
+}
+
 int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id)
 {
 	u64 path;
 
-	path = (mac_id == 0) ?  MTK_ETH_PATH_GMAC1_SGMII :
-				MTK_ETH_PATH_GMAC2_SGMII;
+	path = (mac_id == MTK_GMAC1_ID) ? MTK_ETH_PATH_GMAC1_SGMII :
+	       (mac_id == MTK_GMAC2_ID) ? MTK_ETH_PATH_GMAC2_SGMII :
+					  MTK_ETH_PATH_GMAC3_SGMII;
+
+	/* Setup proper MUXes along the path */
+	return mtk_eth_mux_setup(eth, path);
+}
+
+int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id)
+{
+	u64 path = 0;
+
+	if (mac_id == MTK_GMAC2_ID)
+		path = MTK_ETH_PATH_GMAC2_2P5GPHY;
+
+	if (!path)
+		return -EINVAL;
 
 	/* Setup proper MUXes along the path */
 	return mtk_eth_mux_setup(eth, path);
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 3cf6589cfdacf..a550cf7ab0d91 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -22,6 +22,7 @@
 #include <linux/pinctrl/devinfo.h>
 #include <linux/phylink.h>
 #include <linux/pcs/pcs-mtk-lynxi.h>
+#include <linux/pcs/pcs-mtk-usxgmii.h>
 #include <linux/jhash.h>
 #include <linux/bitfield.h>
 #include <net/dsa.h>
@@ -260,12 +261,8 @@ static const char * const mtk_clks_source_name[] = {
 	"ethwarp_wocpu2",
 	"ethwarp_wocpu1",
 	"ethwarp_wocpu0",
-	"top_usxgmii0_sel",
-	"top_usxgmii1_sel",
 	"top_sgm0_sel",
 	"top_sgm1_sel",
-	"top_xfi_phy0_xtal_sel",
-	"top_xfi_phy1_xtal_sel",
 	"top_eth_gmii_sel",
 	"top_eth_refck_50m_sel",
 	"top_eth_sys_200m_sel",
@@ -508,6 +505,30 @@ static void mtk_setup_bridge_switch(struct mtk_eth *eth)
 		MTK_GSW_CFG);
 }
 
+static bool mtk_check_gmac23_idle(struct mtk_mac *mac)
+{
+	u32 mac_fsm, gdm_fsm;
+
+	mac_fsm = mtk_r32(mac->hw, MTK_MAC_FSM(mac->id));
+
+	switch (mac->id) {
+	case MTK_GMAC2_ID:
+		gdm_fsm = mtk_r32(mac->hw, MTK_FE_GDM2_FSM);
+		break;
+	case MTK_GMAC3_ID:
+		gdm_fsm = mtk_r32(mac->hw, MTK_FE_GDM3_FSM);
+		break;
+	default:
+		return true;
+	};
+
+	if ((mac_fsm & 0xFFFF0000) == 0x01010000 &&
+	    (gdm_fsm & 0xFFFF0000) == 0x00000000)
+		return true;
+
+	return false;
+}
+
 static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
 					      phy_interface_t interface)
 {
@@ -516,6 +537,14 @@ static struct phylink_pcs *mtk_mac_select_pcs(struct phylink_config *config,
 	struct mtk_eth *eth = mac->hw;
 	unsigned int sid;
 
+	if (mtk_is_netsys_v3_or_greater(eth)) {
+#if IS_ENABLED(CONFIG_NET_MEDIATEK_SOC_USXGMII)
+		return mtk_usxgmii_select_pcs(mac->pcs_of_node, interface);
+#else
+		return NULL;
+#endif
+	}
+
 	if (interface == PHY_INTERFACE_MODE_SGMII ||
 	    phy_interface_mode_is_8023z(interface)) {
 		sid = (MTK_HAS_CAPS(eth->soc->caps, MTK_SHARED_SGMII)) ?
@@ -567,7 +596,22 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode,
 					goto init_err;
 			}
 			break;
+		case PHY_INTERFACE_MODE_USXGMII:
+		case PHY_INTERFACE_MODE_10GBASER:
+		case PHY_INTERFACE_MODE_5GBASER:
+			if (MTK_HAS_CAPS(eth->soc->caps, MTK_USXGMII)) {
+				err = mtk_gmac_usxgmii_path_setup(eth, mac->id);
+				if (err)
+					goto init_err;
+			}
+			break;
 		case PHY_INTERFACE_MODE_INTERNAL:
+			if (mac->id == MTK_GMAC2_ID &&
+			    MTK_HAS_CAPS(eth->soc->caps, MTK_2P5GPHY)) {
+				err = mtk_gmac_2p5gphy_path_setup(eth, mac->id);
+				if (err)
+					goto init_err;
+			}
 			break;
 		default:
 			goto err_phy;
@@ -614,8 +658,6 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode,
 		val &= ~SYSCFG0_GE_MODE(SYSCFG0_GE_MASK, mac->id);
 		val |= SYSCFG0_GE_MODE(ge_mode, mac->id);
 		regmap_write(eth->ethsys, ETHSYS_SYSCFG0, val);
-
-		mac->interface = state->interface;
 	}
 
 	/* SGMII */
@@ -632,21 +674,40 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode,
 
 		/* Save the syscfg0 value for mac_finish */
 		mac->syscfg0 = val;
-	} else if (phylink_autoneg_inband(mode)) {
+	} else if (state->interface != PHY_INTERFACE_MODE_USXGMII &&
+		   state->interface != PHY_INTERFACE_MODE_10GBASER &&
+		   state->interface != PHY_INTERFACE_MODE_5GBASER &&
+		   phylink_autoneg_inband(mode)) {
 		dev_err(eth->dev,
-			"In-band mode not supported in non SGMII mode!\n");
+			"In-band mode not supported in non-SerDes modes!\n");
 		return;
 	}
 
 	/* Setup gmac */
-	if (mtk_is_netsys_v3_or_greater(eth) &&
-	    mac->interface == PHY_INTERFACE_MODE_INTERNAL) {
-		mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id));
-		mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id));
+	if (mtk_is_netsys_v3_or_greater(eth)) {
+		if (mtk_interface_mode_is_xgmii(state->interface)) {
+			mtk_w32(mac->hw, MTK_GDMA_XGDM_SEL, MTK_GDMA_EG_CTRL(mac->id));
+			mtk_w32(mac->hw, MAC_MCR_FORCE_LINK_DOWN, MTK_MAC_MCR(mac->id));
 
-		mtk_setup_bridge_switch(eth);
+			if (mac->id == MTK_GMAC1_ID)
+				mtk_setup_bridge_switch(eth);
+		} else {
+			mtk_w32(eth, 0, MTK_GDMA_EG_CTRL(mac->id));
+
+			/* FIXME: In current hardware design, we have to reset FE
+			 * when swtiching XGDM to GDM. Therefore, here trigger an SER
+			 * to let GDM go back to the initial state.
+			 */
+			if ((mtk_interface_mode_is_xgmii(mac->interface) ||
+			     mac->interface == PHY_INTERFACE_MODE_NA) &&
+			    !mtk_check_gmac23_idle(mac) &&
+			    !test_bit(MTK_RESETTING, &eth->state))
+				schedule_work(&eth->pending_work);
+		}
 	}
 
+	mac->interface = state->interface;
+
 	return;
 
 err_phy:
@@ -692,10 +753,13 @@ static void mtk_mac_link_down(struct phylink_config *config, unsigned int mode,
 {
 	struct mtk_mac *mac = container_of(config, struct mtk_mac,
 					   phylink_config);
-	u32 mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
 
-	mcr &= ~(MAC_MCR_TX_EN | MAC_MCR_RX_EN);
-	mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
+	if (!mtk_interface_mode_is_xgmii(interface)) {
+		mtk_m32(mac->hw, MAC_MCR_TX_EN | MAC_MCR_RX_EN, 0, MTK_MAC_MCR(mac->id));
+		mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), 0, MTK_XGMAC_STS(mac->id));
+	} else if (mac->id != MTK_GMAC1_ID) {
+		mtk_m32(mac->hw, XMAC_MCR_TRX_DISABLE, XMAC_MCR_TRX_DISABLE, MTK_XMAC_MCR(mac->id));
+	}
 }
 
 static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx,
@@ -767,13 +831,11 @@ static void mtk_set_queue_speed(struct mtk_eth *eth, unsigned int idx,
 	mtk_w32(eth, val, soc->reg_map->qdma.qtx_sch + ofs);
 }
 
-static void mtk_mac_link_up(struct phylink_config *config,
-			    struct phy_device *phy,
-			    unsigned int mode, phy_interface_t interface,
-			    int speed, int duplex, bool tx_pause, bool rx_pause)
+static void mtk_gdm_mac_link_up(struct mtk_mac *mac,
+				struct phy_device *phy,
+				unsigned int mode, phy_interface_t interface,
+				int speed, int duplex, bool tx_pause, bool rx_pause)
 {
-	struct mtk_mac *mac = container_of(config, struct mtk_mac,
-					   phylink_config);
 	u32 mcr;
 
 	mcr = mtk_r32(mac->hw, MTK_MAC_MCR(mac->id));
@@ -807,6 +869,55 @@ static void mtk_mac_link_up(struct phylink_config *config,
 	mtk_w32(mac->hw, mcr, MTK_MAC_MCR(mac->id));
 }
 
+static void mtk_xgdm_mac_link_up(struct mtk_mac *mac,
+				 struct phy_device *phy,
+				 unsigned int mode, phy_interface_t interface,
+				 int speed, int duplex, bool tx_pause, bool rx_pause)
+{
+	u32 mcr, force_link = 0;
+
+	if (mac->id == MTK_GMAC1_ID)
+		return;
+
+	/* Eliminate the interference(before link-up) caused by PHY noise */
+	mtk_m32(mac->hw, XMAC_LOGIC_RST, 0, MTK_XMAC_LOGIC_RST(mac->id));
+	mdelay(20);
+	mtk_m32(mac->hw, XMAC_GLB_CNTCLR, XMAC_GLB_CNTCLR, MTK_XMAC_CNT_CTRL(mac->id));
+
+	if (mac->interface == PHY_INTERFACE_MODE_INTERNAL || mac->id == MTK_GMAC3_ID)
+		force_link = MTK_XGMAC_FORCE_LINK(mac->id);
+
+	mtk_m32(mac->hw, MTK_XGMAC_FORCE_LINK(mac->id), force_link, MTK_XGMAC_STS(mac->id));
+
+	mcr = mtk_r32(mac->hw, MTK_XMAC_MCR(mac->id));
+	mcr &= ~(XMAC_MCR_FORCE_TX_FC | XMAC_MCR_FORCE_RX_FC | XMAC_MCR_TRX_DISABLE);
+	/* Configure pause modes -
+	 * phylink will avoid these for half duplex
+	 */
+	if (tx_pause)
+		mcr |= XMAC_MCR_FORCE_TX_FC;
+	if (rx_pause)
+		mcr |= XMAC_MCR_FORCE_RX_FC;
+
+	mtk_w32(mac->hw, mcr, MTK_XMAC_MCR(mac->id));
+}
+
+static void mtk_mac_link_up(struct phylink_config *config,
+			    struct phy_device *phy,
+			    unsigned int mode, phy_interface_t interface,
+			    int speed, int duplex, bool tx_pause, bool rx_pause)
+{
+	struct mtk_mac *mac = container_of(config, struct mtk_mac,
+					   phylink_config);
+
+	if (mtk_interface_mode_is_xgmii(interface))
+		mtk_xgdm_mac_link_up(mac, phy, mode, interface, speed, duplex,
+				     tx_pause, rx_pause);
+	else
+		mtk_gdm_mac_link_up(mac, phy, mode, interface, speed, duplex,
+				    tx_pause, rx_pause);
+}
+
 static const struct phylink_mac_ops mtk_phylink_ops = {
 	.mac_select_pcs = mtk_mac_select_pcs,
 	.mac_config = mtk_mac_config,
@@ -4484,6 +4595,7 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
 	const __be32 *_id = of_get_property(np, "reg", NULL);
 	phy_interface_t phy_mode;
 	struct phylink *phylink;
+	struct phylink_pcs *pcs;
 	struct mtk_mac *mac;
 	int id, err;
 	int txqs = 1;
@@ -4518,6 +4630,12 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
 	mac->id = id;
 	mac->hw = eth;
 	mac->of_node = np;
+	mac->pcs_of_node = of_parse_phandle(mac->of_node, "pcs-handle", 0);
+	if (mac->pcs_of_node) {
+		pcs = mtk_usxgmii_select_pcs(mac->pcs_of_node, PHY_INTERFACE_MODE_NA);
+		if (IS_ERR(pcs))
+			return PTR_ERR(pcs);
+	}
 
 	err = of_get_ethdev_address(mac->of_node, eth->netdev[id]);
 	if (err == -EPROBE_DEFER)
@@ -4610,8 +4728,21 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
 		phy_interface_zero(mac->phylink_config.supported_interfaces);
 		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
 			  mac->phylink_config.supported_interfaces);
+	} else if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_USXGMII)) {
+		mac->phylink_config.mac_capabilities |= MAC_5000FD | MAC_10000FD;
+		__set_bit(PHY_INTERFACE_MODE_5GBASER,
+			  mac->phylink_config.supported_interfaces);
+		__set_bit(PHY_INTERFACE_MODE_10GBASER,
+			  mac->phylink_config.supported_interfaces);
+		__set_bit(PHY_INTERFACE_MODE_USXGMII,
+			  mac->phylink_config.supported_interfaces);
 	}
 
+	if (MTK_HAS_CAPS(mac->hw->soc->caps, MTK_2P5GPHY) &&
+	    id == MTK_GMAC2_ID)
+		__set_bit(PHY_INTERFACE_MODE_INTERNAL,
+			  mac->phylink_config.supported_interfaces);
+
 	phylink = phylink_create(&mac->phylink_config,
 				 of_fwnode_handle(mac->of_node),
 				 phy_mode, &mtk_phylink_ops);
@@ -4805,7 +4936,8 @@ static int mtk_probe(struct platform_device *pdev)
 			regmap_write(cci, 0, 3);
 	}
 
-	if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII)) {
+	if (MTK_HAS_CAPS(eth->soc->caps, MTK_SGMII) &&
+	    !mtk_is_netsys_v3_or_greater(eth)) {
 		err = mtk_sgmii_init(eth);
 
 		if (err)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 9ae3b8a71d0e6..ba5998ef7965e 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -15,6 +15,7 @@
 #include <linux/u64_stats_sync.h>
 #include <linux/refcount.h>
 #include <linux/phylink.h>
+#include <linux/reset.h>
 #include <linux/rhashtable.h>
 #include <linux/dim.h>
 #include <linux/bitfield.h>
@@ -503,6 +504,21 @@
 #define INTF_MODE_RGMII_1000    (TRGMII_MODE | TRGMII_CENTRAL_ALIGNED)
 #define INTF_MODE_RGMII_10_100  0
 
+/* XFI Mac control registers */
+#define MTK_XMAC_BASE(x)	(0x12000 + (((x) - 1) * 0x1000))
+#define MTK_XMAC_MCR(x)		(MTK_XMAC_BASE(x))
+#define XMAC_MCR_TRX_DISABLE	0xf
+#define XMAC_MCR_FORCE_TX_FC	BIT(5)
+#define XMAC_MCR_FORCE_RX_FC	BIT(4)
+
+/* XFI Mac logic reset registers */
+#define MTK_XMAC_LOGIC_RST(x)	(MTK_XMAC_BASE(x) + 0x10)
+#define XMAC_LOGIC_RST		BIT(0)
+
+/* XFI Mac count global control */
+#define MTK_XMAC_CNT_CTRL(x)	(MTK_XMAC_BASE(x) + 0x100)
+#define XMAC_GLB_CNTCLR		BIT(0)
+
 /* GPIO port control registers for GMAC 2*/
 #define GPIO_OD33_CTRL8		0x4c0
 #define GPIO_BIAS_CTRL		0xed0
@@ -528,6 +544,7 @@
 #define SYSCFG0_SGMII_GMAC2    ((3 << 8) & SYSCFG0_SGMII_MASK)
 #define SYSCFG0_SGMII_GMAC1_V2 BIT(9)
 #define SYSCFG0_SGMII_GMAC2_V2 BIT(8)
+#define SYSCFG0_SGMII_GMAC3_V2 BIT(7)
 
 
 /* ethernet subsystem clock register */
@@ -566,6 +583,11 @@
 #define GEPHY_MAC_SEL          BIT(1)
 
 /* Top misc registers */
+#define TOP_MISC_NETSYS_PCS_MUX	0x84
+#define NETSYS_PCS_MUX_MASK	GENMASK(1, 0)
+#define	MUX_G2_USXGMII_SEL	BIT(1)
+#define MUX_HSGMII1_G1_SEL	BIT(0)
+
 #define USB_PHY_SWITCH_REG	0x218
 #define QPHY_SEL_MASK		GENMASK(1, 0)
 #define SGMII_QPHY_SEL		0x2
@@ -590,6 +612,8 @@
 #define MT7628_SDM_RBCNT	(MT7628_SDM_OFFSET + 0x10c)
 #define MT7628_SDM_CS_ERR	(MT7628_SDM_OFFSET + 0x110)
 
+/* Debug Purpose Register */
+#define MTK_PSE_FQFC_CFG	0x100
 #define MTK_FE_CDM1_FSM		0x220
 #define MTK_FE_CDM2_FSM		0x224
 #define MTK_FE_CDM3_FSM		0x238
@@ -598,6 +622,11 @@
 #define MTK_FE_CDM6_FSM		0x328
 #define MTK_FE_GDM1_FSM		0x228
 #define MTK_FE_GDM2_FSM		0x22C
+#define MTK_FE_GDM3_FSM		0x23C
+#define MTK_FE_PSE_FREE		0x240
+#define MTK_FE_DROP_FQ		0x244
+#define MTK_FE_DROP_FC		0x248
+#define MTK_FE_DROP_PPE		0x24C
 
 #define MTK_MAC_FSM(x)		(0x1010C + ((x) * 0x100))
 
@@ -722,12 +751,8 @@ enum mtk_clks_map {
 	MTK_CLK_ETHWARP_WOCPU2,
 	MTK_CLK_ETHWARP_WOCPU1,
 	MTK_CLK_ETHWARP_WOCPU0,
-	MTK_CLK_TOP_USXGMII_SBUS_0_SEL,
-	MTK_CLK_TOP_USXGMII_SBUS_1_SEL,
 	MTK_CLK_TOP_SGM_0_SEL,
 	MTK_CLK_TOP_SGM_1_SEL,
-	MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL,
-	MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL,
 	MTK_CLK_TOP_ETH_GMII_SEL,
 	MTK_CLK_TOP_ETH_REFCK_50M_SEL,
 	MTK_CLK_TOP_ETH_SYS_200M_SEL,
@@ -798,19 +823,9 @@ enum mtk_clks_map {
 				 BIT_ULL(MTK_CLK_GP3) | BIT_ULL(MTK_CLK_XGP1) | \
 				 BIT_ULL(MTK_CLK_XGP2) | BIT_ULL(MTK_CLK_XGP3) | \
 				 BIT_ULL(MTK_CLK_CRYPTO) | \
-				 BIT_ULL(MTK_CLK_SGMII_TX_250M) | \
-				 BIT_ULL(MTK_CLK_SGMII_RX_250M) | \
-				 BIT_ULL(MTK_CLK_SGMII2_TX_250M) | \
-				 BIT_ULL(MTK_CLK_SGMII2_RX_250M) | \
 				 BIT_ULL(MTK_CLK_ETHWARP_WOCPU2) | \
 				 BIT_ULL(MTK_CLK_ETHWARP_WOCPU1) | \
 				 BIT_ULL(MTK_CLK_ETHWARP_WOCPU0) | \
-				 BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_0_SEL) | \
-				 BIT_ULL(MTK_CLK_TOP_USXGMII_SBUS_1_SEL) | \
-				 BIT_ULL(MTK_CLK_TOP_SGM_0_SEL) | \
-				 BIT_ULL(MTK_CLK_TOP_SGM_1_SEL) | \
-				 BIT_ULL(MTK_CLK_TOP_XFI_PHY_0_XTAL_SEL) | \
-				 BIT_ULL(MTK_CLK_TOP_XFI_PHY_1_XTAL_SEL) | \
 				 BIT_ULL(MTK_CLK_TOP_ETH_GMII_SEL) | \
 				 BIT_ULL(MTK_CLK_TOP_ETH_REFCK_50M_SEL) | \
 				 BIT_ULL(MTK_CLK_TOP_ETH_SYS_200M_SEL) | \
@@ -944,6 +959,8 @@ enum mkt_eth_capabilities {
 	MTK_RGMII_BIT = 0,
 	MTK_TRGMII_BIT,
 	MTK_SGMII_BIT,
+	MTK_USXGMII_BIT,
+	MTK_2P5GPHY_BIT,
 	MTK_ESW_BIT,
 	MTK_GEPHY_BIT,
 	MTK_MUX_BIT,
@@ -964,8 +981,11 @@ enum mkt_eth_capabilities {
 	MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
 	MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT,
 	MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT,
+	MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT,
 	MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT,
 	MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT,
+	MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT,
+	MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT,
 
 	/* PATH BITS */
 	MTK_ETH_PATH_GMAC1_RGMII_BIT,
@@ -973,14 +993,21 @@ enum mkt_eth_capabilities {
 	MTK_ETH_PATH_GMAC1_SGMII_BIT,
 	MTK_ETH_PATH_GMAC2_RGMII_BIT,
 	MTK_ETH_PATH_GMAC2_SGMII_BIT,
+	MTK_ETH_PATH_GMAC2_2P5GPHY_BIT,
 	MTK_ETH_PATH_GMAC2_GEPHY_BIT,
+	MTK_ETH_PATH_GMAC3_SGMII_BIT,
 	MTK_ETH_PATH_GDM1_ESW_BIT,
+	MTK_ETH_PATH_GMAC1_USXGMII_BIT,
+	MTK_ETH_PATH_GMAC2_USXGMII_BIT,
+	MTK_ETH_PATH_GMAC3_USXGMII_BIT,
 };
 
 /* Supported hardware group on SoCs */
 #define MTK_RGMII		BIT_ULL(MTK_RGMII_BIT)
 #define MTK_TRGMII		BIT_ULL(MTK_TRGMII_BIT)
 #define MTK_SGMII		BIT_ULL(MTK_SGMII_BIT)
+#define MTK_USXGMII		BIT_ULL(MTK_USXGMII_BIT)
+#define MTK_2P5GPHY		BIT_ULL(MTK_2P5GPHY_BIT)
 #define MTK_ESW			BIT_ULL(MTK_ESW_BIT)
 #define MTK_GEPHY		BIT_ULL(MTK_GEPHY_BIT)
 #define MTK_MUX			BIT_ULL(MTK_MUX_BIT)
@@ -1003,10 +1030,16 @@ enum mkt_eth_capabilities {
 	BIT_ULL(MTK_ETH_MUX_GMAC2_GMAC0_TO_GEPHY_BIT)
 #define MTK_ETH_MUX_U3_GMAC2_TO_QPHY		\
 	BIT_ULL(MTK_ETH_MUX_U3_GMAC2_TO_QPHY_BIT)
+#define MTK_ETH_MUX_GMAC2_TO_2P5GPHY		\
+	BIT_ULL(MTK_ETH_MUX_GMAC2_TO_2P5GPHY_BIT)
 #define MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII	\
 	BIT_ULL(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII_BIT)
 #define MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII	\
 	BIT_ULL(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII_BIT)
+#define MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII	\
+	BIT_ULL(MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII_BIT)
+#define MTK_ETH_MUX_GMAC123_TO_USXGMII	\
+	BIT_ULL(MTK_ETH_MUX_GMAC123_TO_USXGMII_BIT)
 
 /* Supported path present on SoCs */
 #define MTK_ETH_PATH_GMAC1_RGMII	BIT_ULL(MTK_ETH_PATH_GMAC1_RGMII_BIT)
@@ -1014,8 +1047,13 @@ enum mkt_eth_capabilities {
 #define MTK_ETH_PATH_GMAC1_SGMII	BIT_ULL(MTK_ETH_PATH_GMAC1_SGMII_BIT)
 #define MTK_ETH_PATH_GMAC2_RGMII	BIT_ULL(MTK_ETH_PATH_GMAC2_RGMII_BIT)
 #define MTK_ETH_PATH_GMAC2_SGMII	BIT_ULL(MTK_ETH_PATH_GMAC2_SGMII_BIT)
+#define MTK_ETH_PATH_GMAC2_2P5GPHY	BIT_ULL(MTK_ETH_PATH_GMAC2_2P5GPHY_BIT)
 #define MTK_ETH_PATH_GMAC2_GEPHY	BIT_ULL(MTK_ETH_PATH_GMAC2_GEPHY_BIT)
+#define MTK_ETH_PATH_GMAC3_SGMII	BIT_ULL(MTK_ETH_PATH_GMAC3_SGMII_BIT)
 #define MTK_ETH_PATH_GDM1_ESW		BIT_ULL(MTK_ETH_PATH_GDM1_ESW_BIT)
+#define MTK_ETH_PATH_GMAC1_USXGMII	BIT_ULL(MTK_ETH_PATH_GMAC1_USXGMII_BIT)
+#define MTK_ETH_PATH_GMAC2_USXGMII	BIT_ULL(MTK_ETH_PATH_GMAC2_USXGMII_BIT)
+#define MTK_ETH_PATH_GMAC3_USXGMII	BIT_ULL(MTK_ETH_PATH_GMAC3_USXGMII_BIT)
 
 #define MTK_GMAC1_RGMII		(MTK_ETH_PATH_GMAC1_RGMII | MTK_RGMII)
 #define MTK_GMAC1_TRGMII	(MTK_ETH_PATH_GMAC1_TRGMII | MTK_TRGMII)
@@ -1023,7 +1061,12 @@ enum mkt_eth_capabilities {
 #define MTK_GMAC2_RGMII		(MTK_ETH_PATH_GMAC2_RGMII | MTK_RGMII)
 #define MTK_GMAC2_SGMII		(MTK_ETH_PATH_GMAC2_SGMII | MTK_SGMII)
 #define MTK_GMAC2_GEPHY		(MTK_ETH_PATH_GMAC2_GEPHY | MTK_GEPHY)
+#define MTK_GMAC2_2P5GPHY	(MTK_ETH_PATH_GMAC2_2P5GPHY | MTK_2P5GPHY)
+#define MTK_GMAC3_SGMII		(MTK_ETH_PATH_GMAC3_SGMII | MTK_SGMII)
 #define MTK_GDM1_ESW		(MTK_ETH_PATH_GDM1_ESW | MTK_ESW)
+#define MTK_GMAC1_USXGMII	(MTK_ETH_PATH_GMAC1_USXGMII | MTK_USXGMII)
+#define MTK_GMAC2_USXGMII	(MTK_ETH_PATH_GMAC2_USXGMII | MTK_USXGMII)
+#define MTK_GMAC3_USXGMII	(MTK_ETH_PATH_GMAC3_USXGMII | MTK_USXGMII)
 
 /* MUXes present on SoCs */
 /* 0: GDM1 -> GMAC1, 1: GDM1 -> ESW */
@@ -1042,10 +1085,20 @@ enum mkt_eth_capabilities {
 	(MTK_ETH_MUX_GMAC1_GMAC2_TO_SGMII_RGMII | MTK_MUX | \
 	MTK_SHARED_SGMII)
 
+/* 2: GMAC2 -> XGMII */
+#define MTK_MUX_GMAC2_TO_2P5GPHY      \
+	(MTK_ETH_MUX_GMAC2_TO_2P5GPHY | MTK_MUX | MTK_INFRA)
+
 /* 0: GMACx -> GEPHY, 1: GMACx -> SGMII where x is 1 or 2 */
 #define MTK_MUX_GMAC12_TO_GEPHY_SGMII   \
 	(MTK_ETH_MUX_GMAC12_TO_GEPHY_SGMII | MTK_MUX)
 
+#define MTK_MUX_GMAC123_TO_GEPHY_SGMII   \
+	(MTK_ETH_MUX_GMAC123_TO_GEPHY_SGMII | MTK_MUX)
+
+#define MTK_MUX_GMAC123_TO_USXGMII   \
+	(MTK_ETH_MUX_GMAC123_TO_USXGMII | MTK_MUX | MTK_INFRA)
+
 #define MTK_HAS_CAPS(caps, _x)		(((caps) & (_x)) == (_x))
 
 #define MT7621_CAPS  (MTK_GMAC1_RGMII | MTK_GMAC1_TRGMII | \
@@ -1077,8 +1130,12 @@ enum mkt_eth_capabilities {
 		      MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
 		      MTK_RSTCTRL_PPE1 | MTK_SRAM)
 
-#define MT7988_CAPS  (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_QDMA | \
-		      MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM)
+#define MT7988_CAPS  (MTK_36BIT_DMA | MTK_GDM1_ESW | MTK_GMAC1_SGMII | \
+		      MTK_GMAC2_2P5GPHY | MTK_GMAC2_SGMII | MTK_GMAC2_USXGMII | \
+		      MTK_GMAC3_SGMII | MTK_GMAC3_USXGMII | \
+		      MTK_MUX_GMAC123_TO_GEPHY_SGMII | \
+		      MTK_MUX_GMAC123_TO_USXGMII | MTK_MUX_GMAC2_TO_2P5GPHY | \
+		      MTK_QDMA | MTK_RSTCTRL_PPE1 | MTK_RSTCTRL_PPE2 | MTK_SRAM)
 
 struct mtk_tx_dma_desc_info {
 	dma_addr_t	addr;
@@ -1313,6 +1370,7 @@ struct mtk_mac {
 	phy_interface_t			interface;
 	int				speed;
 	struct device_node		*of_node;
+	struct device_node		*pcs_of_node;
 	struct phylink			*phylink;
 	struct phylink_config		phylink_config;
 	struct mtk_eth			*hw;
@@ -1421,6 +1479,19 @@ static inline u32 mtk_get_ib2_multicast_mask(struct mtk_eth *eth)
 	return MTK_FOE_IB2_MULTICAST;
 }
 
+static inline bool mtk_interface_mode_is_xgmii(phy_interface_t interface)
+{
+	switch (interface) {
+	case PHY_INTERFACE_MODE_INTERNAL:
+	case PHY_INTERFACE_MODE_USXGMII:
+	case PHY_INTERFACE_MODE_10GBASER:
+	case PHY_INTERFACE_MODE_5GBASER:
+		return true;
+	default:
+		return false;
+	}
+}
+
 /* read the hardware status register */
 void mtk_stats_update_mac(struct mtk_mac *mac);
 
@@ -1429,8 +1500,10 @@ u32 mtk_r32(struct mtk_eth *eth, unsigned reg);
 u32 mtk_m32(struct mtk_eth *eth, u32 mask, u32 set, unsigned int reg);
 
 int mtk_gmac_sgmii_path_setup(struct mtk_eth *eth, int mac_id);
+int mtk_gmac_2p5gphy_path_setup(struct mtk_eth *eth, int mac_id);
 int mtk_gmac_gephy_path_setup(struct mtk_eth *eth, int mac_id);
 int mtk_gmac_rgmii_path_setup(struct mtk_eth *eth, int mac_id);
+int mtk_gmac_usxgmii_path_setup(struct mtk_eth *eth, int mac_id);
 
 int mtk_eth_offload_init(struct mtk_eth *eth);
 int mtk_eth_setup_tc(struct net_device *dev, enum tc_setup_type type,
-- 
2.42.1

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [RFC PATCH 1/8] dt-bindings: phy: mediatek,xfi-pextp: add new bindings
  2023-11-09 21:50   ` Daniel Golle
  (?)
@ 2023-11-09 21:55     ` Andrew Lunn
  -1 siblings, 0 replies; 73+ messages in thread
From: Andrew Lunn @ 2023-11-09 21:55 UTC (permalink / raw)
  To: Daniel Golle
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Heiner Kallweit, Russell King,
	Alexander Couzens, Philipp Zabel, netdev, devicetree,
	linux-kernel, linux-arm-kernel, linux-mediatek, linux-phy

> +  mediatek,usxgmii-performance-errata:
> +    $ref: /schemas/types.yaml#/definitions/flag
> +    description:
> +      USXGMII0 on MT7988 suffers from a performance problem in 10GBase-R
> +      mode which needs a work-around in the driver. The work-around is
> +      enabled using this flag.

Is there more details about this? I'm just wondering if this should be
based on the compatible, rather than a bool property.

      Andrew

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

* Re: [RFC PATCH 1/8] dt-bindings: phy: mediatek,xfi-pextp: add new bindings
@ 2023-11-09 21:55     ` Andrew Lunn
  0 siblings, 0 replies; 73+ messages in thread
From: Andrew Lunn @ 2023-11-09 21:55 UTC (permalink / raw)
  To: Daniel Golle
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Heiner Kallweit, Russell King,
	Alexander Couzens, Philipp Zabel, netdev, devicetree,
	linux-kernel, linux-arm-kernel, linux-mediatek, linux-phy

> +  mediatek,usxgmii-performance-errata:
> +    $ref: /schemas/types.yaml#/definitions/flag
> +    description:
> +      USXGMII0 on MT7988 suffers from a performance problem in 10GBase-R
> +      mode which needs a work-around in the driver. The work-around is
> +      enabled using this flag.

Is there more details about this? I'm just wondering if this should be
based on the compatible, rather than a bool property.

      Andrew

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [RFC PATCH 1/8] dt-bindings: phy: mediatek,xfi-pextp: add new bindings
@ 2023-11-09 21:55     ` Andrew Lunn
  0 siblings, 0 replies; 73+ messages in thread
From: Andrew Lunn @ 2023-11-09 21:55 UTC (permalink / raw)
  To: Daniel Golle
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Heiner Kallweit, Russell King,
	Alexander Couzens, Philipp Zabel, netdev, devicetree,
	linux-kernel, linux-arm-kernel, linux-mediatek, linux-phy

> +  mediatek,usxgmii-performance-errata:
> +    $ref: /schemas/types.yaml#/definitions/flag
> +    description:
> +      USXGMII0 on MT7988 suffers from a performance problem in 10GBase-R
> +      mode which needs a work-around in the driver. The work-around is
> +      enabled using this flag.

Is there more details about this? I'm just wondering if this should be
based on the compatible, rather than a bool property.

      Andrew

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [RFC PATCH 1/8] dt-bindings: phy: mediatek,xfi-pextp: add new bindings
  2023-11-09 21:55     ` Andrew Lunn
  (?)
@ 2023-11-09 23:11       ` Daniel Golle
  -1 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 23:11 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Heiner Kallweit, Russell King,
	Alexander Couzens, Philipp Zabel, netdev, devicetree,
	linux-kernel, linux-arm-kernel, linux-mediatek, linux-phy

Hi Andrew,

On Thu, Nov 09, 2023 at 10:55:55PM +0100, Andrew Lunn wrote:
> > +  mediatek,usxgmii-performance-errata:
> > +    $ref: /schemas/types.yaml#/definitions/flag
> > +    description:
> > +      USXGMII0 on MT7988 suffers from a performance problem in 10GBase-R
> > +      mode which needs a work-around in the driver. The work-around is
> > +      enabled using this flag.
> 
> Is there more details about this? I'm just wondering if this should be
> based on the compatible, rather than a bool property.

The vendor sources where this is coming from are here:

https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/a500d94cd47e279015ce22947e1ce396a7516598%5E%21/#F0

And I'm afraid this is as much detail as it gets. And yes, we could
also base this on the compatible and just have two different ones for
the two PEXTP instances found in MT7988.
Let me know your conclusion in that regard.


Cheers


Daniel

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

* Re: [RFC PATCH 1/8] dt-bindings: phy: mediatek,xfi-pextp: add new bindings
@ 2023-11-09 23:11       ` Daniel Golle
  0 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 23:11 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Heiner Kallweit, Russell King,
	Alexander Couzens, Philipp Zabel, netdev, devicetree,
	linux-kernel, linux-arm-kernel, linux-mediatek, linux-phy

Hi Andrew,

On Thu, Nov 09, 2023 at 10:55:55PM +0100, Andrew Lunn wrote:
> > +  mediatek,usxgmii-performance-errata:
> > +    $ref: /schemas/types.yaml#/definitions/flag
> > +    description:
> > +      USXGMII0 on MT7988 suffers from a performance problem in 10GBase-R
> > +      mode which needs a work-around in the driver. The work-around is
> > +      enabled using this flag.
> 
> Is there more details about this? I'm just wondering if this should be
> based on the compatible, rather than a bool property.

The vendor sources where this is coming from are here:

https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/a500d94cd47e279015ce22947e1ce396a7516598%5E%21/#F0

And I'm afraid this is as much detail as it gets. And yes, we could
also base this on the compatible and just have two different ones for
the two PEXTP instances found in MT7988.
Let me know your conclusion in that regard.


Cheers


Daniel

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [RFC PATCH 1/8] dt-bindings: phy: mediatek,xfi-pextp: add new bindings
@ 2023-11-09 23:11       ` Daniel Golle
  0 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-09 23:11 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Heiner Kallweit, Russell King,
	Alexander Couzens, Philipp Zabel, netdev, devicetree,
	linux-kernel, linux-arm-kernel, linux-mediatek, linux-phy

Hi Andrew,

On Thu, Nov 09, 2023 at 10:55:55PM +0100, Andrew Lunn wrote:
> > +  mediatek,usxgmii-performance-errata:
> > +    $ref: /schemas/types.yaml#/definitions/flag
> > +    description:
> > +      USXGMII0 on MT7988 suffers from a performance problem in 10GBase-R
> > +      mode which needs a work-around in the driver. The work-around is
> > +      enabled using this flag.
> 
> Is there more details about this? I'm just wondering if this should be
> based on the compatible, rather than a bool property.

The vendor sources where this is coming from are here:

https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/a500d94cd47e279015ce22947e1ce396a7516598%5E%21/#F0

And I'm afraid this is as much detail as it gets. And yes, we could
also base this on the compatible and just have two different ones for
the two PEXTP instances found in MT7988.
Let me know your conclusion in that regard.


Cheers


Daniel

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [RFC PATCH 3/8] net: pcs: pcs-mtk-lynxi: use 2500Base-X without AN
  2023-11-09 21:51   ` Daniel Golle
  (?)
@ 2023-11-10  8:54     ` Russell King (Oracle)
  -1 siblings, 0 replies; 73+ messages in thread
From: Russell King (Oracle) @ 2023-11-10  8:54 UTC (permalink / raw)
  To: Daniel Golle
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Alexander Couzens, Philipp Zabel, netdev, devicetree,
	linux-kernel, linux-arm-kernel, linux-mediatek, linux-phy

On Thu, Nov 09, 2023 at 09:51:22PM +0000, Daniel Golle wrote:
> Using 2500Base-T SFP modules e.g. on the BananaPi R3 requires manually
> disabling auto-negotiation, e.g. using ethtool. While a proper fix
> using SFP quirks is being discussed upstream, bring a work-around to
> restore user experience to what it was before the switch to the
> dedicated SGMII PCS driver.

No.

> @@ -129,7 +138,8 @@ static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode,
>  	if (neg_mode & PHYLINK_PCS_NEG_INBAND)
>  		sgm_mode |= SGMII_REMOTE_FAULT_DIS;
>  
> -	if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
> +	if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED &&
> +	    interface != PHY_INTERFACE_MODE_2500BASEX) {
>  		if (interface == PHY_INTERFACE_MODE_SGMII)
>  			sgm_mode |= SGMII_SPEED_DUPLEX_AN;
>  		bmcr = BMCR_ANENABLE;

Phylink is asking you to have inband enabled. If inband needs to be
disabled, then we need to arrange for phylink to pass
PHYLINK_PCS_NEG_INBAND_DISABLED.

Please don't hack special handling and behaviour into drivers.

Thanks.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!

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

* Re: [RFC PATCH 3/8] net: pcs: pcs-mtk-lynxi: use 2500Base-X without AN
@ 2023-11-10  8:54     ` Russell King (Oracle)
  0 siblings, 0 replies; 73+ messages in thread
From: Russell King (Oracle) @ 2023-11-10  8:54 UTC (permalink / raw)
  To: Daniel Golle
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Alexander Couzens, Philipp Zabel, netdev, devicetree,
	linux-kernel, linux-arm-kernel, linux-mediatek, linux-phy

On Thu, Nov 09, 2023 at 09:51:22PM +0000, Daniel Golle wrote:
> Using 2500Base-T SFP modules e.g. on the BananaPi R3 requires manually
> disabling auto-negotiation, e.g. using ethtool. While a proper fix
> using SFP quirks is being discussed upstream, bring a work-around to
> restore user experience to what it was before the switch to the
> dedicated SGMII PCS driver.

No.

> @@ -129,7 +138,8 @@ static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode,
>  	if (neg_mode & PHYLINK_PCS_NEG_INBAND)
>  		sgm_mode |= SGMII_REMOTE_FAULT_DIS;
>  
> -	if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
> +	if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED &&
> +	    interface != PHY_INTERFACE_MODE_2500BASEX) {
>  		if (interface == PHY_INTERFACE_MODE_SGMII)
>  			sgm_mode |= SGMII_SPEED_DUPLEX_AN;
>  		bmcr = BMCR_ANENABLE;

Phylink is asking you to have inband enabled. If inband needs to be
disabled, then we need to arrange for phylink to pass
PHYLINK_PCS_NEG_INBAND_DISABLED.

Please don't hack special handling and behaviour into drivers.

Thanks.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [RFC PATCH 3/8] net: pcs: pcs-mtk-lynxi: use 2500Base-X without AN
@ 2023-11-10  8:54     ` Russell King (Oracle)
  0 siblings, 0 replies; 73+ messages in thread
From: Russell King (Oracle) @ 2023-11-10  8:54 UTC (permalink / raw)
  To: Daniel Golle
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Alexander Couzens, Philipp Zabel, netdev, devicetree,
	linux-kernel, linux-arm-kernel, linux-mediatek, linux-phy

On Thu, Nov 09, 2023 at 09:51:22PM +0000, Daniel Golle wrote:
> Using 2500Base-T SFP modules e.g. on the BananaPi R3 requires manually
> disabling auto-negotiation, e.g. using ethtool. While a proper fix
> using SFP quirks is being discussed upstream, bring a work-around to
> restore user experience to what it was before the switch to the
> dedicated SGMII PCS driver.

No.

> @@ -129,7 +138,8 @@ static int mtk_pcs_lynxi_config(struct phylink_pcs *pcs, unsigned int neg_mode,
>  	if (neg_mode & PHYLINK_PCS_NEG_INBAND)
>  		sgm_mode |= SGMII_REMOTE_FAULT_DIS;
>  
> -	if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED) {
> +	if (neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED &&
> +	    interface != PHY_INTERFACE_MODE_2500BASEX) {
>  		if (interface == PHY_INTERFACE_MODE_SGMII)
>  			sgm_mode |= SGMII_SPEED_DUPLEX_AN;
>  		bmcr = BMCR_ANENABLE;

Phylink is asking you to have inband enabled. If inband needs to be
disabled, then we need to arrange for phylink to pass
PHYLINK_PCS_NEG_INBAND_DISABLED.

Please don't hack special handling and behaviour into drivers.

Thanks.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [RFC PATCH 1/8] dt-bindings: phy: mediatek,xfi-pextp: add new bindings
  2023-11-09 21:50   ` Daniel Golle
  (?)
@ 2023-11-10 20:08     ` Rob Herring
  -1 siblings, 0 replies; 73+ messages in thread
From: Rob Herring @ 2023-11-10 20:08 UTC (permalink / raw)
  To: Daniel Golle
  Cc: Andrew Lunn, Lorenzo Bianconi, Alexander Couzens, linux-kernel,
	linux-mediatek, David S. Miller, Krzysztof Kozlowski,
	Jakub Kicinski, Felix Fietkau, Russell King, Paolo Abeni,
	Mark Lee, netdev, linux-arm-kernel, Conor Dooley, Vinod Koul,
	Rob Herring, Kishon Vijay Abraham I, Heiner Kallweit, devicetree,
	Sean Wang, Philipp Zabel, Chunfeng Yun, linux-phy,
	Matthias Brugger, John Crispin, AngeloGioacchino Del Regno,
	Eric Dumazet


On Thu, 09 Nov 2023 21:50:55 +0000, Daniel Golle wrote:
> Add bindings for the MediaTek PEXTP Ethernet SerDes PHY found in the
> MediaTek MT7988 SoC which can operate at various interfaces modes:
> 
>  * USXGMII
>  * 10GBase-R
>  * 5GBase-R
>  * 2500Base-X
>  * 1000Base-X
>  * Cisco SGMII (MAC side)
> 
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
>  .../bindings/phy/mediatek,xfi-pextp.yaml      | 71 +++++++++++++++++++
>  1 file changed, 71 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.example.dts:18:18: fatal error: dt-bindings/clock/mediatek,mt7988-clk.h: No such file or directory
   18 |         #include <dt-bindings/clock/mediatek,mt7988-clk.h>
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [scripts/Makefile.lib:419: Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.example.dtb] Error 1
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [/builds/robherring/dt-review-ci/linux/Makefile:1427: dt_binding_check] Error 2
make: *** [Makefile:234: __sub-make] Error 2

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/924c2c6316e6d51a17423eded3a2c5c5bbf349d2.1699565880.git.daniel@makrotopia.org

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.


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

* Re: [RFC PATCH 1/8] dt-bindings: phy: mediatek,xfi-pextp: add new bindings
@ 2023-11-10 20:08     ` Rob Herring
  0 siblings, 0 replies; 73+ messages in thread
From: Rob Herring @ 2023-11-10 20:08 UTC (permalink / raw)
  To: Daniel Golle
  Cc: Andrew Lunn, Lorenzo Bianconi, Alexander Couzens, linux-kernel,
	linux-mediatek, David S. Miller, Krzysztof Kozlowski,
	Jakub Kicinski, Felix Fietkau, Russell King, Paolo Abeni,
	Mark Lee, netdev, linux-arm-kernel, Conor Dooley, Vinod Koul,
	Rob Herring, Kishon Vijay Abraham I, Heiner Kallweit, devicetree,
	Sean Wang, Philipp Zabel, Chunfeng Yun, linux-phy,
	Matthias Brugger, John Crispin, AngeloGioacchino Del Regno,
	Eric Dumazet


On Thu, 09 Nov 2023 21:50:55 +0000, Daniel Golle wrote:
> Add bindings for the MediaTek PEXTP Ethernet SerDes PHY found in the
> MediaTek MT7988 SoC which can operate at various interfaces modes:
> 
>  * USXGMII
>  * 10GBase-R
>  * 5GBase-R
>  * 2500Base-X
>  * 1000Base-X
>  * Cisco SGMII (MAC side)
> 
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
>  .../bindings/phy/mediatek,xfi-pextp.yaml      | 71 +++++++++++++++++++
>  1 file changed, 71 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.example.dts:18:18: fatal error: dt-bindings/clock/mediatek,mt7988-clk.h: No such file or directory
   18 |         #include <dt-bindings/clock/mediatek,mt7988-clk.h>
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [scripts/Makefile.lib:419: Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.example.dtb] Error 1
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [/builds/robherring/dt-review-ci/linux/Makefile:1427: dt_binding_check] Error 2
make: *** [Makefile:234: __sub-make] Error 2

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/924c2c6316e6d51a17423eded3a2c5c5bbf349d2.1699565880.git.daniel@makrotopia.org

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [RFC PATCH 1/8] dt-bindings: phy: mediatek,xfi-pextp: add new bindings
@ 2023-11-10 20:08     ` Rob Herring
  0 siblings, 0 replies; 73+ messages in thread
From: Rob Herring @ 2023-11-10 20:08 UTC (permalink / raw)
  To: Daniel Golle
  Cc: Andrew Lunn, Lorenzo Bianconi, Alexander Couzens, linux-kernel,
	linux-mediatek, David S. Miller, Krzysztof Kozlowski,
	Jakub Kicinski, Felix Fietkau, Russell King, Paolo Abeni,
	Mark Lee, netdev, linux-arm-kernel, Conor Dooley, Vinod Koul,
	Rob Herring, Kishon Vijay Abraham I, Heiner Kallweit, devicetree,
	Sean Wang, Philipp Zabel, Chunfeng Yun, linux-phy,
	Matthias Brugger, John Crispin, AngeloGioacchino Del Regno,
	Eric Dumazet


On Thu, 09 Nov 2023 21:50:55 +0000, Daniel Golle wrote:
> Add bindings for the MediaTek PEXTP Ethernet SerDes PHY found in the
> MediaTek MT7988 SoC which can operate at various interfaces modes:
> 
>  * USXGMII
>  * 10GBase-R
>  * 5GBase-R
>  * 2500Base-X
>  * 1000Base-X
>  * Cisco SGMII (MAC side)
> 
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
>  .../bindings/phy/mediatek,xfi-pextp.yaml      | 71 +++++++++++++++++++
>  1 file changed, 71 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml
> 

My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):

yamllint warnings/errors:

dtschema/dtc warnings/errors:
Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.example.dts:18:18: fatal error: dt-bindings/clock/mediatek,mt7988-clk.h: No such file or directory
   18 |         #include <dt-bindings/clock/mediatek,mt7988-clk.h>
      |                  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
make[2]: *** [scripts/Makefile.lib:419: Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.example.dtb] Error 1
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [/builds/robherring/dt-review-ci/linux/Makefile:1427: dt_binding_check] Error 2
make: *** [Makefile:234: __sub-make] Error 2

doc reference errors (make refcheckdocs):

See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/924c2c6316e6d51a17423eded3a2c5c5bbf349d2.1699565880.git.daniel@makrotopia.org

The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.

If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:

pip3 install dtschema --upgrade

Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [RFC PATCH 6/8] net: pcs: add driver for MediaTek USXGMII PCS
  2023-11-09 21:51   ` Daniel Golle
  (?)
  (?)
@ 2023-11-10 22:48   ` kernel test robot
  -1 siblings, 0 replies; 73+ messages in thread
From: kernel test robot @ 2023-11-10 22:48 UTC (permalink / raw)
  To: Daniel Golle; +Cc: oe-kbuild-all

Hi Daniel,

[This is a private test report for your RFC patch.]
kernel test robot noticed the following build errors:

[auto build test ERROR on robh/for-next]
[also build test ERROR on net-next/main net/main linus/master v6.6 next-20231110]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Daniel-Golle/dt-bindings-phy-mediatek-xfi-pextp-add-new-bindings/20231110-055440
base:   https://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git for-next
patch link:    https://lore.kernel.org/r/b9f787f3e4aa36e148d7595495af60db53f74417.1699565880.git.daniel%40makrotopia.org
patch subject: [RFC PATCH 6/8] net: pcs: add driver for MediaTek USXGMII PCS
config: x86_64-buildonly-randconfig-003-20231111 (https://download.01.org/0day-ci/archive/20231111/202311110611.RMxLQYxV-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20231111/202311110611.RMxLQYxV-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202311110611.RMxLQYxV-lkp@intel.com/

All errors (new ones prefixed by >>):

   ld: vmlinux.o: in function `mtk_pcs_lynxi_get_state':
>> pcs-mtk-lynxi.c:(.text+0x13acb97): undefined reference to `phylink_mii_c22_pcs_decode_state'
   ld: vmlinux.o: in function `mtk_pcs_lynxi_config':
>> pcs-mtk-lynxi.c:(.text+0x13acf7b): undefined reference to `phylink_mii_c22_pcs_encode_advertisement'
   ld: vmlinux.o: in function `mtk_usxgmii_pcs_get_state':
>> pcs-mtk-usxgmii.c:(.text+0x13ada3d): undefined reference to `phylink_decode_usxgmii_word'

Kconfig warnings: (for reference only)
   WARNING: unmet direct dependencies detected for PHY_MTK_PEXTP
   Depends on [n]: (ARCH_MEDIATEK || COMPILE_TEST [=y]) && OF [=n] && OF_ADDRESS [=n] && HAS_IOMEM [=y]
   Selected by [y]:
   - PCS_MTK_USXGMII [=y] && NETDEVICES [=y]

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

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

* Re: [RFC PATCH 5/8] dt-bindings: net: pcs: add bindings for MediaTek USXGMII PCS
  2023-11-09 21:51   ` Daniel Golle
  (?)
@ 2023-11-11  8:13     ` Krzysztof Kozlowski
  -1 siblings, 0 replies; 73+ messages in thread
From: Krzysztof Kozlowski @ 2023-11-11  8:13 UTC (permalink / raw)
  To: Daniel Golle, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Chunfeng Yun, Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau,
	John Crispin, Sean Wang, Mark Lee, Lorenzo Bianconi,
	Matthias Brugger, AngeloGioacchino Del Regno, Andrew Lunn,
	Heiner Kallweit, Russell King, Alexander Couzens, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

On 09/11/2023 22:51, Daniel Golle wrote:
> MediaTek's USXGMII can be found in the MT7988 SoC. We need to access
> it in order to configure and monitor the Ethernet SerDes link in
> USXGMII, 10GBase-R and 5GBase-R mode. By including a wrapped
> legacy 1000Base-X/2500Base-X/Cisco SGMII LynxI PCS as well, those
> interface modes are also available.
> 

A nit, subject: drop second/last, redundant "bindings for". The
"dt-bindings" prefix is already stating that these are bindings.

> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
>  .../bindings/net/pcs/mediatek,usxgmii.yaml    | 105 ++++++++++++++++++

Use compatible as filename (especially that you do not expect it to grow).

>  1 file changed, 105 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
> 
> diff --git a/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml b/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
> new file mode 100644
> index 0000000000000..199cf47859e31
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
> @@ -0,0 +1,105 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/net/pcs/mediatek,usxgmii.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MediaTek USXGMII PCS

MT7888 I guess?

> +
> +maintainers:
> +  - Daniel Golle <daniel@makrotopia.org>
> +
> +description:
> +  The MediaTek USXGMII PCS provides physical link control and status
> +  for USXGMII, 10GBase-R and 5GBase-R links on the SerDes interfaces
> +  provided by the PEXTP PHY.
> +  In order to also support legacy 2500Base-X, 1000Base-X and Cisco
> +  SGMII an existing mediatek,*-sgmiisys LynxI PCS is wrapped to
> +  provide those interfaces modes on the same SerDes interfaces shared
> +  with the USXGMII PCS.
> +
> +properties:
> +  $nodename:
> +    pattern: "^pcs@[0-9a-f]+$"

Drop, we do not enforce naming in individual device schemas.

> +
> +  compatible:
> +    const: mediatek,mt7988-usxgmiisys
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    items:
> +      - description: USXGMII top-level clock
> +      - description: SGMII top-level clock
> +      - description: SGMII subsystem TX clock
> +      - description: SGMII subsystem RX clock
> +      - description: XFI PLL clock
> +
> +  clock-names:
> +    items:
> +      - const: usxgmii
> +      - const: sgmii_sel
> +      - const: sgmii_tx
> +      - const: sgmii_rx
> +      - const: xfi_pll
> +
> +  phys:
> +    items:
> +      - description: PEXTP SerDes PHY
> +
> +  mediatek,sgmiisys:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      Phandle to the syscon node of the corresponding SGMII LynxI PCS.

"syscon node" is Linux term. Instead describe to what part of hardware
this phandle is and why do you need it.

> +
> +  resets:
> +    items:
> +      - description: XFI reset
> +      - description: SGMII reset
> +
> +  reset-names:
> +    items:
> +      - const: xfi
> +      - const: sgmii
> +
> +  "#pcs-cells":
> +    const: 0
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - clock-names
> +  - phys
> +  - mediatek,sgmiisys
> +  - resets
> +  - reset-names
> +  - "#pcs-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/mediatek,mt7988-clk.h>
> +    #include <dt-bindings/reset/mediatek,mt7988-resets.h>
> +    soc {
> +      #address-cells = <2>;
> +      #size-cells = <2>;
> +        usxgmiisys0: pcs@10080000 {

Odd/Messed indentation.

Use 4 spaces for example indentation.



Best regards,
Krzysztof


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

* Re: [RFC PATCH 5/8] dt-bindings: net: pcs: add bindings for MediaTek USXGMII PCS
@ 2023-11-11  8:13     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 73+ messages in thread
From: Krzysztof Kozlowski @ 2023-11-11  8:13 UTC (permalink / raw)
  To: Daniel Golle, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Chunfeng Yun, Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau,
	John Crispin, Sean Wang, Mark Lee, Lorenzo Bianconi,
	Matthias Brugger, AngeloGioacchino Del Regno, Andrew Lunn,
	Heiner Kallweit, Russell King, Alexander Couzens, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

On 09/11/2023 22:51, Daniel Golle wrote:
> MediaTek's USXGMII can be found in the MT7988 SoC. We need to access
> it in order to configure and monitor the Ethernet SerDes link in
> USXGMII, 10GBase-R and 5GBase-R mode. By including a wrapped
> legacy 1000Base-X/2500Base-X/Cisco SGMII LynxI PCS as well, those
> interface modes are also available.
> 

A nit, subject: drop second/last, redundant "bindings for". The
"dt-bindings" prefix is already stating that these are bindings.

> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
>  .../bindings/net/pcs/mediatek,usxgmii.yaml    | 105 ++++++++++++++++++

Use compatible as filename (especially that you do not expect it to grow).

>  1 file changed, 105 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
> 
> diff --git a/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml b/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
> new file mode 100644
> index 0000000000000..199cf47859e31
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
> @@ -0,0 +1,105 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/net/pcs/mediatek,usxgmii.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MediaTek USXGMII PCS

MT7888 I guess?

> +
> +maintainers:
> +  - Daniel Golle <daniel@makrotopia.org>
> +
> +description:
> +  The MediaTek USXGMII PCS provides physical link control and status
> +  for USXGMII, 10GBase-R and 5GBase-R links on the SerDes interfaces
> +  provided by the PEXTP PHY.
> +  In order to also support legacy 2500Base-X, 1000Base-X and Cisco
> +  SGMII an existing mediatek,*-sgmiisys LynxI PCS is wrapped to
> +  provide those interfaces modes on the same SerDes interfaces shared
> +  with the USXGMII PCS.
> +
> +properties:
> +  $nodename:
> +    pattern: "^pcs@[0-9a-f]+$"

Drop, we do not enforce naming in individual device schemas.

> +
> +  compatible:
> +    const: mediatek,mt7988-usxgmiisys
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    items:
> +      - description: USXGMII top-level clock
> +      - description: SGMII top-level clock
> +      - description: SGMII subsystem TX clock
> +      - description: SGMII subsystem RX clock
> +      - description: XFI PLL clock
> +
> +  clock-names:
> +    items:
> +      - const: usxgmii
> +      - const: sgmii_sel
> +      - const: sgmii_tx
> +      - const: sgmii_rx
> +      - const: xfi_pll
> +
> +  phys:
> +    items:
> +      - description: PEXTP SerDes PHY
> +
> +  mediatek,sgmiisys:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      Phandle to the syscon node of the corresponding SGMII LynxI PCS.

"syscon node" is Linux term. Instead describe to what part of hardware
this phandle is and why do you need it.

> +
> +  resets:
> +    items:
> +      - description: XFI reset
> +      - description: SGMII reset
> +
> +  reset-names:
> +    items:
> +      - const: xfi
> +      - const: sgmii
> +
> +  "#pcs-cells":
> +    const: 0
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - clock-names
> +  - phys
> +  - mediatek,sgmiisys
> +  - resets
> +  - reset-names
> +  - "#pcs-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/mediatek,mt7988-clk.h>
> +    #include <dt-bindings/reset/mediatek,mt7988-resets.h>
> +    soc {
> +      #address-cells = <2>;
> +      #size-cells = <2>;
> +        usxgmiisys0: pcs@10080000 {

Odd/Messed indentation.

Use 4 spaces for example indentation.



Best regards,
Krzysztof


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [RFC PATCH 5/8] dt-bindings: net: pcs: add bindings for MediaTek USXGMII PCS
@ 2023-11-11  8:13     ` Krzysztof Kozlowski
  0 siblings, 0 replies; 73+ messages in thread
From: Krzysztof Kozlowski @ 2023-11-11  8:13 UTC (permalink / raw)
  To: Daniel Golle, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Chunfeng Yun, Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau,
	John Crispin, Sean Wang, Mark Lee, Lorenzo Bianconi,
	Matthias Brugger, AngeloGioacchino Del Regno, Andrew Lunn,
	Heiner Kallweit, Russell King, Alexander Couzens, Philipp Zabel,
	netdev, devicetree, linux-kernel, linux-arm-kernel,
	linux-mediatek, linux-phy

On 09/11/2023 22:51, Daniel Golle wrote:
> MediaTek's USXGMII can be found in the MT7988 SoC. We need to access
> it in order to configure and monitor the Ethernet SerDes link in
> USXGMII, 10GBase-R and 5GBase-R mode. By including a wrapped
> legacy 1000Base-X/2500Base-X/Cisco SGMII LynxI PCS as well, those
> interface modes are also available.
> 

A nit, subject: drop second/last, redundant "bindings for". The
"dt-bindings" prefix is already stating that these are bindings.

> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
>  .../bindings/net/pcs/mediatek,usxgmii.yaml    | 105 ++++++++++++++++++

Use compatible as filename (especially that you do not expect it to grow).

>  1 file changed, 105 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
> 
> diff --git a/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml b/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
> new file mode 100644
> index 0000000000000..199cf47859e31
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
> @@ -0,0 +1,105 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/net/pcs/mediatek,usxgmii.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MediaTek USXGMII PCS

MT7888 I guess?

> +
> +maintainers:
> +  - Daniel Golle <daniel@makrotopia.org>
> +
> +description:
> +  The MediaTek USXGMII PCS provides physical link control and status
> +  for USXGMII, 10GBase-R and 5GBase-R links on the SerDes interfaces
> +  provided by the PEXTP PHY.
> +  In order to also support legacy 2500Base-X, 1000Base-X and Cisco
> +  SGMII an existing mediatek,*-sgmiisys LynxI PCS is wrapped to
> +  provide those interfaces modes on the same SerDes interfaces shared
> +  with the USXGMII PCS.
> +
> +properties:
> +  $nodename:
> +    pattern: "^pcs@[0-9a-f]+$"

Drop, we do not enforce naming in individual device schemas.

> +
> +  compatible:
> +    const: mediatek,mt7988-usxgmiisys
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    items:
> +      - description: USXGMII top-level clock
> +      - description: SGMII top-level clock
> +      - description: SGMII subsystem TX clock
> +      - description: SGMII subsystem RX clock
> +      - description: XFI PLL clock
> +
> +  clock-names:
> +    items:
> +      - const: usxgmii
> +      - const: sgmii_sel
> +      - const: sgmii_tx
> +      - const: sgmii_rx
> +      - const: xfi_pll
> +
> +  phys:
> +    items:
> +      - description: PEXTP SerDes PHY
> +
> +  mediatek,sgmiisys:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      Phandle to the syscon node of the corresponding SGMII LynxI PCS.

"syscon node" is Linux term. Instead describe to what part of hardware
this phandle is and why do you need it.

> +
> +  resets:
> +    items:
> +      - description: XFI reset
> +      - description: SGMII reset
> +
> +  reset-names:
> +    items:
> +      - const: xfi
> +      - const: sgmii
> +
> +  "#pcs-cells":
> +    const: 0
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - clock-names
> +  - phys
> +  - mediatek,sgmiisys
> +  - resets
> +  - reset-names
> +  - "#pcs-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/mediatek,mt7988-clk.h>
> +    #include <dt-bindings/reset/mediatek,mt7988-resets.h>
> +    soc {
> +      #address-cells = <2>;
> +      #size-cells = <2>;
> +        usxgmiisys0: pcs@10080000 {

Odd/Messed indentation.

Use 4 spaces for example indentation.



Best regards,
Krzysztof


-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [RFC PATCH 1/8] dt-bindings: phy: mediatek,xfi-pextp: add new bindings
  2023-11-09 21:50   ` Daniel Golle
  (?)
@ 2023-11-14 13:43     ` Rob Herring
  -1 siblings, 0 replies; 73+ messages in thread
From: Rob Herring @ 2023-11-14 13:43 UTC (permalink / raw)
  To: Daniel Golle
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun, Vinod Koul,
	Kishon Vijay Abraham I, Felix Fietkau, John Crispin, Sean Wang,
	Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Philipp Zabel, netdev,
	devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-phy

On Thu, Nov 09, 2023 at 09:50:55PM +0000, Daniel Golle wrote:
> Add bindings for the MediaTek PEXTP Ethernet SerDes PHY found in the
> MediaTek MT7988 SoC which can operate at various interfaces modes:
> 
>  * USXGMII
>  * 10GBase-R
>  * 5GBase-R
>  * 2500Base-X
>  * 1000Base-X
>  * Cisco SGMII (MAC side)
> 
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
>  .../bindings/phy/mediatek,xfi-pextp.yaml      | 71 +++++++++++++++++++
>  1 file changed, 71 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml
> 
> diff --git a/Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml b/Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml
> new file mode 100644
> index 0000000000000..948d5031af1e3
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml
> @@ -0,0 +1,71 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/phy/mediatek,xfi-pextp.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MediaTek XFI PEXTP SerDes PHY
> +
> +maintainers:
> +  - Daniel Golle <daniel@makrotopia.org>
> +
> +description: |

Don't need '|' here.

> +  The MediaTek XFI PEXTP SerDes PHY provides the physical SerDes lanes
> +  used by the MediaTek USXGMII PCS.
> +
> +properties:
> +  $nodename:
> +    pattern: "^phy@[0-9a-f]+$"
> +
> +  compatible:
> +    const: mediatek,mt7988-xfi-pextp
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    items:
> +      - description: XFI PHY clock
> +
> +  resets:
> +    items:
> +      - description: PEXTP reset
> +
> +  mediatek,usxgmii-performance-errata:
> +    $ref: /schemas/types.yaml#/definitions/flag
> +    description:
> +      USXGMII0 on MT7988 suffers from a performance problem in 10GBase-R
> +      mode which needs a work-around in the driver. The work-around is
> +      enabled using this flag.
> +
> +  "#phy-cells":
> +    const: 0
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - resets
> +  - "#phy-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/mediatek,mt7988-clk.h>
> +    #include <dt-bindings/reset/mediatek,mt7988-resets.h>
> +    soc {
> +      #address-cells = <2>;
> +      #size-cells = <2>;
> +
> +      xfi_pextp0: phy@11f20000 {

Drop unused labels.

> +        compatible = "mediatek,mt7988-xfi-pextp";
> +        reg = <0 0x11f20000 0 0x10000>;
> +        clocks = <&topckgen CLK_TOP_XFI_PHY_0_XTAL_SEL>;
> +        resets = <&watchdog MT7988_TOPRGU_XFI_PEXTP0_GRST>;
> +        mediatek,usxgmii-performance-errata;
> +        #phy-cells = <0>;
> +      };
> +    };
> +
> +...
> -- 
> 2.42.1

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

* Re: [RFC PATCH 1/8] dt-bindings: phy: mediatek,xfi-pextp: add new bindings
@ 2023-11-14 13:43     ` Rob Herring
  0 siblings, 0 replies; 73+ messages in thread
From: Rob Herring @ 2023-11-14 13:43 UTC (permalink / raw)
  To: Daniel Golle
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun, Vinod Koul,
	Kishon Vijay Abraham I, Felix Fietkau, John Crispin, Sean Wang,
	Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Philipp Zabel, netdev,
	devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-phy

On Thu, Nov 09, 2023 at 09:50:55PM +0000, Daniel Golle wrote:
> Add bindings for the MediaTek PEXTP Ethernet SerDes PHY found in the
> MediaTek MT7988 SoC which can operate at various interfaces modes:
> 
>  * USXGMII
>  * 10GBase-R
>  * 5GBase-R
>  * 2500Base-X
>  * 1000Base-X
>  * Cisco SGMII (MAC side)
> 
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
>  .../bindings/phy/mediatek,xfi-pextp.yaml      | 71 +++++++++++++++++++
>  1 file changed, 71 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml
> 
> diff --git a/Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml b/Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml
> new file mode 100644
> index 0000000000000..948d5031af1e3
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml
> @@ -0,0 +1,71 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/phy/mediatek,xfi-pextp.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MediaTek XFI PEXTP SerDes PHY
> +
> +maintainers:
> +  - Daniel Golle <daniel@makrotopia.org>
> +
> +description: |

Don't need '|' here.

> +  The MediaTek XFI PEXTP SerDes PHY provides the physical SerDes lanes
> +  used by the MediaTek USXGMII PCS.
> +
> +properties:
> +  $nodename:
> +    pattern: "^phy@[0-9a-f]+$"
> +
> +  compatible:
> +    const: mediatek,mt7988-xfi-pextp
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    items:
> +      - description: XFI PHY clock
> +
> +  resets:
> +    items:
> +      - description: PEXTP reset
> +
> +  mediatek,usxgmii-performance-errata:
> +    $ref: /schemas/types.yaml#/definitions/flag
> +    description:
> +      USXGMII0 on MT7988 suffers from a performance problem in 10GBase-R
> +      mode which needs a work-around in the driver. The work-around is
> +      enabled using this flag.
> +
> +  "#phy-cells":
> +    const: 0
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - resets
> +  - "#phy-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/mediatek,mt7988-clk.h>
> +    #include <dt-bindings/reset/mediatek,mt7988-resets.h>
> +    soc {
> +      #address-cells = <2>;
> +      #size-cells = <2>;
> +
> +      xfi_pextp0: phy@11f20000 {

Drop unused labels.

> +        compatible = "mediatek,mt7988-xfi-pextp";
> +        reg = <0 0x11f20000 0 0x10000>;
> +        clocks = <&topckgen CLK_TOP_XFI_PHY_0_XTAL_SEL>;
> +        resets = <&watchdog MT7988_TOPRGU_XFI_PEXTP0_GRST>;
> +        mediatek,usxgmii-performance-errata;
> +        #phy-cells = <0>;
> +      };
> +    };
> +
> +...
> -- 
> 2.42.1

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [RFC PATCH 1/8] dt-bindings: phy: mediatek,xfi-pextp: add new bindings
@ 2023-11-14 13:43     ` Rob Herring
  0 siblings, 0 replies; 73+ messages in thread
From: Rob Herring @ 2023-11-14 13:43 UTC (permalink / raw)
  To: Daniel Golle
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun, Vinod Koul,
	Kishon Vijay Abraham I, Felix Fietkau, John Crispin, Sean Wang,
	Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Philipp Zabel, netdev,
	devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-phy

On Thu, Nov 09, 2023 at 09:50:55PM +0000, Daniel Golle wrote:
> Add bindings for the MediaTek PEXTP Ethernet SerDes PHY found in the
> MediaTek MT7988 SoC which can operate at various interfaces modes:
> 
>  * USXGMII
>  * 10GBase-R
>  * 5GBase-R
>  * 2500Base-X
>  * 1000Base-X
>  * Cisco SGMII (MAC side)
> 
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
>  .../bindings/phy/mediatek,xfi-pextp.yaml      | 71 +++++++++++++++++++
>  1 file changed, 71 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml
> 
> diff --git a/Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml b/Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml
> new file mode 100644
> index 0000000000000..948d5031af1e3
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/mediatek,xfi-pextp.yaml
> @@ -0,0 +1,71 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/phy/mediatek,xfi-pextp.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MediaTek XFI PEXTP SerDes PHY
> +
> +maintainers:
> +  - Daniel Golle <daniel@makrotopia.org>
> +
> +description: |

Don't need '|' here.

> +  The MediaTek XFI PEXTP SerDes PHY provides the physical SerDes lanes
> +  used by the MediaTek USXGMII PCS.
> +
> +properties:
> +  $nodename:
> +    pattern: "^phy@[0-9a-f]+$"
> +
> +  compatible:
> +    const: mediatek,mt7988-xfi-pextp
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    items:
> +      - description: XFI PHY clock
> +
> +  resets:
> +    items:
> +      - description: PEXTP reset
> +
> +  mediatek,usxgmii-performance-errata:
> +    $ref: /schemas/types.yaml#/definitions/flag
> +    description:
> +      USXGMII0 on MT7988 suffers from a performance problem in 10GBase-R
> +      mode which needs a work-around in the driver. The work-around is
> +      enabled using this flag.
> +
> +  "#phy-cells":
> +    const: 0
> +
> +required:
> +  - compatible
> +  - reg
> +  - clocks
> +  - resets
> +  - "#phy-cells"
> +
> +additionalProperties: false
> +
> +examples:
> +  - |
> +    #include <dt-bindings/clock/mediatek,mt7988-clk.h>
> +    #include <dt-bindings/reset/mediatek,mt7988-resets.h>
> +    soc {
> +      #address-cells = <2>;
> +      #size-cells = <2>;
> +
> +      xfi_pextp0: phy@11f20000 {

Drop unused labels.

> +        compatible = "mediatek,mt7988-xfi-pextp";
> +        reg = <0 0x11f20000 0 0x10000>;
> +        clocks = <&topckgen CLK_TOP_XFI_PHY_0_XTAL_SEL>;
> +        resets = <&watchdog MT7988_TOPRGU_XFI_PEXTP0_GRST>;
> +        mediatek,usxgmii-performance-errata;
> +        #phy-cells = <0>;
> +      };
> +    };
> +
> +...
> -- 
> 2.42.1

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [RFC PATCH 1/8] dt-bindings: phy: mediatek,xfi-pextp: add new bindings
  2023-11-09 23:11       ` Daniel Golle
  (?)
@ 2023-11-14 13:44         ` Rob Herring
  -1 siblings, 0 replies; 73+ messages in thread
From: Rob Herring @ 2023-11-14 13:44 UTC (permalink / raw)
  To: Daniel Golle
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Heiner Kallweit, Russell King,
	Alexander Couzens, Philipp Zabel, netdev, devicetree,
	linux-kernel, linux-arm-kernel, linux-mediatek, linux-phy

On Thu, Nov 09, 2023 at 11:11:02PM +0000, Daniel Golle wrote:
> Hi Andrew,
> 
> On Thu, Nov 09, 2023 at 10:55:55PM +0100, Andrew Lunn wrote:
> > > +  mediatek,usxgmii-performance-errata:
> > > +    $ref: /schemas/types.yaml#/definitions/flag
> > > +    description:
> > > +      USXGMII0 on MT7988 suffers from a performance problem in 10GBase-R
> > > +      mode which needs a work-around in the driver. The work-around is
> > > +      enabled using this flag.
> > 
> > Is there more details about this? I'm just wondering if this should be
> > based on the compatible, rather than a bool property.
> 
> The vendor sources where this is coming from are here:
> 
> https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/a500d94cd47e279015ce22947e1ce396a7516598%5E%21/#F0
> 
> And I'm afraid this is as much detail as it gets. And yes, we could
> also base this on the compatible and just have two different ones for
> the two PEXTP instances found in MT7988.
> Let me know your conclusion in that regard.

I'd go with a property in this case unless you think there may be other 
per instance differences.

Rob

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

* Re: [RFC PATCH 1/8] dt-bindings: phy: mediatek,xfi-pextp: add new bindings
@ 2023-11-14 13:44         ` Rob Herring
  0 siblings, 0 replies; 73+ messages in thread
From: Rob Herring @ 2023-11-14 13:44 UTC (permalink / raw)
  To: Daniel Golle
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Heiner Kallweit, Russell King,
	Alexander Couzens, Philipp Zabel, netdev, devicetree,
	linux-kernel, linux-arm-kernel, linux-mediatek, linux-phy

On Thu, Nov 09, 2023 at 11:11:02PM +0000, Daniel Golle wrote:
> Hi Andrew,
> 
> On Thu, Nov 09, 2023 at 10:55:55PM +0100, Andrew Lunn wrote:
> > > +  mediatek,usxgmii-performance-errata:
> > > +    $ref: /schemas/types.yaml#/definitions/flag
> > > +    description:
> > > +      USXGMII0 on MT7988 suffers from a performance problem in 10GBase-R
> > > +      mode which needs a work-around in the driver. The work-around is
> > > +      enabled using this flag.
> > 
> > Is there more details about this? I'm just wondering if this should be
> > based on the compatible, rather than a bool property.
> 
> The vendor sources where this is coming from are here:
> 
> https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/a500d94cd47e279015ce22947e1ce396a7516598%5E%21/#F0
> 
> And I'm afraid this is as much detail as it gets. And yes, we could
> also base this on the compatible and just have two different ones for
> the two PEXTP instances found in MT7988.
> Let me know your conclusion in that regard.

I'd go with a property in this case unless you think there may be other 
per instance differences.

Rob

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [RFC PATCH 1/8] dt-bindings: phy: mediatek,xfi-pextp: add new bindings
@ 2023-11-14 13:44         ` Rob Herring
  0 siblings, 0 replies; 73+ messages in thread
From: Rob Herring @ 2023-11-14 13:44 UTC (permalink / raw)
  To: Daniel Golle
  Cc: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Heiner Kallweit, Russell King,
	Alexander Couzens, Philipp Zabel, netdev, devicetree,
	linux-kernel, linux-arm-kernel, linux-mediatek, linux-phy

On Thu, Nov 09, 2023 at 11:11:02PM +0000, Daniel Golle wrote:
> Hi Andrew,
> 
> On Thu, Nov 09, 2023 at 10:55:55PM +0100, Andrew Lunn wrote:
> > > +  mediatek,usxgmii-performance-errata:
> > > +    $ref: /schemas/types.yaml#/definitions/flag
> > > +    description:
> > > +      USXGMII0 on MT7988 suffers from a performance problem in 10GBase-R
> > > +      mode which needs a work-around in the driver. The work-around is
> > > +      enabled using this flag.
> > 
> > Is there more details about this? I'm just wondering if this should be
> > based on the compatible, rather than a bool property.
> 
> The vendor sources where this is coming from are here:
> 
> https://git01.mediatek.com/plugins/gitiles/openwrt/feeds/mtk-openwrt-feeds/+/a500d94cd47e279015ce22947e1ce396a7516598%5E%21/#F0
> 
> And I'm afraid this is as much detail as it gets. And yes, we could
> also base this on the compatible and just have two different ones for
> the two PEXTP instances found in MT7988.
> Let me know your conclusion in that regard.

I'd go with a property in this case unless you think there may be other 
per instance differences.

Rob

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [RFC PATCH 5/8] dt-bindings: net: pcs: add bindings for MediaTek USXGMII PCS
  2023-11-09 21:51   ` Daniel Golle
  (?)
@ 2023-11-14 13:56     ` Rob Herring
  -1 siblings, 0 replies; 73+ messages in thread
From: Rob Herring @ 2023-11-14 13:56 UTC (permalink / raw)
  To: Daniel Golle
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun, Vinod Koul,
	Kishon Vijay Abraham I, Felix Fietkau, John Crispin, Sean Wang,
	Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Philipp Zabel, netdev,
	devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-phy

On Thu, Nov 09, 2023 at 09:51:47PM +0000, Daniel Golle wrote:
> MediaTek's USXGMII can be found in the MT7988 SoC. We need to access
> it in order to configure and monitor the Ethernet SerDes link in
> USXGMII, 10GBase-R and 5GBase-R mode. By including a wrapped
> legacy 1000Base-X/2500Base-X/Cisco SGMII LynxI PCS as well, those
> interface modes are also available.
> 
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
>  .../bindings/net/pcs/mediatek,usxgmii.yaml    | 105 ++++++++++++++++++
>  1 file changed, 105 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
> 
> diff --git a/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml b/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
> new file mode 100644
> index 0000000000000..199cf47859e31
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
> @@ -0,0 +1,105 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/net/pcs/mediatek,usxgmii.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MediaTek USXGMII PCS
> +
> +maintainers:
> +  - Daniel Golle <daniel@makrotopia.org>
> +
> +description:
> +  The MediaTek USXGMII PCS provides physical link control and status
> +  for USXGMII, 10GBase-R and 5GBase-R links on the SerDes interfaces
> +  provided by the PEXTP PHY.
> +  In order to also support legacy 2500Base-X, 1000Base-X and Cisco
> +  SGMII an existing mediatek,*-sgmiisys LynxI PCS is wrapped to
> +  provide those interfaces modes on the same SerDes interfaces shared
> +  with the USXGMII PCS.
> +
> +properties:
> +  $nodename:
> +    pattern: "^pcs@[0-9a-f]+$"
> +
> +  compatible:
> +    const: mediatek,mt7988-usxgmiisys
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    items:
> +      - description: USXGMII top-level clock
> +      - description: SGMII top-level clock
> +      - description: SGMII subsystem TX clock
> +      - description: SGMII subsystem RX clock
> +      - description: XFI PLL clock
> +
> +  clock-names:
> +    items:
> +      - const: usxgmii
> +      - const: sgmii_sel
> +      - const: sgmii_tx
> +      - const: sgmii_rx
> +      - const: xfi_pll
> +
> +  phys:
> +    items:
> +      - description: PEXTP SerDes PHY
> +
> +  mediatek,sgmiisys:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      Phandle to the syscon node of the corresponding SGMII LynxI PCS.
> +
> +  resets:
> +    items:
> +      - description: XFI reset
> +      - description: SGMII reset
> +
> +  reset-names:
> +    items:
> +      - const: xfi
> +      - const: sgmii
> +
> +  "#pcs-cells":

There is no such property defined.

Rob

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

* Re: [RFC PATCH 5/8] dt-bindings: net: pcs: add bindings for MediaTek USXGMII PCS
@ 2023-11-14 13:56     ` Rob Herring
  0 siblings, 0 replies; 73+ messages in thread
From: Rob Herring @ 2023-11-14 13:56 UTC (permalink / raw)
  To: Daniel Golle
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun, Vinod Koul,
	Kishon Vijay Abraham I, Felix Fietkau, John Crispin, Sean Wang,
	Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Philipp Zabel, netdev,
	devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-phy

On Thu, Nov 09, 2023 at 09:51:47PM +0000, Daniel Golle wrote:
> MediaTek's USXGMII can be found in the MT7988 SoC. We need to access
> it in order to configure and monitor the Ethernet SerDes link in
> USXGMII, 10GBase-R and 5GBase-R mode. By including a wrapped
> legacy 1000Base-X/2500Base-X/Cisco SGMII LynxI PCS as well, those
> interface modes are also available.
> 
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
>  .../bindings/net/pcs/mediatek,usxgmii.yaml    | 105 ++++++++++++++++++
>  1 file changed, 105 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
> 
> diff --git a/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml b/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
> new file mode 100644
> index 0000000000000..199cf47859e31
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
> @@ -0,0 +1,105 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/net/pcs/mediatek,usxgmii.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MediaTek USXGMII PCS
> +
> +maintainers:
> +  - Daniel Golle <daniel@makrotopia.org>
> +
> +description:
> +  The MediaTek USXGMII PCS provides physical link control and status
> +  for USXGMII, 10GBase-R and 5GBase-R links on the SerDes interfaces
> +  provided by the PEXTP PHY.
> +  In order to also support legacy 2500Base-X, 1000Base-X and Cisco
> +  SGMII an existing mediatek,*-sgmiisys LynxI PCS is wrapped to
> +  provide those interfaces modes on the same SerDes interfaces shared
> +  with the USXGMII PCS.
> +
> +properties:
> +  $nodename:
> +    pattern: "^pcs@[0-9a-f]+$"
> +
> +  compatible:
> +    const: mediatek,mt7988-usxgmiisys
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    items:
> +      - description: USXGMII top-level clock
> +      - description: SGMII top-level clock
> +      - description: SGMII subsystem TX clock
> +      - description: SGMII subsystem RX clock
> +      - description: XFI PLL clock
> +
> +  clock-names:
> +    items:
> +      - const: usxgmii
> +      - const: sgmii_sel
> +      - const: sgmii_tx
> +      - const: sgmii_rx
> +      - const: xfi_pll
> +
> +  phys:
> +    items:
> +      - description: PEXTP SerDes PHY
> +
> +  mediatek,sgmiisys:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      Phandle to the syscon node of the corresponding SGMII LynxI PCS.
> +
> +  resets:
> +    items:
> +      - description: XFI reset
> +      - description: SGMII reset
> +
> +  reset-names:
> +    items:
> +      - const: xfi
> +      - const: sgmii
> +
> +  "#pcs-cells":

There is no such property defined.

Rob

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [RFC PATCH 5/8] dt-bindings: net: pcs: add bindings for MediaTek USXGMII PCS
@ 2023-11-14 13:56     ` Rob Herring
  0 siblings, 0 replies; 73+ messages in thread
From: Rob Herring @ 2023-11-14 13:56 UTC (permalink / raw)
  To: Daniel Golle
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun, Vinod Koul,
	Kishon Vijay Abraham I, Felix Fietkau, John Crispin, Sean Wang,
	Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Philipp Zabel, netdev,
	devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-phy

On Thu, Nov 09, 2023 at 09:51:47PM +0000, Daniel Golle wrote:
> MediaTek's USXGMII can be found in the MT7988 SoC. We need to access
> it in order to configure and monitor the Ethernet SerDes link in
> USXGMII, 10GBase-R and 5GBase-R mode. By including a wrapped
> legacy 1000Base-X/2500Base-X/Cisco SGMII LynxI PCS as well, those
> interface modes are also available.
> 
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
>  .../bindings/net/pcs/mediatek,usxgmii.yaml    | 105 ++++++++++++++++++
>  1 file changed, 105 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
> 
> diff --git a/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml b/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
> new file mode 100644
> index 0000000000000..199cf47859e31
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/pcs/mediatek,usxgmii.yaml
> @@ -0,0 +1,105 @@
> +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/net/pcs/mediatek,usxgmii.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MediaTek USXGMII PCS
> +
> +maintainers:
> +  - Daniel Golle <daniel@makrotopia.org>
> +
> +description:
> +  The MediaTek USXGMII PCS provides physical link control and status
> +  for USXGMII, 10GBase-R and 5GBase-R links on the SerDes interfaces
> +  provided by the PEXTP PHY.
> +  In order to also support legacy 2500Base-X, 1000Base-X and Cisco
> +  SGMII an existing mediatek,*-sgmiisys LynxI PCS is wrapped to
> +  provide those interfaces modes on the same SerDes interfaces shared
> +  with the USXGMII PCS.
> +
> +properties:
> +  $nodename:
> +    pattern: "^pcs@[0-9a-f]+$"
> +
> +  compatible:
> +    const: mediatek,mt7988-usxgmiisys
> +
> +  reg:
> +    maxItems: 1
> +
> +  clocks:
> +    items:
> +      - description: USXGMII top-level clock
> +      - description: SGMII top-level clock
> +      - description: SGMII subsystem TX clock
> +      - description: SGMII subsystem RX clock
> +      - description: XFI PLL clock
> +
> +  clock-names:
> +    items:
> +      - const: usxgmii
> +      - const: sgmii_sel
> +      - const: sgmii_tx
> +      - const: sgmii_rx
> +      - const: xfi_pll
> +
> +  phys:
> +    items:
> +      - description: PEXTP SerDes PHY
> +
> +  mediatek,sgmiisys:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      Phandle to the syscon node of the corresponding SGMII LynxI PCS.
> +
> +  resets:
> +    items:
> +      - description: XFI reset
> +      - description: SGMII reset
> +
> +  reset-names:
> +    items:
> +      - const: xfi
> +      - const: sgmii
> +
> +  "#pcs-cells":

There is no such property defined.

Rob

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [RFC PATCH 7/8] dt-bindings: net: mediatek,net: fix and complete mt7988-eth binding
  2023-11-09 21:52   ` Daniel Golle
  (?)
@ 2023-11-14 14:07     ` Rob Herring
  -1 siblings, 0 replies; 73+ messages in thread
From: Rob Herring @ 2023-11-14 14:07 UTC (permalink / raw)
  To: Daniel Golle
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun, Vinod Koul,
	Kishon Vijay Abraham I, Felix Fietkau, John Crispin, Sean Wang,
	Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Philipp Zabel, netdev,
	devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-phy

On Thu, Nov 09, 2023 at 09:52:09PM +0000, Daniel Golle wrote:
> Remove clocks which were copied from the vendor driver but are now taken
> care of by dedicated drivers for PCS and PHY in the upstream driver.
> Also remove mediatek,sgmiisys phandle which isn't required on MT7988
> because we use pcs-handle on the MAC nodes instead.
> Last but not least, add an example for MT7988.

'Also' is a clue for it should be a separate patch. These changes are 
all ABI breakage. Please explain why that's okay.

> 
> Fixes: c94a9aabec36 ("dt-bindings: net: mediatek,net: add mt7988-eth binding")
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
>  .../devicetree/bindings/net/mediatek,net.yaml | 171 +++++++++++++++---
>  1 file changed, 142 insertions(+), 29 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/net/mediatek,net.yaml b/Documentation/devicetree/bindings/net/mediatek,net.yaml
> index e74502a0afe86..c0f7bb6f3ef8d 100644
> --- a/Documentation/devicetree/bindings/net/mediatek,net.yaml
> +++ b/Documentation/devicetree/bindings/net/mediatek,net.yaml
> @@ -27,9 +27,6 @@ properties:
>        - mediatek,mt7988-eth
>        - ralink,rt5350-eth
>  
> -  reg:
> -    maxItems: 1
> -

It's not clear what this change is from the commit msg.

This should stay and be:

reg:
  minItems: 1
  items:
    - description: what's in the 1st region
    - description: what's in the 2nd region

>    clocks: true
>    clock-names: true
>  
> @@ -115,6 +112,9 @@ allOf:
>                - mediatek,mt7623-eth
>      then:
>        properties:
> +        reg:
> +          maxItems: 1
> +
>          interrupts:
>            maxItems: 3
>  
> @@ -149,6 +149,9 @@ allOf:
>                - mediatek,mt7621-eth
>      then:
>        properties:
> +        reg:
> +          maxItems: 1
> +
>          interrupts:
>            maxItems: 1
>  
> @@ -174,6 +177,9 @@ allOf:
>              const: mediatek,mt7622-eth
>      then:
>        properties:
> +        reg:
> +          maxItems: 1
> +
>          interrupts:
>            maxItems: 3
>  
> @@ -215,6 +221,9 @@ allOf:
>              const: mediatek,mt7629-eth
>      then:
>        properties:
> +        reg:
> +          maxItems: 1
> +
>          interrupts:
>            maxItems: 3
>  
> @@ -257,6 +266,9 @@ allOf:
>              const: mediatek,mt7981-eth
>      then:
>        properties:
> +        reg:
> +          maxItems: 1
> +
>          interrupts:
>            minItems: 4
>  
> @@ -295,6 +307,9 @@ allOf:
>              const: mediatek,mt7986-eth
>      then:
>        properties:
> +        reg:
> +          maxItems: 1
> +

Looks like lots of duplication. Perhaps there's a cleaner way.

>          interrupts:
>            minItems: 4
>  
> @@ -333,36 +348,32 @@ allOf:
>              const: mediatek,mt7988-eth
>      then:
>        properties:
> +        reg:
> +          maxItems: 2
> +          minItems: 2
> +
>          interrupts:
>            minItems: 4
> +          maxItems: 4
>  
>          clocks:
> -          minItems: 34
> -          maxItems: 34
> +          minItems: 24
> +          maxItems: 24
>  
>          clock-names:
>            items:
> -            - const: crypto
> +            - const: xgp1
> +            - const: xgp2
> +            - const: xgp3
>              - const: fe
>              - const: gp2
>              - const: gp1
>              - const: gp3
> +            - const: esw
> +            - const: crypto
>              - const: ethwarp_wocpu2
>              - const: ethwarp_wocpu1
>              - const: ethwarp_wocpu0
> -            - const: esw
> -            - const: netsys0
> -            - const: netsys1
> -            - const: sgmii_tx250m
> -            - const: sgmii_rx250m
> -            - const: sgmii2_tx250m
> -            - const: sgmii2_rx250m
> -            - const: top_usxgmii0_sel
> -            - const: top_usxgmii1_sel
> -            - const: top_sgm0_sel
> -            - const: top_sgm1_sel
> -            - const: top_xfi_phy0_xtal_sel
> -            - const: top_xfi_phy1_xtal_sel
>              - const: top_eth_gmii_sel
>              - const: top_eth_refck_50m_sel
>              - const: top_eth_sys_200m_sel
> @@ -375,18 +386,9 @@ allOf:
>              - const: top_netsys_sync_250m_sel
>              - const: top_netsys_ppefb_250m_sel
>              - const: top_netsys_warp_sel
> -            - const: wocpu1
> -            - const: wocpu0
> -            - const: xgp1
> -            - const: xgp2
> -            - const: xgp3
> -
> -        mediatek,sgmiisys:
> -          minItems: 2
> -          maxItems: 2
>  
>  patternProperties:
> -  "^mac@[0-1]$":
> +  "^mac@[0-2]$":
>      type: object
>      unevaluatedProperties: false
>      allOf:
> @@ -577,3 +579,114 @@ examples:
>          };
>        };
>      };
> +
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/clock/mediatek,mt7988-clk.h>
> +
> +    soc {
> +      #address-cells = <2>;
> +      #size-cells = <2>;
> +
> +      ethernet@15100000 {
> +        compatible = "mediatek,mt7988-eth";
> +        reg = <0 0x15100000 0 0x80000>, <0 0x15400000 0 0x380000>;
> +        interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
> +                     <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
> +                     <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
> +                     <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
> +
> +        clocks = <&ethsys CLK_ETHDMA_XGP1_EN>,
> +                 <&ethsys CLK_ETHDMA_XGP2_EN>,
> +                 <&ethsys CLK_ETHDMA_XGP3_EN>,
> +                 <&ethsys CLK_ETHDMA_FE_EN>,
> +                 <&ethsys CLK_ETHDMA_GP2_EN>,
> +                 <&ethsys CLK_ETHDMA_GP1_EN>,
> +                 <&ethsys CLK_ETHDMA_GP3_EN>,
> +                 <&ethsys CLK_ETHDMA_ESW_EN>,
> +                 <&ethsys CLK_ETHDMA_CRYPT0_EN>,
> +                 <&ethwarp CLK_ETHWARP_WOCPU2_EN>,
> +                 <&ethwarp CLK_ETHWARP_WOCPU1_EN>,
> +                 <&ethwarp CLK_ETHWARP_WOCPU0_EN>,
> +                 <&topckgen CLK_TOP_ETH_GMII_SEL>,
> +                 <&topckgen CLK_TOP_ETH_REFCK_50M_SEL>,
> +                 <&topckgen CLK_TOP_ETH_SYS_200M_SEL>,
> +                 <&topckgen CLK_TOP_ETH_SYS_SEL>,
> +                 <&topckgen CLK_TOP_ETH_XGMII_SEL>,
> +                 <&topckgen CLK_TOP_ETH_MII_SEL>,
> +                 <&topckgen CLK_TOP_NETSYS_SEL>,
> +                 <&topckgen CLK_TOP_NETSYS_500M_SEL>,
> +                 <&topckgen CLK_TOP_NETSYS_PAO_2X_SEL>,
> +                 <&topckgen CLK_TOP_NETSYS_SYNC_250M_SEL>,
> +                 <&topckgen CLK_TOP_NETSYS_PPEFB_250M_SEL>,
> +                 <&topckgen CLK_TOP_NETSYS_WARP_SEL>;
> +
> +        clock-names = "xgp1", "xgp2", "xgp3", "fe", "gp2", "gp1",
> +                      "gp3", "esw", "crypto",
> +                      "ethwarp_wocpu2", "ethwarp_wocpu1",
> +                      "ethwarp_wocpu0", "top_eth_gmii_sel",
> +                      "top_eth_refck_50m_sel", "top_eth_sys_200m_sel",
> +                      "top_eth_sys_sel", "top_eth_xgmii_sel",
> +                      "top_eth_mii_sel", "top_netsys_sel",
> +                      "top_netsys_500m_sel", "top_netsys_pao_2x_sel",
> +                      "top_netsys_sync_250m_sel",
> +                      "top_netsys_ppefb_250m_sel",
> +                      "top_netsys_warp_sel";
> +        assigned-clocks = <&topckgen CLK_TOP_NETSYS_2X_SEL>,
> +                          <&topckgen CLK_TOP_NETSYS_GSW_SEL>,
> +                          <&topckgen CLK_TOP_USXGMII_SBUS_0_SEL>,
> +                          <&topckgen CLK_TOP_USXGMII_SBUS_1_SEL>,
> +                          <&topckgen CLK_TOP_SGM_0_SEL>,
> +                          <&topckgen CLK_TOP_SGM_1_SEL>;
> +        assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>,
> +                                 <&topckgen CLK_TOP_NET1PLL_D4>,
> +                                 <&topckgen CLK_TOP_NET1PLL_D8_D4>,
> +                                 <&topckgen CLK_TOP_NET1PLL_D8_D4>,
> +                                 <&apmixedsys CLK_APMIXED_SGMPLL>,
> +                                 <&apmixedsys CLK_APMIXED_SGMPLL>;
> +        mediatek,ethsys = <&ethsys>;
> +        mediatek,infracfg = <&topmisc>;
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        mac@0 {
> +          compatible = "mediatek,eth-mac";
> +          reg = <0>;
> +          phy-mode = "internal";
> +          status = "disabled";

Examples should be enabled.

> +
> +          fixed-link {
> +            speed = <10000>;
> +            full-duplex;
> +            pause;
> +          };
> +        };
> +
> +        mac@1 {
> +          compatible = "mediatek,eth-mac";
> +          reg = <1>;
> +          status = "disabled";
> +          pcs-handle = <&usxgmiisys1>;
> +        };
> +
> +        mac@2 {
> +          compatible = "mediatek,eth-mac";
> +          reg = <2>;
> +          status = "disabled";
> +          pcs-handle = <&usxgmiisys0>;
> +        };
> +
> +        mdio_bus: mdio-bus {

mdio {

> +          #address-cells = <1>;
> +          #size-cells = <0>;
> +
> +          /* internal 2.5G PHY */
> +          int_2p5g_phy: ethernet-phy@15 {
> +            reg = <15>;
> +            compatible = "ethernet-phy-ieee802.3-c45";
> +            phy-mode = "internal";
> +          };
> +        };
> +      };
> +    };
> -- 
> 2.42.1

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

* Re: [RFC PATCH 7/8] dt-bindings: net: mediatek,net: fix and complete mt7988-eth binding
@ 2023-11-14 14:07     ` Rob Herring
  0 siblings, 0 replies; 73+ messages in thread
From: Rob Herring @ 2023-11-14 14:07 UTC (permalink / raw)
  To: Daniel Golle
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun, Vinod Koul,
	Kishon Vijay Abraham I, Felix Fietkau, John Crispin, Sean Wang,
	Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Philipp Zabel, netdev,
	devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-phy

On Thu, Nov 09, 2023 at 09:52:09PM +0000, Daniel Golle wrote:
> Remove clocks which were copied from the vendor driver but are now taken
> care of by dedicated drivers for PCS and PHY in the upstream driver.
> Also remove mediatek,sgmiisys phandle which isn't required on MT7988
> because we use pcs-handle on the MAC nodes instead.
> Last but not least, add an example for MT7988.

'Also' is a clue for it should be a separate patch. These changes are 
all ABI breakage. Please explain why that's okay.

> 
> Fixes: c94a9aabec36 ("dt-bindings: net: mediatek,net: add mt7988-eth binding")
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
>  .../devicetree/bindings/net/mediatek,net.yaml | 171 +++++++++++++++---
>  1 file changed, 142 insertions(+), 29 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/net/mediatek,net.yaml b/Documentation/devicetree/bindings/net/mediatek,net.yaml
> index e74502a0afe86..c0f7bb6f3ef8d 100644
> --- a/Documentation/devicetree/bindings/net/mediatek,net.yaml
> +++ b/Documentation/devicetree/bindings/net/mediatek,net.yaml
> @@ -27,9 +27,6 @@ properties:
>        - mediatek,mt7988-eth
>        - ralink,rt5350-eth
>  
> -  reg:
> -    maxItems: 1
> -

It's not clear what this change is from the commit msg.

This should stay and be:

reg:
  minItems: 1
  items:
    - description: what's in the 1st region
    - description: what's in the 2nd region

>    clocks: true
>    clock-names: true
>  
> @@ -115,6 +112,9 @@ allOf:
>                - mediatek,mt7623-eth
>      then:
>        properties:
> +        reg:
> +          maxItems: 1
> +
>          interrupts:
>            maxItems: 3
>  
> @@ -149,6 +149,9 @@ allOf:
>                - mediatek,mt7621-eth
>      then:
>        properties:
> +        reg:
> +          maxItems: 1
> +
>          interrupts:
>            maxItems: 1
>  
> @@ -174,6 +177,9 @@ allOf:
>              const: mediatek,mt7622-eth
>      then:
>        properties:
> +        reg:
> +          maxItems: 1
> +
>          interrupts:
>            maxItems: 3
>  
> @@ -215,6 +221,9 @@ allOf:
>              const: mediatek,mt7629-eth
>      then:
>        properties:
> +        reg:
> +          maxItems: 1
> +
>          interrupts:
>            maxItems: 3
>  
> @@ -257,6 +266,9 @@ allOf:
>              const: mediatek,mt7981-eth
>      then:
>        properties:
> +        reg:
> +          maxItems: 1
> +
>          interrupts:
>            minItems: 4
>  
> @@ -295,6 +307,9 @@ allOf:
>              const: mediatek,mt7986-eth
>      then:
>        properties:
> +        reg:
> +          maxItems: 1
> +

Looks like lots of duplication. Perhaps there's a cleaner way.

>          interrupts:
>            minItems: 4
>  
> @@ -333,36 +348,32 @@ allOf:
>              const: mediatek,mt7988-eth
>      then:
>        properties:
> +        reg:
> +          maxItems: 2
> +          minItems: 2
> +
>          interrupts:
>            minItems: 4
> +          maxItems: 4
>  
>          clocks:
> -          minItems: 34
> -          maxItems: 34
> +          minItems: 24
> +          maxItems: 24
>  
>          clock-names:
>            items:
> -            - const: crypto
> +            - const: xgp1
> +            - const: xgp2
> +            - const: xgp3
>              - const: fe
>              - const: gp2
>              - const: gp1
>              - const: gp3
> +            - const: esw
> +            - const: crypto
>              - const: ethwarp_wocpu2
>              - const: ethwarp_wocpu1
>              - const: ethwarp_wocpu0
> -            - const: esw
> -            - const: netsys0
> -            - const: netsys1
> -            - const: sgmii_tx250m
> -            - const: sgmii_rx250m
> -            - const: sgmii2_tx250m
> -            - const: sgmii2_rx250m
> -            - const: top_usxgmii0_sel
> -            - const: top_usxgmii1_sel
> -            - const: top_sgm0_sel
> -            - const: top_sgm1_sel
> -            - const: top_xfi_phy0_xtal_sel
> -            - const: top_xfi_phy1_xtal_sel
>              - const: top_eth_gmii_sel
>              - const: top_eth_refck_50m_sel
>              - const: top_eth_sys_200m_sel
> @@ -375,18 +386,9 @@ allOf:
>              - const: top_netsys_sync_250m_sel
>              - const: top_netsys_ppefb_250m_sel
>              - const: top_netsys_warp_sel
> -            - const: wocpu1
> -            - const: wocpu0
> -            - const: xgp1
> -            - const: xgp2
> -            - const: xgp3
> -
> -        mediatek,sgmiisys:
> -          minItems: 2
> -          maxItems: 2
>  
>  patternProperties:
> -  "^mac@[0-1]$":
> +  "^mac@[0-2]$":
>      type: object
>      unevaluatedProperties: false
>      allOf:
> @@ -577,3 +579,114 @@ examples:
>          };
>        };
>      };
> +
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/clock/mediatek,mt7988-clk.h>
> +
> +    soc {
> +      #address-cells = <2>;
> +      #size-cells = <2>;
> +
> +      ethernet@15100000 {
> +        compatible = "mediatek,mt7988-eth";
> +        reg = <0 0x15100000 0 0x80000>, <0 0x15400000 0 0x380000>;
> +        interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
> +                     <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
> +                     <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
> +                     <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
> +
> +        clocks = <&ethsys CLK_ETHDMA_XGP1_EN>,
> +                 <&ethsys CLK_ETHDMA_XGP2_EN>,
> +                 <&ethsys CLK_ETHDMA_XGP3_EN>,
> +                 <&ethsys CLK_ETHDMA_FE_EN>,
> +                 <&ethsys CLK_ETHDMA_GP2_EN>,
> +                 <&ethsys CLK_ETHDMA_GP1_EN>,
> +                 <&ethsys CLK_ETHDMA_GP3_EN>,
> +                 <&ethsys CLK_ETHDMA_ESW_EN>,
> +                 <&ethsys CLK_ETHDMA_CRYPT0_EN>,
> +                 <&ethwarp CLK_ETHWARP_WOCPU2_EN>,
> +                 <&ethwarp CLK_ETHWARP_WOCPU1_EN>,
> +                 <&ethwarp CLK_ETHWARP_WOCPU0_EN>,
> +                 <&topckgen CLK_TOP_ETH_GMII_SEL>,
> +                 <&topckgen CLK_TOP_ETH_REFCK_50M_SEL>,
> +                 <&topckgen CLK_TOP_ETH_SYS_200M_SEL>,
> +                 <&topckgen CLK_TOP_ETH_SYS_SEL>,
> +                 <&topckgen CLK_TOP_ETH_XGMII_SEL>,
> +                 <&topckgen CLK_TOP_ETH_MII_SEL>,
> +                 <&topckgen CLK_TOP_NETSYS_SEL>,
> +                 <&topckgen CLK_TOP_NETSYS_500M_SEL>,
> +                 <&topckgen CLK_TOP_NETSYS_PAO_2X_SEL>,
> +                 <&topckgen CLK_TOP_NETSYS_SYNC_250M_SEL>,
> +                 <&topckgen CLK_TOP_NETSYS_PPEFB_250M_SEL>,
> +                 <&topckgen CLK_TOP_NETSYS_WARP_SEL>;
> +
> +        clock-names = "xgp1", "xgp2", "xgp3", "fe", "gp2", "gp1",
> +                      "gp3", "esw", "crypto",
> +                      "ethwarp_wocpu2", "ethwarp_wocpu1",
> +                      "ethwarp_wocpu0", "top_eth_gmii_sel",
> +                      "top_eth_refck_50m_sel", "top_eth_sys_200m_sel",
> +                      "top_eth_sys_sel", "top_eth_xgmii_sel",
> +                      "top_eth_mii_sel", "top_netsys_sel",
> +                      "top_netsys_500m_sel", "top_netsys_pao_2x_sel",
> +                      "top_netsys_sync_250m_sel",
> +                      "top_netsys_ppefb_250m_sel",
> +                      "top_netsys_warp_sel";
> +        assigned-clocks = <&topckgen CLK_TOP_NETSYS_2X_SEL>,
> +                          <&topckgen CLK_TOP_NETSYS_GSW_SEL>,
> +                          <&topckgen CLK_TOP_USXGMII_SBUS_0_SEL>,
> +                          <&topckgen CLK_TOP_USXGMII_SBUS_1_SEL>,
> +                          <&topckgen CLK_TOP_SGM_0_SEL>,
> +                          <&topckgen CLK_TOP_SGM_1_SEL>;
> +        assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>,
> +                                 <&topckgen CLK_TOP_NET1PLL_D4>,
> +                                 <&topckgen CLK_TOP_NET1PLL_D8_D4>,
> +                                 <&topckgen CLK_TOP_NET1PLL_D8_D4>,
> +                                 <&apmixedsys CLK_APMIXED_SGMPLL>,
> +                                 <&apmixedsys CLK_APMIXED_SGMPLL>;
> +        mediatek,ethsys = <&ethsys>;
> +        mediatek,infracfg = <&topmisc>;
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        mac@0 {
> +          compatible = "mediatek,eth-mac";
> +          reg = <0>;
> +          phy-mode = "internal";
> +          status = "disabled";

Examples should be enabled.

> +
> +          fixed-link {
> +            speed = <10000>;
> +            full-duplex;
> +            pause;
> +          };
> +        };
> +
> +        mac@1 {
> +          compatible = "mediatek,eth-mac";
> +          reg = <1>;
> +          status = "disabled";
> +          pcs-handle = <&usxgmiisys1>;
> +        };
> +
> +        mac@2 {
> +          compatible = "mediatek,eth-mac";
> +          reg = <2>;
> +          status = "disabled";
> +          pcs-handle = <&usxgmiisys0>;
> +        };
> +
> +        mdio_bus: mdio-bus {

mdio {

> +          #address-cells = <1>;
> +          #size-cells = <0>;
> +
> +          /* internal 2.5G PHY */
> +          int_2p5g_phy: ethernet-phy@15 {
> +            reg = <15>;
> +            compatible = "ethernet-phy-ieee802.3-c45";
> +            phy-mode = "internal";
> +          };
> +        };
> +      };
> +    };
> -- 
> 2.42.1

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [RFC PATCH 7/8] dt-bindings: net: mediatek,net: fix and complete mt7988-eth binding
@ 2023-11-14 14:07     ` Rob Herring
  0 siblings, 0 replies; 73+ messages in thread
From: Rob Herring @ 2023-11-14 14:07 UTC (permalink / raw)
  To: Daniel Golle
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun, Vinod Koul,
	Kishon Vijay Abraham I, Felix Fietkau, John Crispin, Sean Wang,
	Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Philipp Zabel, netdev,
	devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-phy

On Thu, Nov 09, 2023 at 09:52:09PM +0000, Daniel Golle wrote:
> Remove clocks which were copied from the vendor driver but are now taken
> care of by dedicated drivers for PCS and PHY in the upstream driver.
> Also remove mediatek,sgmiisys phandle which isn't required on MT7988
> because we use pcs-handle on the MAC nodes instead.
> Last but not least, add an example for MT7988.

'Also' is a clue for it should be a separate patch. These changes are 
all ABI breakage. Please explain why that's okay.

> 
> Fixes: c94a9aabec36 ("dt-bindings: net: mediatek,net: add mt7988-eth binding")
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
>  .../devicetree/bindings/net/mediatek,net.yaml | 171 +++++++++++++++---
>  1 file changed, 142 insertions(+), 29 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/net/mediatek,net.yaml b/Documentation/devicetree/bindings/net/mediatek,net.yaml
> index e74502a0afe86..c0f7bb6f3ef8d 100644
> --- a/Documentation/devicetree/bindings/net/mediatek,net.yaml
> +++ b/Documentation/devicetree/bindings/net/mediatek,net.yaml
> @@ -27,9 +27,6 @@ properties:
>        - mediatek,mt7988-eth
>        - ralink,rt5350-eth
>  
> -  reg:
> -    maxItems: 1
> -

It's not clear what this change is from the commit msg.

This should stay and be:

reg:
  minItems: 1
  items:
    - description: what's in the 1st region
    - description: what's in the 2nd region

>    clocks: true
>    clock-names: true
>  
> @@ -115,6 +112,9 @@ allOf:
>                - mediatek,mt7623-eth
>      then:
>        properties:
> +        reg:
> +          maxItems: 1
> +
>          interrupts:
>            maxItems: 3
>  
> @@ -149,6 +149,9 @@ allOf:
>                - mediatek,mt7621-eth
>      then:
>        properties:
> +        reg:
> +          maxItems: 1
> +
>          interrupts:
>            maxItems: 1
>  
> @@ -174,6 +177,9 @@ allOf:
>              const: mediatek,mt7622-eth
>      then:
>        properties:
> +        reg:
> +          maxItems: 1
> +
>          interrupts:
>            maxItems: 3
>  
> @@ -215,6 +221,9 @@ allOf:
>              const: mediatek,mt7629-eth
>      then:
>        properties:
> +        reg:
> +          maxItems: 1
> +
>          interrupts:
>            maxItems: 3
>  
> @@ -257,6 +266,9 @@ allOf:
>              const: mediatek,mt7981-eth
>      then:
>        properties:
> +        reg:
> +          maxItems: 1
> +
>          interrupts:
>            minItems: 4
>  
> @@ -295,6 +307,9 @@ allOf:
>              const: mediatek,mt7986-eth
>      then:
>        properties:
> +        reg:
> +          maxItems: 1
> +

Looks like lots of duplication. Perhaps there's a cleaner way.

>          interrupts:
>            minItems: 4
>  
> @@ -333,36 +348,32 @@ allOf:
>              const: mediatek,mt7988-eth
>      then:
>        properties:
> +        reg:
> +          maxItems: 2
> +          minItems: 2
> +
>          interrupts:
>            minItems: 4
> +          maxItems: 4
>  
>          clocks:
> -          minItems: 34
> -          maxItems: 34
> +          minItems: 24
> +          maxItems: 24
>  
>          clock-names:
>            items:
> -            - const: crypto
> +            - const: xgp1
> +            - const: xgp2
> +            - const: xgp3
>              - const: fe
>              - const: gp2
>              - const: gp1
>              - const: gp3
> +            - const: esw
> +            - const: crypto
>              - const: ethwarp_wocpu2
>              - const: ethwarp_wocpu1
>              - const: ethwarp_wocpu0
> -            - const: esw
> -            - const: netsys0
> -            - const: netsys1
> -            - const: sgmii_tx250m
> -            - const: sgmii_rx250m
> -            - const: sgmii2_tx250m
> -            - const: sgmii2_rx250m
> -            - const: top_usxgmii0_sel
> -            - const: top_usxgmii1_sel
> -            - const: top_sgm0_sel
> -            - const: top_sgm1_sel
> -            - const: top_xfi_phy0_xtal_sel
> -            - const: top_xfi_phy1_xtal_sel
>              - const: top_eth_gmii_sel
>              - const: top_eth_refck_50m_sel
>              - const: top_eth_sys_200m_sel
> @@ -375,18 +386,9 @@ allOf:
>              - const: top_netsys_sync_250m_sel
>              - const: top_netsys_ppefb_250m_sel
>              - const: top_netsys_warp_sel
> -            - const: wocpu1
> -            - const: wocpu0
> -            - const: xgp1
> -            - const: xgp2
> -            - const: xgp3
> -
> -        mediatek,sgmiisys:
> -          minItems: 2
> -          maxItems: 2
>  
>  patternProperties:
> -  "^mac@[0-1]$":
> +  "^mac@[0-2]$":
>      type: object
>      unevaluatedProperties: false
>      allOf:
> @@ -577,3 +579,114 @@ examples:
>          };
>        };
>      };
> +
> +  - |
> +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> +    #include <dt-bindings/interrupt-controller/irq.h>
> +    #include <dt-bindings/clock/mediatek,mt7988-clk.h>
> +
> +    soc {
> +      #address-cells = <2>;
> +      #size-cells = <2>;
> +
> +      ethernet@15100000 {
> +        compatible = "mediatek,mt7988-eth";
> +        reg = <0 0x15100000 0 0x80000>, <0 0x15400000 0 0x380000>;
> +        interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
> +                     <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
> +                     <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
> +                     <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
> +
> +        clocks = <&ethsys CLK_ETHDMA_XGP1_EN>,
> +                 <&ethsys CLK_ETHDMA_XGP2_EN>,
> +                 <&ethsys CLK_ETHDMA_XGP3_EN>,
> +                 <&ethsys CLK_ETHDMA_FE_EN>,
> +                 <&ethsys CLK_ETHDMA_GP2_EN>,
> +                 <&ethsys CLK_ETHDMA_GP1_EN>,
> +                 <&ethsys CLK_ETHDMA_GP3_EN>,
> +                 <&ethsys CLK_ETHDMA_ESW_EN>,
> +                 <&ethsys CLK_ETHDMA_CRYPT0_EN>,
> +                 <&ethwarp CLK_ETHWARP_WOCPU2_EN>,
> +                 <&ethwarp CLK_ETHWARP_WOCPU1_EN>,
> +                 <&ethwarp CLK_ETHWARP_WOCPU0_EN>,
> +                 <&topckgen CLK_TOP_ETH_GMII_SEL>,
> +                 <&topckgen CLK_TOP_ETH_REFCK_50M_SEL>,
> +                 <&topckgen CLK_TOP_ETH_SYS_200M_SEL>,
> +                 <&topckgen CLK_TOP_ETH_SYS_SEL>,
> +                 <&topckgen CLK_TOP_ETH_XGMII_SEL>,
> +                 <&topckgen CLK_TOP_ETH_MII_SEL>,
> +                 <&topckgen CLK_TOP_NETSYS_SEL>,
> +                 <&topckgen CLK_TOP_NETSYS_500M_SEL>,
> +                 <&topckgen CLK_TOP_NETSYS_PAO_2X_SEL>,
> +                 <&topckgen CLK_TOP_NETSYS_SYNC_250M_SEL>,
> +                 <&topckgen CLK_TOP_NETSYS_PPEFB_250M_SEL>,
> +                 <&topckgen CLK_TOP_NETSYS_WARP_SEL>;
> +
> +        clock-names = "xgp1", "xgp2", "xgp3", "fe", "gp2", "gp1",
> +                      "gp3", "esw", "crypto",
> +                      "ethwarp_wocpu2", "ethwarp_wocpu1",
> +                      "ethwarp_wocpu0", "top_eth_gmii_sel",
> +                      "top_eth_refck_50m_sel", "top_eth_sys_200m_sel",
> +                      "top_eth_sys_sel", "top_eth_xgmii_sel",
> +                      "top_eth_mii_sel", "top_netsys_sel",
> +                      "top_netsys_500m_sel", "top_netsys_pao_2x_sel",
> +                      "top_netsys_sync_250m_sel",
> +                      "top_netsys_ppefb_250m_sel",
> +                      "top_netsys_warp_sel";
> +        assigned-clocks = <&topckgen CLK_TOP_NETSYS_2X_SEL>,
> +                          <&topckgen CLK_TOP_NETSYS_GSW_SEL>,
> +                          <&topckgen CLK_TOP_USXGMII_SBUS_0_SEL>,
> +                          <&topckgen CLK_TOP_USXGMII_SBUS_1_SEL>,
> +                          <&topckgen CLK_TOP_SGM_0_SEL>,
> +                          <&topckgen CLK_TOP_SGM_1_SEL>;
> +        assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>,
> +                                 <&topckgen CLK_TOP_NET1PLL_D4>,
> +                                 <&topckgen CLK_TOP_NET1PLL_D8_D4>,
> +                                 <&topckgen CLK_TOP_NET1PLL_D8_D4>,
> +                                 <&apmixedsys CLK_APMIXED_SGMPLL>,
> +                                 <&apmixedsys CLK_APMIXED_SGMPLL>;
> +        mediatek,ethsys = <&ethsys>;
> +        mediatek,infracfg = <&topmisc>;
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        mac@0 {
> +          compatible = "mediatek,eth-mac";
> +          reg = <0>;
> +          phy-mode = "internal";
> +          status = "disabled";

Examples should be enabled.

> +
> +          fixed-link {
> +            speed = <10000>;
> +            full-duplex;
> +            pause;
> +          };
> +        };
> +
> +        mac@1 {
> +          compatible = "mediatek,eth-mac";
> +          reg = <1>;
> +          status = "disabled";
> +          pcs-handle = <&usxgmiisys1>;
> +        };
> +
> +        mac@2 {
> +          compatible = "mediatek,eth-mac";
> +          reg = <2>;
> +          status = "disabled";
> +          pcs-handle = <&usxgmiisys0>;
> +        };
> +
> +        mdio_bus: mdio-bus {

mdio {

> +          #address-cells = <1>;
> +          #size-cells = <0>;
> +
> +          /* internal 2.5G PHY */
> +          int_2p5g_phy: ethernet-phy@15 {
> +            reg = <15>;
> +            compatible = "ethernet-phy-ieee802.3-c45";
> +            phy-mode = "internal";
> +          };
> +        };
> +      };
> +    };
> -- 
> 2.42.1

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [RFC PATCH 7/8] dt-bindings: net: mediatek,net: fix and complete mt7988-eth binding
  2023-11-14 14:07     ` Rob Herring
  (?)
@ 2023-11-14 17:42       ` Daniel Golle
  -1 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-14 17:42 UTC (permalink / raw)
  To: Rob Herring
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun, Vinod Koul,
	Kishon Vijay Abraham I, Felix Fietkau, John Crispin, Sean Wang,
	Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Philipp Zabel, netdev,
	devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-phy

Hi Rob,

thank you for reviewing this patch.

On Tue, Nov 14, 2023 at 08:07:19AM -0600, Rob Herring wrote:
> On Thu, Nov 09, 2023 at 09:52:09PM +0000, Daniel Golle wrote:
> > Remove clocks which were copied from the vendor driver but are now taken
> > care of by dedicated drivers for PCS and PHY in the upstream driver.
> > Also remove mediatek,sgmiisys phandle which isn't required on MT7988
> > because we use pcs-handle on the MAC nodes instead.
> > Last but not least, add an example for MT7988.
> 
> 'Also' is a clue for it should be a separate patch. These changes are 
> all ABI breakage. Please explain why that's okay.

I hope that it's ok because the driver at this point never supported
any SerDes modes and we are still in the process of bringing up
mainline support for this SoC. All of clk, pinctrl, reset, ... driver
and dt-bindings are still pending or being prepared for submission.

> 
> > 
> > Fixes: c94a9aabec36 ("dt-bindings: net: mediatek,net: add mt7988-eth binding")
> > Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> > ---
> >  .../devicetree/bindings/net/mediatek,net.yaml | 171 +++++++++++++++---
> >  1 file changed, 142 insertions(+), 29 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/net/mediatek,net.yaml b/Documentation/devicetree/bindings/net/mediatek,net.yaml
> > index e74502a0afe86..c0f7bb6f3ef8d 100644
> > --- a/Documentation/devicetree/bindings/net/mediatek,net.yaml
> > +++ b/Documentation/devicetree/bindings/net/mediatek,net.yaml
> > @@ -27,9 +27,6 @@ properties:
> >        - mediatek,mt7988-eth
> >        - ralink,rt5350-eth
> >  
> > -  reg:
> > -    maxItems: 1
> > -
> 
> It's not clear what this change is from the commit msg.
> 
> This should stay and be:
> 
> reg:
>   minItems: 1
>   items:
>     - description: what's in the 1st region
>     - description: what's in the 2nd region

Ack.

> 
> >    clocks: true
> >    clock-names: true
> >  
> > @@ -115,6 +112,9 @@ allOf:
> >                - mediatek,mt7623-eth
> >      then:
> >        properties:
> > +        reg:
> > +          maxItems: 1
> > +
> >          interrupts:
> >            maxItems: 3
> >  
> > @@ -149,6 +149,9 @@ allOf:
> >                - mediatek,mt7621-eth
> >      then:
> >        properties:
> > +        reg:
> > +          maxItems: 1
> > +
> >          interrupts:
> >            maxItems: 1
> >  
> > @@ -174,6 +177,9 @@ allOf:
> >              const: mediatek,mt7622-eth
> >      then:
> >        properties:
> > +        reg:
> > +          maxItems: 1
> > +
> >          interrupts:
> >            maxItems: 3
> >  
> > @@ -215,6 +221,9 @@ allOf:
> >              const: mediatek,mt7629-eth
> >      then:
> >        properties:
> > +        reg:
> > +          maxItems: 1
> > +
> >          interrupts:
> >            maxItems: 3
> >  
> > @@ -257,6 +266,9 @@ allOf:
> >              const: mediatek,mt7981-eth
> >      then:
> >        properties:
> > +        reg:
> > +          maxItems: 1
> > +
> >          interrupts:
> >            minItems: 4
> >  
> > @@ -295,6 +307,9 @@ allOf:
> >              const: mediatek,mt7986-eth
> >      then:
> >        properties:
> > +        reg:
> > +          maxItems: 1
> > +
> 
> Looks like lots of duplication. Perhaps there's a cleaner way.

Hm, I don't really see any better way. Suggestions anyone?

> 
> >          interrupts:
> >            minItems: 4
> >  
> > @@ -333,36 +348,32 @@ allOf:
> >              const: mediatek,mt7988-eth
> >      then:
> >        properties:
> > +        reg:
> > +          maxItems: 2
> > +          minItems: 2
> > +
> >          interrupts:
> >            minItems: 4
> > +          maxItems: 4
> >  
> >          clocks:
> > -          minItems: 34
> > -          maxItems: 34
> > +          minItems: 24
> > +          maxItems: 24
> >  
> >          clock-names:
> >            items:
> > -            - const: crypto
> > +            - const: xgp1
> > +            - const: xgp2
> > +            - const: xgp3
> >              - const: fe
> >              - const: gp2
> >              - const: gp1
> >              - const: gp3
> > +            - const: esw
> > +            - const: crypto
> >              - const: ethwarp_wocpu2
> >              - const: ethwarp_wocpu1
> >              - const: ethwarp_wocpu0
> > -            - const: esw
> > -            - const: netsys0
> > -            - const: netsys1
> > -            - const: sgmii_tx250m
> > -            - const: sgmii_rx250m
> > -            - const: sgmii2_tx250m
> > -            - const: sgmii2_rx250m
> > -            - const: top_usxgmii0_sel
> > -            - const: top_usxgmii1_sel
> > -            - const: top_sgm0_sel
> > -            - const: top_sgm1_sel
> > -            - const: top_xfi_phy0_xtal_sel
> > -            - const: top_xfi_phy1_xtal_sel
> >              - const: top_eth_gmii_sel
> >              - const: top_eth_refck_50m_sel
> >              - const: top_eth_sys_200m_sel
> > @@ -375,18 +386,9 @@ allOf:
> >              - const: top_netsys_sync_250m_sel
> >              - const: top_netsys_ppefb_250m_sel
> >              - const: top_netsys_warp_sel
> > -            - const: wocpu1
> > -            - const: wocpu0
> > -            - const: xgp1
> > -            - const: xgp2
> > -            - const: xgp3
> > -
> > -        mediatek,sgmiisys:
> > -          minItems: 2
> > -          maxItems: 2
> >  
> >  patternProperties:
> > -  "^mac@[0-1]$":
> > +  "^mac@[0-2]$":
> >      type: object
> >      unevaluatedProperties: false
> >      allOf:
> > @@ -577,3 +579,114 @@ examples:
> >          };
> >        };
> >      };
> > +
> > +  - |
> > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > +    #include <dt-bindings/interrupt-controller/irq.h>
> > +    #include <dt-bindings/clock/mediatek,mt7988-clk.h>
> > +
> > +    soc {
> > +      #address-cells = <2>;
> > +      #size-cells = <2>;
> > +
> > +      ethernet@15100000 {
> > +        compatible = "mediatek,mt7988-eth";
> > +        reg = <0 0x15100000 0 0x80000>, <0 0x15400000 0 0x380000>;
> > +        interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
> > +                     <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
> > +                     <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
> > +                     <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
> > +
> > +        clocks = <&ethsys CLK_ETHDMA_XGP1_EN>,
> > +                 <&ethsys CLK_ETHDMA_XGP2_EN>,
> > +                 <&ethsys CLK_ETHDMA_XGP3_EN>,
> > +                 <&ethsys CLK_ETHDMA_FE_EN>,
> > +                 <&ethsys CLK_ETHDMA_GP2_EN>,
> > +                 <&ethsys CLK_ETHDMA_GP1_EN>,
> > +                 <&ethsys CLK_ETHDMA_GP3_EN>,
> > +                 <&ethsys CLK_ETHDMA_ESW_EN>,
> > +                 <&ethsys CLK_ETHDMA_CRYPT0_EN>,
> > +                 <&ethwarp CLK_ETHWARP_WOCPU2_EN>,
> > +                 <&ethwarp CLK_ETHWARP_WOCPU1_EN>,
> > +                 <&ethwarp CLK_ETHWARP_WOCPU0_EN>,
> > +                 <&topckgen CLK_TOP_ETH_GMII_SEL>,
> > +                 <&topckgen CLK_TOP_ETH_REFCK_50M_SEL>,
> > +                 <&topckgen CLK_TOP_ETH_SYS_200M_SEL>,
> > +                 <&topckgen CLK_TOP_ETH_SYS_SEL>,
> > +                 <&topckgen CLK_TOP_ETH_XGMII_SEL>,
> > +                 <&topckgen CLK_TOP_ETH_MII_SEL>,
> > +                 <&topckgen CLK_TOP_NETSYS_SEL>,
> > +                 <&topckgen CLK_TOP_NETSYS_500M_SEL>,
> > +                 <&topckgen CLK_TOP_NETSYS_PAO_2X_SEL>,
> > +                 <&topckgen CLK_TOP_NETSYS_SYNC_250M_SEL>,
> > +                 <&topckgen CLK_TOP_NETSYS_PPEFB_250M_SEL>,
> > +                 <&topckgen CLK_TOP_NETSYS_WARP_SEL>;
> > +
> > +        clock-names = "xgp1", "xgp2", "xgp3", "fe", "gp2", "gp1",
> > +                      "gp3", "esw", "crypto",
> > +                      "ethwarp_wocpu2", "ethwarp_wocpu1",
> > +                      "ethwarp_wocpu0", "top_eth_gmii_sel",
> > +                      "top_eth_refck_50m_sel", "top_eth_sys_200m_sel",
> > +                      "top_eth_sys_sel", "top_eth_xgmii_sel",
> > +                      "top_eth_mii_sel", "top_netsys_sel",
> > +                      "top_netsys_500m_sel", "top_netsys_pao_2x_sel",
> > +                      "top_netsys_sync_250m_sel",
> > +                      "top_netsys_ppefb_250m_sel",
> > +                      "top_netsys_warp_sel";
> > +        assigned-clocks = <&topckgen CLK_TOP_NETSYS_2X_SEL>,
> > +                          <&topckgen CLK_TOP_NETSYS_GSW_SEL>,
> > +                          <&topckgen CLK_TOP_USXGMII_SBUS_0_SEL>,
> > +                          <&topckgen CLK_TOP_USXGMII_SBUS_1_SEL>,
> > +                          <&topckgen CLK_TOP_SGM_0_SEL>,
> > +                          <&topckgen CLK_TOP_SGM_1_SEL>;
> > +        assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>,
> > +                                 <&topckgen CLK_TOP_NET1PLL_D4>,
> > +                                 <&topckgen CLK_TOP_NET1PLL_D8_D4>,
> > +                                 <&topckgen CLK_TOP_NET1PLL_D8_D4>,
> > +                                 <&apmixedsys CLK_APMIXED_SGMPLL>,
> > +                                 <&apmixedsys CLK_APMIXED_SGMPLL>;
> > +        mediatek,ethsys = <&ethsys>;
> > +        mediatek,infracfg = <&topmisc>;
> > +        #address-cells = <1>;
> > +        #size-cells = <0>;
> > +
> > +        mac@0 {
> > +          compatible = "mediatek,eth-mac";
> > +          reg = <0>;
> > +          phy-mode = "internal";
> > +          status = "disabled";
> 
> Examples should be enabled.

Ack.

> 
> > +
> > +          fixed-link {
> > +            speed = <10000>;
> > +            full-duplex;
> > +            pause;
> > +          };
> > +        };
> > +
> > +        mac@1 {
> > +          compatible = "mediatek,eth-mac";
> > +          reg = <1>;
> > +          status = "disabled";
> > +          pcs-handle = <&usxgmiisys1>;
> > +        };
> > +
> > +        mac@2 {
> > +          compatible = "mediatek,eth-mac";
> > +          reg = <2>;
> > +          status = "disabled";
> > +          pcs-handle = <&usxgmiisys0>;
> > +        };
> > +
> > +        mdio_bus: mdio-bus {
> 
> mdio {
> 
> > +          #address-cells = <1>;
> > +          #size-cells = <0>;
> > +
> > +          /* internal 2.5G PHY */
> > +          int_2p5g_phy: ethernet-phy@15 {
> > +            reg = <15>;
> > +            compatible = "ethernet-phy-ieee802.3-c45";
> > +            phy-mode = "internal";
> > +          };
> > +        };
> > +      };
> > +    };
> > -- 
> > 2.42.1
> 

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

* Re: [RFC PATCH 7/8] dt-bindings: net: mediatek,net: fix and complete mt7988-eth binding
@ 2023-11-14 17:42       ` Daniel Golle
  0 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-14 17:42 UTC (permalink / raw)
  To: Rob Herring
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun, Vinod Koul,
	Kishon Vijay Abraham I, Felix Fietkau, John Crispin, Sean Wang,
	Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Philipp Zabel, netdev,
	devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-phy

Hi Rob,

thank you for reviewing this patch.

On Tue, Nov 14, 2023 at 08:07:19AM -0600, Rob Herring wrote:
> On Thu, Nov 09, 2023 at 09:52:09PM +0000, Daniel Golle wrote:
> > Remove clocks which were copied from the vendor driver but are now taken
> > care of by dedicated drivers for PCS and PHY in the upstream driver.
> > Also remove mediatek,sgmiisys phandle which isn't required on MT7988
> > because we use pcs-handle on the MAC nodes instead.
> > Last but not least, add an example for MT7988.
> 
> 'Also' is a clue for it should be a separate patch. These changes are 
> all ABI breakage. Please explain why that's okay.

I hope that it's ok because the driver at this point never supported
any SerDes modes and we are still in the process of bringing up
mainline support for this SoC. All of clk, pinctrl, reset, ... driver
and dt-bindings are still pending or being prepared for submission.

> 
> > 
> > Fixes: c94a9aabec36 ("dt-bindings: net: mediatek,net: add mt7988-eth binding")
> > Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> > ---
> >  .../devicetree/bindings/net/mediatek,net.yaml | 171 +++++++++++++++---
> >  1 file changed, 142 insertions(+), 29 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/net/mediatek,net.yaml b/Documentation/devicetree/bindings/net/mediatek,net.yaml
> > index e74502a0afe86..c0f7bb6f3ef8d 100644
> > --- a/Documentation/devicetree/bindings/net/mediatek,net.yaml
> > +++ b/Documentation/devicetree/bindings/net/mediatek,net.yaml
> > @@ -27,9 +27,6 @@ properties:
> >        - mediatek,mt7988-eth
> >        - ralink,rt5350-eth
> >  
> > -  reg:
> > -    maxItems: 1
> > -
> 
> It's not clear what this change is from the commit msg.
> 
> This should stay and be:
> 
> reg:
>   minItems: 1
>   items:
>     - description: what's in the 1st region
>     - description: what's in the 2nd region

Ack.

> 
> >    clocks: true
> >    clock-names: true
> >  
> > @@ -115,6 +112,9 @@ allOf:
> >                - mediatek,mt7623-eth
> >      then:
> >        properties:
> > +        reg:
> > +          maxItems: 1
> > +
> >          interrupts:
> >            maxItems: 3
> >  
> > @@ -149,6 +149,9 @@ allOf:
> >                - mediatek,mt7621-eth
> >      then:
> >        properties:
> > +        reg:
> > +          maxItems: 1
> > +
> >          interrupts:
> >            maxItems: 1
> >  
> > @@ -174,6 +177,9 @@ allOf:
> >              const: mediatek,mt7622-eth
> >      then:
> >        properties:
> > +        reg:
> > +          maxItems: 1
> > +
> >          interrupts:
> >            maxItems: 3
> >  
> > @@ -215,6 +221,9 @@ allOf:
> >              const: mediatek,mt7629-eth
> >      then:
> >        properties:
> > +        reg:
> > +          maxItems: 1
> > +
> >          interrupts:
> >            maxItems: 3
> >  
> > @@ -257,6 +266,9 @@ allOf:
> >              const: mediatek,mt7981-eth
> >      then:
> >        properties:
> > +        reg:
> > +          maxItems: 1
> > +
> >          interrupts:
> >            minItems: 4
> >  
> > @@ -295,6 +307,9 @@ allOf:
> >              const: mediatek,mt7986-eth
> >      then:
> >        properties:
> > +        reg:
> > +          maxItems: 1
> > +
> 
> Looks like lots of duplication. Perhaps there's a cleaner way.

Hm, I don't really see any better way. Suggestions anyone?

> 
> >          interrupts:
> >            minItems: 4
> >  
> > @@ -333,36 +348,32 @@ allOf:
> >              const: mediatek,mt7988-eth
> >      then:
> >        properties:
> > +        reg:
> > +          maxItems: 2
> > +          minItems: 2
> > +
> >          interrupts:
> >            minItems: 4
> > +          maxItems: 4
> >  
> >          clocks:
> > -          minItems: 34
> > -          maxItems: 34
> > +          minItems: 24
> > +          maxItems: 24
> >  
> >          clock-names:
> >            items:
> > -            - const: crypto
> > +            - const: xgp1
> > +            - const: xgp2
> > +            - const: xgp3
> >              - const: fe
> >              - const: gp2
> >              - const: gp1
> >              - const: gp3
> > +            - const: esw
> > +            - const: crypto
> >              - const: ethwarp_wocpu2
> >              - const: ethwarp_wocpu1
> >              - const: ethwarp_wocpu0
> > -            - const: esw
> > -            - const: netsys0
> > -            - const: netsys1
> > -            - const: sgmii_tx250m
> > -            - const: sgmii_rx250m
> > -            - const: sgmii2_tx250m
> > -            - const: sgmii2_rx250m
> > -            - const: top_usxgmii0_sel
> > -            - const: top_usxgmii1_sel
> > -            - const: top_sgm0_sel
> > -            - const: top_sgm1_sel
> > -            - const: top_xfi_phy0_xtal_sel
> > -            - const: top_xfi_phy1_xtal_sel
> >              - const: top_eth_gmii_sel
> >              - const: top_eth_refck_50m_sel
> >              - const: top_eth_sys_200m_sel
> > @@ -375,18 +386,9 @@ allOf:
> >              - const: top_netsys_sync_250m_sel
> >              - const: top_netsys_ppefb_250m_sel
> >              - const: top_netsys_warp_sel
> > -            - const: wocpu1
> > -            - const: wocpu0
> > -            - const: xgp1
> > -            - const: xgp2
> > -            - const: xgp3
> > -
> > -        mediatek,sgmiisys:
> > -          minItems: 2
> > -          maxItems: 2
> >  
> >  patternProperties:
> > -  "^mac@[0-1]$":
> > +  "^mac@[0-2]$":
> >      type: object
> >      unevaluatedProperties: false
> >      allOf:
> > @@ -577,3 +579,114 @@ examples:
> >          };
> >        };
> >      };
> > +
> > +  - |
> > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > +    #include <dt-bindings/interrupt-controller/irq.h>
> > +    #include <dt-bindings/clock/mediatek,mt7988-clk.h>
> > +
> > +    soc {
> > +      #address-cells = <2>;
> > +      #size-cells = <2>;
> > +
> > +      ethernet@15100000 {
> > +        compatible = "mediatek,mt7988-eth";
> > +        reg = <0 0x15100000 0 0x80000>, <0 0x15400000 0 0x380000>;
> > +        interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
> > +                     <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
> > +                     <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
> > +                     <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
> > +
> > +        clocks = <&ethsys CLK_ETHDMA_XGP1_EN>,
> > +                 <&ethsys CLK_ETHDMA_XGP2_EN>,
> > +                 <&ethsys CLK_ETHDMA_XGP3_EN>,
> > +                 <&ethsys CLK_ETHDMA_FE_EN>,
> > +                 <&ethsys CLK_ETHDMA_GP2_EN>,
> > +                 <&ethsys CLK_ETHDMA_GP1_EN>,
> > +                 <&ethsys CLK_ETHDMA_GP3_EN>,
> > +                 <&ethsys CLK_ETHDMA_ESW_EN>,
> > +                 <&ethsys CLK_ETHDMA_CRYPT0_EN>,
> > +                 <&ethwarp CLK_ETHWARP_WOCPU2_EN>,
> > +                 <&ethwarp CLK_ETHWARP_WOCPU1_EN>,
> > +                 <&ethwarp CLK_ETHWARP_WOCPU0_EN>,
> > +                 <&topckgen CLK_TOP_ETH_GMII_SEL>,
> > +                 <&topckgen CLK_TOP_ETH_REFCK_50M_SEL>,
> > +                 <&topckgen CLK_TOP_ETH_SYS_200M_SEL>,
> > +                 <&topckgen CLK_TOP_ETH_SYS_SEL>,
> > +                 <&topckgen CLK_TOP_ETH_XGMII_SEL>,
> > +                 <&topckgen CLK_TOP_ETH_MII_SEL>,
> > +                 <&topckgen CLK_TOP_NETSYS_SEL>,
> > +                 <&topckgen CLK_TOP_NETSYS_500M_SEL>,
> > +                 <&topckgen CLK_TOP_NETSYS_PAO_2X_SEL>,
> > +                 <&topckgen CLK_TOP_NETSYS_SYNC_250M_SEL>,
> > +                 <&topckgen CLK_TOP_NETSYS_PPEFB_250M_SEL>,
> > +                 <&topckgen CLK_TOP_NETSYS_WARP_SEL>;
> > +
> > +        clock-names = "xgp1", "xgp2", "xgp3", "fe", "gp2", "gp1",
> > +                      "gp3", "esw", "crypto",
> > +                      "ethwarp_wocpu2", "ethwarp_wocpu1",
> > +                      "ethwarp_wocpu0", "top_eth_gmii_sel",
> > +                      "top_eth_refck_50m_sel", "top_eth_sys_200m_sel",
> > +                      "top_eth_sys_sel", "top_eth_xgmii_sel",
> > +                      "top_eth_mii_sel", "top_netsys_sel",
> > +                      "top_netsys_500m_sel", "top_netsys_pao_2x_sel",
> > +                      "top_netsys_sync_250m_sel",
> > +                      "top_netsys_ppefb_250m_sel",
> > +                      "top_netsys_warp_sel";
> > +        assigned-clocks = <&topckgen CLK_TOP_NETSYS_2X_SEL>,
> > +                          <&topckgen CLK_TOP_NETSYS_GSW_SEL>,
> > +                          <&topckgen CLK_TOP_USXGMII_SBUS_0_SEL>,
> > +                          <&topckgen CLK_TOP_USXGMII_SBUS_1_SEL>,
> > +                          <&topckgen CLK_TOP_SGM_0_SEL>,
> > +                          <&topckgen CLK_TOP_SGM_1_SEL>;
> > +        assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>,
> > +                                 <&topckgen CLK_TOP_NET1PLL_D4>,
> > +                                 <&topckgen CLK_TOP_NET1PLL_D8_D4>,
> > +                                 <&topckgen CLK_TOP_NET1PLL_D8_D4>,
> > +                                 <&apmixedsys CLK_APMIXED_SGMPLL>,
> > +                                 <&apmixedsys CLK_APMIXED_SGMPLL>;
> > +        mediatek,ethsys = <&ethsys>;
> > +        mediatek,infracfg = <&topmisc>;
> > +        #address-cells = <1>;
> > +        #size-cells = <0>;
> > +
> > +        mac@0 {
> > +          compatible = "mediatek,eth-mac";
> > +          reg = <0>;
> > +          phy-mode = "internal";
> > +          status = "disabled";
> 
> Examples should be enabled.

Ack.

> 
> > +
> > +          fixed-link {
> > +            speed = <10000>;
> > +            full-duplex;
> > +            pause;
> > +          };
> > +        };
> > +
> > +        mac@1 {
> > +          compatible = "mediatek,eth-mac";
> > +          reg = <1>;
> > +          status = "disabled";
> > +          pcs-handle = <&usxgmiisys1>;
> > +        };
> > +
> > +        mac@2 {
> > +          compatible = "mediatek,eth-mac";
> > +          reg = <2>;
> > +          status = "disabled";
> > +          pcs-handle = <&usxgmiisys0>;
> > +        };
> > +
> > +        mdio_bus: mdio-bus {
> 
> mdio {
> 
> > +          #address-cells = <1>;
> > +          #size-cells = <0>;
> > +
> > +          /* internal 2.5G PHY */
> > +          int_2p5g_phy: ethernet-phy@15 {
> > +            reg = <15>;
> > +            compatible = "ethernet-phy-ieee802.3-c45";
> > +            phy-mode = "internal";
> > +          };
> > +        };
> > +      };
> > +    };
> > -- 
> > 2.42.1
> 

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [RFC PATCH 7/8] dt-bindings: net: mediatek,net: fix and complete mt7988-eth binding
@ 2023-11-14 17:42       ` Daniel Golle
  0 siblings, 0 replies; 73+ messages in thread
From: Daniel Golle @ 2023-11-14 17:42 UTC (permalink / raw)
  To: Rob Herring
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun, Vinod Koul,
	Kishon Vijay Abraham I, Felix Fietkau, John Crispin, Sean Wang,
	Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Philipp Zabel, netdev,
	devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-phy

Hi Rob,

thank you for reviewing this patch.

On Tue, Nov 14, 2023 at 08:07:19AM -0600, Rob Herring wrote:
> On Thu, Nov 09, 2023 at 09:52:09PM +0000, Daniel Golle wrote:
> > Remove clocks which were copied from the vendor driver but are now taken
> > care of by dedicated drivers for PCS and PHY in the upstream driver.
> > Also remove mediatek,sgmiisys phandle which isn't required on MT7988
> > because we use pcs-handle on the MAC nodes instead.
> > Last but not least, add an example for MT7988.
> 
> 'Also' is a clue for it should be a separate patch. These changes are 
> all ABI breakage. Please explain why that's okay.

I hope that it's ok because the driver at this point never supported
any SerDes modes and we are still in the process of bringing up
mainline support for this SoC. All of clk, pinctrl, reset, ... driver
and dt-bindings are still pending or being prepared for submission.

> 
> > 
> > Fixes: c94a9aabec36 ("dt-bindings: net: mediatek,net: add mt7988-eth binding")
> > Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> > ---
> >  .../devicetree/bindings/net/mediatek,net.yaml | 171 +++++++++++++++---
> >  1 file changed, 142 insertions(+), 29 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/net/mediatek,net.yaml b/Documentation/devicetree/bindings/net/mediatek,net.yaml
> > index e74502a0afe86..c0f7bb6f3ef8d 100644
> > --- a/Documentation/devicetree/bindings/net/mediatek,net.yaml
> > +++ b/Documentation/devicetree/bindings/net/mediatek,net.yaml
> > @@ -27,9 +27,6 @@ properties:
> >        - mediatek,mt7988-eth
> >        - ralink,rt5350-eth
> >  
> > -  reg:
> > -    maxItems: 1
> > -
> 
> It's not clear what this change is from the commit msg.
> 
> This should stay and be:
> 
> reg:
>   minItems: 1
>   items:
>     - description: what's in the 1st region
>     - description: what's in the 2nd region

Ack.

> 
> >    clocks: true
> >    clock-names: true
> >  
> > @@ -115,6 +112,9 @@ allOf:
> >                - mediatek,mt7623-eth
> >      then:
> >        properties:
> > +        reg:
> > +          maxItems: 1
> > +
> >          interrupts:
> >            maxItems: 3
> >  
> > @@ -149,6 +149,9 @@ allOf:
> >                - mediatek,mt7621-eth
> >      then:
> >        properties:
> > +        reg:
> > +          maxItems: 1
> > +
> >          interrupts:
> >            maxItems: 1
> >  
> > @@ -174,6 +177,9 @@ allOf:
> >              const: mediatek,mt7622-eth
> >      then:
> >        properties:
> > +        reg:
> > +          maxItems: 1
> > +
> >          interrupts:
> >            maxItems: 3
> >  
> > @@ -215,6 +221,9 @@ allOf:
> >              const: mediatek,mt7629-eth
> >      then:
> >        properties:
> > +        reg:
> > +          maxItems: 1
> > +
> >          interrupts:
> >            maxItems: 3
> >  
> > @@ -257,6 +266,9 @@ allOf:
> >              const: mediatek,mt7981-eth
> >      then:
> >        properties:
> > +        reg:
> > +          maxItems: 1
> > +
> >          interrupts:
> >            minItems: 4
> >  
> > @@ -295,6 +307,9 @@ allOf:
> >              const: mediatek,mt7986-eth
> >      then:
> >        properties:
> > +        reg:
> > +          maxItems: 1
> > +
> 
> Looks like lots of duplication. Perhaps there's a cleaner way.

Hm, I don't really see any better way. Suggestions anyone?

> 
> >          interrupts:
> >            minItems: 4
> >  
> > @@ -333,36 +348,32 @@ allOf:
> >              const: mediatek,mt7988-eth
> >      then:
> >        properties:
> > +        reg:
> > +          maxItems: 2
> > +          minItems: 2
> > +
> >          interrupts:
> >            minItems: 4
> > +          maxItems: 4
> >  
> >          clocks:
> > -          minItems: 34
> > -          maxItems: 34
> > +          minItems: 24
> > +          maxItems: 24
> >  
> >          clock-names:
> >            items:
> > -            - const: crypto
> > +            - const: xgp1
> > +            - const: xgp2
> > +            - const: xgp3
> >              - const: fe
> >              - const: gp2
> >              - const: gp1
> >              - const: gp3
> > +            - const: esw
> > +            - const: crypto
> >              - const: ethwarp_wocpu2
> >              - const: ethwarp_wocpu1
> >              - const: ethwarp_wocpu0
> > -            - const: esw
> > -            - const: netsys0
> > -            - const: netsys1
> > -            - const: sgmii_tx250m
> > -            - const: sgmii_rx250m
> > -            - const: sgmii2_tx250m
> > -            - const: sgmii2_rx250m
> > -            - const: top_usxgmii0_sel
> > -            - const: top_usxgmii1_sel
> > -            - const: top_sgm0_sel
> > -            - const: top_sgm1_sel
> > -            - const: top_xfi_phy0_xtal_sel
> > -            - const: top_xfi_phy1_xtal_sel
> >              - const: top_eth_gmii_sel
> >              - const: top_eth_refck_50m_sel
> >              - const: top_eth_sys_200m_sel
> > @@ -375,18 +386,9 @@ allOf:
> >              - const: top_netsys_sync_250m_sel
> >              - const: top_netsys_ppefb_250m_sel
> >              - const: top_netsys_warp_sel
> > -            - const: wocpu1
> > -            - const: wocpu0
> > -            - const: xgp1
> > -            - const: xgp2
> > -            - const: xgp3
> > -
> > -        mediatek,sgmiisys:
> > -          minItems: 2
> > -          maxItems: 2
> >  
> >  patternProperties:
> > -  "^mac@[0-1]$":
> > +  "^mac@[0-2]$":
> >      type: object
> >      unevaluatedProperties: false
> >      allOf:
> > @@ -577,3 +579,114 @@ examples:
> >          };
> >        };
> >      };
> > +
> > +  - |
> > +    #include <dt-bindings/interrupt-controller/arm-gic.h>
> > +    #include <dt-bindings/interrupt-controller/irq.h>
> > +    #include <dt-bindings/clock/mediatek,mt7988-clk.h>
> > +
> > +    soc {
> > +      #address-cells = <2>;
> > +      #size-cells = <2>;
> > +
> > +      ethernet@15100000 {
> > +        compatible = "mediatek,mt7988-eth";
> > +        reg = <0 0x15100000 0 0x80000>, <0 0x15400000 0 0x380000>;
> > +        interrupts = <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>,
> > +                     <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>,
> > +                     <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>,
> > +                     <GIC_SPI 199 IRQ_TYPE_LEVEL_HIGH>;
> > +
> > +        clocks = <&ethsys CLK_ETHDMA_XGP1_EN>,
> > +                 <&ethsys CLK_ETHDMA_XGP2_EN>,
> > +                 <&ethsys CLK_ETHDMA_XGP3_EN>,
> > +                 <&ethsys CLK_ETHDMA_FE_EN>,
> > +                 <&ethsys CLK_ETHDMA_GP2_EN>,
> > +                 <&ethsys CLK_ETHDMA_GP1_EN>,
> > +                 <&ethsys CLK_ETHDMA_GP3_EN>,
> > +                 <&ethsys CLK_ETHDMA_ESW_EN>,
> > +                 <&ethsys CLK_ETHDMA_CRYPT0_EN>,
> > +                 <&ethwarp CLK_ETHWARP_WOCPU2_EN>,
> > +                 <&ethwarp CLK_ETHWARP_WOCPU1_EN>,
> > +                 <&ethwarp CLK_ETHWARP_WOCPU0_EN>,
> > +                 <&topckgen CLK_TOP_ETH_GMII_SEL>,
> > +                 <&topckgen CLK_TOP_ETH_REFCK_50M_SEL>,
> > +                 <&topckgen CLK_TOP_ETH_SYS_200M_SEL>,
> > +                 <&topckgen CLK_TOP_ETH_SYS_SEL>,
> > +                 <&topckgen CLK_TOP_ETH_XGMII_SEL>,
> > +                 <&topckgen CLK_TOP_ETH_MII_SEL>,
> > +                 <&topckgen CLK_TOP_NETSYS_SEL>,
> > +                 <&topckgen CLK_TOP_NETSYS_500M_SEL>,
> > +                 <&topckgen CLK_TOP_NETSYS_PAO_2X_SEL>,
> > +                 <&topckgen CLK_TOP_NETSYS_SYNC_250M_SEL>,
> > +                 <&topckgen CLK_TOP_NETSYS_PPEFB_250M_SEL>,
> > +                 <&topckgen CLK_TOP_NETSYS_WARP_SEL>;
> > +
> > +        clock-names = "xgp1", "xgp2", "xgp3", "fe", "gp2", "gp1",
> > +                      "gp3", "esw", "crypto",
> > +                      "ethwarp_wocpu2", "ethwarp_wocpu1",
> > +                      "ethwarp_wocpu0", "top_eth_gmii_sel",
> > +                      "top_eth_refck_50m_sel", "top_eth_sys_200m_sel",
> > +                      "top_eth_sys_sel", "top_eth_xgmii_sel",
> > +                      "top_eth_mii_sel", "top_netsys_sel",
> > +                      "top_netsys_500m_sel", "top_netsys_pao_2x_sel",
> > +                      "top_netsys_sync_250m_sel",
> > +                      "top_netsys_ppefb_250m_sel",
> > +                      "top_netsys_warp_sel";
> > +        assigned-clocks = <&topckgen CLK_TOP_NETSYS_2X_SEL>,
> > +                          <&topckgen CLK_TOP_NETSYS_GSW_SEL>,
> > +                          <&topckgen CLK_TOP_USXGMII_SBUS_0_SEL>,
> > +                          <&topckgen CLK_TOP_USXGMII_SBUS_1_SEL>,
> > +                          <&topckgen CLK_TOP_SGM_0_SEL>,
> > +                          <&topckgen CLK_TOP_SGM_1_SEL>;
> > +        assigned-clock-parents = <&apmixedsys CLK_APMIXED_NET2PLL>,
> > +                                 <&topckgen CLK_TOP_NET1PLL_D4>,
> > +                                 <&topckgen CLK_TOP_NET1PLL_D8_D4>,
> > +                                 <&topckgen CLK_TOP_NET1PLL_D8_D4>,
> > +                                 <&apmixedsys CLK_APMIXED_SGMPLL>,
> > +                                 <&apmixedsys CLK_APMIXED_SGMPLL>;
> > +        mediatek,ethsys = <&ethsys>;
> > +        mediatek,infracfg = <&topmisc>;
> > +        #address-cells = <1>;
> > +        #size-cells = <0>;
> > +
> > +        mac@0 {
> > +          compatible = "mediatek,eth-mac";
> > +          reg = <0>;
> > +          phy-mode = "internal";
> > +          status = "disabled";
> 
> Examples should be enabled.

Ack.

> 
> > +
> > +          fixed-link {
> > +            speed = <10000>;
> > +            full-duplex;
> > +            pause;
> > +          };
> > +        };
> > +
> > +        mac@1 {
> > +          compatible = "mediatek,eth-mac";
> > +          reg = <1>;
> > +          status = "disabled";
> > +          pcs-handle = <&usxgmiisys1>;
> > +        };
> > +
> > +        mac@2 {
> > +          compatible = "mediatek,eth-mac";
> > +          reg = <2>;
> > +          status = "disabled";
> > +          pcs-handle = <&usxgmiisys0>;
> > +        };
> > +
> > +        mdio_bus: mdio-bus {
> 
> mdio {
> 
> > +          #address-cells = <1>;
> > +          #size-cells = <0>;
> > +
> > +          /* internal 2.5G PHY */
> > +          int_2p5g_phy: ethernet-phy@15 {
> > +            reg = <15>;
> > +            compatible = "ethernet-phy-ieee802.3-c45";
> > +            phy-mode = "internal";
> > +          };
> > +        };
> > +      };
> > +    };
> > -- 
> > 2.42.1
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [RFC PATCH 2/8] phy: add driver for MediaTek pextp 10GE SerDes PHY
  2023-11-09 21:51   ` Daniel Golle
  (?)
@ 2023-11-27 13:16     ` Vinod Koul
  -1 siblings, 0 replies; 73+ messages in thread
From: Vinod Koul @ 2023-11-27 13:16 UTC (permalink / raw)
  To: Daniel Golle
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Kishon Vijay Abraham I, Felix Fietkau, John Crispin, Sean Wang,
	Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Philipp Zabel, netdev,
	devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-phy

On 09-11-23, 21:51, Daniel Golle wrote:
> Add driver for MediaTek's pextp 10 Gigabit/s Ethernet SerDes PHY which
> can be found in the MT7988 SoC.
> 
> The PHY can operates only in PHY_MODE_ETHERNET, the submode is one of
> PHY_INTERFACE_MODE_* corresponding to the supported modes:
> 
>  * USXGMII
>  * 10GBase-R
>  * 5GBase-R
>  * 2500Base-X
>  * 1000Base-X
>  * Cisco SGMII (MAC side)
> 
> In order to work-around a performance issue present on the first of
> two PEXTP present in MT7988 special tuning is applied which can be
> selected by adding the mediatek,usxgmii-performance-errata property to
> the device tree node.
> 
> There is no documentation what-so-ever for the pextp registers and
> this driver is based on a GPL licensed implementation found in
> MediaTek's SDK.
> 
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
>  MAINTAINERS                          |   1 +
>  drivers/phy/mediatek/Kconfig         |  11 +
>  drivers/phy/mediatek/Makefile        |   1 +
>  drivers/phy/mediatek/phy-mtk-pextp.c | 355 +++++++++++++++++++++++++++
>  4 files changed, 368 insertions(+)
>  create mode 100644 drivers/phy/mediatek/phy-mtk-pextp.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 7b151710e8c58..6499acd8f3874 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -13527,6 +13527,7 @@ L:	netdev@vger.kernel.org
>  S:	Maintained
>  F:	drivers/net/phy/mediatek-ge-soc.c
>  F:	drivers/net/phy/mediatek-ge.c
> +F:	drivers/phy/mediatek/phy-mediatek-pextp.c
>  
>  MEDIATEK I2C CONTROLLER DRIVER
>  M:	Qii Wang <qii.wang@mediatek.com>
> diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig
> index 3125ecb5d119f..a7749a6d96541 100644
> --- a/drivers/phy/mediatek/Kconfig
> +++ b/drivers/phy/mediatek/Kconfig
> @@ -13,6 +13,17 @@ config PHY_MTK_PCIE
>  	  callback for PCIe GEN3 port, it supports software efuse
>  	  initialization.
>  
> +config PHY_MTK_PEXTP
> +	tristate "MediaTek PEXTP Driver"
> +	depends on ARCH_MEDIATEK || COMPILE_TEST
> +	depends on OF && OF_ADDRESS
> +	depends on HAS_IOMEM
> +	select GENERIC_PHY
> +	help
> +	  Say 'Y' here to add support for MediaTek pextp PHY driver.
> +	  The driver provides access to the Ethernet SerDes PHY supporting
> +	  various 1GE, 2.5GE, 5GE and 10GE modes.
> +
>  config PHY_MTK_TPHY
>  	tristate "MediaTek T-PHY Driver"
>  	depends on ARCH_MEDIATEK || COMPILE_TEST
> diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
> index c9a50395533eb..ca60c7b9b02ac 100644
> --- a/drivers/phy/mediatek/Makefile
> +++ b/drivers/phy/mediatek/Makefile
> @@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_MTK_PCIE)		+= phy-mtk-pcie.o
>  obj-$(CONFIG_PHY_MTK_TPHY)		+= phy-mtk-tphy.o
>  obj-$(CONFIG_PHY_MTK_UFS)		+= phy-mtk-ufs.o
>  obj-$(CONFIG_PHY_MTK_XSPHY)		+= phy-mtk-xsphy.o
> +obj-$(CONFIG_PHY_MTK_PEXTP)		+= phy-mtk-pextp.o
>  
>  phy-mtk-hdmi-drv-y			:= phy-mtk-hdmi.o
>  phy-mtk-hdmi-drv-y			+= phy-mtk-hdmi-mt2701.o
> diff --git a/drivers/phy/mediatek/phy-mtk-pextp.c b/drivers/phy/mediatek/phy-mtk-pextp.c
> new file mode 100644
> index 0000000000000..272bff4f37a96
> --- /dev/null
> +++ b/drivers/phy/mediatek/phy-mtk-pextp.c
> @@ -0,0 +1,355 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/* MediaTek 10GE SerDes PHY driver
> + *
> + * Copyright (c) 2023 Daniel Golle <daniel@makrotopia.org>
> + * based on mtk_usxgmii.c found in MediaTek's SDK released under GPL-2.0
> + * Copyright (c) 2022 MediaTek Inc.
> + * Author: Henry Yen <henry.yen@mediatek.com>
> + */
> +
> +#include <linux/module.h>
> +#include <linux/device.h>
> +#include <linux/netdevice.h>
> +#include <linux/platform_device.h>
> +#include <linux/of.h>
> +#include <linux/io.h>
> +#include <linux/clk.h>
> +#include <linux/reset.h>
> +#include <linux/phy.h>
> +#include <linux/phy/phy.h>
> +
> +struct mtk_pextp_phy {
> +	void __iomem		*base;
> +	struct device		*dev;
> +	struct reset_control	*reset;
> +	struct clk		*clk;
> +	bool			da_war;
> +};
> +
> +static inline bool mtk_interface_mode_is_xgmii(phy_interface_t interface)
> +{
> +	switch (interface) {
> +	case PHY_INTERFACE_MODE_INTERNAL:
> +	case PHY_INTERFACE_MODE_USXGMII:
> +	case PHY_INTERFACE_MODE_10GBASER:
> +	case PHY_INTERFACE_MODE_5GBASER:
> +		return true;
> +	default:
> +		return false;
> +	}
> +}
> +
> +static void mtk_pextp_setup(struct mtk_pextp_phy *pextp, phy_interface_t interface)
> +{
> +	bool is_10g = (interface == PHY_INTERFACE_MODE_10GBASER ||
> +		       interface == PHY_INTERFACE_MODE_USXGMII);
> +	bool is_2p5g = (interface == PHY_INTERFACE_MODE_2500BASEX);
> +	bool is_5g = (interface == PHY_INTERFACE_MODE_5GBASER);
> +
> +	dev_dbg(pextp->dev, "setting up for mode %s\n", phy_modes(interface));
> +
> +	/* Setup operation mode */
> +	if (is_10g)
> +		iowrite32(0x00C9071C, pextp->base + 0x9024);

what are these magic numbers? also lower case hex values pls

> +	else
> +		iowrite32(0x00D9071C, pextp->base + 0x9024);
> +
> +	if (is_5g)
> +		iowrite32(0xAAA5A5AA, pextp->base + 0x2020);
> +	else
> +		iowrite32(0xAA8585AA, pextp->base + 0x2020);
> +
> +	if (is_2p5g || is_5g || is_10g) {
> +		iowrite32(0x0C020707, pextp->base + 0x2030);
> +		iowrite32(0x0E050F0F, pextp->base + 0x2034);
> +		iowrite32(0x00140032, pextp->base + 0x2040);
> +	} else {
> +		iowrite32(0x0C020207, pextp->base + 0x2030);
> +		iowrite32(0x0E05050F, pextp->base + 0x2034);
> +		iowrite32(0x00200032, pextp->base + 0x2040);
> +	}
> +
> +	if (is_2p5g || is_10g)
> +		iowrite32(0x00C014AA, pextp->base + 0x50F0);
> +	else if (is_5g)
> +		iowrite32(0x00C018AA, pextp->base + 0x50F0);
> +	else
> +		iowrite32(0x00C014BA, pextp->base + 0x50F0);
> +
> +	if (is_5g) {
> +		iowrite32(0x3777812B, pextp->base + 0x50E0);
> +		iowrite32(0x005C9CFF, pextp->base + 0x506C);
> +		iowrite32(0x9DFAFAFA, pextp->base + 0x5070);
> +		iowrite32(0x273F3F3F, pextp->base + 0x5074);
> +		iowrite32(0xA8883868, pextp->base + 0x5078);
> +		iowrite32(0x14661466, pextp->base + 0x507C);
> +	} else {
> +		iowrite32(0x3777C12B, pextp->base + 0x50E0);
> +		iowrite32(0x005F9CFF, pextp->base + 0x506C);
> +		iowrite32(0x9D9DFAFA, pextp->base + 0x5070);
> +		iowrite32(0x27273F3F, pextp->base + 0x5074);
> +		iowrite32(0xA7883C68, pextp->base + 0x5078);
> +		iowrite32(0x11661166, pextp->base + 0x507C);
> +	}
> +
> +	if (is_2p5g || is_10g) {
> +		iowrite32(0x0E000AAF, pextp->base + 0x5080);
> +		iowrite32(0x08080D0D, pextp->base + 0x5084);
> +		iowrite32(0x02030909, pextp->base + 0x5088);
> +	} else if (is_5g) {
> +		iowrite32(0x0E001ABF, pextp->base + 0x5080);
> +		iowrite32(0x080B0D0D, pextp->base + 0x5084);
> +		iowrite32(0x02050909, pextp->base + 0x5088);
> +	} else {
> +		iowrite32(0x0E000EAF, pextp->base + 0x5080);
> +		iowrite32(0x08080E0D, pextp->base + 0x5084);
> +		iowrite32(0x02030B09, pextp->base + 0x5088);
> +	}
> +
> +	if (is_5g) {
> +		iowrite32(0x0C000000, pextp->base + 0x50E4);
> +		iowrite32(0x04000000, pextp->base + 0x50E8);
> +	} else {
> +		iowrite32(0x0C0C0000, pextp->base + 0x50E4);
> +		iowrite32(0x04040000, pextp->base + 0x50E8);
> +	}
> +
> +	if (is_2p5g || mtk_interface_mode_is_xgmii(interface))
> +		iowrite32(0x0F0F0C06, pextp->base + 0x50EC);
> +	else
> +		iowrite32(0x0F0F0606, pextp->base + 0x50EC);
> +
> +	if (is_5g) {
> +		iowrite32(0x50808C8C, pextp->base + 0x50A8);
> +		iowrite32(0x18000000, pextp->base + 0x6004);
> +	} else {
> +		iowrite32(0x506E8C8C, pextp->base + 0x50A8);
> +		iowrite32(0x18190000, pextp->base + 0x6004);
> +	}
> +
> +	if (is_10g)
> +		iowrite32(0x01423342, pextp->base + 0x00F8);
> +	else if (is_5g)
> +		iowrite32(0x00A132A1, pextp->base + 0x00F8);
> +	else if (is_2p5g)
> +		iowrite32(0x009C329C, pextp->base + 0x00F8);
> +	else
> +		iowrite32(0x00FA32FA, pextp->base + 0x00F8);
> +
> +	/* Force SGDT_OUT off and select PCS */
> +	if (mtk_interface_mode_is_xgmii(interface))
> +		iowrite32(0x80201F20, pextp->base + 0x00F4);
> +	else
> +		iowrite32(0x80201F21, pextp->base + 0x00F4);
> +
> +	/* Force GLB_CKDET_OUT */
> +	iowrite32(0x00050C00, pextp->base + 0x0030);
> +
> +	/* Force AEQ on */
> +	iowrite32(0x02002800, pextp->base + 0x0070);
> +	ndelay(1020);
> +
> +	/* Setup DA default value */
> +	iowrite32(0x00000020, pextp->base + 0x30B0);
> +	iowrite32(0x00008A01, pextp->base + 0x3028);
> +	iowrite32(0x0000A884, pextp->base + 0x302C);
> +	iowrite32(0x00083002, pextp->base + 0x3024);
> +	if (mtk_interface_mode_is_xgmii(interface)) {
> +		iowrite32(0x00022220, pextp->base + 0x3010);
> +		iowrite32(0x0F020A01, pextp->base + 0x5064);
> +		iowrite32(0x06100600, pextp->base + 0x50B4);
> +		if (interface == PHY_INTERFACE_MODE_USXGMII)
> +			iowrite32(0x40704000, pextp->base + 0x3048);
> +		else
> +			iowrite32(0x47684100, pextp->base + 0x3048);
> +	} else {
> +		iowrite32(0x00011110, pextp->base + 0x3010);
> +		iowrite32(0x40704000, pextp->base + 0x3048);
> +	}
> +
> +	if (!mtk_interface_mode_is_xgmii(interface) && !is_2p5g)
> +		iowrite32(0x0000C000, pextp->base + 0x3064);
> +
> +	if (interface == PHY_INTERFACE_MODE_USXGMII) {
> +		iowrite32(0xA8000000, pextp->base + 0x3050);
> +		iowrite32(0x000000AA, pextp->base + 0x3054);
> +	} else if (mtk_interface_mode_is_xgmii(interface)) {
> +		iowrite32(0x00000000, pextp->base + 0x3050);
> +		iowrite32(0x00000000, pextp->base + 0x3054);
> +	} else {
> +		iowrite32(0xA8000000, pextp->base + 0x3050);
> +		iowrite32(0x000000AA, pextp->base + 0x3054);
> +	}
> +
> +	if (mtk_interface_mode_is_xgmii(interface))
> +		iowrite32(0x00000F00, pextp->base + 0x306C);
> +	else if (is_2p5g)
> +		iowrite32(0x22000F00, pextp->base + 0x306C);
> +	else
> +		iowrite32(0x20200F00, pextp->base + 0x306C);
> +
> +	if (interface == PHY_INTERFACE_MODE_10GBASER && pextp->da_war)
> +		iowrite32(0x0007B400, pextp->base + 0xA008);
> +
> +	if (mtk_interface_mode_is_xgmii(interface))
> +		iowrite32(0x00040000, pextp->base + 0xA060);
> +	else
> +		iowrite32(0x00050000, pextp->base + 0xA060);
> +
> +	if (is_10g)
> +		iowrite32(0x00000001, pextp->base + 0x90D0);
> +	else if (is_5g)
> +		iowrite32(0x00000003, pextp->base + 0x90D0);
> +	else if (is_2p5g)
> +		iowrite32(0x00000005, pextp->base + 0x90D0);
> +	else
> +		iowrite32(0x00000007, pextp->base + 0x90D0);
> +
> +	/* Release reset */
> +	iowrite32(0x0200E800, pextp->base + 0x0070);
> +	usleep_range(150, 500);
> +
> +	/* Switch to P0 */
> +	iowrite32(0x0200C111, pextp->base + 0x0070);
> +	ndelay(1020);
> +	iowrite32(0x0200C101, pextp->base + 0x0070);
> +	usleep_range(15, 50);
> +
> +	if (mtk_interface_mode_is_xgmii(interface)) {
> +		/* Switch to Gen3 */
> +		iowrite32(0x0202C111, pextp->base + 0x0070);
> +	} else {
> +		/* Switch to Gen2 */
> +		iowrite32(0x0201C111, pextp->base + 0x0070);
> +	}
> +	ndelay(1020);
> +	if (mtk_interface_mode_is_xgmii(interface))
> +		iowrite32(0x0202C101, pextp->base + 0x0070);
> +	else
> +		iowrite32(0x0201C101, pextp->base + 0x0070);
> +	usleep_range(100, 500);
> +	iowrite32(0x00000030, pextp->base + 0x30B0);
> +	if (mtk_interface_mode_is_xgmii(interface))
> +		iowrite32(0x80201F00, pextp->base + 0x00F4);
> +	else
> +		iowrite32(0x80201F01, pextp->base + 0x00F4);
> +
> +	iowrite32(0x30000000, pextp->base + 0x3040);
> +	usleep_range(400, 1000);
> +}
> +
> +static int mtk_pextp_set_mode(struct phy *phy, enum phy_mode mode, int submode)
> +{
> +	struct mtk_pextp_phy *pextp = phy_get_drvdata(phy);
> +
> +	if (mode != PHY_MODE_ETHERNET)
> +		return -EINVAL;
> +
> +	switch (submode) {
> +	case PHY_INTERFACE_MODE_1000BASEX:
> +	case PHY_INTERFACE_MODE_2500BASEX:
> +	case PHY_INTERFACE_MODE_SGMII:
> +	case PHY_INTERFACE_MODE_5GBASER:
> +	case PHY_INTERFACE_MODE_10GBASER:
> +	case PHY_INTERFACE_MODE_USXGMII:
> +		mtk_pextp_setup(pextp, submode);
> +		return 0;
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +static int mtk_pextp_reset(struct phy *phy)
> +{
> +	struct mtk_pextp_phy *pextp = phy_get_drvdata(phy);
> +
> +	reset_control_assert(pextp->reset);
> +	usleep_range(100, 500);
> +	reset_control_deassert(pextp->reset);
> +	mdelay(10);
> +
> +	return 0;
> +}
> +
> +static int mtk_pextp_power_on(struct phy *phy)
> +{
> +	struct mtk_pextp_phy *pextp = phy_get_drvdata(phy);
> +
> +	return clk_prepare_enable(pextp->clk);
> +}
> +
> +static int mtk_pextp_power_off(struct phy *phy)
> +{
> +	struct mtk_pextp_phy *pextp = phy_get_drvdata(phy);
> +
> +	clk_disable_unprepare(pextp->clk);
> +
> +	return 0;
> +}
> +
> +static const struct phy_ops mtk_pextp_ops = {
> +	.power_on	= mtk_pextp_power_on,
> +	.power_off	= mtk_pextp_power_off,
> +	.set_mode	= mtk_pextp_set_mode,
> +	.reset		= mtk_pextp_reset,
> +	.owner		= THIS_MODULE,
> +};
> +
> +static int mtk_pextp_probe(struct platform_device *pdev)
> +{
> +	struct device_node *np = pdev->dev.of_node;
> +	struct phy_provider *phy_provider;
> +	struct mtk_pextp_phy *pextp;
> +	struct phy *phy;
> +
> +	if (!np)
> +		return -ENODEV;
> +
> +	pextp = devm_kzalloc(&pdev->dev, sizeof(*pextp), GFP_KERNEL);
> +	if (!pextp)
> +		return -ENOMEM;
> +
> +	pextp->base = devm_of_iomap(&pdev->dev, np, 0, NULL);
> +	if (!pextp->base)
> +		return -EIO;
> +
> +	pextp->dev = &pdev->dev;
> +	pextp->clk = devm_clk_get(&pdev->dev, NULL);
> +	if (IS_ERR(pextp->clk))
> +		return PTR_ERR(pextp->clk);
> +
> +	pextp->reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
> +	if (IS_ERR(pextp->reset))
> +		return PTR_ERR(pextp->reset);
> +
> +	pextp->da_war = of_property_read_bool(np, "mediatek,usxgmii-performance-errata");
> +
> +	phy = devm_phy_create(&pdev->dev, NULL, &mtk_pextp_ops);
> +	if (IS_ERR(phy))
> +		return PTR_ERR(phy);
> +
> +	phy_set_drvdata(phy, pextp);
> +
> +	phy_provider = devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate);
> +
> +	return PTR_ERR_OR_ZERO(phy_provider);
> +}
> +
> +static const struct of_device_id mtk_pextp_match[] = {
> +	{ .compatible = "mediatek,mt7988-xfi-pextp", },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, mtk_pextp_match);
> +
> +static struct platform_driver mtk_pextp_driver = {
> +	.probe = mtk_pextp_probe,
> +	.driver = {
> +		.name = "mtk-pextp",
> +		.of_match_table = mtk_pextp_match,
> +	},
> +};
> +module_platform_driver(mtk_pextp_driver);
> +
> +MODULE_DESCRIPTION("MediaTek pextp SerDes PHY driver");
> +MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
> +MODULE_LICENSE("GPL");
> -- 
> 2.42.1

-- 
~Vinod

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

* Re: [RFC PATCH 2/8] phy: add driver for MediaTek pextp 10GE SerDes PHY
@ 2023-11-27 13:16     ` Vinod Koul
  0 siblings, 0 replies; 73+ messages in thread
From: Vinod Koul @ 2023-11-27 13:16 UTC (permalink / raw)
  To: Daniel Golle
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Kishon Vijay Abraham I, Felix Fietkau, John Crispin, Sean Wang,
	Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Philipp Zabel, netdev,
	devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-phy

On 09-11-23, 21:51, Daniel Golle wrote:
> Add driver for MediaTek's pextp 10 Gigabit/s Ethernet SerDes PHY which
> can be found in the MT7988 SoC.
> 
> The PHY can operates only in PHY_MODE_ETHERNET, the submode is one of
> PHY_INTERFACE_MODE_* corresponding to the supported modes:
> 
>  * USXGMII
>  * 10GBase-R
>  * 5GBase-R
>  * 2500Base-X
>  * 1000Base-X
>  * Cisco SGMII (MAC side)
> 
> In order to work-around a performance issue present on the first of
> two PEXTP present in MT7988 special tuning is applied which can be
> selected by adding the mediatek,usxgmii-performance-errata property to
> the device tree node.
> 
> There is no documentation what-so-ever for the pextp registers and
> this driver is based on a GPL licensed implementation found in
> MediaTek's SDK.
> 
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
>  MAINTAINERS                          |   1 +
>  drivers/phy/mediatek/Kconfig         |  11 +
>  drivers/phy/mediatek/Makefile        |   1 +
>  drivers/phy/mediatek/phy-mtk-pextp.c | 355 +++++++++++++++++++++++++++
>  4 files changed, 368 insertions(+)
>  create mode 100644 drivers/phy/mediatek/phy-mtk-pextp.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 7b151710e8c58..6499acd8f3874 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -13527,6 +13527,7 @@ L:	netdev@vger.kernel.org
>  S:	Maintained
>  F:	drivers/net/phy/mediatek-ge-soc.c
>  F:	drivers/net/phy/mediatek-ge.c
> +F:	drivers/phy/mediatek/phy-mediatek-pextp.c
>  
>  MEDIATEK I2C CONTROLLER DRIVER
>  M:	Qii Wang <qii.wang@mediatek.com>
> diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig
> index 3125ecb5d119f..a7749a6d96541 100644
> --- a/drivers/phy/mediatek/Kconfig
> +++ b/drivers/phy/mediatek/Kconfig
> @@ -13,6 +13,17 @@ config PHY_MTK_PCIE
>  	  callback for PCIe GEN3 port, it supports software efuse
>  	  initialization.
>  
> +config PHY_MTK_PEXTP
> +	tristate "MediaTek PEXTP Driver"
> +	depends on ARCH_MEDIATEK || COMPILE_TEST
> +	depends on OF && OF_ADDRESS
> +	depends on HAS_IOMEM
> +	select GENERIC_PHY
> +	help
> +	  Say 'Y' here to add support for MediaTek pextp PHY driver.
> +	  The driver provides access to the Ethernet SerDes PHY supporting
> +	  various 1GE, 2.5GE, 5GE and 10GE modes.
> +
>  config PHY_MTK_TPHY
>  	tristate "MediaTek T-PHY Driver"
>  	depends on ARCH_MEDIATEK || COMPILE_TEST
> diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
> index c9a50395533eb..ca60c7b9b02ac 100644
> --- a/drivers/phy/mediatek/Makefile
> +++ b/drivers/phy/mediatek/Makefile
> @@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_MTK_PCIE)		+= phy-mtk-pcie.o
>  obj-$(CONFIG_PHY_MTK_TPHY)		+= phy-mtk-tphy.o
>  obj-$(CONFIG_PHY_MTK_UFS)		+= phy-mtk-ufs.o
>  obj-$(CONFIG_PHY_MTK_XSPHY)		+= phy-mtk-xsphy.o
> +obj-$(CONFIG_PHY_MTK_PEXTP)		+= phy-mtk-pextp.o
>  
>  phy-mtk-hdmi-drv-y			:= phy-mtk-hdmi.o
>  phy-mtk-hdmi-drv-y			+= phy-mtk-hdmi-mt2701.o
> diff --git a/drivers/phy/mediatek/phy-mtk-pextp.c b/drivers/phy/mediatek/phy-mtk-pextp.c
> new file mode 100644
> index 0000000000000..272bff4f37a96
> --- /dev/null
> +++ b/drivers/phy/mediatek/phy-mtk-pextp.c
> @@ -0,0 +1,355 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/* MediaTek 10GE SerDes PHY driver
> + *
> + * Copyright (c) 2023 Daniel Golle <daniel@makrotopia.org>
> + * based on mtk_usxgmii.c found in MediaTek's SDK released under GPL-2.0
> + * Copyright (c) 2022 MediaTek Inc.
> + * Author: Henry Yen <henry.yen@mediatek.com>
> + */
> +
> +#include <linux/module.h>
> +#include <linux/device.h>
> +#include <linux/netdevice.h>
> +#include <linux/platform_device.h>
> +#include <linux/of.h>
> +#include <linux/io.h>
> +#include <linux/clk.h>
> +#include <linux/reset.h>
> +#include <linux/phy.h>
> +#include <linux/phy/phy.h>
> +
> +struct mtk_pextp_phy {
> +	void __iomem		*base;
> +	struct device		*dev;
> +	struct reset_control	*reset;
> +	struct clk		*clk;
> +	bool			da_war;
> +};
> +
> +static inline bool mtk_interface_mode_is_xgmii(phy_interface_t interface)
> +{
> +	switch (interface) {
> +	case PHY_INTERFACE_MODE_INTERNAL:
> +	case PHY_INTERFACE_MODE_USXGMII:
> +	case PHY_INTERFACE_MODE_10GBASER:
> +	case PHY_INTERFACE_MODE_5GBASER:
> +		return true;
> +	default:
> +		return false;
> +	}
> +}
> +
> +static void mtk_pextp_setup(struct mtk_pextp_phy *pextp, phy_interface_t interface)
> +{
> +	bool is_10g = (interface == PHY_INTERFACE_MODE_10GBASER ||
> +		       interface == PHY_INTERFACE_MODE_USXGMII);
> +	bool is_2p5g = (interface == PHY_INTERFACE_MODE_2500BASEX);
> +	bool is_5g = (interface == PHY_INTERFACE_MODE_5GBASER);
> +
> +	dev_dbg(pextp->dev, "setting up for mode %s\n", phy_modes(interface));
> +
> +	/* Setup operation mode */
> +	if (is_10g)
> +		iowrite32(0x00C9071C, pextp->base + 0x9024);

what are these magic numbers? also lower case hex values pls

> +	else
> +		iowrite32(0x00D9071C, pextp->base + 0x9024);
> +
> +	if (is_5g)
> +		iowrite32(0xAAA5A5AA, pextp->base + 0x2020);
> +	else
> +		iowrite32(0xAA8585AA, pextp->base + 0x2020);
> +
> +	if (is_2p5g || is_5g || is_10g) {
> +		iowrite32(0x0C020707, pextp->base + 0x2030);
> +		iowrite32(0x0E050F0F, pextp->base + 0x2034);
> +		iowrite32(0x00140032, pextp->base + 0x2040);
> +	} else {
> +		iowrite32(0x0C020207, pextp->base + 0x2030);
> +		iowrite32(0x0E05050F, pextp->base + 0x2034);
> +		iowrite32(0x00200032, pextp->base + 0x2040);
> +	}
> +
> +	if (is_2p5g || is_10g)
> +		iowrite32(0x00C014AA, pextp->base + 0x50F0);
> +	else if (is_5g)
> +		iowrite32(0x00C018AA, pextp->base + 0x50F0);
> +	else
> +		iowrite32(0x00C014BA, pextp->base + 0x50F0);
> +
> +	if (is_5g) {
> +		iowrite32(0x3777812B, pextp->base + 0x50E0);
> +		iowrite32(0x005C9CFF, pextp->base + 0x506C);
> +		iowrite32(0x9DFAFAFA, pextp->base + 0x5070);
> +		iowrite32(0x273F3F3F, pextp->base + 0x5074);
> +		iowrite32(0xA8883868, pextp->base + 0x5078);
> +		iowrite32(0x14661466, pextp->base + 0x507C);
> +	} else {
> +		iowrite32(0x3777C12B, pextp->base + 0x50E0);
> +		iowrite32(0x005F9CFF, pextp->base + 0x506C);
> +		iowrite32(0x9D9DFAFA, pextp->base + 0x5070);
> +		iowrite32(0x27273F3F, pextp->base + 0x5074);
> +		iowrite32(0xA7883C68, pextp->base + 0x5078);
> +		iowrite32(0x11661166, pextp->base + 0x507C);
> +	}
> +
> +	if (is_2p5g || is_10g) {
> +		iowrite32(0x0E000AAF, pextp->base + 0x5080);
> +		iowrite32(0x08080D0D, pextp->base + 0x5084);
> +		iowrite32(0x02030909, pextp->base + 0x5088);
> +	} else if (is_5g) {
> +		iowrite32(0x0E001ABF, pextp->base + 0x5080);
> +		iowrite32(0x080B0D0D, pextp->base + 0x5084);
> +		iowrite32(0x02050909, pextp->base + 0x5088);
> +	} else {
> +		iowrite32(0x0E000EAF, pextp->base + 0x5080);
> +		iowrite32(0x08080E0D, pextp->base + 0x5084);
> +		iowrite32(0x02030B09, pextp->base + 0x5088);
> +	}
> +
> +	if (is_5g) {
> +		iowrite32(0x0C000000, pextp->base + 0x50E4);
> +		iowrite32(0x04000000, pextp->base + 0x50E8);
> +	} else {
> +		iowrite32(0x0C0C0000, pextp->base + 0x50E4);
> +		iowrite32(0x04040000, pextp->base + 0x50E8);
> +	}
> +
> +	if (is_2p5g || mtk_interface_mode_is_xgmii(interface))
> +		iowrite32(0x0F0F0C06, pextp->base + 0x50EC);
> +	else
> +		iowrite32(0x0F0F0606, pextp->base + 0x50EC);
> +
> +	if (is_5g) {
> +		iowrite32(0x50808C8C, pextp->base + 0x50A8);
> +		iowrite32(0x18000000, pextp->base + 0x6004);
> +	} else {
> +		iowrite32(0x506E8C8C, pextp->base + 0x50A8);
> +		iowrite32(0x18190000, pextp->base + 0x6004);
> +	}
> +
> +	if (is_10g)
> +		iowrite32(0x01423342, pextp->base + 0x00F8);
> +	else if (is_5g)
> +		iowrite32(0x00A132A1, pextp->base + 0x00F8);
> +	else if (is_2p5g)
> +		iowrite32(0x009C329C, pextp->base + 0x00F8);
> +	else
> +		iowrite32(0x00FA32FA, pextp->base + 0x00F8);
> +
> +	/* Force SGDT_OUT off and select PCS */
> +	if (mtk_interface_mode_is_xgmii(interface))
> +		iowrite32(0x80201F20, pextp->base + 0x00F4);
> +	else
> +		iowrite32(0x80201F21, pextp->base + 0x00F4);
> +
> +	/* Force GLB_CKDET_OUT */
> +	iowrite32(0x00050C00, pextp->base + 0x0030);
> +
> +	/* Force AEQ on */
> +	iowrite32(0x02002800, pextp->base + 0x0070);
> +	ndelay(1020);
> +
> +	/* Setup DA default value */
> +	iowrite32(0x00000020, pextp->base + 0x30B0);
> +	iowrite32(0x00008A01, pextp->base + 0x3028);
> +	iowrite32(0x0000A884, pextp->base + 0x302C);
> +	iowrite32(0x00083002, pextp->base + 0x3024);
> +	if (mtk_interface_mode_is_xgmii(interface)) {
> +		iowrite32(0x00022220, pextp->base + 0x3010);
> +		iowrite32(0x0F020A01, pextp->base + 0x5064);
> +		iowrite32(0x06100600, pextp->base + 0x50B4);
> +		if (interface == PHY_INTERFACE_MODE_USXGMII)
> +			iowrite32(0x40704000, pextp->base + 0x3048);
> +		else
> +			iowrite32(0x47684100, pextp->base + 0x3048);
> +	} else {
> +		iowrite32(0x00011110, pextp->base + 0x3010);
> +		iowrite32(0x40704000, pextp->base + 0x3048);
> +	}
> +
> +	if (!mtk_interface_mode_is_xgmii(interface) && !is_2p5g)
> +		iowrite32(0x0000C000, pextp->base + 0x3064);
> +
> +	if (interface == PHY_INTERFACE_MODE_USXGMII) {
> +		iowrite32(0xA8000000, pextp->base + 0x3050);
> +		iowrite32(0x000000AA, pextp->base + 0x3054);
> +	} else if (mtk_interface_mode_is_xgmii(interface)) {
> +		iowrite32(0x00000000, pextp->base + 0x3050);
> +		iowrite32(0x00000000, pextp->base + 0x3054);
> +	} else {
> +		iowrite32(0xA8000000, pextp->base + 0x3050);
> +		iowrite32(0x000000AA, pextp->base + 0x3054);
> +	}
> +
> +	if (mtk_interface_mode_is_xgmii(interface))
> +		iowrite32(0x00000F00, pextp->base + 0x306C);
> +	else if (is_2p5g)
> +		iowrite32(0x22000F00, pextp->base + 0x306C);
> +	else
> +		iowrite32(0x20200F00, pextp->base + 0x306C);
> +
> +	if (interface == PHY_INTERFACE_MODE_10GBASER && pextp->da_war)
> +		iowrite32(0x0007B400, pextp->base + 0xA008);
> +
> +	if (mtk_interface_mode_is_xgmii(interface))
> +		iowrite32(0x00040000, pextp->base + 0xA060);
> +	else
> +		iowrite32(0x00050000, pextp->base + 0xA060);
> +
> +	if (is_10g)
> +		iowrite32(0x00000001, pextp->base + 0x90D0);
> +	else if (is_5g)
> +		iowrite32(0x00000003, pextp->base + 0x90D0);
> +	else if (is_2p5g)
> +		iowrite32(0x00000005, pextp->base + 0x90D0);
> +	else
> +		iowrite32(0x00000007, pextp->base + 0x90D0);
> +
> +	/* Release reset */
> +	iowrite32(0x0200E800, pextp->base + 0x0070);
> +	usleep_range(150, 500);
> +
> +	/* Switch to P0 */
> +	iowrite32(0x0200C111, pextp->base + 0x0070);
> +	ndelay(1020);
> +	iowrite32(0x0200C101, pextp->base + 0x0070);
> +	usleep_range(15, 50);
> +
> +	if (mtk_interface_mode_is_xgmii(interface)) {
> +		/* Switch to Gen3 */
> +		iowrite32(0x0202C111, pextp->base + 0x0070);
> +	} else {
> +		/* Switch to Gen2 */
> +		iowrite32(0x0201C111, pextp->base + 0x0070);
> +	}
> +	ndelay(1020);
> +	if (mtk_interface_mode_is_xgmii(interface))
> +		iowrite32(0x0202C101, pextp->base + 0x0070);
> +	else
> +		iowrite32(0x0201C101, pextp->base + 0x0070);
> +	usleep_range(100, 500);
> +	iowrite32(0x00000030, pextp->base + 0x30B0);
> +	if (mtk_interface_mode_is_xgmii(interface))
> +		iowrite32(0x80201F00, pextp->base + 0x00F4);
> +	else
> +		iowrite32(0x80201F01, pextp->base + 0x00F4);
> +
> +	iowrite32(0x30000000, pextp->base + 0x3040);
> +	usleep_range(400, 1000);
> +}
> +
> +static int mtk_pextp_set_mode(struct phy *phy, enum phy_mode mode, int submode)
> +{
> +	struct mtk_pextp_phy *pextp = phy_get_drvdata(phy);
> +
> +	if (mode != PHY_MODE_ETHERNET)
> +		return -EINVAL;
> +
> +	switch (submode) {
> +	case PHY_INTERFACE_MODE_1000BASEX:
> +	case PHY_INTERFACE_MODE_2500BASEX:
> +	case PHY_INTERFACE_MODE_SGMII:
> +	case PHY_INTERFACE_MODE_5GBASER:
> +	case PHY_INTERFACE_MODE_10GBASER:
> +	case PHY_INTERFACE_MODE_USXGMII:
> +		mtk_pextp_setup(pextp, submode);
> +		return 0;
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +static int mtk_pextp_reset(struct phy *phy)
> +{
> +	struct mtk_pextp_phy *pextp = phy_get_drvdata(phy);
> +
> +	reset_control_assert(pextp->reset);
> +	usleep_range(100, 500);
> +	reset_control_deassert(pextp->reset);
> +	mdelay(10);
> +
> +	return 0;
> +}
> +
> +static int mtk_pextp_power_on(struct phy *phy)
> +{
> +	struct mtk_pextp_phy *pextp = phy_get_drvdata(phy);
> +
> +	return clk_prepare_enable(pextp->clk);
> +}
> +
> +static int mtk_pextp_power_off(struct phy *phy)
> +{
> +	struct mtk_pextp_phy *pextp = phy_get_drvdata(phy);
> +
> +	clk_disable_unprepare(pextp->clk);
> +
> +	return 0;
> +}
> +
> +static const struct phy_ops mtk_pextp_ops = {
> +	.power_on	= mtk_pextp_power_on,
> +	.power_off	= mtk_pextp_power_off,
> +	.set_mode	= mtk_pextp_set_mode,
> +	.reset		= mtk_pextp_reset,
> +	.owner		= THIS_MODULE,
> +};
> +
> +static int mtk_pextp_probe(struct platform_device *pdev)
> +{
> +	struct device_node *np = pdev->dev.of_node;
> +	struct phy_provider *phy_provider;
> +	struct mtk_pextp_phy *pextp;
> +	struct phy *phy;
> +
> +	if (!np)
> +		return -ENODEV;
> +
> +	pextp = devm_kzalloc(&pdev->dev, sizeof(*pextp), GFP_KERNEL);
> +	if (!pextp)
> +		return -ENOMEM;
> +
> +	pextp->base = devm_of_iomap(&pdev->dev, np, 0, NULL);
> +	if (!pextp->base)
> +		return -EIO;
> +
> +	pextp->dev = &pdev->dev;
> +	pextp->clk = devm_clk_get(&pdev->dev, NULL);
> +	if (IS_ERR(pextp->clk))
> +		return PTR_ERR(pextp->clk);
> +
> +	pextp->reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
> +	if (IS_ERR(pextp->reset))
> +		return PTR_ERR(pextp->reset);
> +
> +	pextp->da_war = of_property_read_bool(np, "mediatek,usxgmii-performance-errata");
> +
> +	phy = devm_phy_create(&pdev->dev, NULL, &mtk_pextp_ops);
> +	if (IS_ERR(phy))
> +		return PTR_ERR(phy);
> +
> +	phy_set_drvdata(phy, pextp);
> +
> +	phy_provider = devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate);
> +
> +	return PTR_ERR_OR_ZERO(phy_provider);
> +}
> +
> +static const struct of_device_id mtk_pextp_match[] = {
> +	{ .compatible = "mediatek,mt7988-xfi-pextp", },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, mtk_pextp_match);
> +
> +static struct platform_driver mtk_pextp_driver = {
> +	.probe = mtk_pextp_probe,
> +	.driver = {
> +		.name = "mtk-pextp",
> +		.of_match_table = mtk_pextp_match,
> +	},
> +};
> +module_platform_driver(mtk_pextp_driver);
> +
> +MODULE_DESCRIPTION("MediaTek pextp SerDes PHY driver");
> +MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
> +MODULE_LICENSE("GPL");
> -- 
> 2.42.1

-- 
~Vinod

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [RFC PATCH 2/8] phy: add driver for MediaTek pextp 10GE SerDes PHY
@ 2023-11-27 13:16     ` Vinod Koul
  0 siblings, 0 replies; 73+ messages in thread
From: Vinod Koul @ 2023-11-27 13:16 UTC (permalink / raw)
  To: Daniel Golle
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Kishon Vijay Abraham I, Felix Fietkau, John Crispin, Sean Wang,
	Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Russell King, Alexander Couzens, Philipp Zabel, netdev,
	devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-phy

On 09-11-23, 21:51, Daniel Golle wrote:
> Add driver for MediaTek's pextp 10 Gigabit/s Ethernet SerDes PHY which
> can be found in the MT7988 SoC.
> 
> The PHY can operates only in PHY_MODE_ETHERNET, the submode is one of
> PHY_INTERFACE_MODE_* corresponding to the supported modes:
> 
>  * USXGMII
>  * 10GBase-R
>  * 5GBase-R
>  * 2500Base-X
>  * 1000Base-X
>  * Cisco SGMII (MAC side)
> 
> In order to work-around a performance issue present on the first of
> two PEXTP present in MT7988 special tuning is applied which can be
> selected by adding the mediatek,usxgmii-performance-errata property to
> the device tree node.
> 
> There is no documentation what-so-ever for the pextp registers and
> this driver is based on a GPL licensed implementation found in
> MediaTek's SDK.
> 
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
>  MAINTAINERS                          |   1 +
>  drivers/phy/mediatek/Kconfig         |  11 +
>  drivers/phy/mediatek/Makefile        |   1 +
>  drivers/phy/mediatek/phy-mtk-pextp.c | 355 +++++++++++++++++++++++++++
>  4 files changed, 368 insertions(+)
>  create mode 100644 drivers/phy/mediatek/phy-mtk-pextp.c
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 7b151710e8c58..6499acd8f3874 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -13527,6 +13527,7 @@ L:	netdev@vger.kernel.org
>  S:	Maintained
>  F:	drivers/net/phy/mediatek-ge-soc.c
>  F:	drivers/net/phy/mediatek-ge.c
> +F:	drivers/phy/mediatek/phy-mediatek-pextp.c
>  
>  MEDIATEK I2C CONTROLLER DRIVER
>  M:	Qii Wang <qii.wang@mediatek.com>
> diff --git a/drivers/phy/mediatek/Kconfig b/drivers/phy/mediatek/Kconfig
> index 3125ecb5d119f..a7749a6d96541 100644
> --- a/drivers/phy/mediatek/Kconfig
> +++ b/drivers/phy/mediatek/Kconfig
> @@ -13,6 +13,17 @@ config PHY_MTK_PCIE
>  	  callback for PCIe GEN3 port, it supports software efuse
>  	  initialization.
>  
> +config PHY_MTK_PEXTP
> +	tristate "MediaTek PEXTP Driver"
> +	depends on ARCH_MEDIATEK || COMPILE_TEST
> +	depends on OF && OF_ADDRESS
> +	depends on HAS_IOMEM
> +	select GENERIC_PHY
> +	help
> +	  Say 'Y' here to add support for MediaTek pextp PHY driver.
> +	  The driver provides access to the Ethernet SerDes PHY supporting
> +	  various 1GE, 2.5GE, 5GE and 10GE modes.
> +
>  config PHY_MTK_TPHY
>  	tristate "MediaTek T-PHY Driver"
>  	depends on ARCH_MEDIATEK || COMPILE_TEST
> diff --git a/drivers/phy/mediatek/Makefile b/drivers/phy/mediatek/Makefile
> index c9a50395533eb..ca60c7b9b02ac 100644
> --- a/drivers/phy/mediatek/Makefile
> +++ b/drivers/phy/mediatek/Makefile
> @@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_MTK_PCIE)		+= phy-mtk-pcie.o
>  obj-$(CONFIG_PHY_MTK_TPHY)		+= phy-mtk-tphy.o
>  obj-$(CONFIG_PHY_MTK_UFS)		+= phy-mtk-ufs.o
>  obj-$(CONFIG_PHY_MTK_XSPHY)		+= phy-mtk-xsphy.o
> +obj-$(CONFIG_PHY_MTK_PEXTP)		+= phy-mtk-pextp.o
>  
>  phy-mtk-hdmi-drv-y			:= phy-mtk-hdmi.o
>  phy-mtk-hdmi-drv-y			+= phy-mtk-hdmi-mt2701.o
> diff --git a/drivers/phy/mediatek/phy-mtk-pextp.c b/drivers/phy/mediatek/phy-mtk-pextp.c
> new file mode 100644
> index 0000000000000..272bff4f37a96
> --- /dev/null
> +++ b/drivers/phy/mediatek/phy-mtk-pextp.c
> @@ -0,0 +1,355 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/* MediaTek 10GE SerDes PHY driver
> + *
> + * Copyright (c) 2023 Daniel Golle <daniel@makrotopia.org>
> + * based on mtk_usxgmii.c found in MediaTek's SDK released under GPL-2.0
> + * Copyright (c) 2022 MediaTek Inc.
> + * Author: Henry Yen <henry.yen@mediatek.com>
> + */
> +
> +#include <linux/module.h>
> +#include <linux/device.h>
> +#include <linux/netdevice.h>
> +#include <linux/platform_device.h>
> +#include <linux/of.h>
> +#include <linux/io.h>
> +#include <linux/clk.h>
> +#include <linux/reset.h>
> +#include <linux/phy.h>
> +#include <linux/phy/phy.h>
> +
> +struct mtk_pextp_phy {
> +	void __iomem		*base;
> +	struct device		*dev;
> +	struct reset_control	*reset;
> +	struct clk		*clk;
> +	bool			da_war;
> +};
> +
> +static inline bool mtk_interface_mode_is_xgmii(phy_interface_t interface)
> +{
> +	switch (interface) {
> +	case PHY_INTERFACE_MODE_INTERNAL:
> +	case PHY_INTERFACE_MODE_USXGMII:
> +	case PHY_INTERFACE_MODE_10GBASER:
> +	case PHY_INTERFACE_MODE_5GBASER:
> +		return true;
> +	default:
> +		return false;
> +	}
> +}
> +
> +static void mtk_pextp_setup(struct mtk_pextp_phy *pextp, phy_interface_t interface)
> +{
> +	bool is_10g = (interface == PHY_INTERFACE_MODE_10GBASER ||
> +		       interface == PHY_INTERFACE_MODE_USXGMII);
> +	bool is_2p5g = (interface == PHY_INTERFACE_MODE_2500BASEX);
> +	bool is_5g = (interface == PHY_INTERFACE_MODE_5GBASER);
> +
> +	dev_dbg(pextp->dev, "setting up for mode %s\n", phy_modes(interface));
> +
> +	/* Setup operation mode */
> +	if (is_10g)
> +		iowrite32(0x00C9071C, pextp->base + 0x9024);

what are these magic numbers? also lower case hex values pls

> +	else
> +		iowrite32(0x00D9071C, pextp->base + 0x9024);
> +
> +	if (is_5g)
> +		iowrite32(0xAAA5A5AA, pextp->base + 0x2020);
> +	else
> +		iowrite32(0xAA8585AA, pextp->base + 0x2020);
> +
> +	if (is_2p5g || is_5g || is_10g) {
> +		iowrite32(0x0C020707, pextp->base + 0x2030);
> +		iowrite32(0x0E050F0F, pextp->base + 0x2034);
> +		iowrite32(0x00140032, pextp->base + 0x2040);
> +	} else {
> +		iowrite32(0x0C020207, pextp->base + 0x2030);
> +		iowrite32(0x0E05050F, pextp->base + 0x2034);
> +		iowrite32(0x00200032, pextp->base + 0x2040);
> +	}
> +
> +	if (is_2p5g || is_10g)
> +		iowrite32(0x00C014AA, pextp->base + 0x50F0);
> +	else if (is_5g)
> +		iowrite32(0x00C018AA, pextp->base + 0x50F0);
> +	else
> +		iowrite32(0x00C014BA, pextp->base + 0x50F0);
> +
> +	if (is_5g) {
> +		iowrite32(0x3777812B, pextp->base + 0x50E0);
> +		iowrite32(0x005C9CFF, pextp->base + 0x506C);
> +		iowrite32(0x9DFAFAFA, pextp->base + 0x5070);
> +		iowrite32(0x273F3F3F, pextp->base + 0x5074);
> +		iowrite32(0xA8883868, pextp->base + 0x5078);
> +		iowrite32(0x14661466, pextp->base + 0x507C);
> +	} else {
> +		iowrite32(0x3777C12B, pextp->base + 0x50E0);
> +		iowrite32(0x005F9CFF, pextp->base + 0x506C);
> +		iowrite32(0x9D9DFAFA, pextp->base + 0x5070);
> +		iowrite32(0x27273F3F, pextp->base + 0x5074);
> +		iowrite32(0xA7883C68, pextp->base + 0x5078);
> +		iowrite32(0x11661166, pextp->base + 0x507C);
> +	}
> +
> +	if (is_2p5g || is_10g) {
> +		iowrite32(0x0E000AAF, pextp->base + 0x5080);
> +		iowrite32(0x08080D0D, pextp->base + 0x5084);
> +		iowrite32(0x02030909, pextp->base + 0x5088);
> +	} else if (is_5g) {
> +		iowrite32(0x0E001ABF, pextp->base + 0x5080);
> +		iowrite32(0x080B0D0D, pextp->base + 0x5084);
> +		iowrite32(0x02050909, pextp->base + 0x5088);
> +	} else {
> +		iowrite32(0x0E000EAF, pextp->base + 0x5080);
> +		iowrite32(0x08080E0D, pextp->base + 0x5084);
> +		iowrite32(0x02030B09, pextp->base + 0x5088);
> +	}
> +
> +	if (is_5g) {
> +		iowrite32(0x0C000000, pextp->base + 0x50E4);
> +		iowrite32(0x04000000, pextp->base + 0x50E8);
> +	} else {
> +		iowrite32(0x0C0C0000, pextp->base + 0x50E4);
> +		iowrite32(0x04040000, pextp->base + 0x50E8);
> +	}
> +
> +	if (is_2p5g || mtk_interface_mode_is_xgmii(interface))
> +		iowrite32(0x0F0F0C06, pextp->base + 0x50EC);
> +	else
> +		iowrite32(0x0F0F0606, pextp->base + 0x50EC);
> +
> +	if (is_5g) {
> +		iowrite32(0x50808C8C, pextp->base + 0x50A8);
> +		iowrite32(0x18000000, pextp->base + 0x6004);
> +	} else {
> +		iowrite32(0x506E8C8C, pextp->base + 0x50A8);
> +		iowrite32(0x18190000, pextp->base + 0x6004);
> +	}
> +
> +	if (is_10g)
> +		iowrite32(0x01423342, pextp->base + 0x00F8);
> +	else if (is_5g)
> +		iowrite32(0x00A132A1, pextp->base + 0x00F8);
> +	else if (is_2p5g)
> +		iowrite32(0x009C329C, pextp->base + 0x00F8);
> +	else
> +		iowrite32(0x00FA32FA, pextp->base + 0x00F8);
> +
> +	/* Force SGDT_OUT off and select PCS */
> +	if (mtk_interface_mode_is_xgmii(interface))
> +		iowrite32(0x80201F20, pextp->base + 0x00F4);
> +	else
> +		iowrite32(0x80201F21, pextp->base + 0x00F4);
> +
> +	/* Force GLB_CKDET_OUT */
> +	iowrite32(0x00050C00, pextp->base + 0x0030);
> +
> +	/* Force AEQ on */
> +	iowrite32(0x02002800, pextp->base + 0x0070);
> +	ndelay(1020);
> +
> +	/* Setup DA default value */
> +	iowrite32(0x00000020, pextp->base + 0x30B0);
> +	iowrite32(0x00008A01, pextp->base + 0x3028);
> +	iowrite32(0x0000A884, pextp->base + 0x302C);
> +	iowrite32(0x00083002, pextp->base + 0x3024);
> +	if (mtk_interface_mode_is_xgmii(interface)) {
> +		iowrite32(0x00022220, pextp->base + 0x3010);
> +		iowrite32(0x0F020A01, pextp->base + 0x5064);
> +		iowrite32(0x06100600, pextp->base + 0x50B4);
> +		if (interface == PHY_INTERFACE_MODE_USXGMII)
> +			iowrite32(0x40704000, pextp->base + 0x3048);
> +		else
> +			iowrite32(0x47684100, pextp->base + 0x3048);
> +	} else {
> +		iowrite32(0x00011110, pextp->base + 0x3010);
> +		iowrite32(0x40704000, pextp->base + 0x3048);
> +	}
> +
> +	if (!mtk_interface_mode_is_xgmii(interface) && !is_2p5g)
> +		iowrite32(0x0000C000, pextp->base + 0x3064);
> +
> +	if (interface == PHY_INTERFACE_MODE_USXGMII) {
> +		iowrite32(0xA8000000, pextp->base + 0x3050);
> +		iowrite32(0x000000AA, pextp->base + 0x3054);
> +	} else if (mtk_interface_mode_is_xgmii(interface)) {
> +		iowrite32(0x00000000, pextp->base + 0x3050);
> +		iowrite32(0x00000000, pextp->base + 0x3054);
> +	} else {
> +		iowrite32(0xA8000000, pextp->base + 0x3050);
> +		iowrite32(0x000000AA, pextp->base + 0x3054);
> +	}
> +
> +	if (mtk_interface_mode_is_xgmii(interface))
> +		iowrite32(0x00000F00, pextp->base + 0x306C);
> +	else if (is_2p5g)
> +		iowrite32(0x22000F00, pextp->base + 0x306C);
> +	else
> +		iowrite32(0x20200F00, pextp->base + 0x306C);
> +
> +	if (interface == PHY_INTERFACE_MODE_10GBASER && pextp->da_war)
> +		iowrite32(0x0007B400, pextp->base + 0xA008);
> +
> +	if (mtk_interface_mode_is_xgmii(interface))
> +		iowrite32(0x00040000, pextp->base + 0xA060);
> +	else
> +		iowrite32(0x00050000, pextp->base + 0xA060);
> +
> +	if (is_10g)
> +		iowrite32(0x00000001, pextp->base + 0x90D0);
> +	else if (is_5g)
> +		iowrite32(0x00000003, pextp->base + 0x90D0);
> +	else if (is_2p5g)
> +		iowrite32(0x00000005, pextp->base + 0x90D0);
> +	else
> +		iowrite32(0x00000007, pextp->base + 0x90D0);
> +
> +	/* Release reset */
> +	iowrite32(0x0200E800, pextp->base + 0x0070);
> +	usleep_range(150, 500);
> +
> +	/* Switch to P0 */
> +	iowrite32(0x0200C111, pextp->base + 0x0070);
> +	ndelay(1020);
> +	iowrite32(0x0200C101, pextp->base + 0x0070);
> +	usleep_range(15, 50);
> +
> +	if (mtk_interface_mode_is_xgmii(interface)) {
> +		/* Switch to Gen3 */
> +		iowrite32(0x0202C111, pextp->base + 0x0070);
> +	} else {
> +		/* Switch to Gen2 */
> +		iowrite32(0x0201C111, pextp->base + 0x0070);
> +	}
> +	ndelay(1020);
> +	if (mtk_interface_mode_is_xgmii(interface))
> +		iowrite32(0x0202C101, pextp->base + 0x0070);
> +	else
> +		iowrite32(0x0201C101, pextp->base + 0x0070);
> +	usleep_range(100, 500);
> +	iowrite32(0x00000030, pextp->base + 0x30B0);
> +	if (mtk_interface_mode_is_xgmii(interface))
> +		iowrite32(0x80201F00, pextp->base + 0x00F4);
> +	else
> +		iowrite32(0x80201F01, pextp->base + 0x00F4);
> +
> +	iowrite32(0x30000000, pextp->base + 0x3040);
> +	usleep_range(400, 1000);
> +}
> +
> +static int mtk_pextp_set_mode(struct phy *phy, enum phy_mode mode, int submode)
> +{
> +	struct mtk_pextp_phy *pextp = phy_get_drvdata(phy);
> +
> +	if (mode != PHY_MODE_ETHERNET)
> +		return -EINVAL;
> +
> +	switch (submode) {
> +	case PHY_INTERFACE_MODE_1000BASEX:
> +	case PHY_INTERFACE_MODE_2500BASEX:
> +	case PHY_INTERFACE_MODE_SGMII:
> +	case PHY_INTERFACE_MODE_5GBASER:
> +	case PHY_INTERFACE_MODE_10GBASER:
> +	case PHY_INTERFACE_MODE_USXGMII:
> +		mtk_pextp_setup(pextp, submode);
> +		return 0;
> +	default:
> +		return -EINVAL;
> +	}
> +}
> +
> +static int mtk_pextp_reset(struct phy *phy)
> +{
> +	struct mtk_pextp_phy *pextp = phy_get_drvdata(phy);
> +
> +	reset_control_assert(pextp->reset);
> +	usleep_range(100, 500);
> +	reset_control_deassert(pextp->reset);
> +	mdelay(10);
> +
> +	return 0;
> +}
> +
> +static int mtk_pextp_power_on(struct phy *phy)
> +{
> +	struct mtk_pextp_phy *pextp = phy_get_drvdata(phy);
> +
> +	return clk_prepare_enable(pextp->clk);
> +}
> +
> +static int mtk_pextp_power_off(struct phy *phy)
> +{
> +	struct mtk_pextp_phy *pextp = phy_get_drvdata(phy);
> +
> +	clk_disable_unprepare(pextp->clk);
> +
> +	return 0;
> +}
> +
> +static const struct phy_ops mtk_pextp_ops = {
> +	.power_on	= mtk_pextp_power_on,
> +	.power_off	= mtk_pextp_power_off,
> +	.set_mode	= mtk_pextp_set_mode,
> +	.reset		= mtk_pextp_reset,
> +	.owner		= THIS_MODULE,
> +};
> +
> +static int mtk_pextp_probe(struct platform_device *pdev)
> +{
> +	struct device_node *np = pdev->dev.of_node;
> +	struct phy_provider *phy_provider;
> +	struct mtk_pextp_phy *pextp;
> +	struct phy *phy;
> +
> +	if (!np)
> +		return -ENODEV;
> +
> +	pextp = devm_kzalloc(&pdev->dev, sizeof(*pextp), GFP_KERNEL);
> +	if (!pextp)
> +		return -ENOMEM;
> +
> +	pextp->base = devm_of_iomap(&pdev->dev, np, 0, NULL);
> +	if (!pextp->base)
> +		return -EIO;
> +
> +	pextp->dev = &pdev->dev;
> +	pextp->clk = devm_clk_get(&pdev->dev, NULL);
> +	if (IS_ERR(pextp->clk))
> +		return PTR_ERR(pextp->clk);
> +
> +	pextp->reset = devm_reset_control_get_exclusive(&pdev->dev, NULL);
> +	if (IS_ERR(pextp->reset))
> +		return PTR_ERR(pextp->reset);
> +
> +	pextp->da_war = of_property_read_bool(np, "mediatek,usxgmii-performance-errata");
> +
> +	phy = devm_phy_create(&pdev->dev, NULL, &mtk_pextp_ops);
> +	if (IS_ERR(phy))
> +		return PTR_ERR(phy);
> +
> +	phy_set_drvdata(phy, pextp);
> +
> +	phy_provider = devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate);
> +
> +	return PTR_ERR_OR_ZERO(phy_provider);
> +}
> +
> +static const struct of_device_id mtk_pextp_match[] = {
> +	{ .compatible = "mediatek,mt7988-xfi-pextp", },
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, mtk_pextp_match);
> +
> +static struct platform_driver mtk_pextp_driver = {
> +	.probe = mtk_pextp_probe,
> +	.driver = {
> +		.name = "mtk-pextp",
> +		.of_match_table = mtk_pextp_match,
> +	},
> +};
> +module_platform_driver(mtk_pextp_driver);
> +
> +MODULE_DESCRIPTION("MediaTek pextp SerDes PHY driver");
> +MODULE_AUTHOR("Daniel Golle <daniel@makrotopia.org>");
> +MODULE_LICENSE("GPL");
> -- 
> 2.42.1

-- 
~Vinod

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [RFC PATCH 6/8] net: pcs: add driver for MediaTek USXGMII PCS
  2023-11-09 21:51   ` Daniel Golle
  (?)
@ 2023-11-27 13:25     ` Philipp Zabel
  -1 siblings, 0 replies; 73+ messages in thread
From: Philipp Zabel @ 2023-11-27 13:25 UTC (permalink / raw)
  To: Daniel Golle, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Chunfeng Yun, Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau,
	John Crispin, Sean Wang, Mark Lee, Lorenzo Bianconi,
	Matthias Brugger, AngeloGioacchino Del Regno, Andrew Lunn,
	Heiner Kallweit, Russell King, Alexander Couzens, netdev,
	devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-phy

On Do, 2023-11-09 at 21:51 +0000, Daniel Golle wrote:
> Add driver for USXGMII PCS found in the MediaTek MT7988 SoC and supporting
> USXGMII, 10GBase-R and 5GBase-R interface modes. In order to support
> Cisco SGMII, 1000Base-X and 2500Base-X via the also present LynxI PCS
> create a wrapped PCS taking care of the components shared between the
> new USXGMII PCS and the legacy LynxI PCS.
> 
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
[...]
> diff --git a/drivers/net/pcs/pcs-mtk-usxgmii.c b/drivers/net/pcs/pcs-mtk-usxgmii.c
> new file mode 100644
> index 0000000000000..b3ca66c9df2a9
> --- /dev/null
> +++ b/drivers/net/pcs/pcs-mtk-usxgmii.c
> @@ -0,0 +1,688 @@
[...]
> +static int mtk_sgmii_wrapper_init(struct mtk_usxgmii_pcs *mpcs)
> +{
> +	struct device_node *r = mpcs->dev->of_node, *np;
[...]
> +	rstc = of_reset_control_get_shared(r, "sgmii");
> +

Superfluous whitespace.

> +	if (IS_ERR(rstc))
> +		return PTR_ERR(rstc);

Here you correctly check rstc for errors ...

[...]
> +	wp->reset = rstc;
[...]
> +
> +	if (IS_ERR(wp->reset))
> +		return PTR_ERR(wp->reset);

And here you check it again. The second check can be dropped.


regards
Philipp

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

* Re: [RFC PATCH 6/8] net: pcs: add driver for MediaTek USXGMII PCS
@ 2023-11-27 13:25     ` Philipp Zabel
  0 siblings, 0 replies; 73+ messages in thread
From: Philipp Zabel @ 2023-11-27 13:25 UTC (permalink / raw)
  To: Daniel Golle, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Chunfeng Yun, Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau,
	John Crispin, Sean Wang, Mark Lee, Lorenzo Bianconi,
	Matthias Brugger, AngeloGioacchino Del Regno, Andrew Lunn,
	Heiner Kallweit, Russell King, Alexander Couzens, netdev,
	devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-phy

On Do, 2023-11-09 at 21:51 +0000, Daniel Golle wrote:
> Add driver for USXGMII PCS found in the MediaTek MT7988 SoC and supporting
> USXGMII, 10GBase-R and 5GBase-R interface modes. In order to support
> Cisco SGMII, 1000Base-X and 2500Base-X via the also present LynxI PCS
> create a wrapped PCS taking care of the components shared between the
> new USXGMII PCS and the legacy LynxI PCS.
> 
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
[...]
> diff --git a/drivers/net/pcs/pcs-mtk-usxgmii.c b/drivers/net/pcs/pcs-mtk-usxgmii.c
> new file mode 100644
> index 0000000000000..b3ca66c9df2a9
> --- /dev/null
> +++ b/drivers/net/pcs/pcs-mtk-usxgmii.c
> @@ -0,0 +1,688 @@
[...]
> +static int mtk_sgmii_wrapper_init(struct mtk_usxgmii_pcs *mpcs)
> +{
> +	struct device_node *r = mpcs->dev->of_node, *np;
[...]
> +	rstc = of_reset_control_get_shared(r, "sgmii");
> +

Superfluous whitespace.

> +	if (IS_ERR(rstc))
> +		return PTR_ERR(rstc);

Here you correctly check rstc for errors ...

[...]
> +	wp->reset = rstc;
[...]
> +
> +	if (IS_ERR(wp->reset))
> +		return PTR_ERR(wp->reset);

And here you check it again. The second check can be dropped.


regards
Philipp

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [RFC PATCH 6/8] net: pcs: add driver for MediaTek USXGMII PCS
@ 2023-11-27 13:25     ` Philipp Zabel
  0 siblings, 0 replies; 73+ messages in thread
From: Philipp Zabel @ 2023-11-27 13:25 UTC (permalink / raw)
  To: Daniel Golle, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Chunfeng Yun, Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau,
	John Crispin, Sean Wang, Mark Lee, Lorenzo Bianconi,
	Matthias Brugger, AngeloGioacchino Del Regno, Andrew Lunn,
	Heiner Kallweit, Russell King, Alexander Couzens, netdev,
	devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-phy

On Do, 2023-11-09 at 21:51 +0000, Daniel Golle wrote:
> Add driver for USXGMII PCS found in the MediaTek MT7988 SoC and supporting
> USXGMII, 10GBase-R and 5GBase-R interface modes. In order to support
> Cisco SGMII, 1000Base-X and 2500Base-X via the also present LynxI PCS
> create a wrapped PCS taking care of the components shared between the
> new USXGMII PCS and the legacy LynxI PCS.
> 
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
[...]
> diff --git a/drivers/net/pcs/pcs-mtk-usxgmii.c b/drivers/net/pcs/pcs-mtk-usxgmii.c
> new file mode 100644
> index 0000000000000..b3ca66c9df2a9
> --- /dev/null
> +++ b/drivers/net/pcs/pcs-mtk-usxgmii.c
> @@ -0,0 +1,688 @@
[...]
> +static int mtk_sgmii_wrapper_init(struct mtk_usxgmii_pcs *mpcs)
> +{
> +	struct device_node *r = mpcs->dev->of_node, *np;
[...]
> +	rstc = of_reset_control_get_shared(r, "sgmii");
> +

Superfluous whitespace.

> +	if (IS_ERR(rstc))
> +		return PTR_ERR(rstc);

Here you correctly check rstc for errors ...

[...]
> +	wp->reset = rstc;
[...]
> +
> +	if (IS_ERR(wp->reset))
> +		return PTR_ERR(wp->reset);

And here you check it again. The second check can be dropped.


regards
Philipp

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [RFC PATCH 8/8] net: ethernet: mtk_eth_soc: add paths and SerDes modes for MT7988
  2023-11-09 21:52   ` Daniel Golle
  (?)
@ 2023-11-27 13:27     ` Philipp Zabel
  -1 siblings, 0 replies; 73+ messages in thread
From: Philipp Zabel @ 2023-11-27 13:27 UTC (permalink / raw)
  To: Daniel Golle, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Chunfeng Yun, Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau,
	John Crispin, Sean Wang, Mark Lee, Lorenzo Bianconi,
	Matthias Brugger, AngeloGioacchino Del Regno, Andrew Lunn,
	Heiner Kallweit, Russell King, Alexander Couzens, netdev,
	devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-phy

On Do, 2023-11-09 at 21:52 +0000, Daniel Golle wrote:
> MT7988 comes with a built-in 2.5G PHY as well as SerDes lanes to
> connect external PHYs or transceivers in USXGMII, 10GBase-R, 5GBase-R,
> 2500Base-X, 1000Base-X and Cisco SGMII interface modes.
> 
> Implement support for configuring for the new paths to SerDes interfaces
> and the internal 2.5G PHY.
> 
> Add USXGMII PCS driver for 10GBase-R, 5GBase-R and USXGMII mode, and
> setup the new PHYA on MT7988 to access the also still existing old
> LynxI PCS for 1000Base-X, 2500Base-X and Cisco SGMII PCS interface
> modes.
> 
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
[...]
> diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
> index 9ae3b8a71d0e6..ba5998ef7965e 100644
> --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
> +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
> @@ -15,6 +15,7 @@
>  #include <linux/u64_stats_sync.h>
>  #include <linux/refcount.h>
>  #include <linux/phylink.h>
> +#include <linux/reset.h>

I can't see what this is required for?

regards
Philipp

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

* Re: [RFC PATCH 8/8] net: ethernet: mtk_eth_soc: add paths and SerDes modes for MT7988
@ 2023-11-27 13:27     ` Philipp Zabel
  0 siblings, 0 replies; 73+ messages in thread
From: Philipp Zabel @ 2023-11-27 13:27 UTC (permalink / raw)
  To: Daniel Golle, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Chunfeng Yun, Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau,
	John Crispin, Sean Wang, Mark Lee, Lorenzo Bianconi,
	Matthias Brugger, AngeloGioacchino Del Regno, Andrew Lunn,
	Heiner Kallweit, Russell King, Alexander Couzens, netdev,
	devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-phy

On Do, 2023-11-09 at 21:52 +0000, Daniel Golle wrote:
> MT7988 comes with a built-in 2.5G PHY as well as SerDes lanes to
> connect external PHYs or transceivers in USXGMII, 10GBase-R, 5GBase-R,
> 2500Base-X, 1000Base-X and Cisco SGMII interface modes.
> 
> Implement support for configuring for the new paths to SerDes interfaces
> and the internal 2.5G PHY.
> 
> Add USXGMII PCS driver for 10GBase-R, 5GBase-R and USXGMII mode, and
> setup the new PHYA on MT7988 to access the also still existing old
> LynxI PCS for 1000Base-X, 2500Base-X and Cisco SGMII PCS interface
> modes.
> 
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
[...]
> diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
> index 9ae3b8a71d0e6..ba5998ef7965e 100644
> --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
> +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
> @@ -15,6 +15,7 @@
>  #include <linux/u64_stats_sync.h>
>  #include <linux/refcount.h>
>  #include <linux/phylink.h>
> +#include <linux/reset.h>

I can't see what this is required for?

regards
Philipp

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [RFC PATCH 8/8] net: ethernet: mtk_eth_soc: add paths and SerDes modes for MT7988
@ 2023-11-27 13:27     ` Philipp Zabel
  0 siblings, 0 replies; 73+ messages in thread
From: Philipp Zabel @ 2023-11-27 13:27 UTC (permalink / raw)
  To: Daniel Golle, David S. Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Chunfeng Yun, Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau,
	John Crispin, Sean Wang, Mark Lee, Lorenzo Bianconi,
	Matthias Brugger, AngeloGioacchino Del Regno, Andrew Lunn,
	Heiner Kallweit, Russell King, Alexander Couzens, netdev,
	devicetree, linux-kernel, linux-arm-kernel, linux-mediatek,
	linux-phy

On Do, 2023-11-09 at 21:52 +0000, Daniel Golle wrote:
> MT7988 comes with a built-in 2.5G PHY as well as SerDes lanes to
> connect external PHYs or transceivers in USXGMII, 10GBase-R, 5GBase-R,
> 2500Base-X, 1000Base-X and Cisco SGMII interface modes.
> 
> Implement support for configuring for the new paths to SerDes interfaces
> and the internal 2.5G PHY.
> 
> Add USXGMII PCS driver for 10GBase-R, 5GBase-R and USXGMII mode, and
> setup the new PHYA on MT7988 to access the also still existing old
> LynxI PCS for 1000Base-X, 2500Base-X and Cisco SGMII PCS interface
> modes.
> 
> Signed-off-by: Daniel Golle <daniel@makrotopia.org>
> ---
[...]
> diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
> index 9ae3b8a71d0e6..ba5998ef7965e 100644
> --- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
> +++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
> @@ -15,6 +15,7 @@
>  #include <linux/u64_stats_sync.h>
>  #include <linux/refcount.h>
>  #include <linux/phylink.h>
> +#include <linux/reset.h>

I can't see what this is required for?

regards
Philipp

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [RFC PATCH 6/8] net: pcs: add driver for MediaTek USXGMII PCS
  2023-11-09 21:51   ` Daniel Golle
  (?)
@ 2023-11-27 15:08     ` Russell King (Oracle)
  -1 siblings, 0 replies; 73+ messages in thread
From: Russell King (Oracle) @ 2023-11-27 15:08 UTC (permalink / raw)
  To: Daniel Golle
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Alexander Couzens, Philipp Zabel, netdev, devicetree,
	linux-kernel, linux-arm-kernel, linux-mediatek, linux-phy

On Thu, Nov 09, 2023 at 09:51:57PM +0000, Daniel Golle wrote:
> Add driver for USXGMII PCS found in the MediaTek MT7988 SoC and supporting
> USXGMII, 10GBase-R and 5GBase-R interface modes. In order to support
> Cisco SGMII, 1000Base-X and 2500Base-X via the also present LynxI PCS
> create a wrapped PCS taking care of the components shared between the
> new USXGMII PCS and the legacy LynxI PCS.

What is the actual hardware setup here?

From what I can tell, it's something like this:

         .---- LynxI PCS ----.
 MAC ---+                     +--- PEXP --- external
         `--- USXGMII PCS ---'

Where PEXP is the serdes, handled by the drivers/phy layer in the
kernel. This is not an unusual setup, but we don't have the serdes PHY
controlled by the PCS driver.

You seem to be combining the whole lot into one driver, which seems
rather odd.

I would suggest that the serdes PHY is handled in the MAC driver, using
the mac_prepare(), mac_config() and mac_finish() methods, as well as
other parts of the driver:

- when the netdev is opened, call phy_power_on(pextp)
- when the netdev is closed, call phy_power_off(pextp)
- in mac_prepare(), if the interface has changed, call phy_reset(pextp)
- in mac_finish(), if the interface has changed, update your recorded
  interface mode to detect future changes in either mac_prepare() or
  mac_finish(), and call phy_set_mode_ext(pextp, PHY_MODE_ETHERNET,
  interface).

That will move most of what seems to be duplicated between the two PCS
instances out of the PCS driver and to MAC level, and then the PCS parts
become more about just driving the PCS hardware and nothing beyond that.
More specifically, the wrapping's only function then is to deal with the
sgmii reset. What exactly is that reset signal controlling? The reset to
the LynxI PCS or something else?

If you don't do that (and I prefer that you _do_ the above), then the
following comments apply to the code here:

1. the use of phy_power_on() without any calls to phy_power_off().
   These are counted calls, and after the first call to phy_power_on(),
   the only effect will be to increase the enable-counts of any
   associated regulator and the power count. So, basically you're
   missing calls to phy_power_off(). I suggest a call to phy_power_off()
   in the pcs_disable() function.

2. calling phy_power_on() in pcs_config() is entirely unnecessary.
   pcs_config() will not be called unless pcs_enable() has _already_
   been called, so the call to phy_power_on() in the pcs_enable()
   function is entirely sufficient.

With these two fixed, it means that the pextp PHY will be powered up
when one of the pcs_enable() functions is called, and powered down
when one of the pcs_disable() functions is called.

3. the complicated reset sequence, which is basically:
   - phy_reset(pextp)
   - reset_control_assert(sgmii or xfi reset)
   - *sleep* 100-500us (yes, sleep)
   - reset_control_deassert(sgmii or xfi reset)
   - *delay* 10ms (not sleep, but spin wait)
   If we are in a schedulable context (which the usleep_range() suggests
   we are) then why bother sleeping for the short delay, and
   spin-waiting for the longer delay? A bit of consistency seems to be
   needed here.

4. really needs to explain why it's necessary to repeatedly call the
   pcs_config() function at each get_state() if the link is down.

   Note that with the code the way it is, phy_power_on() will be
   repeatedly called, and at some point the "power_count" will overflow
   which would probably be bad. The counting in the regulator core will
   probably also overflow as well. So this is bad.

   Apart from the overflow issue, the only thing I can see that this
   achieves is to call the core of the pcs_config function. In the case
   of the lynxi, calling its pcs_config() repeatedly with the same
   parameters. Looking at pcs-mtk-lynxi.c, I can't see what this would
   achieve.

With the above issues dealt with, from the point of view of the lynxi /
sgmii code, the only things I can see that the wrapping achieves are:

a) when pcs_enable() is called, call phy_power_on(pextp)
b) when pcs_disable() is called, call phy_power_offpextp)
c) when pcs_config() is called, if the interface has changed:
   i)  call phy_reset() and assert/deassert the "sgmii" reset before
       calling the lynxi PCS
   ii) call phy_set_mode_ext(pextp) for the new interface mode after
       calling the lynxi PCS

I haven't picked through the usxgmii code completely, so I'm not
specifically commenting on it, although some of the above applies
there as well.

Thanks.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!

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

* Re: [RFC PATCH 6/8] net: pcs: add driver for MediaTek USXGMII PCS
@ 2023-11-27 15:08     ` Russell King (Oracle)
  0 siblings, 0 replies; 73+ messages in thread
From: Russell King (Oracle) @ 2023-11-27 15:08 UTC (permalink / raw)
  To: Daniel Golle
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Alexander Couzens, Philipp Zabel, netdev, devicetree,
	linux-kernel, linux-arm-kernel, linux-mediatek, linux-phy

On Thu, Nov 09, 2023 at 09:51:57PM +0000, Daniel Golle wrote:
> Add driver for USXGMII PCS found in the MediaTek MT7988 SoC and supporting
> USXGMII, 10GBase-R and 5GBase-R interface modes. In order to support
> Cisco SGMII, 1000Base-X and 2500Base-X via the also present LynxI PCS
> create a wrapped PCS taking care of the components shared between the
> new USXGMII PCS and the legacy LynxI PCS.

What is the actual hardware setup here?

From what I can tell, it's something like this:

         .---- LynxI PCS ----.
 MAC ---+                     +--- PEXP --- external
         `--- USXGMII PCS ---'

Where PEXP is the serdes, handled by the drivers/phy layer in the
kernel. This is not an unusual setup, but we don't have the serdes PHY
controlled by the PCS driver.

You seem to be combining the whole lot into one driver, which seems
rather odd.

I would suggest that the serdes PHY is handled in the MAC driver, using
the mac_prepare(), mac_config() and mac_finish() methods, as well as
other parts of the driver:

- when the netdev is opened, call phy_power_on(pextp)
- when the netdev is closed, call phy_power_off(pextp)
- in mac_prepare(), if the interface has changed, call phy_reset(pextp)
- in mac_finish(), if the interface has changed, update your recorded
  interface mode to detect future changes in either mac_prepare() or
  mac_finish(), and call phy_set_mode_ext(pextp, PHY_MODE_ETHERNET,
  interface).

That will move most of what seems to be duplicated between the two PCS
instances out of the PCS driver and to MAC level, and then the PCS parts
become more about just driving the PCS hardware and nothing beyond that.
More specifically, the wrapping's only function then is to deal with the
sgmii reset. What exactly is that reset signal controlling? The reset to
the LynxI PCS or something else?

If you don't do that (and I prefer that you _do_ the above), then the
following comments apply to the code here:

1. the use of phy_power_on() without any calls to phy_power_off().
   These are counted calls, and after the first call to phy_power_on(),
   the only effect will be to increase the enable-counts of any
   associated regulator and the power count. So, basically you're
   missing calls to phy_power_off(). I suggest a call to phy_power_off()
   in the pcs_disable() function.

2. calling phy_power_on() in pcs_config() is entirely unnecessary.
   pcs_config() will not be called unless pcs_enable() has _already_
   been called, so the call to phy_power_on() in the pcs_enable()
   function is entirely sufficient.

With these two fixed, it means that the pextp PHY will be powered up
when one of the pcs_enable() functions is called, and powered down
when one of the pcs_disable() functions is called.

3. the complicated reset sequence, which is basically:
   - phy_reset(pextp)
   - reset_control_assert(sgmii or xfi reset)
   - *sleep* 100-500us (yes, sleep)
   - reset_control_deassert(sgmii or xfi reset)
   - *delay* 10ms (not sleep, but spin wait)
   If we are in a schedulable context (which the usleep_range() suggests
   we are) then why bother sleeping for the short delay, and
   spin-waiting for the longer delay? A bit of consistency seems to be
   needed here.

4. really needs to explain why it's necessary to repeatedly call the
   pcs_config() function at each get_state() if the link is down.

   Note that with the code the way it is, phy_power_on() will be
   repeatedly called, and at some point the "power_count" will overflow
   which would probably be bad. The counting in the regulator core will
   probably also overflow as well. So this is bad.

   Apart from the overflow issue, the only thing I can see that this
   achieves is to call the core of the pcs_config function. In the case
   of the lynxi, calling its pcs_config() repeatedly with the same
   parameters. Looking at pcs-mtk-lynxi.c, I can't see what this would
   achieve.

With the above issues dealt with, from the point of view of the lynxi /
sgmii code, the only things I can see that the wrapping achieves are:

a) when pcs_enable() is called, call phy_power_on(pextp)
b) when pcs_disable() is called, call phy_power_offpextp)
c) when pcs_config() is called, if the interface has changed:
   i)  call phy_reset() and assert/deassert the "sgmii" reset before
       calling the lynxi PCS
   ii) call phy_set_mode_ext(pextp) for the new interface mode after
       calling the lynxi PCS

I haven't picked through the usxgmii code completely, so I'm not
specifically commenting on it, although some of the above applies
there as well.

Thanks.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [RFC PATCH 6/8] net: pcs: add driver for MediaTek USXGMII PCS
@ 2023-11-27 15:08     ` Russell King (Oracle)
  0 siblings, 0 replies; 73+ messages in thread
From: Russell King (Oracle) @ 2023-11-27 15:08 UTC (permalink / raw)
  To: Daniel Golle
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Alexander Couzens, Philipp Zabel, netdev, devicetree,
	linux-kernel, linux-arm-kernel, linux-mediatek, linux-phy

On Thu, Nov 09, 2023 at 09:51:57PM +0000, Daniel Golle wrote:
> Add driver for USXGMII PCS found in the MediaTek MT7988 SoC and supporting
> USXGMII, 10GBase-R and 5GBase-R interface modes. In order to support
> Cisco SGMII, 1000Base-X and 2500Base-X via the also present LynxI PCS
> create a wrapped PCS taking care of the components shared between the
> new USXGMII PCS and the legacy LynxI PCS.

What is the actual hardware setup here?

From what I can tell, it's something like this:

         .---- LynxI PCS ----.
 MAC ---+                     +--- PEXP --- external
         `--- USXGMII PCS ---'

Where PEXP is the serdes, handled by the drivers/phy layer in the
kernel. This is not an unusual setup, but we don't have the serdes PHY
controlled by the PCS driver.

You seem to be combining the whole lot into one driver, which seems
rather odd.

I would suggest that the serdes PHY is handled in the MAC driver, using
the mac_prepare(), mac_config() and mac_finish() methods, as well as
other parts of the driver:

- when the netdev is opened, call phy_power_on(pextp)
- when the netdev is closed, call phy_power_off(pextp)
- in mac_prepare(), if the interface has changed, call phy_reset(pextp)
- in mac_finish(), if the interface has changed, update your recorded
  interface mode to detect future changes in either mac_prepare() or
  mac_finish(), and call phy_set_mode_ext(pextp, PHY_MODE_ETHERNET,
  interface).

That will move most of what seems to be duplicated between the two PCS
instances out of the PCS driver and to MAC level, and then the PCS parts
become more about just driving the PCS hardware and nothing beyond that.
More specifically, the wrapping's only function then is to deal with the
sgmii reset. What exactly is that reset signal controlling? The reset to
the LynxI PCS or something else?

If you don't do that (and I prefer that you _do_ the above), then the
following comments apply to the code here:

1. the use of phy_power_on() without any calls to phy_power_off().
   These are counted calls, and after the first call to phy_power_on(),
   the only effect will be to increase the enable-counts of any
   associated regulator and the power count. So, basically you're
   missing calls to phy_power_off(). I suggest a call to phy_power_off()
   in the pcs_disable() function.

2. calling phy_power_on() in pcs_config() is entirely unnecessary.
   pcs_config() will not be called unless pcs_enable() has _already_
   been called, so the call to phy_power_on() in the pcs_enable()
   function is entirely sufficient.

With these two fixed, it means that the pextp PHY will be powered up
when one of the pcs_enable() functions is called, and powered down
when one of the pcs_disable() functions is called.

3. the complicated reset sequence, which is basically:
   - phy_reset(pextp)
   - reset_control_assert(sgmii or xfi reset)
   - *sleep* 100-500us (yes, sleep)
   - reset_control_deassert(sgmii or xfi reset)
   - *delay* 10ms (not sleep, but spin wait)
   If we are in a schedulable context (which the usleep_range() suggests
   we are) then why bother sleeping for the short delay, and
   spin-waiting for the longer delay? A bit of consistency seems to be
   needed here.

4. really needs to explain why it's necessary to repeatedly call the
   pcs_config() function at each get_state() if the link is down.

   Note that with the code the way it is, phy_power_on() will be
   repeatedly called, and at some point the "power_count" will overflow
   which would probably be bad. The counting in the regulator core will
   probably also overflow as well. So this is bad.

   Apart from the overflow issue, the only thing I can see that this
   achieves is to call the core of the pcs_config function. In the case
   of the lynxi, calling its pcs_config() repeatedly with the same
   parameters. Looking at pcs-mtk-lynxi.c, I can't see what this would
   achieve.

With the above issues dealt with, from the point of view of the lynxi /
sgmii code, the only things I can see that the wrapping achieves are:

a) when pcs_enable() is called, call phy_power_on(pextp)
b) when pcs_disable() is called, call phy_power_offpextp)
c) when pcs_config() is called, if the interface has changed:
   i)  call phy_reset() and assert/deassert the "sgmii" reset before
       calling the lynxi PCS
   ii) call phy_set_mode_ext(pextp) for the new interface mode after
       calling the lynxi PCS

I haven't picked through the usxgmii code completely, so I'm not
specifically commenting on it, although some of the above applies
there as well.

Thanks.

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [RFC PATCH 5/8] dt-bindings: net: pcs: add bindings for MediaTek USXGMII PCS
  2023-11-09 21:51   ` Daniel Golle
  (?)
@ 2023-11-27 15:47     ` Russell King (Oracle)
  -1 siblings, 0 replies; 73+ messages in thread
From: Russell King (Oracle) @ 2023-11-27 15:47 UTC (permalink / raw)
  To: Daniel Golle
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Alexander Couzens, Philipp Zabel, netdev, devicetree,
	linux-kernel, linux-arm-kernel, linux-mediatek, linux-phy

On Thu, Nov 09, 2023 at 09:51:47PM +0000, Daniel Golle wrote:
> MediaTek's USXGMII can be found in the MT7988 SoC. We need to access
> it in order to configure and monitor the Ethernet SerDes link in
> USXGMII, 10GBase-R and 5GBase-R mode. By including a wrapped
> legacy 1000Base-X/2500Base-X/Cisco SGMII LynxI PCS as well, those
> interface modes are also available.

I think this binding is based on the implementation than on hardware.

What I believe you have is this setup:

        .---- LynxI PCS ----.
MAC ---+                     +--- PEXTP --- world
        `--- USXGMII PCS ---'

You are representing the PEXTP as a separate entity in DT, but then
you're representing the LynxI PCS and the USXGMII PCS as a single
block, which seems to be how you've decided to implement it.

Given that the LynxI PCS is already in use elsewhere in the Mediatek
range, I suggest that the LynxI PCS is one block of IP, and the USXGMII
PCS is a separate block of IP.

1) Would it not be better to model the two PCS seperately?

2) The addition of the SGMII reset needs more information - is this
   controlling a reset for the LynxI block? If so, it should be part
   of a LynxI PCS binding.

3) The PEXTP is presumably a separate block which can be shared between
   several devices - for example, the LynxI, USXGMII, and probably SATA
   and PCIe as well. From the 802.3's network model, the PEXTP is the
   PMA/PMD.

   From the point of view of 802.3's model, a network interface has
   various layers such as the MAC, PCS and PMA/PMD, and sitting above
   these layers is the management of the system. Rather than chasing
   the data flow (which in a network device can be complex) wouldn't
   it be better to continue with the 802.3 model as we are doing with
   other devices, rather than trying to go with a new approach here?

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!

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

* Re: [RFC PATCH 5/8] dt-bindings: net: pcs: add bindings for MediaTek USXGMII PCS
@ 2023-11-27 15:47     ` Russell King (Oracle)
  0 siblings, 0 replies; 73+ messages in thread
From: Russell King (Oracle) @ 2023-11-27 15:47 UTC (permalink / raw)
  To: Daniel Golle
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Alexander Couzens, Philipp Zabel, netdev, devicetree,
	linux-kernel, linux-arm-kernel, linux-mediatek, linux-phy

On Thu, Nov 09, 2023 at 09:51:47PM +0000, Daniel Golle wrote:
> MediaTek's USXGMII can be found in the MT7988 SoC. We need to access
> it in order to configure and monitor the Ethernet SerDes link in
> USXGMII, 10GBase-R and 5GBase-R mode. By including a wrapped
> legacy 1000Base-X/2500Base-X/Cisco SGMII LynxI PCS as well, those
> interface modes are also available.

I think this binding is based on the implementation than on hardware.

What I believe you have is this setup:

        .---- LynxI PCS ----.
MAC ---+                     +--- PEXTP --- world
        `--- USXGMII PCS ---'

You are representing the PEXTP as a separate entity in DT, but then
you're representing the LynxI PCS and the USXGMII PCS as a single
block, which seems to be how you've decided to implement it.

Given that the LynxI PCS is already in use elsewhere in the Mediatek
range, I suggest that the LynxI PCS is one block of IP, and the USXGMII
PCS is a separate block of IP.

1) Would it not be better to model the two PCS seperately?

2) The addition of the SGMII reset needs more information - is this
   controlling a reset for the LynxI block? If so, it should be part
   of a LynxI PCS binding.

3) The PEXTP is presumably a separate block which can be shared between
   several devices - for example, the LynxI, USXGMII, and probably SATA
   and PCIe as well. From the 802.3's network model, the PEXTP is the
   PMA/PMD.

   From the point of view of 802.3's model, a network interface has
   various layers such as the MAC, PCS and PMA/PMD, and sitting above
   these layers is the management of the system. Rather than chasing
   the data flow (which in a network device can be complex) wouldn't
   it be better to continue with the 802.3 model as we are doing with
   other devices, rather than trying to go with a new approach here?

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!

-- 
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy

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

* Re: [RFC PATCH 5/8] dt-bindings: net: pcs: add bindings for MediaTek USXGMII PCS
@ 2023-11-27 15:47     ` Russell King (Oracle)
  0 siblings, 0 replies; 73+ messages in thread
From: Russell King (Oracle) @ 2023-11-27 15:47 UTC (permalink / raw)
  To: Daniel Golle
  Cc: David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Rob Herring, Krzysztof Kozlowski, Conor Dooley, Chunfeng Yun,
	Vinod Koul, Kishon Vijay Abraham I, Felix Fietkau, John Crispin,
	Sean Wang, Mark Lee, Lorenzo Bianconi, Matthias Brugger,
	AngeloGioacchino Del Regno, Andrew Lunn, Heiner Kallweit,
	Alexander Couzens, Philipp Zabel, netdev, devicetree,
	linux-kernel, linux-arm-kernel, linux-mediatek, linux-phy

On Thu, Nov 09, 2023 at 09:51:47PM +0000, Daniel Golle wrote:
> MediaTek's USXGMII can be found in the MT7988 SoC. We need to access
> it in order to configure and monitor the Ethernet SerDes link in
> USXGMII, 10GBase-R and 5GBase-R mode. By including a wrapped
> legacy 1000Base-X/2500Base-X/Cisco SGMII LynxI PCS as well, those
> interface modes are also available.

I think this binding is based on the implementation than on hardware.

What I believe you have is this setup:

        .---- LynxI PCS ----.
MAC ---+                     +--- PEXTP --- world
        `--- USXGMII PCS ---'

You are representing the PEXTP as a separate entity in DT, but then
you're representing the LynxI PCS and the USXGMII PCS as a single
block, which seems to be how you've decided to implement it.

Given that the LynxI PCS is already in use elsewhere in the Mediatek
range, I suggest that the LynxI PCS is one block of IP, and the USXGMII
PCS is a separate block of IP.

1) Would it not be better to model the two PCS seperately?

2) The addition of the SGMII reset needs more information - is this
   controlling a reset for the LynxI block? If so, it should be part
   of a LynxI PCS binding.

3) The PEXTP is presumably a separate block which can be shared between
   several devices - for example, the LynxI, USXGMII, and probably SATA
   and PCIe as well. From the 802.3's network model, the PEXTP is the
   PMA/PMD.

   From the point of view of 802.3's model, a network interface has
   various layers such as the MAC, PCS and PMA/PMD, and sitting above
   these layers is the management of the system. Rather than chasing
   the data flow (which in a network device can be complex) wouldn't
   it be better to continue with the 802.3 model as we are doing with
   other devices, rather than trying to go with a new approach here?

-- 
RMK's Patch system: https://www.armlinux.org.uk/developer/patches/
FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

end of thread, other threads:[~2023-11-27 15:48 UTC | newest]

Thread overview: 73+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-09 21:50 [RFC PATCH 0/8] Add support for 10G Ethernet SerDes on MT7988 Daniel Golle
2023-11-09 21:50 ` Daniel Golle
2023-11-09 21:50 ` Daniel Golle
2023-11-09 21:50 ` [RFC PATCH 1/8] dt-bindings: phy: mediatek,xfi-pextp: add new bindings Daniel Golle
2023-11-09 21:50   ` Daniel Golle
2023-11-09 21:50   ` Daniel Golle
2023-11-09 21:55   ` Andrew Lunn
2023-11-09 21:55     ` Andrew Lunn
2023-11-09 21:55     ` Andrew Lunn
2023-11-09 23:11     ` Daniel Golle
2023-11-09 23:11       ` Daniel Golle
2023-11-09 23:11       ` Daniel Golle
2023-11-14 13:44       ` Rob Herring
2023-11-14 13:44         ` Rob Herring
2023-11-14 13:44         ` Rob Herring
2023-11-10 20:08   ` Rob Herring
2023-11-10 20:08     ` Rob Herring
2023-11-10 20:08     ` Rob Herring
2023-11-14 13:43   ` Rob Herring
2023-11-14 13:43     ` Rob Herring
2023-11-14 13:43     ` Rob Herring
2023-11-09 21:51 ` [RFC PATCH 2/8] phy: add driver for MediaTek pextp 10GE SerDes PHY Daniel Golle
2023-11-09 21:51   ` Daniel Golle
2023-11-09 21:51   ` Daniel Golle
2023-11-27 13:16   ` Vinod Koul
2023-11-27 13:16     ` Vinod Koul
2023-11-27 13:16     ` Vinod Koul
2023-11-09 21:51 ` [RFC PATCH 3/8] net: pcs: pcs-mtk-lynxi: use 2500Base-X without AN Daniel Golle
2023-11-09 21:51   ` Daniel Golle
2023-11-09 21:51   ` Daniel Golle
2023-11-10  8:54   ` Russell King (Oracle)
2023-11-10  8:54     ` Russell King (Oracle)
2023-11-10  8:54     ` Russell King (Oracle)
2023-11-09 21:51 ` [RFC PATCH 4/8] net: pcs: pcs-mtk-lynxi: allow calling with NULL advertising Daniel Golle
2023-11-09 21:51   ` Daniel Golle
2023-11-09 21:51   ` Daniel Golle
2023-11-09 21:51 ` [RFC PATCH 5/8] dt-bindings: net: pcs: add bindings for MediaTek USXGMII PCS Daniel Golle
2023-11-09 21:51   ` Daniel Golle
2023-11-09 21:51   ` Daniel Golle
2023-11-11  8:13   ` Krzysztof Kozlowski
2023-11-11  8:13     ` Krzysztof Kozlowski
2023-11-11  8:13     ` Krzysztof Kozlowski
2023-11-14 13:56   ` Rob Herring
2023-11-14 13:56     ` Rob Herring
2023-11-14 13:56     ` Rob Herring
2023-11-27 15:47   ` Russell King (Oracle)
2023-11-27 15:47     ` Russell King (Oracle)
2023-11-27 15:47     ` Russell King (Oracle)
2023-11-09 21:51 ` [RFC PATCH 6/8] net: pcs: add driver " Daniel Golle
2023-11-09 21:51   ` Daniel Golle
2023-11-09 21:51   ` Daniel Golle
2023-11-10 22:48   ` kernel test robot
2023-11-27 13:25   ` Philipp Zabel
2023-11-27 13:25     ` Philipp Zabel
2023-11-27 13:25     ` Philipp Zabel
2023-11-27 15:08   ` Russell King (Oracle)
2023-11-27 15:08     ` Russell King (Oracle)
2023-11-27 15:08     ` Russell King (Oracle)
2023-11-09 21:52 ` [RFC PATCH 7/8] dt-bindings: net: mediatek,net: fix and complete mt7988-eth binding Daniel Golle
2023-11-09 21:52   ` Daniel Golle
2023-11-09 21:52   ` Daniel Golle
2023-11-14 14:07   ` Rob Herring
2023-11-14 14:07     ` Rob Herring
2023-11-14 14:07     ` Rob Herring
2023-11-14 17:42     ` Daniel Golle
2023-11-14 17:42       ` Daniel Golle
2023-11-14 17:42       ` Daniel Golle
2023-11-09 21:52 ` [RFC PATCH 8/8] net: ethernet: mtk_eth_soc: add paths and SerDes modes for MT7988 Daniel Golle
2023-11-09 21:52   ` Daniel Golle
2023-11-09 21:52   ` Daniel Golle
2023-11-27 13:27   ` Philipp Zabel
2023-11-27 13:27     ` Philipp Zabel
2023-11-27 13:27     ` Philipp Zabel

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