* [PATCH net-next 00/28] [RFC] net: dpaa: Convert to phylink
@ 2022-06-17 20:32 Sean Anderson
2022-06-17 20:32 ` [PATCH net-next 01/28] dt-bindings: phy: Add QorIQ SerDes binding Sean Anderson
` (5 more replies)
0 siblings, 6 replies; 25+ messages in thread
From: Sean Anderson @ 2022-06-17 20:32 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Madalin Bucur, netdev
Cc: linux-kernel, linux-arm-kernel, Paolo Abeni, Russell King,
Eric Dumazet, Sean Anderson, Ioana Ciornei, Jonathan Corbet,
Kishon Vijay Abraham I, Krzysztof Kozlowski, Li Yang, Rob Herring,
Shawn Guo, Vinod Koul, devicetree, linux-phy
This series converts the DPAA driver to phylink. Additionally,
it also adds a serdes driver to allow for dynamic reconfiguration
between 1g and 10g interfaces (such as in an SFP+ slot). These changes
are submitted together for this RFC, but they will eventually be
submitted separately to the appropriate subsystem maintainers.
Only the mEMAC driver has gotten the phylink treatment for this RFC. I
would appreciate any help towards converting/testing the 10GEC and dTSEC
drivers. I don't have any boards with those MACs, so a large conversion
like this has a high risk of breakage.
I have tried to maintain backwards compatibility with existing device
trees whereever possible. However, one area where I was unable to
achieve this was with QSGMII. Please refer to patch 2 for details.
The serdes driver is mostly functional (but not quite, see patch 25).
However, I am not quite sure about the implementation details. I have made
a fairly extensive commentary on the driver in patch 1, so hopefully that
can provide some context. This series only adds support for the
LS1046ARDB SerDes, but it should be fairly straightforward to add
support for other SoCs and boards. Patches 26-27 should show the typical
steps.
Most of this series can be applied as-is. In particular, patches 4-21
are essentially cleanups which stand on their own merits.
Patches 4-8 were first submitted as [1].
[1] https://lore.kernel.org/netdev/20220531195851.1592220-1-sean.anderson@seco.com/
Sean Anderson (28):
dt-bindings: phy: Add QorIQ SerDes binding
dt-bindings: net: fman: Add additional interface properties
phy: fsl: Add QorIQ SerDes driver
net: fman: Convert to SPDX identifiers
net: fman: Don't pass comm_mode to enable/disable
net: fman: Store en/disable in mac_device instead of mac_priv_s
net: fman: dtsec: Always gracefully stop/start
net: fman: Get PCS node in per-mac init
net: fman: Store initialization function in match data
net: fman: Move struct dev to mac_device
net: fman: Configure fixed link in memac_initialization
net: fman: Export/rename some common functions
net: fman: memac: Use params instead of priv for max_speed
net: fman: Move initialization to mac-specific files
net: fman: Mark mac methods static
net: fman: Inline several functions into initialization
net: fman: Remove internal_phy_node from params
net: fman: Map the base address once
net: fman: Pass params directly to mac init
net: fman: Use mac_dev for some params
net: fman: Clean up error handling
net: fman: memac: Add serdes support
net: fman: memac: Use lynx pcs driver
net: dpaa: Use mac_dev variable in dpaa_netdev_init
[RFC] net: dpaa: Convert to phylink
arm64: dts: ls1046ardb: Add serdes bindings
arm64: dts: ls1046a: Add SerDes bindings
arm64: dts: ls1046a: Specify which MACs support RGMII
.../devicetree/bindings/net/fsl-fman.txt | 49 +-
.../bindings/phy/fsl,qoriq-serdes.yaml | 78 +
Documentation/driver-api/phy/index.rst | 1 +
Documentation/driver-api/phy/qoriq.rst | 91 ++
MAINTAINERS | 6 +
.../boot/dts/freescale/fsl-ls1046-post.dtsi | 8 +
.../boot/dts/freescale/fsl-ls1046a-rdb.dts | 32 +
.../arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 12 +
drivers/net/ethernet/freescale/dpaa/Kconfig | 4 +-
.../net/ethernet/freescale/dpaa/dpaa_eth.c | 100 +-
.../ethernet/freescale/dpaa/dpaa_eth_sysfs.c | 2 +-
.../ethernet/freescale/dpaa/dpaa_ethtool.c | 82 +-
drivers/net/ethernet/freescale/fman/Makefile | 3 +-
drivers/net/ethernet/freescale/fman/fman.c | 31 +-
drivers/net/ethernet/freescale/fman/fman.h | 31 +-
.../net/ethernet/freescale/fman/fman_dtsec.c | 319 ++--
.../net/ethernet/freescale/fman/fman_dtsec.h | 58 +-
.../net/ethernet/freescale/fman/fman_keygen.c | 29 +-
.../net/ethernet/freescale/fman/fman_keygen.h | 29 +-
.../net/ethernet/freescale/fman/fman_mac.h | 29 -
.../net/ethernet/freescale/fman/fman_memac.c | 864 +++++-----
.../net/ethernet/freescale/fman/fman_memac.h | 57 +-
.../net/ethernet/freescale/fman/fman_muram.c | 31 +-
.../net/ethernet/freescale/fman/fman_muram.h | 32 +-
.../net/ethernet/freescale/fman/fman_port.c | 29 +-
.../net/ethernet/freescale/fman/fman_port.h | 29 +-
drivers/net/ethernet/freescale/fman/fman_sp.c | 29 +-
drivers/net/ethernet/freescale/fman/fman_sp.h | 28 +-
.../net/ethernet/freescale/fman/fman_tgec.c | 155 +-
.../net/ethernet/freescale/fman/fman_tgec.h | 54 +-
drivers/net/ethernet/freescale/fman/mac.c | 645 +-------
drivers/net/ethernet/freescale/fman/mac.h | 62 +-
drivers/phy/freescale/Kconfig | 19 +
drivers/phy/freescale/Makefile | 1 +
drivers/phy/freescale/phy-qoriq.c | 1441 +++++++++++++++++
35 files changed, 2562 insertions(+), 1908 deletions(-)
create mode 100644 Documentation/devicetree/bindings/phy/fsl,qoriq-serdes.yaml
create mode 100644 Documentation/driver-api/phy/qoriq.rst
create mode 100644 drivers/phy/freescale/phy-qoriq.c
--
2.35.1.1320.gc452695387.dirty
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH net-next 01/28] dt-bindings: phy: Add QorIQ SerDes binding
2022-06-17 20:32 [PATCH net-next 00/28] [RFC] net: dpaa: Convert to phylink Sean Anderson
@ 2022-06-17 20:32 ` Sean Anderson
2022-06-17 23:27 ` Rob Herring
2022-06-18 1:15 ` Krzysztof Kozlowski
2022-06-17 20:32 ` [PATCH net-next 02/28] dt-bindings: net: fman: Add additional interface properties Sean Anderson
` (4 subsequent siblings)
5 siblings, 2 replies; 25+ messages in thread
From: Sean Anderson @ 2022-06-17 20:32 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Madalin Bucur, netdev
Cc: linux-kernel, linux-arm-kernel, Paolo Abeni, Russell King,
Eric Dumazet, Sean Anderson, Kishon Vijay Abraham I,
Krzysztof Kozlowski, Rob Herring, Vinod Koul, devicetree,
linux-phy
This adds a binding for the SerDes module found on QorIQ processors. The
phy reference has two cells, one for the first lane and one for the
last. This should allow for good support of multi-lane protocols when
(if) they are added. There is no protocol option, because the driver is
designed to be able to completely reconfigure lanes at runtime.
Generally, the phy consumer can select the appropriate protocol using
set_mode. For the most part there is only one protocol controller
(consumer) per lane/protocol combination. The exception to this is the
B4860 processor, which has some lanes which can be connected to
multiple MACs. For that processor, I anticipate the easiest way to
resolve this will be to add an additional cell with a "protocol
controller instance" property.
Each serdes has a unique set of supported protocols (and lanes). The
support matrix is stored in the driver and is selected based on the
compatible string. It is anticipated that a new compatible string will
need to be added for each serdes on each SoC that drivers support is
added for.
There are two PLLs, each of which can be used as the master clock for
each lane. Each PLL has its own reference. For the moment they are
required, because it simplifies the driver implementation. Absent
reference clocks can be modeled by a fixed-clock with a rate of 0.
Signed-off-by: Sean Anderson <sean.anderson@seco.com>
---
.../bindings/phy/fsl,qoriq-serdes.yaml | 78 +++++++++++++++++++
1 file changed, 78 insertions(+)
create mode 100644 Documentation/devicetree/bindings/phy/fsl,qoriq-serdes.yaml
diff --git a/Documentation/devicetree/bindings/phy/fsl,qoriq-serdes.yaml b/Documentation/devicetree/bindings/phy/fsl,qoriq-serdes.yaml
new file mode 100644
index 000000000000..4b9c1fcdab10
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/fsl,qoriq-serdes.yaml
@@ -0,0 +1,78 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/phy/fsl,qoriq-serdes.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP QorIQ SerDes Device Tree Bindings
+
+maintainers:
+ - Sean Anderson <sean.anderson@seco.com>
+
+description: |
+ This binding describes the SerDes devices found in NXP's QorIQ line of
+ processors. The SerDes provides up to eight lanes. Each lane may be
+ configured individually, or may be combined with adjacent lanes for a
+ multi-lane protocol. The SerDes supports a variety of protocols, including up
+ to 10G Ethernet, PCIe, SATA, and others. The specific protocols supported for
+ each lane depend on the particular SoC.
+
+properties:
+ "#phy-cells":
+ const: 2
+ description: |
+ The cells contain the following arguments.
+
+ - description: |
+ The first lane in the group. Lanes are numbered based on the register
+ offsets, not the I/O ports. This corresponds to the letter-based
+ ("Lane A") naming scheme, and not the number-based ("Lane 0") naming
+ scheme. On most SoCs, "Lane A" is "Lane 0", but not always.
+ minimum: 0
+ maximum: 7
+ - description: |
+ Last lane. For single-lane protocols, this should be the same as the
+ first lane.
+ minimum: 0
+ maximum: 7
+
+ compatible:
+ enum:
+ - fsl,ls1046a-serdes-1
+ - fsl,ls1046a-serdes-2
+
+ clocks:
+ minItems: 2
+ maxItems: 2
+ description: |
+ Clock for each PLL reference clock input.
+
+ clock-names:
+ minItems: 2
+ maxItems: 2
+ items:
+ pattern: "^ref[0-1]$"
+
+ reg:
+ maxItems: 1
+
+required:
+ - "#phy-cells"
+ - compatible
+ - clocks
+ - clock-names
+ - reg
+
+additionalProperties: false
+
+examples:
+ - |
+ serdes1: phy@1ea0000 {
+ #phy-cells = <2>;
+ compatible = "fsl,ls1046a-serdes-1";
+ reg = <0x0 0x1ea0000 0x0 0x2000>;
+ clocks = <&clk_100mhz>, <&clk_156mhz>;
+ clock-names = "ref0", "ref1";
+ };
+
+...
--
2.35.1.1320.gc452695387.dirty
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH net-next 02/28] dt-bindings: net: fman: Add additional interface properties
2022-06-17 20:32 [PATCH net-next 00/28] [RFC] net: dpaa: Convert to phylink Sean Anderson
2022-06-17 20:32 ` [PATCH net-next 01/28] dt-bindings: phy: Add QorIQ SerDes binding Sean Anderson
@ 2022-06-17 20:32 ` Sean Anderson
2022-06-18 1:16 ` Krzysztof Kozlowski
2022-06-17 20:32 ` [PATCH net-next 03/28] phy: fsl: Add QorIQ SerDes driver Sean Anderson
` (3 subsequent siblings)
5 siblings, 1 reply; 25+ messages in thread
From: Sean Anderson @ 2022-06-17 20:32 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Madalin Bucur, netdev
Cc: linux-kernel, linux-arm-kernel, Paolo Abeni, Russell King,
Eric Dumazet, Sean Anderson, Krzysztof Kozlowski, Rob Herring,
devicetree
At the moment, MEMACs are configured almost completely based on the
phy-connection-type. That is, if the phy interface is RGMII, it assumed
that RGMII is supported. For some interfaces, it is assumed that the
RCW/bootloader has set up the SerDes properly. The actual link state is
never reported.
To address these shortcomings, the driver will need additional
information. First, it needs to know how to access the PCS/PMAs (in
order to configure them and get the link status). The SGMII PCS/PMA is
the only currently-described PCS/PMA. Add the XFI and QSGMII PCS/PMAs as
well. The XFI (and 1GBase-KR) PCS/PMA is a c45 "phy" which sits on the
same MDIO bus as SGMII PCS/PMA. By default they will have conflicting
addresses, but they are also not enabled at the same time by default.
Therefore, we can let the default address for the XFI PCS/PMA be the
same as for SGMII. This will allow for backwards-compatibility.
QSGMII, however, cannot work with the current binding. This is because
the QSGMII PCS/PMAs are only present on one MAC's MDIO bus. At the
moment this is worked around by having every MAC write to the PCS/PMA
addresses (without checking if they are present). This only works if
each MAC has the same configuration, and only if we don't need to know
the status. Because the QSGMII PCS/PMA will typically be located on a
different MDIO bus than the MAC's SGMII PCS/PMA, there is no fallback
for the QSGMII PCS/PMA.
MEMACs (across all SoCs) support the following protocols:
- MII
- RGMII
- SGMII, 1000Base-X, and 1000Base-KX
- 2500Base-X (aka 2.5G SGMII)
- QSGMII
- 10GBase-R (aka XFI) and 10GBase-KR
- XAUI and HiGig
Each line documents a set of orthogonal protocols (e.g. XAUI is
supported if and only if HiGig is supported). Additionally,
- XAUI implies support for 10GBase-R
- 10GBase-R is supported if and only if RGMII is not supported
- 2500Base-X implies support for 1000Base-X
- MII implies support for RGMII
To switch between different protocols, we must reconfigure the SerDes.
This is done by using the standard phys property. We can also use it to
validate whether different protocols are supported (e.g. using
phy_validate). This will work for serial protocols, but not RGMII or
MII. Additionally, we still need to be compatible when there is no
SerDes.
While we can detect 10G support by examining the port speed (as set by
fsl,fman-10g-port), we cannot determine support for any of the other
protocols based on the existing binding. In fact, the binding works
against us in some respects, because pcsphy-handle is required even if
there is no possible PCS/PMA for that MAC. To allow for backwards-
compatibility, we use a boolean-style property for RGMII (instead of
presence/absence-style). When the property for RGMII is missing, we will
assume that it is supported. The exception is MII, since no existing
device trees use it (as far as I could tell).
Unfortunately, QSGMII support will be broken for old device trees. There
is nothing we can do about this because of the PCS/PMA situation (as
described above).
Signed-off-by: Sean Anderson <sean.anderson@seco.com>
---
.../devicetree/bindings/net/fsl-fman.txt | 49 +++++++++++++++++--
1 file changed, 45 insertions(+), 4 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/fsl-fman.txt b/Documentation/devicetree/bindings/net/fsl-fman.txt
index 801efc7d6818..25c7288e1db2 100644
--- a/Documentation/devicetree/bindings/net/fsl-fman.txt
+++ b/Documentation/devicetree/bindings/net/fsl-fman.txt
@@ -322,10 +322,50 @@ PROPERTIES
Value type: <phandle>
Definition: A phandle for 1EEE1588 timer.
+- phys
+ Usage optional for "fsl,fman-memac" MACs
+ Value type: <prop-encoded-array>
+ Definition: A phandle for the SerDes lanes which should be
+ used. This property is required if a pcsphy-handle is
+ specified.
+
+- phy-names
+ Usage optional for "fsl,fman-memac" MACs
+ Value type: <stringlist>
+ Definition: Should be "serdes". Must be present if phys is.
+
- pcsphy-handle
+ Usage optional for "fsl,fman-memac" MACs
+ Value type: <prop-encoded-array>
+ Definition: An array of phandles for PCS/PMA devices. Without a
+ pcs-names property (see below) this should contain a phandle
+ referencing the SGMII PCS/PMA. This property may be absent if
+ no serial interfaces are supported.
+
+- pcs-names
+ Usage optional for "fsl,fman-memac" MACs
+ Value type: <stringlist>
+ Definition: The type of each PCS/PMA, corresponding to
+ pcsphy-handle. Each value may be one of
+ - "sgmii"
+ - "qsgmii"
+ - "xfi"
+ If "xfi" is absent, it will default to the value of "sgmii". If
+ this property is absent, the first phandle in pcsphy-handle
+ will be assumed to be "sgmii".
+
+- rgmii
Usage required for "fsl,fman-memac" MACs
- Value type: <phandle>
- Definition: A phandle for pcsphy.
+ Value type: <u32>
+ Definition: This property should be 1 if RGMII is supported and
+ 0 otherwise.
+
+- mii
+ Usage optional for "fsl,fman-memac" MACs
+ Value type: <empty>
+ Definition: This property should be present if MII is
+ supported. rgmii must be enabled for this property to be
+ effective.
- tbi-handle
Usage required for "fsl,fman-dtsec" MACs
@@ -446,8 +486,9 @@ For internal PHY device on internal mdio bus, a PHY node should be created.
See the definition of the PHY node in booting-without-of.txt for an
example of how to define a PHY (Internal PHY has no interrupt line).
- For "fsl,fman-mdio" compatible internal mdio bus, the PHY is TBI PHY.
-- For "fsl,fman-memac-mdio" compatible internal mdio bus, the PHY is PCS PHY,
- PCS PHY addr must be '0'.
+- For "fsl,fman-memac-mdio" compatible internal mdio bus, the PHY is PCS PHY.
+ The PCS PHY address should correspond to the value of the appropriate
+ MDEV_PORT.
EXAMPLE
--
2.35.1.1320.gc452695387.dirty
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH net-next 03/28] phy: fsl: Add QorIQ SerDes driver
2022-06-17 20:32 [PATCH net-next 00/28] [RFC] net: dpaa: Convert to phylink Sean Anderson
2022-06-17 20:32 ` [PATCH net-next 01/28] dt-bindings: phy: Add QorIQ SerDes binding Sean Anderson
2022-06-17 20:32 ` [PATCH net-next 02/28] dt-bindings: net: fman: Add additional interface properties Sean Anderson
@ 2022-06-17 20:32 ` Sean Anderson
2022-06-18 3:02 ` kernel test robot
[not found] ` <GV1PR04MB905598703F5E9A0989662EFDE0AE9@GV1PR04MB9055.eurprd04.prod.outlook.com>
2022-06-17 20:33 ` [PATCH net-next 26/28] arm64: dts: ls1046ardb: Add serdes bindings Sean Anderson
` (2 subsequent siblings)
5 siblings, 2 replies; 25+ messages in thread
From: Sean Anderson @ 2022-06-17 20:32 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Madalin Bucur, netdev
Cc: linux-kernel, linux-arm-kernel, Paolo Abeni, Russell King,
Eric Dumazet, Sean Anderson, Ioana Ciornei, Jonathan Corbet,
Kishon Vijay Abraham I, Krzysztof Kozlowski, Rob Herring,
Vinod Koul, devicetree, linux-phy
This adds support for the "SerDes" devices found on various NXP QorIQ SoCs.
There may be up to four SerDes devices on each SoC, each supporting up to
eight lanes. Protocol support for each SerDes is highly heterogeneous, with
each SoC typically having a totally different selection of supported
protocols for each lane. Additionally, the SerDes devices on each SoC also
have differing support. One SerDes will typically support Ethernet on most
lanes, while the other will typically support PCIe on most lanes.
There is wide hardware support for this SerDes. I have not done extensive
digging, but it seems to be used on almost every QorIQ device, including
the AMP and Layerscape series. Because each SoC typically has specific
instructions and exceptions for its SerDes, I have limited the initial
scope of this module to just the LS1046A. Additionally, I have only added
support for Ethernet protocols. There is not a great need for dynamic
reconfiguration for other protocols (SATA and PCIe handle rate changes in
hardware), so support for them may never be added.
Nevertheless, I have tried to provide an obvious path for adding support
for other SoCs as well as other protocols. SATA just needs support for
configuring LNmSSCR0. PCIe may need to configure the equalization
registers. It also uses multiple lanes. I have tried to write the driver
with multi-lane support in mind, so there should not need to be any large
changes. Although there are 6 protocols supported, I have only tested SGMII
and XFI. The rest have been implemented as described in the datasheet.
The PLLs are modeled as clocks proper. This lets us take advantage of the
existing clock infrastructure. I have not given the same treatment to the
lane "clocks" (dividers) because they need to be programmed in-concert with
the rest of the lane settings. One tricky thing is that the VCO (pll) rate
exceeds 2^32 (maxing out at around 5GHz). This will be a problem on 32-bit
platforms, since clock rates are stored as unsigned longs. To work around
this, the pll clock rate is generally treated in units of kHz.
The PLLs are configured rather interestingly. Instead of the usual direct
programming of the appropriate divisors, the input and output clock rates
are selected directly. Generally, the only restriction is that the input
and output must be integer multiples of each other. This suggests some kind
of internal look-up table. The datasheets generally list out the supported
combinations explicitly, and not all input/output combinations are
documented. I'm not sure if this is due to lack of support, or due to an
oversight. If this becomes an issue, then some combinations can be
blacklisted (or whitelisted). This may also be necessary for other SoCs
which have more stringent clock requirements.
The general API call list for this PHY is documented under the driver-api
docs. I think this is rather standard, except that most driverts configure
the mode (protocol) at xlate-time. Unlike some other phys where e.g. PCIe
x4 will use 4 separate phys all configured for PCIe, this driver uses one
phy configured to use 4 lanes. This is because while the individual lanes
may be configured individually, the protocol selection acts on all lanes at
once. Additionally, the order which lanes should be configured in is
specified by the datasheet. To coordinate this, lanes are reserved in
phy_init, and released in phy_exit.
When getting a phy, if a phy already exists for those lanes, it is reused.
This is to make things like QSGMII work. Four MACs will all want to ensure
that the lane is configured properly, and we need to ensure they can all
call phy_init, etc. There is refcounting for phy_init and phy_power_on, so
the phy will only be powered on once. However, there is no refcounting for
phy_set_mode. A "rogue" MAC could set the mode to something non-QSGMII and
break the other MACs. Perhaps there is an opportunity for future
enhancement here.
This driver was written with reference to the LS1046A reference manual.
However, it was informed by reference manuals for all processors with
MEMACs, especially the T4240 (which appears to have a "maxed-out"
configuration).
Signed-off-by: Sean Anderson <sean.anderson@seco.com>
---
This appears to be the same underlying hardware as the Lynx 28G phy
added in 8f73b37cf3fb ("phy: add support for the Layerscape SerDes
28G"). I was working off an older Linux when preparing this series, so I
did not notice it. However, I believe this implementation is more
comprehensive/versatile. I will look into resolving the differences in
the future.
Documentation/driver-api/phy/index.rst | 1 +
Documentation/driver-api/phy/qoriq.rst | 91 ++
MAINTAINERS | 6 +
drivers/phy/freescale/Kconfig | 19 +
drivers/phy/freescale/Makefile | 1 +
drivers/phy/freescale/phy-qoriq.c | 1441 ++++++++++++++++++++++++
6 files changed, 1559 insertions(+)
create mode 100644 Documentation/driver-api/phy/qoriq.rst
create mode 100644 drivers/phy/freescale/phy-qoriq.c
diff --git a/Documentation/driver-api/phy/index.rst b/Documentation/driver-api/phy/index.rst
index 69ba1216de72..cc7ded8b969c 100644
--- a/Documentation/driver-api/phy/index.rst
+++ b/Documentation/driver-api/phy/index.rst
@@ -7,6 +7,7 @@ Generic PHY Framework
.. toctree::
phy
+ qoriq
samsung-usb2
.. only:: subproject and html
diff --git a/Documentation/driver-api/phy/qoriq.rst b/Documentation/driver-api/phy/qoriq.rst
new file mode 100644
index 000000000000..ea60fb75a295
--- /dev/null
+++ b/Documentation/driver-api/phy/qoriq.rst
@@ -0,0 +1,91 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+============
+QorIQ SerDes
+============
+
+Using this phy
+--------------
+
+The general order of calls should be::
+
+ [devm_][of_]phy_get()
+ phy_init()
+ phy_power_on()
+ phy_set_mode[_ext]()
+ ...
+ phy_power_off()
+ phy_exit()
+ [[of_]phy_put()]
+
+:c:func:`phy_get` just gets (or creates) a new :c:type:`phy` with the lanes
+described in the phandle. :c:func:`phy_init` is what actually reserves the
+lanes for use. Unlike some other drivers, when the phy is created, there is no
+default protocol. :c:func:`phy_set_mode <phy_set_mode_ext>` must be called in
+order to set the protocol.
+
+Supporting SoCs
+---------------
+
+Each new SoC needs a :c:type:`struct qs_conf <qs_conf>` for each SerDes. The
+most important member is `modes`, which is an array of :c:type:`struct qs_mode
+<qs_mode>`. Each "mode" represents a configuration which can be programmed into
+a protocol control register. Modes can support multiple lanes (such for PCIe x2
+or x4), as well as multiple protocols (such as SGMII and 1000Base-KX). There
+are several helper macros to make configuring each mode easier. It is important
+that the list of modes is complete, even if not all protocols are supported.
+This lets the driver know which lanes are available, and which have been
+configured by the RCW.
+
+If a protocol is missing, add it to :c:type:`enum qs_protocol <qs_protocol>`,
+and to ``UNSUPPORTED_PROTOS``. If the PCCR shifts/masks for your protocol are
+missing, you will need to add them to :c:func:`qs_proto_mode_mask` and
+:c:func:`qs_proto_mode_shift`.
+
+For example, the configuration for SerDes1 of the LS1046A is::
+
+ static const struct qs_mode ls1046a_modes1[] = {
+ CONF_SINGLE(1, PCIE, 0x0, 1, 0b001),
+ CONF_1000BASEKX(0, 0x8, 0, 0b001),
+ CONF_SGMII25KX(1, 0x8, 1, 0b001),
+ CONF_SGMII25KX(2, 0x8, 2, 0b001),
+ CONF_SGMII25KX(3, 0x8, 3, 0b001),
+ CONF_SINGLE(1, QSGMII, 0x9, 2, 0b001),
+ CONF_XFI(2, 0xB, 0, 0b010),
+ CONF_XFI(3, 0xB, 1, 0b001),
+ };
+
+ static const struct qs_conf ls1046a_conf1 = {
+ .modes = ls1046a_modes1,
+ .mode_count = ARRAY_SIZE(ls1046a_modes1),
+ .lanes = 4,
+ .endian = REGMAP_ENDIAN_BIG,
+ };
+
+There is an additional set of configuration for SerDes2, which supports a
+different set of modes. Both configurations should be added to the match table::
+
+ { .compatible = "fsl,ls1046-serdes-1", .data = &ls1046a_conf1 },
+ { .compatible = "fsl,ls1046-serdes-2", .data = &ls1046a_conf2 },
+
+Supporting Protocols
+--------------------
+
+Each protocol is a combination of values which must be programmed into the lane
+registers. To add a new protocol, first add it to :c:type:`enum qs_protocol
+<qs_protocol>`. If it is in ``UNSUPPORTED_PROTOS``, remove it. Add a new entry to
+`qs_proto_params`, and populate the appropriate fields. You may need to add
+some new members to support new fields. Modify `qs_lookup_proto` to map the
+:c:type:`enum phy_mode <phy_mode>` to :c:type:`enum qs_protocol <qs_protocol>`.
+Ensure that :c:func:`qs_proto_mode_mask` and :c:func:`qs_proto_mode_shift` have
+been updated with support for your protocol.
+
+You may need to modify :c:func:`qs_set_mode` in order to support your procotol.
+This can happen when you have added members to :c:type:`struct qs_proto_params
+<qs_proto_params>`. It can also happen if you have specific clocking
+requirements, or protocol-specific registers to program.
+
+Internal API Reference
+----------------------
+
+.. kernel-doc:: drivers/phy/freescale/phy-qoriq.c
diff --git a/MAINTAINERS b/MAINTAINERS
index ca95b1833b97..ef65e2acdb48 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7977,6 +7977,12 @@ F: drivers/ptp/ptp_qoriq.c
F: drivers/ptp/ptp_qoriq_debugfs.c
F: include/linux/fsl/ptp_qoriq.h
+FREESCALE QORIQ SERDES DRIVER
+M: Sean Anderson <sean.anderson@seco.com>
+S: Maintained
+F: Documentation/driver-api/phy/qoriq.rst
+F: drivers/phy/freescale/phy-qoriq.c
+
FREESCALE QUAD SPI DRIVER
M: Han Xu <han.xu@nxp.com>
L: linux-spi@vger.kernel.org
diff --git a/drivers/phy/freescale/Kconfig b/drivers/phy/freescale/Kconfig
index f9c54cd02036..c65dbcc58565 100644
--- a/drivers/phy/freescale/Kconfig
+++ b/drivers/phy/freescale/Kconfig
@@ -38,3 +38,22 @@ config PHY_FSL_LYNX_28G
found on NXP's Layerscape platforms such as LX2160A.
Used to change the protocol running on SerDes lanes at runtime.
Only useful for a restricted set of Ethernet protocols.
+
+config PHY_QORIQ
+ tristate "QorIQ SerDes support"
+ select GENERIC_PHY
+ select REGMAP_MMIO
+ help
+ This adds support for the "SerDes" devices found on various QorIQ
+ SoCs. There may be up to four SerDes devices on each SoC, and each
+ device supports up to eight lanes. The SerDes is configured by
+ default by the RCW, but this module is necessary in order to support
+ dynamic reconfiguration (such as to support 1G and 10G ethernet on
+ the same interface). The hardware supports a variety of protocols,
+ including Ethernet, SATA, PCIe, and more exotic links such as
+ Interlaken and Aurora. This driver only supports Ethernet, but it
+ will try not to touch lanes configured for other protocols.
+
+ If you have a QorIQ processor and want to dynamically reconfigure
+ your SerDes, say Y. If this driver is compiled as a module, it will
+ be named phy-qoriq.
diff --git a/drivers/phy/freescale/Makefile b/drivers/phy/freescale/Makefile
index 3518d5dbe8a7..2aca938d9e75 100644
--- a/drivers/phy/freescale/Makefile
+++ b/drivers/phy/freescale/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_PHY_FSL_IMX8MQ_USB) += phy-fsl-imx8mq-usb.o
obj-$(CONFIG_PHY_MIXEL_MIPI_DPHY) += phy-fsl-imx8-mipi-dphy.o
obj-$(CONFIG_PHY_FSL_IMX8M_PCIE) += phy-fsl-imx8m-pcie.o
obj-$(CONFIG_PHY_FSL_LYNX_28G) += phy-fsl-lynx-28g.o
+obj-$(CONFIG_PHY_QORIQ) += phy-qoriq.o
diff --git a/drivers/phy/freescale/phy-qoriq.c b/drivers/phy/freescale/phy-qoriq.c
new file mode 100644
index 000000000000..6edd770a4c4f
--- /dev/null
+++ b/drivers/phy/freescale/phy-qoriq.c
@@ -0,0 +1,1441 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2022 Sean Anderson <sean.anderson@seco.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/math64.h>
+#include <linux/platform_device.h>
+#include <linux/phy.h>
+#include <linux/phy/phy.h>
+#include <linux/regmap.h>
+#include <linux/units.h>
+
+#define PLL_STRIDE 0x20
+#define PLLa(a, off) ((a) * PLL_STRIDE + (off))
+#define PLLaRSTCTL(a) PLLa(a, 0x00)
+#define PLLaCR0(a) PLLa(a, 0x04)
+
+#define PLLaRSTCTL_RSTREQ BIT(31)
+#define PLLaRSTCTL_RST_DONE BIT(30)
+#define PLLaRSTCTL_RST_ERR BIT(29)
+#define PLLaRSTCTL_PLLRST_B BIT(7)
+#define PLLaRSTCTL_SDRST_B BIT(6)
+#define PLLaRSTCTL_SDEN BIT(5)
+
+#define PLLaCR0_POFF BIT(31)
+#define PLLaCR0_RFCLK_SEL GENMASK(30, 28)
+#define PLLaCR0_PLL_LCK BIT(23)
+#define PLLaCR0_FRATE_SEL GENMASK(19, 16)
+#define PLLaCR0_DLYDIV_SEL GENMASK(1, 0)
+
+#define PCCR_BASE 0x200
+#define PCCR_STRIDE 0x4
+#define PCCRn(n) (PCCR_BASE + n * PCCR_STRIDE)
+
+#define PCCR0_PEXa_MASK GENMASK(2, 0)
+#define PCCR0_PEXa_SHIFT(a) (28 - (a) * 4)
+
+#define PCCR2_SATAa_MASK GENMASK(2, 0)
+#define PCCR2_SATAa_SHIFT(a) (28 - (a) * 4)
+
+#define PCCR8_SGMIIa_KX(a) BIT(31 - ((a) * 4))
+#define PCCR8_SGMIIa_MASK GENMASK(2, 0)
+#define PCCR8_SGMIIa_SHIFT(a) (28 - (a) * 4)
+
+#define PCCR9_QSGMIIa_MASK GENMASK(2, 0)
+#define PCCR9_QSGMIIa_SHIFT(a) (28 - (a) * 4)
+
+#define PCCRB_XFIa_MASK GENMASK(2, 0)
+#define PCCRB_XFIa_SHIFT(a) (28 - (a) * 4)
+
+#define LANE_BASE 0x800
+#define LANE_STRIDE 0x40
+#define LNm(m, off) (LANE_BASE + (m) * LANE_STRIDE + (off))
+#define LNmGCR0(m) LNm(m, 0x00)
+#define LNmGCR1(m) LNm(m, 0x04)
+#define LNmSSCR0(m) LNm(m, 0x0C)
+#define LNmRECR0(m) LNm(m, 0x10)
+#define LNmRECR1(m) LNm(m, 0x14)
+#define LNmTECR0(m) LNm(m, 0x18)
+#define LNmSSCR1(m) LNm(m, 0x1C)
+#define LNmTTLCR0(m) LNm(m, 0x20)
+
+#define LNmGCR0_RPLL_LES BIT(31)
+#define LNmGCR0_RRAT_SEL GENMASK(29, 28)
+#define LNmGCR0_TPLL_LES BIT(27)
+#define LNmGCR0_TRAT_SEL GENMASK(25, 24)
+#define LNmGCR0_RRST_B BIT(22)
+#define LNmGCR0_TRST_B BIT(21)
+#define LNmGCR0_RX_PD BIT(20)
+#define LNmGCR0_TX_PD BIT(19)
+#define LNmGCR0_IF20BIT_EN BIT(18)
+#define LNmGCR0_FIRST_LANE BIT(16)
+#define LNmGCR0_TTRM_VM_SEL GENMASK(13, 12)
+#define LNmGCR0_PROTS GENMASK(11, 7)
+
+#define LNmGCR0_RAT_SEL_SAME 0b00
+#define LNmGCR0_RAT_SEL_HALF 0b01
+#define LNmGCR0_RAT_SEL_QUARTER 0b10
+#define LNmGCR0_RAT_SEL_DOUBLE 0b11
+
+#define LNmGCR0_PROTS_PCIE 0b00000
+#define LNmGCR0_PROTS_SGMII 0b00001
+#define LNmGCR0_PROTS_SATA 0b00010
+#define LNmGCR0_PROTS_XFI 0b01010
+
+#define LNmGCR1_RDAT_INV BIT(31)
+#define LNmGCR1_TDAT_INV BIT(30)
+#define LNmGCR1_OPAD_CTL BIT(26)
+#define LNmGCR1_REIDL_TH GENMASK(22, 20)
+#define LNmGCR1_REIDL_EX_SEL GENMASK(19, 18)
+#define LNmGCR1_REIDL_ET_SEL GENMASK(17, 16)
+#define LNmGCR1_REIDL_EX_MSB BIT(15)
+#define LNmGCR1_REIDL_ET_MSB BIT(14)
+#define LNmGCR1_REQ_CTL_SNP BIT(13)
+#define LNmGCR1_REQ_CDR_SNP BIT(12)
+#define LNmGCR1_TRSTDIR BIT(7)
+#define LNmGCR1_REQ_BIN_SNP BIT(6)
+#define LNmGCR1_ISLEW_RCTL GENMASK(5, 4)
+#define LNmGCR1_OSLEW_RCTL GENMASK(1, 0)
+
+#define LNmRECR0_GK2OVD GENMASK(27, 24)
+#define LNmRECR0_GK3OVD GENMASK(19, 16)
+#define LNmRECR0_GK2OVD_EN BIT(15)
+#define LNmRECR0_GK3OVD_EN BIT(16)
+#define LNmRECR0_BASE_WAND GENMASK(11, 10)
+#define LNmRECR0_OSETOVD GENMASK(5, 0)
+
+#define LNmRECR0_BASE_WAND_OFF 0b00
+#define LNmRECR0_BASE_WAND_DEFAULT 0b01
+#define LNmRECR0_BASE_WAND_ALTERNATE 0b10
+#define LNmRECR0_BASE_WAND_OSETOVD 0b11
+
+#define LNmTECR0_TEQ_TYPE GENMASK(29, 28)
+#define LNmTECR0_SGN_PREQ BIT(26)
+#define LNmTECR0_RATIO_PREQ GENMASK(25, 22)
+#define LNmTECR0_SGN_POST1Q BIT(21)
+#define LNmTECR0_RATIO_PST1Q GENMASK(20, 16)
+#define LNmTECR0_ADPT_EQ GENMASK(13, 8)
+#define LNmTECR0_AMP_RED GENMASK(5, 0)
+
+#define LNmTECR0_TEQ_TYPE_NONE 0b00
+#define LNmTECR0_TEQ_TYPE_PRE 0b01
+#define LNmTECR0_TEQ_TYPE_BOTH 0b10
+
+#define LNmTTLCR0_FLT_SEL GENMASK(29, 24)
+
+#define PCS_STRIDE 0x10
+#define CR_STRIDE 0x4
+#define PCSa(a, base, cr) (base + (a) * PCS_STRIDE + (cr) * CR_STRIDE)
+
+#define PCSaCR1_MDEV_PORT GENMASK(31, 27)
+
+#define SGMII_BASE 0x1800
+#define SGMIIaCR1(a) PCSa(a, SGMII_BASE, 1)
+
+#define SGMIIaCR1_SGPCS_EN BIT(11)
+
+#define QSGMII_OFFSET 0x1880
+#define QSGMIIaCR1(a) PCSa(a, QSGMII_BASE, 1)
+
+#define XFI_OFFSET 0x1980
+#define XFIaCR1(a) PCSa(a, XFI_BASE, 1)
+
+/* The maximum number of lanes in a single serdes */
+#define MAX_LANES 8
+
+enum qs_protocol {
+ QS_PROTO_UNKNOWN = 0,
+ QS_PROTO_SGMII,
+ QS_PROTO_SGMII25,
+ QS_PROTO_1000BASEKX,
+ QS_PROTO_QSGMII,
+ QS_PROTO_XFI,
+ QS_PROTO_10GKR,
+ QS_PROTO_PCIE, /* Not implemented */
+ QS_PROTO_SATA, /* Not implemented */
+ QS_PROTO_LAST,
+};
+
+static const char qs_proto_str[][16] = {
+ [QS_PROTO_UNKNOWN] = "unknown",
+ [QS_PROTO_SGMII] = "SGMII",
+ [QS_PROTO_SGMII25] = "2.5G SGMII",
+ [QS_PROTO_1000BASEKX] = "1000Base-KX",
+ [QS_PROTO_QSGMII] = "QSGMII",
+ [QS_PROTO_XFI] = "XFI",
+ [QS_PROTO_10GKR] = "10GBase-KR",
+ [QS_PROTO_PCIE] = "PCIe",
+ [QS_PROTO_SATA] = "SATA",
+};
+
+#define PROTO_MASK(proto) BIT(QS_PROTO_##proto)
+#define UNSUPPORTED_PROTOS (PROTO_MASK(SATA) | PROTO_MASK(PCIE))
+
+/**
+ * struct qs_proto_params - Parameters for configuring a protocol
+ * @frate_khz: The PLL rate, in kHz
+ * @rat_sel: The divider to get the line rate
+ * @if20bit: Whether the proto is 20 bits or 10 bits
+ * @prots: Lane protocol select
+ * @reidl_th: Receiver electrical idle detection threshold
+ * @reidl_ex: Exit electrical idle filter
+ * @reidl_et: Enter idle filter
+ * @slew: Slew control
+ * @baseline_wander: Enable baseline wander correction
+ * @gain: Adaptive equalization gain override
+ * @offset_override: Adaptive equalization offset override
+ * @teq: Transmit equalization type (none, precursor, or precursor and
+ * postcursor). The next few values are only used for appropriate
+ * equalization types.
+ * @preq_ratio: Ratio of full swing transition bit to pre-cursor
+ * @postq_ratio: Ratio of full swing transition bit to first post-cursor.
+ * @adpt_eq: Transmitter Adjustments for 8G/10G
+ * @amp_red: Overall TX Amplitude Reduction
+ * @flt_sel: TTL configuration selector
+ */
+struct qs_proto_params {
+ u32 frate_khz;
+ u8 rat_sel;
+ u8 prots;
+ u8 reidl_th;
+ u8 reidl_ex;
+ u8 reidl_et;
+ u8 slew;
+ u8 gain;
+ u8 baseline_wander;
+ u8 offset_override;
+ u8 teq;
+ u8 preq_ratio;
+ u8 postq_ratio;
+ u8 adpt_eq;
+ u8 amp_red;
+ u8 flt_sel;
+ bool if20bit;
+};
+
+static const struct qs_proto_params qs_proto_params[] = {
+ [QS_PROTO_SGMII] = {
+ .frate_khz = 5000000,
+ .rat_sel = LNmGCR0_RAT_SEL_QUARTER,
+ .if20bit = false,
+ .prots = LNmGCR0_PROTS_SGMII,
+ .reidl_th = 0b001,
+ .reidl_ex = 0b011,
+ .reidl_et = 0b100,
+ .slew = 0b01,
+ .gain = 0b1111,
+ .offset_override = 0b0011111,
+ .teq = LNmTECR0_TEQ_TYPE_NONE,
+ .adpt_eq = 0b110000,
+ .amp_red = 0b000110,
+ .flt_sel = 0b111001,
+ },
+ [QS_PROTO_1000BASEKX] = {
+ .frate_khz = 5000000,
+ .rat_sel = LNmGCR0_RAT_SEL_QUARTER,
+ .if20bit = false,
+ .prots = LNmGCR0_PROTS_SGMII,
+ .slew = 0b01,
+ .gain = 0b1111,
+ .offset_override = 0b0011111,
+ .teq = LNmTECR0_TEQ_TYPE_NONE,
+ .adpt_eq = 0b110000,
+ .flt_sel = 0b111001,
+ },
+ [QS_PROTO_SGMII25] = {
+ .frate_khz = 3125000,
+ .rat_sel = LNmGCR0_RAT_SEL_SAME,
+ .if20bit = false,
+ .prots = LNmGCR0_PROTS_SGMII,
+ .slew = 0b10,
+ .offset_override = 0b0011111,
+ .teq = LNmTECR0_TEQ_TYPE_PRE,
+ .postq_ratio = 0b00110,
+ .adpt_eq = 0b110000,
+ },
+ [QS_PROTO_QSGMII] = {
+ .frate_khz = 5000000,
+ .rat_sel = LNmGCR0_RAT_SEL_SAME,
+ .if20bit = true,
+ .prots = LNmGCR0_PROTS_SGMII,
+ .slew = 0b01,
+ .offset_override = 0b0011111,
+ .teq = LNmTECR0_TEQ_TYPE_PRE,
+ .postq_ratio = 0b00110,
+ .adpt_eq = 0b110000,
+ .amp_red = 0b000010,
+ },
+ [QS_PROTO_XFI] = {
+ .frate_khz = 5156250,
+ .rat_sel = LNmGCR0_RAT_SEL_DOUBLE,
+ .if20bit = true,
+ .prots = LNmGCR0_PROTS_XFI,
+ .slew = 0b01,
+ .baseline_wander = LNmRECR0_BASE_WAND_DEFAULT,
+ .offset_override = 0b1011111,
+ .teq = LNmTECR0_TEQ_TYPE_PRE,
+ .postq_ratio = 0b00011,
+ .adpt_eq = 0b110000,
+ .amp_red = 0b000111,
+ },
+ [QS_PROTO_10GKR] = {
+ .frate_khz = 5156250,
+ .rat_sel = LNmGCR0_RAT_SEL_DOUBLE,
+ .prots = LNmGCR0_PROTS_XFI,
+ .slew = 0b01,
+ .baseline_wander = LNmRECR0_BASE_WAND_DEFAULT,
+ .offset_override = 0b1011111,
+ .teq = LNmTECR0_TEQ_TYPE_BOTH,
+ .preq_ratio = 0b0011,
+ .postq_ratio = 0b01100,
+ .adpt_eq = 0b110000,
+ },
+};
+
+/**
+ * struct qs_mode - A single configuration of a protocol controller
+ * @protos: A bitmask of the &enum qs_protocol this mode supports
+ * @lanes: A bitbask of the lanes which will be used when this config is
+ * selected
+ * @pccr: The number of the PCCR which contains this mode
+ * @idx: The index of the protocol controller. For example, SGMIIB would have
+ * index 1.
+ * @cfg: The value to program into the controller to select this mode
+ *
+ * The serdes has multiple protocol controllers which can be each be selected
+ * independently. Depending on their configuration, they may use multiple lanes
+ * at once (e.g. AUI or PCIe x4). Additionally, multiple protocols may be
+ * supported by a single mode (XFI and 10GKR differ only in their protocol
+ * parameters).
+ */
+struct qs_mode {
+ u16 protos;
+ u8 lanes;
+ u8 pccr;
+ u8 idx;
+ u8 cfg;
+};
+
+static_assert(QS_PROTO_LAST - 1 <=
+ sizeof_field(struct qs_mode, protos) * BITS_PER_BYTE);
+static_assert(MAX_LANES <=
+ sizeof_field(struct qs_mode, lanes) * BITS_PER_BYTE);
+
+#define CONF(_lanes, _protos, _pccr, _idx, _cfg) { \
+ .lanes = _lanes, \
+ .protos = _protos, \
+ .pccr = _pccr, \
+ .idx = _idx, \
+ .cfg = _cfg, \
+}
+
+#define CONF_SINGLE(lane, proto, pccr, idx, cfg) \
+ CONF(BIT(lane), PROTO_MASK(proto), pccr, idx, cfg)
+
+#define CONF_1000BASEKX(lane, pccr, idx, cfg) \
+ CONF(BIT(lane), PROTO_MASK(SGMII) | PROTO_MASK(1000BASEKX), \
+ pccr, idx, cfg)
+
+#define CONF_SGMII25(lane, pccr, idx, cfg) \
+ CONF(BIT(lane), PROTO_MASK(SGMII) | PROTO_MASK(SGMII25), \
+ pccr, idx, cfg)
+
+#define CONF_SGMII25KX(lane, pccr, idx, cfg) \
+ CONF(BIT(lane), \
+ PROTO_MASK(SGMII) | PROTO_MASK(1000BASEKX) | PROTO_MASK(SGMII25), \
+ pccr, idx, cfg)
+
+#define CONF_XFI(lane, pccr, idx, cfg) \
+ CONF(BIT(lane), PROTO_MASK(XFI) | PROTO_MASK(10GKR), pccr, idx, cfg)
+
+/**
+ * struct qs_conf - Configuration for a particular serdes
+ * @modes: Valid protocol controller configurations
+ * @mode_count: Number of modes in @modes
+ * @lanes: Number of lanes
+ * @endian: Endianness of the registers
+ */
+struct qs_conf {
+ const struct qs_mode *modes;
+ size_t mode_count;
+ unsigned int lanes;
+ enum regmap_endian endian;
+};
+
+struct qs_priv;
+
+/**
+ * struct qs_clk - Driver data for the PLLs
+ * @hw: The clock hardware
+ * @serdes: The parent serdes
+ * @idx: Which PLL this clock is for
+ */
+struct qs_clk {
+ struct clk_hw hw;
+ struct qs_priv *serdes;
+ unsigned int idx;
+};
+
+struct qs_clk *qs_clk_hw_to_priv(struct clk_hw *hw)
+{
+ return container_of(hw, struct qs_clk, hw);
+}
+
+/**
+ * struct qs_priv - Driver data for the serdes
+ * @lock: A lock protecting "common" registers in @regmap, as well as the
+ * members of this struct. Lane-specific registers are protected by the
+ * phy's lock. PLL registers are protected by the clock's lock.
+ * @pll: The PLL clocks
+ * @ref: The reference clocks for the PLLs
+ * @dev: The serdes device
+ * @regmap: The backing regmap
+ * @conf: The configuration for this serdes
+ * @used_lanes: Bitmap of the lanes currently used by phys
+ * @groups: List of the created groups
+ */
+struct qs_priv {
+ struct mutex lock;
+ struct qs_clk pll[2];
+ struct clk *ref[2];
+ struct device *dev;
+ struct regmap *regmap;
+ const struct qs_conf *conf;
+ unsigned int used_lanes;
+ struct list_head groups;
+};
+
+/**
+ * struct qs_group - Driver data for a group of lanes
+ * @groups: List of other groups; protected by @serdes->lock.
+ * @phy: The associated phy
+ * @serdes: The parent serdes
+ * @pll: The currently-used pll
+ * @first_lane: The first lane in the group
+ * @last_lane: The last lane in the group
+ * @proto: The currently-configured protocol
+ * @users: Number of current users; protected by @serdes->lock.
+ */
+struct qs_group {
+ struct list_head groups;
+ struct phy *phy;
+ struct qs_priv *serdes;
+ struct clk *pll;
+ unsigned int first_lane;
+ unsigned int last_lane;
+ enum qs_protocol proto;
+ unsigned int users;
+};
+
+static u32 qs_read(struct qs_priv *serdes, u32 reg)
+{
+ unsigned int ret = 0;
+
+ WARN_ON_ONCE(regmap_read(serdes->regmap, reg, &ret));
+ return ret;
+}
+
+static void qs_write(struct qs_priv *serdes, u32 val, u32 reg)
+{
+ WARN_ON_ONCE(regmap_write(serdes->regmap, reg, val));
+}
+
+/* XXX: The output rate is in kHz to avoid overflow on 32-bit arches */
+
+static void qs_pll_disable(struct clk_hw *hw)
+{
+ struct qs_clk *clk = qs_clk_hw_to_priv(hw);
+ struct qs_priv *serdes = clk->serdes;
+ u32 rstctl = qs_read(serdes, PLLaRSTCTL(clk->idx));
+
+ dev_dbg(clk->serdes->dev, "%s(pll%d)\n", __func__, clk->idx);
+
+ rstctl &= ~PLLaRSTCTL_SDRST_B;
+ qs_write(serdes, rstctl, PLLaRSTCTL(clk->idx));
+ ndelay(50);
+ rstctl &= ~(PLLaRSTCTL_SDEN | PLLaRSTCTL_PLLRST_B);
+ qs_write(serdes, rstctl, PLLaRSTCTL(clk->idx));
+ ndelay(100);
+}
+
+static int qs_pll_enable(struct clk_hw *hw)
+{
+ struct qs_clk *clk = qs_clk_hw_to_priv(hw);
+ struct qs_priv *serdes = clk->serdes;
+ u32 rstctl = qs_read(serdes, PLLaRSTCTL(clk->idx));
+
+ dev_dbg(clk->serdes->dev, "%s(pll%d)\n", __func__, clk->idx);
+
+ rstctl |= PLLaRSTCTL_RSTREQ;
+ qs_write(serdes, rstctl, PLLaRSTCTL(clk->idx));
+
+ rstctl &= ~PLLaRSTCTL_RSTREQ;
+ rstctl |= PLLaRSTCTL_SDEN | PLLaRSTCTL_PLLRST_B | PLLaRSTCTL_SDRST_B;
+ qs_write(serdes, rstctl, PLLaRSTCTL(clk->idx));
+
+ /* TODO: wait for the PLL to lock */
+
+ return 0;
+}
+
+static int qs_pll_is_enabled(struct clk_hw *hw)
+{
+ struct qs_clk *clk = qs_clk_hw_to_priv(hw);
+ struct qs_priv *serdes = clk->serdes;
+ u32 rstctl = qs_read(serdes, PLLaRSTCTL(clk->idx));
+
+ dev_dbg(clk->serdes->dev, "%s(pll%d)\n", __func__, clk->idx);
+
+ return rstctl & PLLaRSTCTL_RST_DONE && !(rstctl & PLLaRSTCTL_RST_ERR);
+}
+
+static const u32 rfclk_sel_map[8] = {
+ [0b000] = 100000000,
+ [0b001] = 125000000,
+ [0b010] = 156250000,
+ [0b011] = 150000000,
+};
+
+/**
+ * qs_rfclk_to_sel() - Convert a reference clock rate to a selector
+ * @rate: The reference clock rate
+ *
+ * To allow for some variation in the reference clock rate, up to 100ppm of
+ * error is allowed.
+ *
+ * Return: An appropriate selector for @rate, or -%EINVAL.
+ */
+static int qs_rfclk_to_sel(u32 rate)
+{
+ int ret;
+
+ for (ret = 0; ret < ARRAY_SIZE(rfclk_sel_map); ret++) {
+ u32 rfclk_rate = rfclk_sel_map[ret];
+ /* Allow an error of 100ppm */
+ u32 error = rfclk_rate / 10000;
+
+ if (rate > rfclk_rate - error && rate < rfclk_rate + error)
+ return ret;
+ }
+
+ return -EINVAL;
+}
+
+static const u32 frate_sel_map[16] = {
+ [0b0000] = 5000000,
+ [0b0101] = 3750000,
+ [0b0110] = 5156250,
+ [0b0111] = 4000000,
+ [0b1001] = 3125000,
+ [0b1010] = 3000000,
+};
+
+/**
+ * qs_frate_to_sel() - Convert a VCO clock rate to a selector
+ * @rate_khz: The VCO frequency, in kHz
+ *
+ * Return: An appropriate selector for @rate_khz, or -%EINVAL.
+ */
+static int qs_frate_to_sel(u32 rate_khz)
+{
+ int ret;
+
+ for (ret = 0; ret < ARRAY_SIZE(frate_sel_map); ret++)
+ if (frate_sel_map[ret] == rate_khz)
+ return ret;
+
+ return -EINVAL;
+}
+
+static u32 qs_pll_ratio(u32 frate_sel, u32 rfclk_sel)
+{
+ u64 frate;
+ u32 rfclk, error, ratio;
+
+ frate = frate_sel_map[frate_sel] * (u64)HZ_PER_KHZ;
+ rfclk = rfclk_sel_map[rfclk_sel];
+
+ if (!frate || !rfclk)
+ return 0;
+
+ ratio = div_u64_rem(frate, rfclk, &error);
+ if (!error)
+ return ratio;
+ return 0;
+}
+
+static unsigned long qs_pll_recalc_rate(struct clk_hw *hw,
+ unsigned long parent_rate)
+{
+ struct qs_clk *clk = qs_clk_hw_to_priv(hw);
+ struct qs_priv *serdes = clk->serdes;
+ u32 cr0 = qs_read(serdes, PLLaCR0(clk->idx));
+ u32 frate_sel = FIELD_GET(PLLaCR0_FRATE_SEL, cr0);
+ u32 rfclk_sel = FIELD_GET(PLLaCR0_RFCLK_SEL, cr0);
+ unsigned long ret;
+
+ dev_dbg(clk->serdes->dev, "%s(pll%d, %lu)\n", __func__,
+ clk->idx, parent_rate);
+
+ ret = mult_frac(parent_rate, qs_pll_ratio(frate_sel, rfclk_sel),
+ HZ_PER_KHZ);
+ return ret;
+}
+
+static long qs_pll_round_rate(struct clk_hw *hw, unsigned long rate_khz,
+ unsigned long *parent_rate)
+{
+ int frate_sel, rfclk_sel;
+ struct qs_clk *clk = qs_clk_hw_to_priv(hw);
+ u32 ratio;
+
+ dev_dbg(clk->serdes->dev, "%s(pll%d, %lu, %lu)\n", __func__,
+ clk->idx, rate_khz, *parent_rate);
+
+ frate_sel = qs_frate_to_sel(rate_khz);
+ if (frate_sel < 0)
+ return frate_sel;
+
+ rfclk_sel = qs_rfclk_to_sel(*parent_rate);
+ if (rfclk_sel >= 0) {
+ ratio = qs_pll_ratio(frate_sel, rfclk_sel);
+ if (ratio)
+ return mult_frac(*parent_rate, ratio, HZ_PER_KHZ);
+ }
+
+ for (rfclk_sel = 0;
+ rfclk_sel < ARRAY_SIZE(rfclk_sel_map);
+ rfclk_sel++) {
+ ratio = qs_pll_ratio(frate_sel, rfclk_sel);
+ if (ratio) {
+ *parent_rate = rfclk_sel_map[rfclk_sel];
+ return mult_frac(*parent_rate, ratio, HZ_PER_KHZ);
+ }
+ }
+
+ return -EINVAL;
+}
+
+static int qs_pll_set_rate(struct clk_hw *hw, unsigned long rate_khz,
+ unsigned long parent_rate)
+{
+ int frate_sel, rfclk_sel, ret;
+ struct qs_clk *clk = qs_clk_hw_to_priv(hw);
+ struct qs_priv *serdes = clk->serdes;
+ u32 ratio, cr0 = qs_read(serdes, PLLaCR0(clk->idx));
+
+ dev_dbg(clk->serdes->dev, "%s(pll%d, %lu, %lu)\n", __func__,
+ clk->idx, rate_khz, parent_rate);
+
+ frate_sel = qs_frate_to_sel(rate_khz);
+ if (frate_sel < 0)
+ return frate_sel;
+
+ /* First try the existing rate */
+ rfclk_sel = qs_rfclk_to_sel(parent_rate);
+ if (rfclk_sel >= 0) {
+ ratio = qs_pll_ratio(frate_sel, rfclk_sel);
+ if (ratio)
+ goto got_rfclk;
+ }
+
+ for (rfclk_sel = 0;
+ rfclk_sel < ARRAY_SIZE(rfclk_sel_map);
+ rfclk_sel++) {
+ ratio = qs_pll_ratio(frate_sel, rfclk_sel);
+ if (ratio) {
+ ret = clk_set_rate(serdes->ref[clk->idx],
+ rfclk_sel_map[rfclk_sel]);
+ if (!ret)
+ goto got_rfclk;
+ }
+ }
+
+ return ret;
+
+got_rfclk:
+ cr0 &= ~(PLLaCR0_RFCLK_SEL | PLLaCR0_FRATE_SEL);
+ cr0 |= FIELD_PREP(PLLaCR0_RFCLK_SEL, rfclk_sel);
+ cr0 |= FIELD_PREP(PLLaCR0_FRATE_SEL, frate_sel);
+ qs_write(serdes, cr0, PLLaCR0(clk->idx));
+ return 0;
+}
+
+static const struct clk_ops qs_pll_clk_ops = {
+ .enable = qs_pll_enable,
+ .disable = qs_pll_disable,
+ .is_enabled = qs_pll_is_enabled,
+ .recalc_rate = qs_pll_recalc_rate,
+ .round_rate = qs_pll_round_rate,
+ .set_rate = qs_pll_set_rate,
+};
+
+/**
+ * qs_lane_bitmap() - Get a bitmap for a group of lanes
+ * @group: The group of lanes
+ *
+ * Return: A mask containing all bits between @group->first and @group->last
+ */
+static unsigned int qs_lane_bitmap(struct qs_group *group)
+{
+ if (group->first_lane > group->last_lane)
+ return GENMASK(group->first_lane, group->last_lane);
+ else
+ return GENMASK(group->last_lane, group->first_lane);
+}
+
+static int qs_init(struct phy *phy)
+{
+ int ret = 0;
+ struct qs_group *group = phy_get_drvdata(phy);
+ struct qs_priv *serdes = group->serdes;
+ unsigned int lane_mask = qs_lane_bitmap(group);
+
+ mutex_lock(&serdes->lock);
+ if (serdes->used_lanes & lane_mask)
+ ret = -EBUSY;
+ else
+ serdes->used_lanes |= lane_mask;
+ mutex_unlock(&serdes->lock);
+ return ret;
+}
+
+static int qs_exit(struct phy *phy)
+{
+ struct qs_group *group = phy_get_drvdata(phy);
+ struct qs_priv *serdes = group->serdes;
+
+ clk_disable_unprepare(group->pll);
+ clk_rate_exclusive_put(group->pll);
+ mutex_lock(&serdes->lock);
+ serdes->used_lanes &= ~qs_lane_bitmap(group);
+ mutex_unlock(&serdes->lock);
+ return 0;
+}
+
+/*
+ * This is tricky. If first_lane=1 and last_lane=0, the condition will see 2,
+ * 1, 0. But the loop body will see 1, 0. We do this to avoid underflow. We
+ * can't pull the same trick when incrementing, because then we might have to
+ * start at -1 if (e.g.) first_lane = 0.
+ */
+#define for_range(val, start, end) \
+ for (val = start < end ? start : start + 1; \
+ start < end ? val <= end : val-- > end; \
+ start < end ? val++ : 0)
+#define for_each_lane(lane, group) \
+ for_range(lane, group->first_lane, group->last_lane)
+#define for_each_lane_reverse(lane, group) \
+ for_range(lane, group->last_lane, group->first_lane)
+
+static int qs_power_on(struct phy *phy)
+{
+ int i;
+ struct qs_group *group = phy_get_drvdata(phy);
+ u32 gcr0;
+
+ for_each_lane(i, group) {
+ gcr0 = qs_read(group->serdes, LNmGCR0(i));
+ gcr0 &= ~(LNmGCR0_RX_PD | LNmGCR0_TX_PD);
+ qs_write(group->serdes, gcr0, LNmGCR0(i));
+
+ usleep_range(15, 30);
+ gcr0 |= LNmGCR0_RRST_B | LNmGCR0_TRST_B;
+ qs_write(group->serdes, gcr0, LNmGCR0(i));
+ }
+
+ return 0;
+}
+
+static int qs_power_off(struct phy *phy)
+{
+ int i;
+ struct qs_group *group = phy_get_drvdata(phy);
+ u32 gcr0;
+
+ for_each_lane_reverse(i, group) {
+ gcr0 = qs_read(group->serdes, LNmGCR0(i));
+ gcr0 |= LNmGCR0_RX_PD | LNmGCR0_TX_PD;
+ gcr0 &= ~(LNmGCR0_RRST_B | LNmGCR0_TRST_B);
+ qs_write(group->serdes, gcr0, LNmGCR0(i));
+ }
+
+ return 0;
+}
+
+/**
+ * qs_lookup_proto() - Convert a phy-subsystem mode to a protocol
+ * @mode: The mode to convert
+ * @submode: The submode of @mode
+ *
+ * Return: A corresponding serdes-specific mode
+ */
+static enum qs_protocol qs_lookup_proto(enum phy_mode mode, int submode)
+{
+ switch (mode) {
+ case PHY_MODE_ETHERNET:
+ switch (submode) {
+ case PHY_INTERFACE_MODE_SGMII:
+ case PHY_INTERFACE_MODE_1000BASEX:
+ return QS_PROTO_SGMII;
+ case PHY_INTERFACE_MODE_2500BASEX:
+ return QS_PROTO_SGMII;
+ case PHY_INTERFACE_MODE_QSGMII:
+ return QS_PROTO_QSGMII;
+ case PHY_INTERFACE_MODE_XGMII:
+ case PHY_INTERFACE_MODE_10GBASER:
+ return QS_PROTO_XFI;
+ case PHY_INTERFACE_MODE_10GKR:
+ return QS_PROTO_10GKR;
+ default:
+ return QS_PROTO_UNKNOWN;
+ }
+ /* Not implemented (yet) */
+ case PHY_MODE_PCIE:
+ case PHY_MODE_SATA:
+ default:
+ return QS_PROTO_UNKNOWN;
+ }
+}
+
+/**
+ * qs_lookup_mode() - Get the mode for a group/protocol combination
+ * @group: The group of lanes to use
+ * @proto: The protocol to use
+ *
+ * Return: An appropriate mode to use, or %NULL if none match.
+ */
+static const struct qs_mode *qs_lookup_mode(struct qs_group *group,
+ enum qs_protocol proto)
+{
+ int i;
+ const struct qs_conf *conf = group->serdes->conf;
+
+ for (i = 0; i < conf->mode_count; i++) {
+ const struct qs_mode *mode = &conf->modes[i];
+
+ if (BIT(proto) & mode->protos &&
+ qs_lane_bitmap(group) == mode->lanes)
+ return mode;
+ }
+
+ return NULL;
+}
+
+static int qs_validate(struct phy *phy, enum phy_mode phy_mode, int submode,
+ union phy_configure_opts *opts)
+{
+ enum qs_protocol proto;
+ struct qs_group *group = phy_get_drvdata(phy);
+ const struct qs_mode *mode;
+
+ proto = qs_lookup_proto(phy_mode, submode);
+ if (proto == QS_PROTO_UNKNOWN)
+ return -EINVAL;
+
+ /* Nothing to do */
+ if (proto == group->proto)
+ return 0;
+
+ mode = qs_lookup_mode(group, proto);
+ if (!mode)
+ return -EINVAL;
+
+ return 0;
+}
+
+/**
+ * qs_proto_mode_mask() - Get the mask for a PCCR config
+ * @mode: The mode to use
+ *
+ * Return: The mask, shifted down to the lsb.
+ */
+static u32 qs_proto_mode_mask(const struct qs_mode *mode)
+{
+ switch (mode->pccr) {
+ case 0x0:
+ if (mode->protos & PROTO_MASK(PCIE))
+ return PCCR0_PEXa_MASK;
+ break;
+ case 0x2:
+ if (mode->protos & PROTO_MASK(SATA))
+ return PCCR2_SATAa_MASK;
+ break;
+ case 0x8:
+ if (mode->protos & PROTO_MASK(SGMII))
+ return PCCR8_SGMIIa_MASK;
+ break;
+ case 0x9:
+ if (mode->protos & PROTO_MASK(QSGMII))
+ return PCCR9_QSGMIIa_MASK;
+ break;
+ case 0xB:
+ if (mode->protos & PROTO_MASK(XFI))
+ return PCCRB_XFIa_MASK;
+ break;
+ }
+ pr_debug("unknown mode PCCR%X %s%c\n", mode->pccr,
+ qs_proto_str[mode->protos], 'A' + mode->idx);
+ return 0;
+}
+
+/**
+ * qs_proto_mode_shift() - Get the shift for a PCCR config
+ * @mode: The mode to use
+ *
+ * Return: The amount of bits to shift the mask.
+ */
+static u32 qs_proto_mode_shift(const struct qs_mode *mode)
+{
+ switch (mode->pccr) {
+ case 0x0:
+ if (mode->protos & PROTO_MASK(PCIE))
+ return PCCR0_PEXa_SHIFT(mode->idx);
+ break;
+ case 0x2:
+ if (mode->protos & PROTO_MASK(SATA))
+ return PCCR2_SATAa_SHIFT(mode->idx);
+ break;
+ case 0x8:
+ if (mode->protos & PROTO_MASK(SGMII))
+ return PCCR8_SGMIIa_SHIFT(mode->idx);
+ break;
+ case 0x9:
+ if (mode->protos & PROTO_MASK(QSGMII))
+ return PCCR9_QSGMIIa_SHIFT(mode->idx);
+ break;
+ case 0xB:
+ if (mode->protos & PROTO_MASK(XFI))
+ return PCCRB_XFIa_SHIFT(mode->idx);
+ break;
+ }
+ pr_debug("unknown mode PCCR%X %s%c\n", mode->pccr,
+ qs_proto_str[mode->protos], 'A' + mode->idx);
+ return 0;
+}
+
+/**
+ * qs_proto_mode_get() - Get the current config for a PCCR mode
+ * @mode: The mode to use
+ * @pccr: The current value of the PCCR
+ *
+ * Return: The current value of the PCCR config for this mode
+ */
+static u32 qs_proto_mode_get(const struct qs_mode *mode, u32 pccr)
+{
+ return (pccr >> qs_proto_mode_shift(mode)) & qs_proto_mode_mask(mode);
+}
+
+/**
+ * qs_proto_mode_prep() - Configure a PCCR for a mode
+ * @mode: The mode to configure
+ * @pccr: The current value of the PCCR
+ * @cfg: The config to program
+ *
+ * Return: The new value for the PCCR
+ */
+static u32 qs_proto_mode_prep(const struct qs_mode *mode, u32 pccr, u32 cfg)
+{
+ u32 shift = qs_proto_mode_shift(mode);
+
+ pccr &= ~(qs_proto_mode_mask(mode) << shift);
+ return pccr | cfg << shift;
+}
+
+#define abs_diff(a, b) ({ \
+ typeof(a) _a = (a); \
+ typeof(b) _b = (b); \
+ _a > _b ? _a - _b : _b - _a; \
+})
+
+static int qs_set_mode(struct phy *phy, enum phy_mode phy_mode, int submode)
+{
+ enum qs_protocol proto;
+ const struct qs_proto_params *params;
+ const struct qs_mode *old_mode = NULL, *new_mode;
+ int i, pll, ret;
+ struct qs_group *group = phy_get_drvdata(phy);
+ struct qs_priv *serdes = group->serdes;
+ u32 mask, tmp;
+ u32 gcr0 = 0, gcr1 = 0, recr0 = 0, tecr0 = 0;
+ u32 gcr0_mask = 0, gcr1_mask = 0, recr0_mask = 0, tecr0_mask = 0;
+
+ proto = qs_lookup_proto(phy_mode, submode);
+ if (proto == QS_PROTO_UNKNOWN) {
+ dev_dbg(&phy->dev, "unknown mode/submode %d/%d\n",
+ phy_mode, submode);
+ return -EINVAL;
+ }
+
+ /* Nothing to do */
+ if (proto == group->proto)
+ return 0;
+
+ new_mode = qs_lookup_mode(group, proto);
+ if (!new_mode) {
+ dev_dbg(&phy->dev, "could not find mode for %s on lanes %u to %u\n",
+ qs_proto_str[proto], group->first_lane,
+ group->last_lane);
+ return -EINVAL;
+ }
+
+ if (group->proto != QS_PROTO_UNKNOWN) {
+ old_mode = qs_lookup_mode(group, group->proto);
+ if (!old_mode) {
+ dev_err(&phy->dev, "could not find mode for %s\n",
+ qs_proto_str[group->proto]);
+ return -EBUSY;
+ }
+ }
+
+ clk_disable_unprepare(group->pll);
+ clk_rate_exclusive_put(group->pll);
+ group->pll = NULL;
+
+ /* First, try to use a PLL which already has the correct rate */
+ params = &qs_proto_params[proto];
+ for (pll = 0; pll < ARRAY_SIZE(serdes->pll); pll++) {
+ struct clk *clk = serdes->pll[pll].hw.clk;
+ unsigned long rate = clk_get_rate(clk);
+ unsigned long error = abs_diff(rate, params->frate_khz);
+
+ dev_dbg(&phy->dev, "pll%d has rate %lu\n", pll, rate);
+ /* Accept up to 100ppm deviation */
+ if ((!error || params->frate_khz / error > 10000) &&
+ !clk_set_rate_exclusive(clk, rate))
+ goto got_pll;
+ /* Someone else got a different rate first */
+ }
+
+ /* If neither PLL has the right rate, try setting it */
+ for (pll = 0; pll < 2; pll++) {
+ ret = clk_set_rate_exclusive(serdes->pll[pll].hw.clk,
+ params->frate_khz);
+ if (!ret)
+ goto got_pll;
+ }
+
+ dev_dbg(&phy->dev, "could not get a pll at %ukHz\n",
+ params->frate_khz);
+ return ret;
+
+got_pll:
+ group->pll = serdes->pll[pll].hw.clk;
+ clk_prepare_enable(group->pll);
+
+ gcr0_mask |= LNmGCR0_RRAT_SEL | LNmGCR0_TRAT_SEL;
+ gcr0_mask |= LNmGCR0_RPLL_LES | LNmGCR0_TPLL_LES;
+ gcr0_mask |= LNmGCR0_RRST_B | LNmGCR0_TRST_B;
+ gcr0_mask |= LNmGCR0_RX_PD | LNmGCR0_TX_PD;
+ gcr0_mask |= LNmGCR0_IF20BIT_EN | LNmGCR0_PROTS;
+ gcr0 |= FIELD_PREP(LNmGCR0_RPLL_LES, !pll);
+ gcr0 |= FIELD_PREP(LNmGCR0_TPLL_LES, !pll);
+ gcr0 |= FIELD_PREP(LNmGCR0_RRAT_SEL, params->rat_sel);
+ gcr0 |= FIELD_PREP(LNmGCR0_TRAT_SEL, params->rat_sel);
+ gcr0 |= FIELD_PREP(LNmGCR0_IF20BIT_EN, params->if20bit);
+ gcr0 |= FIELD_PREP(LNmGCR0_PROTS, params->prots);
+
+ gcr1_mask |= LNmGCR1_RDAT_INV | LNmGCR1_TDAT_INV;
+ gcr1_mask |= LNmGCR1_OPAD_CTL | LNmGCR1_REIDL_TH;
+ gcr1_mask |= LNmGCR1_REIDL_EX_SEL | LNmGCR1_REIDL_ET_SEL;
+ gcr1_mask |= LNmGCR1_REIDL_EX_MSB | LNmGCR1_REIDL_ET_MSB;
+ gcr1_mask |= LNmGCR1_REQ_CTL_SNP | LNmGCR1_REQ_CDR_SNP;
+ gcr1_mask |= LNmGCR1_TRSTDIR | LNmGCR1_REQ_BIN_SNP;
+ gcr1_mask |= LNmGCR1_ISLEW_RCTL | LNmGCR1_OSLEW_RCTL;
+ gcr1 |= FIELD_PREP(LNmGCR1_REIDL_TH, params->reidl_th);
+ gcr1 |= FIELD_PREP(LNmGCR1_REIDL_EX_SEL, params->reidl_ex & 3);
+ gcr1 |= FIELD_PREP(LNmGCR1_REIDL_ET_SEL, params->reidl_et & 3);
+ gcr1 |= FIELD_PREP(LNmGCR1_REIDL_EX_MSB, params->reidl_ex >> 2);
+ gcr1 |= FIELD_PREP(LNmGCR1_REIDL_ET_MSB, params->reidl_et >> 2);
+ gcr1 |= FIELD_PREP(LNmGCR1_TRSTDIR,
+ group->first_lane > group->last_lane);
+ gcr1 |= FIELD_PREP(LNmGCR1_ISLEW_RCTL, params->slew);
+ gcr1 |= FIELD_PREP(LNmGCR1_OSLEW_RCTL, params->slew);
+
+ recr0_mask |= LNmRECR0_GK2OVD | LNmRECR0_GK3OVD;
+ recr0_mask |= LNmRECR0_GK2OVD_EN | LNmRECR0_GK3OVD_EN;
+ recr0_mask |= LNmRECR0_BASE_WAND | LNmRECR0_OSETOVD;
+ if (params->gain) {
+ recr0 |= FIELD_PREP(LNmRECR0_GK2OVD, params->gain);
+ recr0 |= FIELD_PREP(LNmRECR0_GK3OVD, params->gain);
+ recr0 |= LNmRECR0_GK2OVD_EN | LNmRECR0_GK3OVD_EN;
+ }
+ recr0 |= FIELD_PREP(LNmRECR0_BASE_WAND, params->baseline_wander);
+ recr0 |= FIELD_PREP(LNmRECR0_OSETOVD, params->offset_override);
+
+ tecr0_mask |= LNmTECR0_TEQ_TYPE;
+ tecr0_mask |= LNmTECR0_SGN_PREQ | LNmTECR0_RATIO_PREQ;
+ tecr0_mask |= LNmTECR0_SGN_POST1Q | LNmTECR0_RATIO_PST1Q;
+ tecr0_mask |= LNmTECR0_ADPT_EQ | LNmTECR0_AMP_RED;
+ tecr0 |= FIELD_PREP(LNmTECR0_TEQ_TYPE, params->teq);
+ if (params->preq_ratio) {
+ tecr0 |= FIELD_PREP(LNmTECR0_SGN_PREQ, 1);
+ tecr0 |= FIELD_PREP(LNmTECR0_RATIO_PREQ, params->preq_ratio);
+ }
+ if (params->postq_ratio) {
+ tecr0 |= FIELD_PREP(LNmTECR0_SGN_POST1Q, 1);
+ tecr0 |= FIELD_PREP(LNmTECR0_RATIO_PST1Q, params->postq_ratio);
+ }
+ tecr0 |= FIELD_PREP(LNmTECR0_ADPT_EQ, params->adpt_eq);
+ tecr0 |= FIELD_PREP(LNmTECR0_AMP_RED, params->amp_red);
+
+ mutex_lock(&serdes->lock);
+
+ /* Disable the old controller */
+ if (old_mode) {
+ tmp = qs_read(serdes, PCCRn(old_mode->pccr));
+ tmp = qs_proto_mode_prep(old_mode, tmp, 0);
+ qs_write(serdes, tmp, PCCRn(old_mode->pccr));
+
+ if (old_mode->protos & PROTO_MASK(SGMII)) {
+ tmp = qs_read(serdes, SGMIIaCR1(old_mode->idx));
+ tmp &= SGMIIaCR1_SGPCS_EN;
+ qs_write(serdes, tmp, SGMIIaCR1(old_mode->idx));
+ }
+ }
+
+ for_each_lane_reverse(i, group) {
+ tmp = qs_read(serdes, LNmGCR0(i));
+ tmp &= ~(LNmGCR0_RRST_B | LNmGCR0_TRST_B);
+ qs_write(serdes, tmp, LNmGCR0(i));
+ ndelay(50);
+
+ tmp &= ~gcr0_mask;
+ tmp |= gcr0;
+ tmp |= FIELD_PREP(LNmGCR0_FIRST_LANE, i == group->first_lane);
+ qs_write(serdes, tmp, LNmGCR0(i));
+
+ tmp = qs_read(serdes, LNmGCR1(i));
+ tmp &= ~gcr1_mask;
+ tmp |= gcr1;
+ qs_write(serdes, tmp, LNmGCR1(i));
+
+ tmp = qs_read(serdes, LNmRECR0(i));
+ tmp &= ~recr0_mask;
+ tmp |= recr0;
+ qs_write(serdes, tmp, LNmRECR0(i));
+
+ tmp = qs_read(serdes, LNmTECR0(i));
+ tmp &= ~tecr0_mask;
+ tmp |= tecr0;
+ qs_write(serdes, tmp, LNmTECR0(i));
+
+ tmp = qs_read(serdes, LNmTTLCR0(i));
+ tmp &= ~LNmTTLCR0_FLT_SEL;
+ tmp |= FIELD_PREP(LNmTTLCR0_FLT_SEL, params->flt_sel);
+ qs_write(serdes, tmp, LNmTTLCR0(i));
+
+ ndelay(120);
+ tmp = qs_read(serdes, LNmGCR0(i));
+ tmp |= LNmGCR0_RRST_B | LNmGCR0_TRST_B;
+ qs_write(serdes, tmp, LNmGCR0(i));
+ }
+
+ if (proto == QS_PROTO_1000BASEKX) {
+ /* FIXME: this races with clock updates */
+ tmp = qs_read(serdes, PLLaCR0(pll));
+ tmp &= ~PLLaCR0_DLYDIV_SEL;
+ tmp |= FIELD_PREP(PLLaCR0_DLYDIV_SEL, 1);
+ qs_write(serdes, tmp, PLLaCR0(pll));
+ }
+
+ /* Enable the new controller */
+ tmp = qs_read(serdes, PCCRn(new_mode->pccr));
+ tmp = qs_proto_mode_prep(new_mode, tmp, new_mode->cfg);
+ if (new_mode->protos & PROTO_MASK(1000BASEKX)) {
+ if (new_mode->pccr == 8) {
+ mask = PCCR8_SGMIIa_KX(new_mode->idx);
+ } else {
+ dev_err(&phy->dev, "PCCR%X doesn't have a KX bit\n",
+ new_mode->pccr);
+ mask = 0;
+ }
+
+ if (proto == QS_PROTO_1000BASEKX)
+ tmp |= mask;
+ else
+ tmp &= ~mask;
+ }
+ qs_write(serdes, tmp, PCCRn(new_mode->pccr));
+
+ if (new_mode->protos & PROTO_MASK(SGMII)) {
+ tmp = qs_read(serdes, SGMIIaCR1(new_mode->idx));
+ tmp |= SGMIIaCR1_SGPCS_EN;
+ qs_write(serdes, tmp, SGMIIaCR1(new_mode->idx));
+ }
+
+ mutex_unlock(&serdes->lock);
+
+ group->proto = proto;
+ dev_dbg(&phy->dev, "set mode to %s on lanes %u to %u\n",
+ qs_proto_str[proto], group->first_lane, group->last_lane);
+ return 0;
+}
+
+static void qs_release(struct phy *phy)
+{
+ struct qs_group *group = phy_get_drvdata(phy);
+ struct qs_priv *serdes = group->serdes;
+
+ mutex_lock(&serdes->lock);
+ if (--group->users) {
+ mutex_unlock(&serdes->lock);
+ return;
+ }
+ list_del(&group->groups);
+ mutex_unlock(&serdes->lock);
+
+ phy_destroy(phy);
+ kfree(group);
+}
+
+static const struct phy_ops qs_phy_ops = {
+ .init = qs_init,
+ .exit = qs_exit,
+ .power_on = qs_power_on,
+ .power_off = qs_power_off,
+ .set_mode = qs_set_mode,
+ .validate = qs_validate,
+ .release = qs_release,
+ .owner = THIS_MODULE,
+};
+
+static struct phy *qs_xlate(struct device *dev, struct of_phandle_args *args)
+{
+ struct phy *phy;
+ struct list_head *head;
+ struct qs_group *group;
+ struct qs_priv *serdes = dev_get_drvdata(dev);
+
+ if (args->args_count != 2)
+ return ERR_PTR(-EINVAL);
+
+ mutex_lock(&serdes->lock);
+
+ /* Look for an existing group */
+ list_for_each(head, &serdes->groups) {
+ group = container_of(head, struct qs_group, groups);
+ if (group->first_lane == args->args[0] &&
+ group->last_lane == args->args[1]) {
+ group->users++;
+ return group->phy;
+ }
+ }
+
+ /* None found, create our own */
+ group = kzalloc(sizeof(*group), GFP_KERNEL);
+ if (!group) {
+ mutex_unlock(&serdes->lock);
+ return ERR_PTR(-ENOMEM);
+ }
+
+ group->serdes = serdes;
+ group->first_lane = args->args[0];
+ group->last_lane = args->args[1];
+ group->users = 1;
+ phy = phy_create(dev, NULL, &qs_phy_ops);
+ if (IS_ERR(phy)) {
+ kfree(group);
+ } else {
+ group->phy = phy;
+ phy_set_drvdata(phy, group);
+ list_add(&group->groups, &serdes->groups);
+ }
+
+ mutex_unlock(&serdes->lock);
+ return phy;
+}
+
+static int qs_probe(struct platform_device *pdev)
+{
+ bool grabbed_clocks = false;
+ int i, ret;
+ struct device *dev = &pdev->dev;
+ struct qs_priv *serdes;
+ struct regmap_config regmap_config = {};
+ const struct qs_conf *conf;
+ struct resource *res;
+ void __iomem *base;
+
+ serdes = devm_kzalloc(dev, sizeof(*serdes), GFP_KERNEL);
+ if (!serdes)
+ return -ENOMEM;
+ platform_set_drvdata(pdev, serdes);
+ mutex_init(&serdes->lock);
+ INIT_LIST_HEAD(&serdes->groups);
+ serdes->dev = dev;
+
+ base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+ if (IS_ERR(base)) {
+ ret = PTR_ERR(base);
+ dev_err_probe(dev, ret, "could not get/map registers\n");
+ return ret;
+ }
+
+ conf = device_get_match_data(dev);
+ serdes->conf = conf;
+ regmap_config.reg_bits = 32;
+ regmap_config.reg_stride = 4;
+ regmap_config.val_bits = 32;
+ regmap_config.val_format_endian = conf->endian;
+ regmap_config.max_register = res->end - res->start;
+ regmap_config.disable_locking = true;
+ serdes->regmap = devm_regmap_init_mmio(dev, base, ®map_config);
+ if (IS_ERR(serdes->regmap)) {
+ ret = PTR_ERR(serdes->regmap);
+ dev_err_probe(dev, ret, "could not create regmap\n");
+ return ret;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(serdes->ref); i++) {
+ static const char fmt[] = "ref%d";
+ char name[sizeof(fmt)];
+
+ snprintf(name, sizeof(name), fmt, i);
+ serdes->ref[i] = devm_clk_get(dev, name);
+ if (IS_ERR(serdes->ref[i])) {
+ ret = PTR_ERR(serdes->ref[i]);
+ dev_err_probe(dev, ret, "could not get %s\n", name);
+ return ret;
+ }
+ }
+
+ for (i = 0; i < ARRAY_SIZE(serdes->pll); i++) {
+ static const char fmt[] = "%s.pll%d";
+ char *name;
+ const struct clk_hw *ref_hw[] = {
+ __clk_get_hw(serdes->ref[i]),
+ };
+ size_t len;
+ struct clk_init_data init = {};
+
+ len = snprintf(NULL, 0, fmt, pdev->name, i);
+ name = devm_kzalloc(dev, len + 1, GFP_KERNEL);
+ if (!name)
+ return -ENOMEM;
+
+ snprintf(name, len + 1, fmt, pdev->name, i);
+ init.name = name;
+ init.ops = &qs_pll_clk_ops;
+ init.parent_hws = ref_hw;
+ init.num_parents = 1;
+ init.flags = CLK_SET_RATE_GATE | CLK_GET_RATE_NOCACHE;
+ init.flags |= CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE;
+
+ serdes->pll[i].hw.init = &init;
+ serdes->pll[i].serdes = serdes;
+ serdes->pll[i].idx = i;
+ ret = devm_clk_hw_register(dev, &serdes->pll[i].hw);
+ if (ret) {
+ dev_err_probe(dev, ret, "could not register %s\n",
+ name);
+ return ret;
+ }
+ }
+
+ /* Deselect anything configured by the RCW/bootloader */
+ for (i = 0; i < conf->mode_count; i++) {
+ const struct qs_mode *mode = &conf->modes[i];
+ u32 pccr = qs_read(serdes, PCCRn(mode->pccr));
+
+ if (qs_proto_mode_get(mode, pccr) == mode->cfg) {
+ if (mode->protos & UNSUPPORTED_PROTOS) {
+ /* Don't mess with modes we don't support */
+ serdes->used_lanes |= mode->lanes;
+ if (grabbed_clocks)
+ continue;
+
+ grabbed_clocks = true;
+ clk_prepare_enable(serdes->pll[0].hw.clk);
+ clk_prepare_enable(serdes->pll[1].hw.clk);
+ clk_rate_exclusive_get(serdes->pll[0].hw.clk);
+ clk_rate_exclusive_get(serdes->pll[1].hw.clk);
+ } else {
+ /* Otherwise, clear out the existing config */
+ pccr = qs_proto_mode_prep(mode, pccr, 0);
+ qs_write(serdes, pccr, PCCRn(mode->pccr));
+ }
+ }
+ }
+
+ /* TODO: clear SGMIIaCR1 */
+
+ /* TODO: power off unused lanes */
+
+ ret = PTR_ERR_OR_ZERO(devm_of_phy_provider_register(dev, qs_xlate));
+ if (ret)
+ dev_err_probe(dev, ret, "could not register phy provider\n");
+ else
+ dev_info(dev, "probed with %d lanes\n", conf->lanes);
+ return ret;
+}
+
+/*
+ * XXX: For SerDes1, lane A uses pins SD1_RX3_P/N! That is, the lane numbers
+ * and pin numbers are _reversed_. In addition, the PCCR documentation is
+ * _inconsistent_ in its usage of these terms!
+ *
+ * PCCR "Lane 0" refers to...
+ * ==== =====================
+ * 0 Lane A
+ * 2 Lane A
+ * 8 Lane A
+ * 9 Lane A
+ * B Lane D!
+ */
+static const struct qs_mode ls1046a_modes1[] = {
+ CONF_SINGLE(1, PCIE, 0x0, 1, 0b001), /* PCIe.1 */
+ CONF_1000BASEKX(0, 0x8, 0, 0b001), /* SGMII.6 */
+ CONF_SGMII25KX(1, 0x8, 1, 0b001), /* SGMII.5 */
+ CONF_SGMII25KX(2, 0x8, 2, 0b001), /* SGMII.10 */
+ CONF_SGMII25KX(3, 0x8, 3, 0b001), /* SGMII.9 */
+ CONF_SINGLE(1, QSGMII, 0x9, 2, 0b001), /* QSGMII.6,5,10,1 */
+ CONF_XFI(2, 0xB, 0, 0b010), /* XFI.10 */
+ CONF_XFI(3, 0xB, 1, 0b001), /* XFI.9 */
+};
+
+static const struct qs_conf ls1046a_conf1 = {
+ .modes = ls1046a_modes1,
+ .mode_count = ARRAY_SIZE(ls1046a_modes1),
+ .lanes = 4,
+ .endian = REGMAP_ENDIAN_BIG,
+};
+
+static const struct qs_mode ls1046a_modes2[] = {
+ CONF_SINGLE(0, PCIE, 0x0, 0, 0b001), /* PCIe.1 x1 */
+ CONF(GENMASK(3, 0), PROTO_MASK(PCIE), 0x0, 0, 0b011), /* PCIe.1 x4 */
+ CONF_SINGLE(2, PCIE, 0x0, 2, 0b001), /* PCIe.2 x1 */
+ CONF(GENMASK(3, 2), PROTO_MASK(PCIE), 0x0, 2, 0b010), /* PCIe.3 x2 */
+ CONF_SINGLE(3, PCIE, 0x0, 2, 0b011), /* PCIe.3 x1 */
+ CONF_SINGLE(3, SATA, 0x2, 0, 0b001), /* SATA */
+ CONF_1000BASEKX(1, 0x8, 1, 0b001), /* SGMII.2 */
+};
+
+static const struct qs_conf ls1046a_conf2 = {
+ .modes = ls1046a_modes2,
+ .mode_count = ARRAY_SIZE(ls1046a_modes2),
+ .lanes = 4,
+ .endian = REGMAP_ENDIAN_BIG,
+};
+
+static const struct of_device_id qs_of_match[] = {
+ { .compatible = "fsl,ls1046a-serdes-1", .data = &ls1046a_conf1 },
+ { .compatible = "fsl,ls1046a-serdes-2", .data = &ls1046a_conf2 },
+};
+MODULE_DEVICE_TABLE(of, qs_of_match);
+
+static struct platform_driver qs_driver = {
+ .probe = qs_probe,
+ .driver = {
+ .name = "qoriq_serdes",
+ .of_match_table = qs_of_match,
+ },
+};
+module_platform_driver(qs_driver);
+
+MODULE_AUTHOR("Sean Anderson <sean.anderson@seco.com>");
+MODULE_DESCRIPTION("QorIQ SerDes driver");
+MODULE_LICENSE("GPL");
--
2.35.1.1320.gc452695387.dirty
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH net-next 26/28] arm64: dts: ls1046ardb: Add serdes bindings
2022-06-17 20:32 [PATCH net-next 00/28] [RFC] net: dpaa: Convert to phylink Sean Anderson
` (2 preceding siblings ...)
2022-06-17 20:32 ` [PATCH net-next 03/28] phy: fsl: Add QorIQ SerDes driver Sean Anderson
@ 2022-06-17 20:33 ` Sean Anderson
2022-06-17 20:33 ` [PATCH net-next 27/28] arm64: dts: ls1046a: Add SerDes bindings Sean Anderson
2022-06-17 20:33 ` [PATCH net-next 28/28] arm64: dts: ls1046a: Specify which MACs support RGMII Sean Anderson
5 siblings, 0 replies; 25+ messages in thread
From: Sean Anderson @ 2022-06-17 20:33 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Madalin Bucur, netdev
Cc: linux-kernel, linux-arm-kernel, Paolo Abeni, Russell King,
Eric Dumazet, Sean Anderson, Krzysztof Kozlowski, Li Yang,
Rob Herring, Shawn Guo, devicetree
This adds appropriate bindings for the macs which use the SerDes. The
156.25MHz fixed clock is a crystal. The 100MHz clocks (there are
actually 3) come from a Renesas 6V49205B at address 69 on i2c0. There is
no driver for this device (and as far as I know all you can do with the
100MHz clocks is gate them), so I have chosen to model it as a single
fixed clock.
Note: the SerDes1 lane numbering for the LS1046A is *reversed*.
This means that Lane A (what the driver thinks is lane 0) uses pins
SD1_TX3_P/N.
Signed-off-by: Sean Anderson <sean.anderson@seco.com>
---
.../boot/dts/freescale/fsl-ls1046a-rdb.dts | 32 +++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
index 7025aad8ae89..21a153349359 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
@@ -26,6 +26,30 @@ aliases {
chosen {
stdout-path = "serial0:115200n8";
};
+
+ clocks {
+ clk_100mhz: clock-100mhz {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <100000000>;
+ };
+
+ clk_156mhz: clock-156mhz {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-frequency = <156250000>;
+ };
+ };
+};
+
+&serdes1 {
+ clocks = <&clk_100mhz>, <&clk_156mhz>;
+ clock-names = "ref0", "ref1";
+};
+
+&serdes2 {
+ clocks = <&clk_100mhz>, <&clk_100mhz>;
+ clock-names = "ref0", "ref1";
};
&duart0 {
@@ -140,21 +164,29 @@ ethernet@e6000 {
ethernet@e8000 {
phy-handle = <&sgmii_phy1>;
phy-connection-type = "sgmii";
+ phys = <&serdes1 1 1>;
+ phy-names = "serdes";
};
ethernet@ea000 {
phy-handle = <&sgmii_phy2>;
phy-connection-type = "sgmii";
+ phys = <&serdes1 0 0>;
+ phy-names = "serdes";
};
ethernet@f0000 { /* 10GEC1 */
phy-handle = <&aqr106_phy>;
phy-connection-type = "xgmii";
+ phys = <&serdes1 3 3>;
+ phy-names = "serdes";
};
ethernet@f2000 { /* 10GEC2 */
fixed-link = <0 1 1000 0 0>;
phy-connection-type = "xgmii";
+ phys = <&serdes1 2 2>;
+ phy-names = "serdes";
};
mdio@fc000 {
--
2.35.1.1320.gc452695387.dirty
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH net-next 27/28] arm64: dts: ls1046a: Add SerDes bindings
2022-06-17 20:32 [PATCH net-next 00/28] [RFC] net: dpaa: Convert to phylink Sean Anderson
` (3 preceding siblings ...)
2022-06-17 20:33 ` [PATCH net-next 26/28] arm64: dts: ls1046ardb: Add serdes bindings Sean Anderson
@ 2022-06-17 20:33 ` Sean Anderson
2022-06-17 20:33 ` [PATCH net-next 28/28] arm64: dts: ls1046a: Specify which MACs support RGMII Sean Anderson
5 siblings, 0 replies; 25+ messages in thread
From: Sean Anderson @ 2022-06-17 20:33 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Madalin Bucur, netdev
Cc: linux-kernel, linux-arm-kernel, Paolo Abeni, Russell King,
Eric Dumazet, Sean Anderson, Krzysztof Kozlowski, Li Yang,
Rob Herring, Shawn Guo, devicetree
This adds bindings for the SerDes devices.
Signed-off-by: Sean Anderson <sean.anderson@seco.com>
---
arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
index 0085e83adf65..de2cf36824fb 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046a.dtsi
@@ -413,6 +413,18 @@ bportals: bman-portals@508000000 {
ranges = <0x0 0x5 0x08000000 0x8000000>;
};
+ serdes1: phy@1ea0000 {
+ #phy-cells = <2>;
+ compatible = "fsl,ls1046a-serdes-1";
+ reg = <0x0 0x1ea0000 0x0 0x2000>;
+ };
+
+ serdes2: phy@1eb0000 {
+ #phy-cells = <2>;
+ compatible = "fsl,ls1046a-serdes-2";
+ reg = <0x0 0x1eb0000 0x0 0x2000>;
+ };
+
dcfg: dcfg@1ee0000 {
compatible = "fsl,ls1046a-dcfg", "syscon";
reg = <0x0 0x1ee0000 0x0 0x1000>;
--
2.35.1.1320.gc452695387.dirty
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH net-next 28/28] arm64: dts: ls1046a: Specify which MACs support RGMII
2022-06-17 20:32 [PATCH net-next 00/28] [RFC] net: dpaa: Convert to phylink Sean Anderson
` (4 preceding siblings ...)
2022-06-17 20:33 ` [PATCH net-next 27/28] arm64: dts: ls1046a: Add SerDes bindings Sean Anderson
@ 2022-06-17 20:33 ` Sean Anderson
5 siblings, 0 replies; 25+ messages in thread
From: Sean Anderson @ 2022-06-17 20:33 UTC (permalink / raw)
To: David S . Miller, Jakub Kicinski, Madalin Bucur, netdev
Cc: linux-kernel, linux-arm-kernel, Paolo Abeni, Russell King,
Eric Dumazet, Sean Anderson, Krzysztof Kozlowski, Li Yang,
Rob Herring, Shawn Guo, devicetree
For more precise link mode support, we can add a property specifying
which MACs support RGMII. This silences the warning
missing 'rgmii' property; assuming supported
Signed-off-by: Sean Anderson <sean.anderson@seco.com>
---
arch/arm64/boot/dts/freescale/fsl-ls1046-post.dtsi | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1046-post.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1046-post.dtsi
index d6caaea57d90..4bb314388a72 100644
--- a/arch/arm64/boot/dts/freescale/fsl-ls1046-post.dtsi
+++ b/arch/arm64/boot/dts/freescale/fsl-ls1046-post.dtsi
@@ -23,26 +23,34 @@ &soc {
&fman0 {
/* these aliases provide the FMan ports mapping */
enet0: ethernet@e0000 {
+ rgmii = <0>;
};
enet1: ethernet@e2000 {
+ rgmii = <0>;
};
enet2: ethernet@e4000 {
+ rgmii = <1>;
};
enet3: ethernet@e6000 {
+ rgmii = <1>;
};
enet4: ethernet@e8000 {
+ rgmii = <0>;
};
enet5: ethernet@ea000 {
+ rgmii = <0>;
};
enet6: ethernet@f0000 {
+ rgmii = <0>;
};
enet7: ethernet@f2000 {
+ rgmii = <0>;
};
};
--
2.35.1.1320.gc452695387.dirty
^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH net-next 01/28] dt-bindings: phy: Add QorIQ SerDes binding
2022-06-17 20:32 ` [PATCH net-next 01/28] dt-bindings: phy: Add QorIQ SerDes binding Sean Anderson
@ 2022-06-17 23:27 ` Rob Herring
2022-06-18 1:15 ` Krzysztof Kozlowski
1 sibling, 0 replies; 25+ messages in thread
From: Rob Herring @ 2022-06-17 23:27 UTC (permalink / raw)
To: Sean Anderson
Cc: Eric Dumazet, Vinod Koul, netdev, Rob Herring, linux-kernel,
Paolo Abeni, devicetree, linux-arm-kernel, Jakub Kicinski,
Russell King, Kishon Vijay Abraham I, David S . Miller, linux-phy,
Krzysztof Kozlowski, Madalin Bucur
On Fri, 17 Jun 2022 16:32:45 -0400, Sean Anderson wrote:
> This adds a binding for the SerDes module found on QorIQ processors. The
> phy reference has two cells, one for the first lane and one for the
> last. This should allow for good support of multi-lane protocols when
> (if) they are added. There is no protocol option, because the driver is
> designed to be able to completely reconfigure lanes at runtime.
> Generally, the phy consumer can select the appropriate protocol using
> set_mode. For the most part there is only one protocol controller
> (consumer) per lane/protocol combination. The exception to this is the
> B4860 processor, which has some lanes which can be connected to
> multiple MACs. For that processor, I anticipate the easiest way to
> resolve this will be to add an additional cell with a "protocol
> controller instance" property.
>
> Each serdes has a unique set of supported protocols (and lanes). The
> support matrix is stored in the driver and is selected based on the
> compatible string. It is anticipated that a new compatible string will
> need to be added for each serdes on each SoC that drivers support is
> added for.
>
> There are two PLLs, each of which can be used as the master clock for
> each lane. Each PLL has its own reference. For the moment they are
> required, because it simplifies the driver implementation. Absent
> reference clocks can be modeled by a fixed-clock with a rate of 0.
>
> Signed-off-by: Sean Anderson <sean.anderson@seco.com>
> ---
>
> .../bindings/phy/fsl,qoriq-serdes.yaml | 78 +++++++++++++++++++
> 1 file changed, 78 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/phy/fsl,qoriq-serdes.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:
/builds/robherring/linux-dt-review/Documentation/devicetree/bindings/phy/fsl,qoriq-serdes.example.dtb: phy@1ea0000: reg: [[0, 32112640], [0, 8192]] is too long
From schema: /builds/robherring/linux-dt-review/Documentation/devicetree/bindings/phy/fsl,qoriq-serdes.yaml
doc reference errors (make refcheckdocs):
See https://patchwork.ozlabs.org/patch/
This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.
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.
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH net-next 01/28] dt-bindings: phy: Add QorIQ SerDes binding
2022-06-17 20:32 ` [PATCH net-next 01/28] dt-bindings: phy: Add QorIQ SerDes binding Sean Anderson
2022-06-17 23:27 ` Rob Herring
@ 2022-06-18 1:15 ` Krzysztof Kozlowski
2022-06-18 3:38 ` Sean Anderson
1 sibling, 1 reply; 25+ messages in thread
From: Krzysztof Kozlowski @ 2022-06-18 1:15 UTC (permalink / raw)
To: Sean Anderson, David S . Miller, Jakub Kicinski, Madalin Bucur,
netdev
Cc: linux-kernel, linux-arm-kernel, Paolo Abeni, Russell King,
Eric Dumazet, Kishon Vijay Abraham I, Krzysztof Kozlowski,
Rob Herring, Vinod Koul, devicetree, linux-phy
On 17/06/2022 13:32, Sean Anderson wrote:
> This adds a binding for the SerDes module found on QorIQ processors. The
> phy reference has two cells, one for the first lane and one for the
> last. This should allow for good support of multi-lane protocols when
> (if) they are added. There is no protocol option, because the driver is
> designed to be able to completely reconfigure lanes at runtime.
> Generally, the phy consumer can select the appropriate protocol using
> set_mode. For the most part there is only one protocol controller
> (consumer) per lane/protocol combination. The exception to this is the
> B4860 processor, which has some lanes which can be connected to
> multiple MACs. For that processor, I anticipate the easiest way to
> resolve this will be to add an additional cell with a "protocol
> controller instance" property.
>
> Each serdes has a unique set of supported protocols (and lanes). The
> support matrix is stored in the driver and is selected based on the
> compatible string. It is anticipated that a new compatible string will
> need to be added for each serdes on each SoC that drivers support is
> added for.
>
> There are two PLLs, each of which can be used as the master clock for
> each lane. Each PLL has its own reference. For the moment they are
> required, because it simplifies the driver implementation. Absent
> reference clocks can be modeled by a fixed-clock with a rate of 0.
>
> Signed-off-by: Sean Anderson <sean.anderson@seco.com>
> ---
>
> .../bindings/phy/fsl,qoriq-serdes.yaml | 78 +++++++++++++++++++
> 1 file changed, 78 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/phy/fsl,qoriq-serdes.yaml
>
> diff --git a/Documentation/devicetree/bindings/phy/fsl,qoriq-serdes.yaml b/Documentation/devicetree/bindings/phy/fsl,qoriq-serdes.yaml
> new file mode 100644
> index 000000000000..4b9c1fcdab10
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/phy/fsl,qoriq-serdes.yaml
> @@ -0,0 +1,78 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/phy/fsl,qoriq-serdes.yaml#
File name: fsl,ls1046a-serdes.yaml
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: NXP QorIQ SerDes Device Tree Bindings
s/Device Tree Bindings//
> +
> +maintainers:
> + - Sean Anderson <sean.anderson@seco.com>
> +
> +description: |
> + This binding describes the SerDes devices found in NXP's QorIQ line of
Describe the device, not the binding, so wording "This binding" is not
appropriate.
> + processors. The SerDes provides up to eight lanes. Each lane may be
> + configured individually, or may be combined with adjacent lanes for a
> + multi-lane protocol. The SerDes supports a variety of protocols, including up
> + to 10G Ethernet, PCIe, SATA, and others. The specific protocols supported for
> + each lane depend on the particular SoC.
> +
> +properties:
Compatible goes first.
> + "#phy-cells":
> + const: 2
> + description: |
> + The cells contain the following arguments.
> +
> + - description: |
Not a correct schema. What is this "- description" attached to? There is
no items here...
> + The first lane in the group. Lanes are numbered based on the register
> + offsets, not the I/O ports. This corresponds to the letter-based
> + ("Lane A") naming scheme, and not the number-based ("Lane 0") naming
> + scheme. On most SoCs, "Lane A" is "Lane 0", but not always.
> + minimum: 0
> + maximum: 7
> + - description: |
> + Last lane. For single-lane protocols, this should be the same as the
> + first lane.
> + minimum: 0
> + maximum: 7
> +
> + compatible:
> + enum:
> + - fsl,ls1046a-serdes-1
> + - fsl,ls1046a-serdes-2
Does not look like proper compatible and your explanation from commit
msg did not help me. What "1" and "2" stand for? Usually compatibles
cannot have some arbitrary properties encoded.
> +
> + clocks:
> + minItems: 2
No need for minItems.
> + maxItems: 2
> + description: |
> + Clock for each PLL reference clock input.
> +
> + clock-names:
> + minItems: 2
> + maxItems: 2
> + items:
> + pattern: "^ref[0-1]$"
No, instead describe actual items with "const". See other examples.
> +
> + reg:
> + maxItems: 1
> +
> +required:
> + - "#phy-cells"
> + - compatible
> + - clocks
> + - clock-names
> + - reg
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + serdes1: phy@1ea0000 {
> + #phy-cells = <2>;
> + compatible = "fsl,ls1046a-serdes-1";
> + reg = <0x0 0x1ea0000 0x0 0x2000>;
> + clocks = <&clk_100mhz>, <&clk_156mhz>;
> + clock-names = "ref0", "ref1";
> + };
> +
> +...
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH net-next 02/28] dt-bindings: net: fman: Add additional interface properties
2022-06-17 20:32 ` [PATCH net-next 02/28] dt-bindings: net: fman: Add additional interface properties Sean Anderson
@ 2022-06-18 1:16 ` Krzysztof Kozlowski
2022-06-18 15:55 ` Sean Anderson
0 siblings, 1 reply; 25+ messages in thread
From: Krzysztof Kozlowski @ 2022-06-18 1:16 UTC (permalink / raw)
To: Sean Anderson, David S . Miller, Jakub Kicinski, Madalin Bucur,
netdev
Cc: linux-kernel, linux-arm-kernel, Paolo Abeni, Russell King,
Eric Dumazet, Krzysztof Kozlowski, Rob Herring, devicetree
On 17/06/2022 13:32, Sean Anderson wrote:
> At the moment, MEMACs are configured almost completely based on the
> phy-connection-type. That is, if the phy interface is RGMII, it assumed
> that RGMII is supported. For some interfaces, it is assumed that the
> RCW/bootloader has set up the SerDes properly. The actual link state is
> never reported.
>
> To address these shortcomings, the driver will need additional
> information. First, it needs to know how to access the PCS/PMAs (in
> order to configure them and get the link status). The SGMII PCS/PMA is
> the only currently-described PCS/PMA. Add the XFI and QSGMII PCS/PMAs as
> well. The XFI (and 1GBase-KR) PCS/PMA is a c45 "phy" which sits on the
> same MDIO bus as SGMII PCS/PMA. By default they will have conflicting
> addresses, but they are also not enabled at the same time by default.
> Therefore, we can let the default address for the XFI PCS/PMA be the
> same as for SGMII. This will allow for backwards-compatibility.
>
> QSGMII, however, cannot work with the current binding. This is because
> the QSGMII PCS/PMAs are only present on one MAC's MDIO bus. At the
> moment this is worked around by having every MAC write to the PCS/PMA
> addresses (without checking if they are present). This only works if
> each MAC has the same configuration, and only if we don't need to know
> the status. Because the QSGMII PCS/PMA will typically be located on a
> different MDIO bus than the MAC's SGMII PCS/PMA, there is no fallback
> for the QSGMII PCS/PMA.
>
> MEMACs (across all SoCs) support the following protocols:
>
> - MII
> - RGMII
> - SGMII, 1000Base-X, and 1000Base-KX
> - 2500Base-X (aka 2.5G SGMII)
> - QSGMII
> - 10GBase-R (aka XFI) and 10GBase-KR
> - XAUI and HiGig
>
> Each line documents a set of orthogonal protocols (e.g. XAUI is
> supported if and only if HiGig is supported). Additionally,
>
> - XAUI implies support for 10GBase-R
> - 10GBase-R is supported if and only if RGMII is not supported
> - 2500Base-X implies support for 1000Base-X
> - MII implies support for RGMII
>
> To switch between different protocols, we must reconfigure the SerDes.
> This is done by using the standard phys property. We can also use it to
> validate whether different protocols are supported (e.g. using
> phy_validate). This will work for serial protocols, but not RGMII or
> MII. Additionally, we still need to be compatible when there is no
> SerDes.
>
> While we can detect 10G support by examining the port speed (as set by
> fsl,fman-10g-port), we cannot determine support for any of the other
> protocols based on the existing binding. In fact, the binding works
> against us in some respects, because pcsphy-handle is required even if
> there is no possible PCS/PMA for that MAC. To allow for backwards-
> compatibility, we use a boolean-style property for RGMII (instead of
> presence/absence-style). When the property for RGMII is missing, we will
> assume that it is supported. The exception is MII, since no existing
> device trees use it (as far as I could tell).
>
> Unfortunately, QSGMII support will be broken for old device trees. There
> is nothing we can do about this because of the PCS/PMA situation (as
> described above).
>
> Signed-off-by: Sean Anderson <sean.anderson@seco.com>
Thanks for the patch but you add too many new properties. The file
should be converted to YAML/DT schema first.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH net-next 03/28] phy: fsl: Add QorIQ SerDes driver
2022-06-17 20:32 ` [PATCH net-next 03/28] phy: fsl: Add QorIQ SerDes driver Sean Anderson
@ 2022-06-18 3:02 ` kernel test robot
[not found] ` <GV1PR04MB905598703F5E9A0989662EFDE0AE9@GV1PR04MB9055.eurprd04.prod.outlook.com>
1 sibling, 0 replies; 25+ messages in thread
From: kernel test robot @ 2022-06-18 3:02 UTC (permalink / raw)
To: Sean Anderson, David S . Miller, Jakub Kicinski, Madalin Bucur,
netdev
Cc: kbuild-all, linux-kernel, linux-arm-kernel, Paolo Abeni,
Russell King, Eric Dumazet, Sean Anderson, Ioana Ciornei,
Jonathan Corbet, Kishon Vijay Abraham I, Krzysztof Kozlowski,
Rob Herring, Vinod Koul, devicetree, linux-phy
Hi Sean,
I love your patch! Perhaps something to improve:
[auto build test WARNING on net-next/master]
url: https://github.com/intel-lab-lkp/linux/commits/Sean-Anderson/net-dpaa-Convert-to-phylink/20220618-044003
base: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 4875d94c69d5a4836c4225b51429d277c297aae8
config: sh-allmodconfig (https://download.01.org/0day-ci/archive/20220618/202206181015.BLEIZObf-lkp@intel.com/config)
compiler: sh4-linux-gcc (GCC) 11.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/d9c7b1e909ace0c4229445647587ae1f64cf52c0
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Sean-Anderson/net-dpaa-Convert-to-phylink/20220618-044003
git checkout d9c7b1e909ace0c4229445647587ae1f64cf52c0
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.3.0 make.cross W=1 O=build_dir ARCH=sh SHELL=/bin/bash drivers/net/ethernet/freescale/fman/ drivers/phy/freescale/ net/ipv6/
If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
>> drivers/phy/freescale/phy-qoriq.c:382:16: warning: no previous prototype for 'qs_clk_hw_to_priv' [-Wmissing-prototypes]
382 | struct qs_clk *qs_clk_hw_to_priv(struct clk_hw *hw)
| ^~~~~~~~~~~~~~~~~
vim +/qs_clk_hw_to_priv +382 drivers/phy/freescale/phy-qoriq.c
381
> 382 struct qs_clk *qs_clk_hw_to_priv(struct clk_hw *hw)
383 {
384 return container_of(hw, struct qs_clk, hw);
385 }
386
--
0-DAY CI Kernel Test Service
https://01.org/lkp
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH net-next 01/28] dt-bindings: phy: Add QorIQ SerDes binding
2022-06-18 1:15 ` Krzysztof Kozlowski
@ 2022-06-18 3:38 ` Sean Anderson
2022-06-19 11:24 ` Krzysztof Kozlowski
0 siblings, 1 reply; 25+ messages in thread
From: Sean Anderson @ 2022-06-18 3:38 UTC (permalink / raw)
To: Krzysztof Kozlowski, David S . Miller, Jakub Kicinski,
Madalin Bucur, netdev
Cc: linux-kernel, linux-arm-kernel, Paolo Abeni, Russell King,
Eric Dumazet, Kishon Vijay Abraham I, Krzysztof Kozlowski,
Rob Herring, Vinod Koul, devicetree, linux-phy
Hi Krzysztof,
On 6/17/22 9:15 PM, Krzysztof Kozlowski wrote:
> On 17/06/2022 13:32, Sean Anderson wrote:
>> This adds a binding for the SerDes module found on QorIQ processors. The
>> phy reference has two cells, one for the first lane and one for the
>> last. This should allow for good support of multi-lane protocols when
>> (if) they are added. There is no protocol option, because the driver is
>> designed to be able to completely reconfigure lanes at runtime.
>> Generally, the phy consumer can select the appropriate protocol using
>> set_mode. For the most part there is only one protocol controller
>> (consumer) per lane/protocol combination. The exception to this is the
>> B4860 processor, which has some lanes which can be connected to
>> multiple MACs. For that processor, I anticipate the easiest way to
>> resolve this will be to add an additional cell with a "protocol
>> controller instance" property.
>>
>> Each serdes has a unique set of supported protocols (and lanes). The
>> support matrix is stored in the driver and is selected based on the
>> compatible string. It is anticipated that a new compatible string will
>> need to be added for each serdes on each SoC that drivers support is
>> added for.
>>
>> There are two PLLs, each of which can be used as the master clock for
>> each lane. Each PLL has its own reference. For the moment they are
>> required, because it simplifies the driver implementation. Absent
>> reference clocks can be modeled by a fixed-clock with a rate of 0.
>>
>> Signed-off-by: Sean Anderson <sean.anderson@seco.com>
>> ---
>>
>> .../bindings/phy/fsl,qoriq-serdes.yaml | 78 +++++++++++++++++++
>> 1 file changed, 78 insertions(+)
>> create mode 100644 Documentation/devicetree/bindings/phy/fsl,qoriq-serdes.yaml
>>
>> diff --git a/Documentation/devicetree/bindings/phy/fsl,qoriq-serdes.yaml b/Documentation/devicetree/bindings/phy/fsl,qoriq-serdes.yaml
>> new file mode 100644
>> index 000000000000..4b9c1fcdab10
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/phy/fsl,qoriq-serdes.yaml
>> @@ -0,0 +1,78 @@
>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/phy/fsl,qoriq-serdes.yaml#
>
> File name: fsl,ls1046a-serdes.yaml
This is not appropriate, since this binding will be used for many QorIQ
devices, not just LS1046A. The LS1046A is not even an "ur" device (first
model, etc.) but simply the one I have access to.
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: NXP QorIQ SerDes Device Tree Bindings
>
> s/Device Tree Bindings//
OK
>> +
>> +maintainers:
>> + - Sean Anderson <sean.anderson@seco.com>
>> +
>> +description: |
>> + This binding describes the SerDes devices found in NXP's QorIQ line of
>
> Describe the device, not the binding, so wording "This binding" is not
> appropriate.
OK
>> + processors. The SerDes provides up to eight lanes. Each lane may be
>> + configured individually, or may be combined with adjacent lanes for a
>> + multi-lane protocol. The SerDes supports a variety of protocols, including up
>> + to 10G Ethernet, PCIe, SATA, and others. The specific protocols supported for
>> + each lane depend on the particular SoC.
>> +
>> +properties:
>
> Compatible goes first.
>
>> + "#phy-cells":
>> + const: 2
>> + description: |
>> + The cells contain the following arguments.
>> +
>> + - description: |
>
> Not a correct schema. What is this "- description" attached to? There is
> no items here...
This is the same format as used by
Documentation/devicetree/bindings/phy/xlnx,zynqmp-psgtr.yaml
How should the cells be documented?
>> + The first lane in the group. Lanes are numbered based on the register
>> + offsets, not the I/O ports. This corresponds to the letter-based
>> + ("Lane A") naming scheme, and not the number-based ("Lane 0") naming
>> + scheme. On most SoCs, "Lane A" is "Lane 0", but not always.
>> + minimum: 0
>> + maximum: 7
>> + - description: |
>> + Last lane. For single-lane protocols, this should be the same as the
>> + first lane.
>> + minimum: 0
>> + maximum: 7
>> +
>> + compatible:
>> + enum:
>> + - fsl,ls1046a-serdes-1
>> + - fsl,ls1046a-serdes-2
>
> Does not look like proper compatible and your explanation from commit
> msg did not help me. What "1" and "2" stand for? Usually compatibles
> cannot have some arbitrary properties encoded.
Each serdes has a different set of supported protocols for each lane. This is encoded
in the driver data associated with the compatible, along with the appropriate values
to plug into the protocol control registers. Because each serdes has a different set
of supported protocols and register configuration, adding support for a new SoC will
require adding the appropriate configuration to the driver, and adding a new compatible
string. Although most of the driver is generic, this critical portion is shared only
between closely-related SoCs (such as variants with differing numbers of cores).
The 1 and 2 stand for the number of the SerDes on that SoC. e.g. the documentation will
refer to SerDes1 and SerDes2.
So e.g. other compatibles might be
- fsl,ls1043a-serdes-1 # There's only one serdes on this SoC
- fsl,t4042-serdes-1 # This SoC has four serdes
- fsl,t4042-serdes-2
- fsl,t4042-serdes-3
- fsl,t4042-serdes-4
>> +
>> + clocks:
>> + minItems: 2
>
> No need for minItems.
OK
>> + maxItems: 2
>> + description: |
>> + Clock for each PLL reference clock input.
>> +
>> + clock-names:
>> + minItems: 2
>> + maxItems: 2
>> + items:
>> + pattern: "^ref[0-1]$"
>
> No, instead describe actual items with "const". See other examples.
Again, same format as xlnx,zynqmp-psgtr.yaml
I will update this to use items.
>> +
>> + reg:
>> + maxItems: 1
>> +
>> +required:
>> + - "#phy-cells"
>> + - compatible
>> + - clocks
>> + - clock-names
>> + - reg
>> +
>> +additionalProperties: false
>> +
>> +examples:
>> + - |
>> + serdes1: phy@1ea0000 {
>> + #phy-cells = <2>;
>> + compatible = "fsl,ls1046a-serdes-1";
>> + reg = <0x0 0x1ea0000 0x0 0x2000>;
>> + clocks = <&clk_100mhz>, <&clk_156mhz>;
>> + clock-names = "ref0", "ref1";
>> + };
>> +
>> +...
--Sean
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH net-next 03/28] phy: fsl: Add QorIQ SerDes driver
[not found] ` <GV1PR04MB905598703F5E9A0989662EFDE0AE9@GV1PR04MB9055.eurprd04.prod.outlook.com>
@ 2022-06-18 12:39 ` Ioana Ciornei
2022-06-18 15:52 ` Sean Anderson
0 siblings, 1 reply; 25+ messages in thread
From: Ioana Ciornei @ 2022-06-18 12:39 UTC (permalink / raw)
To: Sean Anderson, David S . Miller, Jakub Kicinski, Madalin Bucur,
netdev@vger.kernel.org
Cc: linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, Paolo Abeni, Russell King,
Eric Dumazet, Jonathan Corbet, Kishon Vijay Abraham I,
Krzysztof Kozlowski, Rob Herring, Vinod Koul,
devicetree@vger.kernel.org, linux-phy@lists.infradead.org
> > Subject: [PATCH net-next 03/28] phy: fsl: Add QorIQ SerDes driver
> >
Sorry for the previous HTML formatted email...
>
> Hi Sean,
>
> I am very much interested in giving this driver a go on other SoCs as well
> but at the moment I am in vacation until mid next week.
>
>
> > This adds support for the "SerDes" devices found on various NXP QorIQ SoCs.
> > There may be up to four SerDes devices on each SoC, each supporting up to
> > eight lanes. Protocol support for each SerDes is highly heterogeneous, with
> > each SoC typically having a totally different selection of supported
> > protocols for each lane. Additionally, the SerDes devices on each SoC also
> > have differing support. One SerDes will typically support Ethernet on most
> > lanes, while the other will typically support PCIe on most lanes.
> >
> > There is wide hardware support for this SerDes. I have not done extensive
> > digging, but it seems to be used on almost every QorIQ device, including
> > the AMP and Layerscape series. Because each SoC typically has specific
> > instructions and exceptions for its SerDes, I have limited the initial
> > scope of this module to just the LS1046A. Additionally, I have only added
> > support for Ethernet protocols. There is not a great need for dynamic
> > reconfiguration for other protocols (SATA and PCIe handle rate changes in
> > hardware), so support for them may never be added.>
> > Nevertheless, I have tried to provide an obvious path for adding support
> > for other SoCs as well as other protocols. SATA just needs support for
> > configuring LNmSSCR0. PCIe may need to configure the equalization
> > registers. It also uses multiple lanes. I have tried to write the driver
> > with multi-lane support in mind, so there should not need to be any large
> > changes. Although there are 6 protocols supported, I have only tested SGMII
> > and XFI. The rest have been implemented as described in the datasheet.
> >
> > The PLLs are modeled as clocks proper. This lets us take advantage of the
> > existing clock infrastructure. I have not given the same treatment to the
> > lane "clocks" (dividers) because they need to be programmed in-concert with
> > the rest of the lane settings. One tricky thing is that the VCO (pll) rate
> > exceeds 2^32 (maxing out at around 5GHz). This will be a problem on 32-bit
> > platforms, since clock rates are stored as unsigned longs. To work around
> > this, the pll clock rate is generally treated in units of kHz.>
> > The PLLs are configured rather interestingly. Instead of the usual direct
> > programming of the appropriate divisors, the input and output clock rates
> > are selected directly. Generally, the only restriction is that the input
> > and output must be integer multiples of each other. This suggests some kind
> > of internal look-up table. The datasheets generally list out the supported
> > combinations explicitly, and not all input/output combinations are
> > documented. I'm not sure if this is due to lack of support, or due to an
> > oversight. If this becomes an issue, then some combinations can be
> > blacklisted (or whitelisted). This may also be necessary for other SoCs
> > which have more stringent clock requirements.
>
>
> I didn't get a change to go through the driver like I would like, but are you
> changing the PLL's rate at runtime?
> Do you take into consideration that a PLL might still be used by a PCIe or SATA
> lane (which is not described in the DTS) and deny its rate reconfiguration
> if this happens?
>
> I am asking this because when I added support for the Lynx 28G SerDes block what
> I did in order to support rate change depending of the plugged SFP module was
> just to change the PLL used by the lane, not the PLL rate itself.
> This is because I was afraid of causing more harm then needed for all the
> non-Ethernet lanes.
>
> >
> > The general API call list for this PHY is documented under the driver-api
> > docs. I think this is rather standard, except that most driverts configure
> > the mode (protocol) at xlate-time. Unlike some other phys where e.g. PCIe
> > x4 will use 4 separate phys all configured for PCIe, this driver uses one
> > phy configured to use 4 lanes. This is because while the individual lanes
> > may be configured individually, the protocol selection acts on all lanes at
> > once. Additionally, the order which lanes should be configured in is
> > specified by the datasheet. To coordinate this, lanes are reserved in
> > phy_init, and released in phy_exit.
> >
> > When getting a phy, if a phy already exists for those lanes, it is reused.
> > This is to make things like QSGMII work. Four MACs will all want to ensure
> > that the lane is configured properly, and we need to ensure they can all
> > call phy_init, etc. There is refcounting for phy_init and phy_power_on, so
> > the phy will only be powered on once. However, there is no refcounting for
> > phy_set_mode. A "rogue" MAC could set the mode to something non-QSGMII and
> > break the other MACs. Perhaps there is an opportunity for future
> > enhancement here.
> >
> > This driver was written with reference to the LS1046A reference manual.
> > However, it was informed by reference manuals for all processors with
> > MEMACs, especially the T4240 (which appears to have a "maxed-out"
> > configuration).
> >
> > Signed-off-by: Sean Anderson <sean.anderson@seco.com>
> > ---
> > This appears to be the same underlying hardware as the Lynx 28G phy
> > added in 8f73b37cf3fb ("phy: add support for the Layerscape SerDes
> > 28G").
>
> The SerDes block used on L1046A (and a lot of other SoCs) is not the same
> one as the Lynx 28G that I submitted. The Lynx 28G block is only included
> on the LX2160A SoC and its variants.
>
> The SerDes block that you are adding a driver for is the Lynx 10G SerDes,
> which is why I would suggest renaming it to phy-fsl-lynx-10g.c.
>
> Ioana
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH net-next 03/28] phy: fsl: Add QorIQ SerDes driver
2022-06-18 12:39 ` Ioana Ciornei
@ 2022-06-18 15:52 ` Sean Anderson
2022-06-20 18:53 ` Sean Anderson
0 siblings, 1 reply; 25+ messages in thread
From: Sean Anderson @ 2022-06-18 15:52 UTC (permalink / raw)
To: Ioana Ciornei, David S . Miller, Jakub Kicinski, Madalin Bucur,
netdev@vger.kernel.org
Cc: linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, Paolo Abeni, Russell King,
Eric Dumazet, Jonathan Corbet, Kishon Vijay Abraham I,
Krzysztof Kozlowski, Rob Herring, Vinod Koul,
devicetree@vger.kernel.org, linux-phy@lists.infradead.org
Hi Ioana,
On 6/18/22 8:39 AM, Ioana Ciornei wrote:
>>> Subject: [PATCH net-next 03/28] phy: fsl: Add QorIQ SerDes driver
>>>
>
> Sorry for the previous HTML formatted email...
>
>>
>> Hi Sean,
>>
>> I am very much interested in giving this driver a go on other SoCs as well
>> but at the moment I am in vacation until mid next week.
Please let me know your results. I have documented how to add support for
additional SoCs, so hopefully it should be fairly straightforward.
>>> This adds support for the "SerDes" devices found on various NXP QorIQ SoCs.
>>> There may be up to four SerDes devices on each SoC, each supporting up to
>>> eight lanes. Protocol support for each SerDes is highly heterogeneous, with
>>> each SoC typically having a totally different selection of supported
>>> protocols for each lane. Additionally, the SerDes devices on each SoC also
>>> have differing support. One SerDes will typically support Ethernet on most
>>> lanes, while the other will typically support PCIe on most lanes.
>>>
>>> There is wide hardware support for this SerDes. I have not done extensive
>>> digging, but it seems to be used on almost every QorIQ device, including
>>> the AMP and Layerscape series. Because each SoC typically has specific
>>> instructions and exceptions for its SerDes, I have limited the initial
>>> scope of this module to just the LS1046A. Additionally, I have only added
>>> support for Ethernet protocols. There is not a great need for dynamic
>>> reconfiguration for other protocols (SATA and PCIe handle rate changes in
>>> hardware), so support for them may never be added.>
>>> Nevertheless, I have tried to provide an obvious path for adding support
>>> for other SoCs as well as other protocols. SATA just needs support for
>>> configuring LNmSSCR0. PCIe may need to configure the equalization
>>> registers. It also uses multiple lanes. I have tried to write the driver
>>> with multi-lane support in mind, so there should not need to be any large
>>> changes. Although there are 6 protocols supported, I have only tested SGMII
>>> and XFI. The rest have been implemented as described in the datasheet.
>>>
>>> The PLLs are modeled as clocks proper. This lets us take advantage of the
>>> existing clock infrastructure. I have not given the same treatment to the
>>> lane "clocks" (dividers) because they need to be programmed in-concert with
>>> the rest of the lane settings. One tricky thing is that the VCO (pll) rate
>>> exceeds 2^32 (maxing out at around 5GHz). This will be a problem on 32-bit
>>> platforms, since clock rates are stored as unsigned longs. To work around
>>> this, the pll clock rate is generally treated in units of kHz.>
>>> The PLLs are configured rather interestingly. Instead of the usual direct
>>> programming of the appropriate divisors, the input and output clock rates
>>> are selected directly. Generally, the only restriction is that the input
>>> and output must be integer multiples of each other. This suggests some kind
>>> of internal look-up table. The datasheets generally list out the supported
>>> combinations explicitly, and not all input/output combinations are
>>> documented. I'm not sure if this is due to lack of support, or due to an
>>> oversight. If this becomes an issue, then some combinations can be
>>> blacklisted (or whitelisted). This may also be necessary for other SoCs
>>> which have more stringent clock requirements.
>>
>>
>> I didn't get a change to go through the driver like I would like, but are you
>> changing the PLL's rate at runtime?
Yes.
>> Do you take into consideration that a PLL might still be used by a PCIe or SATA
>> lane (which is not described in the DTS) and deny its rate reconfiguration
>> if this happens?
Yes.
When the device is probed, we go through the PCCRs and reserve any lane which is in
use for a protocol we don't support (PCIe, SATA). We also get both PLL's rates
exclusively and mark them as enabled.
>> I am asking this because when I added support for the Lynx 28G SerDes block what
>> I did in order to support rate change depending of the plugged SFP module was
>> just to change the PLL used by the lane, not the PLL rate itself.
>> This is because I was afraid of causing more harm then needed for all the
>> non-Ethernet lanes.
Yes. Since There is not much need for dynamic reconfiguration for other protocols,
I suspect that non-ethernet support will not be added soon (or perhaps ever).
>>>
>>> The general API call list for this PHY is documented under the driver-api
>>> docs. I think this is rather standard, except that most driverts configure
>>> the mode (protocol) at xlate-time. Unlike some other phys where e.g. PCIe
>>> x4 will use 4 separate phys all configured for PCIe, this driver uses one
>>> phy configured to use 4 lanes. This is because while the individual lanes
>>> may be configured individually, the protocol selection acts on all lanes at
>>> once. Additionally, the order which lanes should be configured in is
>>> specified by the datasheet. To coordinate this, lanes are reserved in
>>> phy_init, and released in phy_exit.
>>>
>>> When getting a phy, if a phy already exists for those lanes, it is reused.
>>> This is to make things like QSGMII work. Four MACs will all want to ensure
>>> that the lane is configured properly, and we need to ensure they can all
>>> call phy_init, etc. There is refcounting for phy_init and phy_power_on, so
>>> the phy will only be powered on once. However, there is no refcounting for
>>> phy_set_mode. A "rogue" MAC could set the mode to something non-QSGMII and
>>> break the other MACs. Perhaps there is an opportunity for future
>>> enhancement here.
>>>
>>> This driver was written with reference to the LS1046A reference manual.
>>> However, it was informed by reference manuals for all processors with
>>> MEMACs, especially the T4240 (which appears to have a "maxed-out"
>>> configuration).
>>>
>>> Signed-off-by: Sean Anderson <sean.anderson@seco.com>
>>> ---
>>> This appears to be the same underlying hardware as the Lynx 28G phy
>>> added in 8f73b37cf3fb ("phy: add support for the Layerscape SerDes
>>> 28G").
>>
>> The SerDes block used on L1046A (and a lot of other SoCs) is not the same
>> one as the Lynx 28G that I submitted. The Lynx 28G block is only included
>> on the LX2160A SoC and its variants.
OK. I looked over it quickly and it seemed to share many of the same registers.
>> The SerDes block that you are adding a driver for is the Lynx 10G SerDes,
>> which is why I would suggest renaming it to phy-fsl-lynx-10g.c.
Ah, thanks. Is this documented anywhere?
--Sean
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH net-next 02/28] dt-bindings: net: fman: Add additional interface properties
2022-06-18 1:16 ` Krzysztof Kozlowski
@ 2022-06-18 15:55 ` Sean Anderson
2022-06-19 10:33 ` Krzysztof Kozlowski
0 siblings, 1 reply; 25+ messages in thread
From: Sean Anderson @ 2022-06-18 15:55 UTC (permalink / raw)
To: Krzysztof Kozlowski, David S . Miller, Jakub Kicinski,
Madalin Bucur, netdev
Cc: linux-kernel, linux-arm-kernel, Paolo Abeni, Russell King,
Eric Dumazet, Krzysztof Kozlowski, Rob Herring, devicetree
Hi Krzysztof,
On 6/17/22 9:16 PM, Krzysztof Kozlowski wrote:
> On 17/06/2022 13:32, Sean Anderson wrote:
>> At the moment, MEMACs are configured almost completely based on the
>> phy-connection-type. That is, if the phy interface is RGMII, it assumed
>> that RGMII is supported. For some interfaces, it is assumed that the
>> RCW/bootloader has set up the SerDes properly. The actual link state is
>> never reported.
>>
>> To address these shortcomings, the driver will need additional
>> information. First, it needs to know how to access the PCS/PMAs (in
>> order to configure them and get the link status). The SGMII PCS/PMA is
>> the only currently-described PCS/PMA. Add the XFI and QSGMII PCS/PMAs as
>> well. The XFI (and 1GBase-KR) PCS/PMA is a c45 "phy" which sits on the
>> same MDIO bus as SGMII PCS/PMA. By default they will have conflicting
>> addresses, but they are also not enabled at the same time by default.
>> Therefore, we can let the default address for the XFI PCS/PMA be the
>> same as for SGMII. This will allow for backwards-compatibility.
>>
>> QSGMII, however, cannot work with the current binding. This is because
>> the QSGMII PCS/PMAs are only present on one MAC's MDIO bus. At the
>> moment this is worked around by having every MAC write to the PCS/PMA
>> addresses (without checking if they are present). This only works if
>> each MAC has the same configuration, and only if we don't need to know
>> the status. Because the QSGMII PCS/PMA will typically be located on a
>> different MDIO bus than the MAC's SGMII PCS/PMA, there is no fallback
>> for the QSGMII PCS/PMA.
>>
>> MEMACs (across all SoCs) support the following protocols:
>>
>> - MII
>> - RGMII
>> - SGMII, 1000Base-X, and 1000Base-KX
>> - 2500Base-X (aka 2.5G SGMII)
>> - QSGMII
>> - 10GBase-R (aka XFI) and 10GBase-KR
>> - XAUI and HiGig
>>
>> Each line documents a set of orthogonal protocols (e.g. XAUI is
>> supported if and only if HiGig is supported). Additionally,
>>
>> - XAUI implies support for 10GBase-R
>> - 10GBase-R is supported if and only if RGMII is not supported
>> - 2500Base-X implies support for 1000Base-X
>> - MII implies support for RGMII
>>
>> To switch between different protocols, we must reconfigure the SerDes.
>> This is done by using the standard phys property. We can also use it to
>> validate whether different protocols are supported (e.g. using
>> phy_validate). This will work for serial protocols, but not RGMII or
>> MII. Additionally, we still need to be compatible when there is no
>> SerDes.
>>
>> While we can detect 10G support by examining the port speed (as set by
>> fsl,fman-10g-port), we cannot determine support for any of the other
>> protocols based on the existing binding. In fact, the binding works
>> against us in some respects, because pcsphy-handle is required even if
>> there is no possible PCS/PMA for that MAC. To allow for backwards-
>> compatibility, we use a boolean-style property for RGMII (instead of
>> presence/absence-style). When the property for RGMII is missing, we will
>> assume that it is supported. The exception is MII, since no existing
>> device trees use it (as far as I could tell).
>>
>> Unfortunately, QSGMII support will be broken for old device trees. There
>> is nothing we can do about this because of the PCS/PMA situation (as
>> described above).
>>
>> Signed-off-by: Sean Anderson <sean.anderson@seco.com>
>
> Thanks for the patch but you add too many new properties. The file
> should be converted to YAML/DT schema first.
Perhaps. However, conversion to yaml is a non-trivial task, especially for
a complicated binding such as this one. I am more than happy to rework this
patch to be based on a yaml conversion, but I do not have the bandwidth to
do so myself.
If you have any comments on the binding changes themselves, that would be
much appreciated.
--Sean
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH net-next 02/28] dt-bindings: net: fman: Add additional interface properties
2022-06-18 15:55 ` Sean Anderson
@ 2022-06-19 10:33 ` Krzysztof Kozlowski
2022-06-27 23:05 ` Rob Herring
0 siblings, 1 reply; 25+ messages in thread
From: Krzysztof Kozlowski @ 2022-06-19 10:33 UTC (permalink / raw)
To: Sean Anderson, David S . Miller, Jakub Kicinski, Madalin Bucur,
netdev
Cc: linux-kernel, linux-arm-kernel, Paolo Abeni, Russell King,
Eric Dumazet, Krzysztof Kozlowski, Rob Herring, devicetree
On 18/06/2022 17:55, Sean Anderson wrote:
> Hi Krzysztof,
>
> On 6/17/22 9:16 PM, Krzysztof Kozlowski wrote:
>> On 17/06/2022 13:32, Sean Anderson wrote:
>>> At the moment, MEMACs are configured almost completely based on the
>>> phy-connection-type. That is, if the phy interface is RGMII, it assumed
>>> that RGMII is supported. For some interfaces, it is assumed that the
>>> RCW/bootloader has set up the SerDes properly. The actual link state is
>>> never reported.
>>>
>>> To address these shortcomings, the driver will need additional
>>> information. First, it needs to know how to access the PCS/PMAs (in
>>> order to configure them and get the link status). The SGMII PCS/PMA is
>>> the only currently-described PCS/PMA. Add the XFI and QSGMII PCS/PMAs as
>>> well. The XFI (and 1GBase-KR) PCS/PMA is a c45 "phy" which sits on the
>>> same MDIO bus as SGMII PCS/PMA. By default they will have conflicting
>>> addresses, but they are also not enabled at the same time by default.
>>> Therefore, we can let the default address for the XFI PCS/PMA be the
>>> same as for SGMII. This will allow for backwards-compatibility.
>>>
>>> QSGMII, however, cannot work with the current binding. This is because
>>> the QSGMII PCS/PMAs are only present on one MAC's MDIO bus. At the
>>> moment this is worked around by having every MAC write to the PCS/PMA
>>> addresses (without checking if they are present). This only works if
>>> each MAC has the same configuration, and only if we don't need to know
>>> the status. Because the QSGMII PCS/PMA will typically be located on a
>>> different MDIO bus than the MAC's SGMII PCS/PMA, there is no fallback
>>> for the QSGMII PCS/PMA.
>>>
>>> MEMACs (across all SoCs) support the following protocols:
>>>
>>> - MII
>>> - RGMII
>>> - SGMII, 1000Base-X, and 1000Base-KX
>>> - 2500Base-X (aka 2.5G SGMII)
>>> - QSGMII
>>> - 10GBase-R (aka XFI) and 10GBase-KR
>>> - XAUI and HiGig
>>>
>>> Each line documents a set of orthogonal protocols (e.g. XAUI is
>>> supported if and only if HiGig is supported). Additionally,
>>>
>>> - XAUI implies support for 10GBase-R
>>> - 10GBase-R is supported if and only if RGMII is not supported
>>> - 2500Base-X implies support for 1000Base-X
>>> - MII implies support for RGMII
>>>
>>> To switch between different protocols, we must reconfigure the SerDes.
>>> This is done by using the standard phys property. We can also use it to
>>> validate whether different protocols are supported (e.g. using
>>> phy_validate). This will work for serial protocols, but not RGMII or
>>> MII. Additionally, we still need to be compatible when there is no
>>> SerDes.
>>>
>>> While we can detect 10G support by examining the port speed (as set by
>>> fsl,fman-10g-port), we cannot determine support for any of the other
>>> protocols based on the existing binding. In fact, the binding works
>>> against us in some respects, because pcsphy-handle is required even if
>>> there is no possible PCS/PMA for that MAC. To allow for backwards-
>>> compatibility, we use a boolean-style property for RGMII (instead of
>>> presence/absence-style). When the property for RGMII is missing, we will
>>> assume that it is supported. The exception is MII, since no existing
>>> device trees use it (as far as I could tell).
>>>
>>> Unfortunately, QSGMII support will be broken for old device trees. There
>>> is nothing we can do about this because of the PCS/PMA situation (as
>>> described above).
>>>
>>> Signed-off-by: Sean Anderson <sean.anderson@seco.com>
>>
>> Thanks for the patch but you add too many new properties. The file
>> should be converted to YAML/DT schema first.
>
> Perhaps. However, conversion to yaml is a non-trivial task, especially for
> a complicated binding such as this one. I am more than happy to rework this
> patch to be based on a yaml conversion, but I do not have the bandwidth to
> do so myself.
I understand. Although since 2020 - since when we expect the bindings
to be in YAML - this file grew by 6 properties, because each person
extends it instead of converting. Each person uses the same excuse...
You add here 5 more, so it would be 11 new properties in total.
>
> If you have any comments on the binding changes themselves, that would be
> much appreciated.
Maybe Rob will ack it, but for me the change is too big to be accepted
in TXT, so no from me.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH net-next 01/28] dt-bindings: phy: Add QorIQ SerDes binding
2022-06-18 3:38 ` Sean Anderson
@ 2022-06-19 11:24 ` Krzysztof Kozlowski
2022-06-19 15:53 ` Sean Anderson
0 siblings, 1 reply; 25+ messages in thread
From: Krzysztof Kozlowski @ 2022-06-19 11:24 UTC (permalink / raw)
To: Sean Anderson, David S . Miller, Jakub Kicinski, Madalin Bucur,
netdev
Cc: linux-kernel, linux-arm-kernel, Paolo Abeni, Russell King,
Eric Dumazet, Kishon Vijay Abraham I, Krzysztof Kozlowski,
Rob Herring, Vinod Koul, devicetree, linux-phy
On 18/06/2022 05:38, Sean Anderson wrote:
> Hi Krzysztof,
>
> On 6/17/22 9:15 PM, Krzysztof Kozlowski wrote:
>> On 17/06/2022 13:32, Sean Anderson wrote:
>>> This adds a binding for the SerDes module found on QorIQ processors. The
>>> phy reference has two cells, one for the first lane and one for the
>>> last. This should allow for good support of multi-lane protocols when
>>> (if) they are added. There is no protocol option, because the driver is
>>> designed to be able to completely reconfigure lanes at runtime.
>>> Generally, the phy consumer can select the appropriate protocol using
>>> set_mode. For the most part there is only one protocol controller
>>> (consumer) per lane/protocol combination. The exception to this is the
>>> B4860 processor, which has some lanes which can be connected to
>>> multiple MACs. For that processor, I anticipate the easiest way to
>>> resolve this will be to add an additional cell with a "protocol
>>> controller instance" property.
>>>
>>> Each serdes has a unique set of supported protocols (and lanes). The
>>> support matrix is stored in the driver and is selected based on the
>>> compatible string. It is anticipated that a new compatible string will
>>> need to be added for each serdes on each SoC that drivers support is
>>> added for.
>>>
>>> There are two PLLs, each of which can be used as the master clock for
>>> each lane. Each PLL has its own reference. For the moment they are
>>> required, because it simplifies the driver implementation. Absent
>>> reference clocks can be modeled by a fixed-clock with a rate of 0.
>>>
>>> Signed-off-by: Sean Anderson <sean.anderson@seco.com>
>>> ---
>>>
>>> .../bindings/phy/fsl,qoriq-serdes.yaml | 78 +++++++++++++++++++
>>> 1 file changed, 78 insertions(+)
>>> create mode 100644 Documentation/devicetree/bindings/phy/fsl,qoriq-serdes.yaml
>>>
>>> diff --git a/Documentation/devicetree/bindings/phy/fsl,qoriq-serdes.yaml b/Documentation/devicetree/bindings/phy/fsl,qoriq-serdes.yaml
>>> new file mode 100644
>>> index 000000000000..4b9c1fcdab10
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/phy/fsl,qoriq-serdes.yaml
>>> @@ -0,0 +1,78 @@
>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>> +%YAML 1.2
>>> +---
>>> +$id: http://devicetree.org/schemas/phy/fsl,qoriq-serdes.yaml#
>>
>> File name: fsl,ls1046a-serdes.yaml
>
> This is not appropriate, since this binding will be used for many QorIQ
> devices, not just LS1046A.
This is the DT bindings convention and naming style, so why do you say
it is not appropriate? If the new SoC at some point requires different
binding what filename do you use? fsl,qoriq-serdes2.yaml? And then again
fsl,qoriq-serdes3.yaml?
Please follow DT bindings convention and name it after first compatible
in the bindings.
> The LS1046A is not even an "ur" device (first
> model, etc.) but simply the one I have access to.
It does not matter that much if it is first in total. Use the first one
from the documented compatibles.
>
>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>> +
>>> +title: NXP QorIQ SerDes Device Tree Bindings
>>
>> s/Device Tree Bindings//
>
> OK
>
>>> +
>>> +maintainers:
>>> + - Sean Anderson <sean.anderson@seco.com>
>>> +
>>> +description: |
>>> + This binding describes the SerDes devices found in NXP's QorIQ line of
>>
>> Describe the device, not the binding, so wording "This binding" is not
>> appropriate.
>
> OK
>
>>> + processors. The SerDes provides up to eight lanes. Each lane may be
>>> + configured individually, or may be combined with adjacent lanes for a
>>> + multi-lane protocol. The SerDes supports a variety of protocols, including up
>>> + to 10G Ethernet, PCIe, SATA, and others. The specific protocols supported for
>>> + each lane depend on the particular SoC.
>>> +
>>> +properties:
>>
>> Compatible goes first.
>>
>>> + "#phy-cells":
>>> + const: 2
>>> + description: |
>>> + The cells contain the following arguments.
>>> +
>>> + - description: |
>>
>> Not a correct schema. What is this "- description" attached to? There is
>> no items here...
>
> This is the same format as used by
> Documentation/devicetree/bindings/phy/xlnx,zynqmp-psgtr.yaml
I'll fix it.
>
> How should the cells be documented?
Could be something like that:
Documentation/devicetree/bindings/phy/microchip,lan966x-serdes.yaml
>
>>> + The first lane in the group. Lanes are numbered based on the register
>>> + offsets, not the I/O ports. This corresponds to the letter-based
>>> + ("Lane A") naming scheme, and not the number-based ("Lane 0") naming
>>> + scheme. On most SoCs, "Lane A" is "Lane 0", but not always.
>>> + minimum: 0
>>> + maximum: 7
>>> + - description: |
>>> + Last lane. For single-lane protocols, this should be the same as the
>>> + first lane.
>>> + minimum: 0
>>> + maximum: 7
>>> +
>>> + compatible:
>>> + enum:
>>> + - fsl,ls1046a-serdes-1
>>> + - fsl,ls1046a-serdes-2
>>
>> Does not look like proper compatible and your explanation from commit
>> msg did not help me. What "1" and "2" stand for? Usually compatibles
>> cannot have some arbitrary properties encoded.
>
> Each serdes has a different set of supported protocols for each lane. This is encoded
> in the driver data associated with the compatible
Implementation does not matter.
> , along with the appropriate values
> to plug into the protocol control registers. Because each serdes has a different set
> of supported protocols
Another way is to express it with a property.
> and register configuration,
What does it mean exactly? The same protocols have different programming
model on the instances?
> adding support for a new SoC will
> require adding the appropriate configuration to the driver, and adding a new compatible
> string. Although most of the driver is generic, this critical portion is shared only
> between closely-related SoCs (such as variants with differing numbers of cores).
>
Again implementation - we do not talk here about driver, but the bindings.
> The 1 and 2 stand for the number of the SerDes on that SoC. e.g. the documentation will
> refer to SerDes1 and SerDes2.
>
> So e.g. other compatibles might be
>
> - fsl,ls1043a-serdes-1 # There's only one serdes on this SoC
> - fsl,t4042-serdes-1 # This SoC has four serdes
> - fsl,t4042-serdes-2
> - fsl,t4042-serdes-3
> - fsl,t4042-serdes-4
If the devices are really different - there is no common parts in the
programming model (registers) - then please find some descriptive
compatible. However if the programming model of common part is
consistent and the differences are only for different protocols (kind of
expected), this should be rather a property describing which protocols
are supported.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH net-next 01/28] dt-bindings: phy: Add QorIQ SerDes binding
2022-06-19 11:24 ` Krzysztof Kozlowski
@ 2022-06-19 15:53 ` Sean Anderson
2022-06-20 10:54 ` Krzysztof Kozlowski
0 siblings, 1 reply; 25+ messages in thread
From: Sean Anderson @ 2022-06-19 15:53 UTC (permalink / raw)
To: Krzysztof Kozlowski, David S . Miller, Jakub Kicinski,
Madalin Bucur, netdev
Cc: linux-kernel, linux-arm-kernel, Paolo Abeni, Russell King,
Eric Dumazet, Kishon Vijay Abraham I, Krzysztof Kozlowski,
Rob Herring, Vinod Koul, devicetree, linux-phy
On 6/19/22 7:24 AM, Krzysztof Kozlowski wrote:
> On 18/06/2022 05:38, Sean Anderson wrote:
>> Hi Krzysztof,
>>
>> On 6/17/22 9:15 PM, Krzysztof Kozlowski wrote:
>>> On 17/06/2022 13:32, Sean Anderson wrote:
>>>> This adds a binding for the SerDes module found on QorIQ processors. The
>>>> phy reference has two cells, one for the first lane and one for the
>>>> last. This should allow for good support of multi-lane protocols when
>>>> (if) they are added. There is no protocol option, because the driver is
>>>> designed to be able to completely reconfigure lanes at runtime.
>>>> Generally, the phy consumer can select the appropriate protocol using
>>>> set_mode. For the most part there is only one protocol controller
>>>> (consumer) per lane/protocol combination. The exception to this is the
>>>> B4860 processor, which has some lanes which can be connected to
>>>> multiple MACs. For that processor, I anticipate the easiest way to
>>>> resolve this will be to add an additional cell with a "protocol
>>>> controller instance" property.
>>>>
>>>> Each serdes has a unique set of supported protocols (and lanes). The
>>>> support matrix is stored in the driver and is selected based on the
>>>> compatible string. It is anticipated that a new compatible string will
>>>> need to be added for each serdes on each SoC that drivers support is
>>>> added for.
>>>>
>>>> There are two PLLs, each of which can be used as the master clock for
>>>> each lane. Each PLL has its own reference. For the moment they are
>>>> required, because it simplifies the driver implementation. Absent
>>>> reference clocks can be modeled by a fixed-clock with a rate of 0.
>>>>
>>>> Signed-off-by: Sean Anderson <sean.anderson@seco.com>
>>>> ---
>>>>
>>>> .../bindings/phy/fsl,qoriq-serdes.yaml | 78 +++++++++++++++++++
>>>> 1 file changed, 78 insertions(+)
>>>> create mode 100644 Documentation/devicetree/bindings/phy/fsl,qoriq-serdes.yaml
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/phy/fsl,qoriq-serdes.yaml b/Documentation/devicetree/bindings/phy/fsl,qoriq-serdes.yaml
>>>> new file mode 100644
>>>> index 000000000000..4b9c1fcdab10
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/phy/fsl,qoriq-serdes.yaml
>>>> @@ -0,0 +1,78 @@
>>>> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
>>>> +%YAML 1.2
>>>> +---
>>>> +$id: http://devicetree.org/schemas/phy/fsl,qoriq-serdes.yaml#
>>>
>>> File name: fsl,ls1046a-serdes.yaml
>>
>> This is not appropriate, since this binding will be used for many QorIQ
>> devices, not just LS1046A.
>
> This is the DT bindings convention and naming style, so why do you say
> it is not appropriate? If the new SoC at some point requires different
> binding what filename do you use? fsl,qoriq-serdes2.yaml? And then again
> fsl,qoriq-serdes3.yaml?
Correct. This serdes has been present in almost every QorIQ product over
a period of 10-15 years.
> Please follow DT bindings convention and name it after first compatible
> in the bindings.
As noted by Ioana, this is apparently a "lynx-10g" serdes, and will be
named appropriately.
>> The LS1046A is not even an "ur" device (first
>> model, etc.) but simply the one I have access to.
>
> It does not matter that much if it is first in total. Use the first one
> from the documented compatibles.
>
>>
>>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>>> +
>>>> +title: NXP QorIQ SerDes Device Tree Bindings
>>>
>>> s/Device Tree Bindings//
>>
>> OK
>>
>>>> +
>>>> +maintainers:
>>>> + - Sean Anderson <sean.anderson@seco.com>
>>>> +
>>>> +description: |
>>>> + This binding describes the SerDes devices found in NXP's QorIQ line of
>>>
>>> Describe the device, not the binding, so wording "This binding" is not
>>> appropriate.
>>
>> OK
>>
>>>> + processors. The SerDes provides up to eight lanes. Each lane may be
>>>> + configured individually, or may be combined with adjacent lanes for a
>>>> + multi-lane protocol. The SerDes supports a variety of protocols, including up
>>>> + to 10G Ethernet, PCIe, SATA, and others. The specific protocols supported for
>>>> + each lane depend on the particular SoC.
>>>> +
>>>> +properties:
>>>
>>> Compatible goes first.
>>>
>>>> + "#phy-cells":
>>>> + const: 2
>>>> + description: |
>>>> + The cells contain the following arguments.
>>>> +
>>>> + - description: |
>>>
>>> Not a correct schema. What is this "- description" attached to? There is
>>> no items here...
>>
>> This is the same format as used by
>> Documentation/devicetree/bindings/phy/xlnx,zynqmp-psgtr.yaml
>
> I'll fix it.
>
>>
>> How should the cells be documented?
>
> Could be something like that:
> Documentation/devicetree/bindings/phy/microchip,lan966x-serdes.yaml
>
>>
>>>> + The first lane in the group. Lanes are numbered based on the register
>>>> + offsets, not the I/O ports. This corresponds to the letter-based
>>>> + ("Lane A") naming scheme, and not the number-based ("Lane 0") naming
>>>> + scheme. On most SoCs, "Lane A" is "Lane 0", but not always.
>>>> + minimum: 0
>>>> + maximum: 7
>>>> + - description: |
>>>> + Last lane. For single-lane protocols, this should be the same as the
>>>> + first lane.
>>>> + minimum: 0
>>>> + maximum: 7
>>>> +
>>>> + compatible:
>>>> + enum:
>>>> + - fsl,ls1046a-serdes-1
>>>> + - fsl,ls1046a-serdes-2
>>>
>>> Does not look like proper compatible and your explanation from commit
>>> msg did not help me. What "1" and "2" stand for? Usually compatibles
>>> cannot have some arbitrary properties encoded.
>>
>> Each serdes has a different set of supported protocols for each lane. This is encoded
>> in the driver data associated with the compatible
>
> Implementation does not matter.
Of *course* implementation matters. Devicetree bindings do not happen in a vacuum. They
describe the hardware, but only in service to the implementation.
>> , along with the appropriate values
>> to plug into the protocol control registers. Because each serdes has a different set
>> of supported protocols
>
> Another way is to express it with a property.
>
>> and register configuration,
>
> What does it mean exactly? The same protocols have different programming
> model on the instances?
(In the below paragraph, when I say "register" I mean "register or field within a
register")
Yes. Every serdes instance has a different way to program protocols into lanes. While
there is a little bit of orthogonality (the same registers are typically used for the
same protocols), each serdes is different. The values programmed into the registers are
unique to the serdes, and the lane which they apply to is also unique (e.g. the same
register may be used to program a different lane with a different protocol).
>> adding support for a new SoC will
>> require adding the appropriate configuration to the driver, and adding a new compatible
>> string. Although most of the driver is generic, this critical portion is shared only
>> between closely-related SoCs (such as variants with differing numbers of cores).
>>
>
> Again implementation - we do not talk here about driver, but the bindings.
>
>> The 1 and 2 stand for the number of the SerDes on that SoC. e.g. the documentation will
>> refer to SerDes1 and SerDes2.
>>
>> So e.g. other compatibles might be
>>
>> - fsl,ls1043a-serdes-1 # There's only one serdes on this SoC
>> - fsl,t4042-serdes-1 # This SoC has four serdes
>> - fsl,t4042-serdes-2
>> - fsl,t4042-serdes-3
>> - fsl,t4042-serdes-4
>
> If the devices are really different - there is no common parts in the
> programming model (registers) - then please find some descriptive
> compatible. However if the programming model of common part is
> consistent and the differences are only for different protocols (kind of
> expected), this should be rather a property describing which protocols
> are supported.
>
I do not want to complicate the driver by attempting to encode such information in the
bindings. Storing the information in the driver is extremely common. Please refer to e.g.
- mvebu_comphy_cp110_modes in drivers/phy/marvell/phy-mvebu-cp110-comphy.c
- mvebu_a3700_comphy_modes in drivers/phy/marvell/phy-mvebu-a3700-comphy.c
- icm_matrix in drivers/phy/xilinx/phy-zynqmp.c
- samsung_usb2_phy_config in drivers/phy/samsung/
- qmp_phy_init_tbl in drivers/phy/qualcomm/phy-qcom-qmp.c
All of these drivers (and there are more)
- Use a driver-internal struct to encode information specific to different device models.
- Select that struct based on the compatible
The other thing is that while the LS1046A SerDes are fairly generic, other SerDes of this
type have particular restructions on the clocks. E.g. on some SoCs, certain protocols
cannot be used together (even if they would otherwise be legal), and some protocols must
use particular PLLs (whereas in general there is no such restriction). There are also
some register fields which are required to program on some SoCs, and which are reserved
on others.
There is, frankly, a large amount of variation between devices as implemented on different
SoCs. Especially because (AIUI) drivers must remain compatible with old devicetrees, I
think using a specific compatible string is especially appropriate here. It will give us
the ability to correct any implementation quirks as they are discovered (and I anticipate
that there will be) rather than having to determine everything up front.
--Sean
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH net-next 01/28] dt-bindings: phy: Add QorIQ SerDes binding
2022-06-19 15:53 ` Sean Anderson
@ 2022-06-20 10:54 ` Krzysztof Kozlowski
2022-06-20 17:19 ` Sean Anderson
0 siblings, 1 reply; 25+ messages in thread
From: Krzysztof Kozlowski @ 2022-06-20 10:54 UTC (permalink / raw)
To: Sean Anderson, David S . Miller, Jakub Kicinski, Madalin Bucur,
netdev
Cc: linux-kernel, linux-arm-kernel, Paolo Abeni, Russell King,
Eric Dumazet, Kishon Vijay Abraham I, Krzysztof Kozlowski,
Rob Herring, Vinod Koul, devicetree, linux-phy
On 19/06/2022 17:53, Sean Anderson wrote:
>>>
>>>>> + The first lane in the group. Lanes are numbered based on the register
>>>>> + offsets, not the I/O ports. This corresponds to the letter-based
>>>>> + ("Lane A") naming scheme, and not the number-based ("Lane 0") naming
>>>>> + scheme. On most SoCs, "Lane A" is "Lane 0", but not always.
>>>>> + minimum: 0
>>>>> + maximum: 7
>>>>> + - description: |
>>>>> + Last lane. For single-lane protocols, this should be the same as the
>>>>> + first lane.
>>>>> + minimum: 0
>>>>> + maximum: 7
>>>>> +
>>>>> + compatible:
>>>>> + enum:
>>>>> + - fsl,ls1046a-serdes-1
>>>>> + - fsl,ls1046a-serdes-2
>>>>
>>>> Does not look like proper compatible and your explanation from commit
>>>> msg did not help me. What "1" and "2" stand for? Usually compatibles
>>>> cannot have some arbitrary properties encoded.
>>>
>>> Each serdes has a different set of supported protocols for each lane. This is encoded
>>> in the driver data associated with the compatible
>>
>> Implementation does not matter.
>
> Of *course* implementation matters. Devicetree bindings do not happen in a vacuum. They
> describe the hardware, but only in service to the implementation.
This is so not true. Bindings do not service implementation. Bindings
happen in vacuum, because they are used by different implementations:
Linux, u-Boot, BSD and several other quite different systems.
Any references to implemention from the bindings is questionable,
although of course not always wrong.
Building bindings per specific implementation is as well usually not
correct.
>
>>> , along with the appropriate values
>>> to plug into the protocol control registers. Because each serdes has a different set
>>> of supported protocols
>>
>> Another way is to express it with a property.
>>
>>> and register configuration,
>>
>> What does it mean exactly? The same protocols have different programming
>> model on the instances?
>
> (In the below paragraph, when I say "register" I mean "register or field within a
> register")
>
> Yes. Every serdes instance has a different way to program protocols into lanes. While
> there is a little bit of orthogonality (the same registers are typically used for the
> same protocols), each serdes is different. The values programmed into the registers are
> unique to the serdes, and the lane which they apply to is also unique (e.g. the same
> register may be used to program a different lane with a different protocol).
That's not answering the point here, but I'll respond to the later
paragraph.
>
>>> adding support for a new SoC will
>>> require adding the appropriate configuration to the driver, and adding a new compatible
>>> string. Although most of the driver is generic, this critical portion is shared only
>>> between closely-related SoCs (such as variants with differing numbers of cores).
>>>
>>
>> Again implementation - we do not talk here about driver, but the bindings.
>>
>>> The 1 and 2 stand for the number of the SerDes on that SoC. e.g. the documentation will
>>> refer to SerDes1 and SerDes2.
>>>
>>> So e.g. other compatibles might be
>>>
>>> - fsl,ls1043a-serdes-1 # There's only one serdes on this SoC
>>> - fsl,t4042-serdes-1 # This SoC has four serdes
>>> - fsl,t4042-serdes-2
>>> - fsl,t4042-serdes-3
>>> - fsl,t4042-serdes-4
>>
>> If the devices are really different - there is no common parts in the
>> programming model (registers) - then please find some descriptive
>> compatible. However if the programming model of common part is
>> consistent and the differences are only for different protocols (kind of
>> expected), this should be rather a property describing which protocols
>> are supported.
>>
>
> I do not want to complicate the driver by attempting to encode such information in the
> bindings. Storing the information in the driver is extremely common. Please refer to e.g.
Yes, quirks are even more common, more flexible and are in general
recommended for more complicated cases. Yet you talk about driver
implementation, which I barely care.
>
> - mvebu_comphy_cp110_modes in drivers/phy/marvell/phy-mvebu-cp110-comphy.c
> - mvebu_a3700_comphy_modes in drivers/phy/marvell/phy-mvebu-a3700-comphy.c
> - icm_matrix in drivers/phy/xilinx/phy-zynqmp.c
> - samsung_usb2_phy_config in drivers/phy/samsung/
This one is a good example - where do you see there compatibles with
arbitrary numbers attached?
> - qmp_phy_init_tbl in drivers/phy/qualcomm/phy-qcom-qmp.c
>
> All of these drivers (and there are more)
>
> - Use a driver-internal struct to encode information specific to different device models.
> - Select that struct based on the compatible
Driver implementation. You can do it in many different ways. Does not
matter for the bindings.
>
> The other thing is that while the LS1046A SerDes are fairly generic, other SerDes of this
> type have particular restructions on the clocks. E.g. on some SoCs, certain protocols
> cannot be used together (even if they would otherwise be legal), and some protocols must
> use particular PLLs (whereas in general there is no such restriction). There are also
> some register fields which are required to program on some SoCs, and which are reserved
> on others.
Just to be clear, because you are quite unspecific here ("some
protocols") - we talk about the same protocol programmed on two of these
serdes (serdes-1 and serdes-2 how you call it). Does it use different
registers? Are some registers - for the same protocol - reserved in one
version?
>
> There is, frankly, a large amount of variation between devices as implemented on different
> SoCs.
This I don't get. You mean different SoCs have entirely different
Serdes? Sure, no problem. We talk here only about this SoC, this
serdes-1 and serdes-2.
> Especially because (AIUI) drivers must remain compatible with old devicetrees, I
> think using a specific compatible string is especially appropriate here.
This argument does not make any sense in case of new bindings and new
drivers, unless you build on top of existing implementation. Anyway no
one asks you to break existing bindings...
> It will give us
> the ability to correct any implementation quirks as they are discovered (and I anticipate
> that there will be) rather than having to determine everything up front.
All the quirks can be also chosen by respective properties.
Anyway, "serdes-1" and "serdes-2" are not correct compatibles, so my NAK
stays. These might be separate compatibles, although that would require
proper naming and proper justification (as you did not answer my actual
questions about differences when using same protocols). Judging by the
bindings and your current description (implementation does not matter),
this also looks like a property.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH net-next 01/28] dt-bindings: phy: Add QorIQ SerDes binding
2022-06-20 10:54 ` Krzysztof Kozlowski
@ 2022-06-20 17:19 ` Sean Anderson
2022-06-20 18:21 ` Krzysztof Kozlowski
0 siblings, 1 reply; 25+ messages in thread
From: Sean Anderson @ 2022-06-20 17:19 UTC (permalink / raw)
To: Krzysztof Kozlowski, David S . Miller, Jakub Kicinski,
Madalin Bucur, netdev
Cc: linux-kernel, linux-arm-kernel, Paolo Abeni, Russell King,
Eric Dumazet, Kishon Vijay Abraham I, Krzysztof Kozlowski,
Rob Herring, Vinod Koul, devicetree, linux-phy
On 6/20/22 6:54 AM, Krzysztof Kozlowski wrote:
> On 19/06/2022 17:53, Sean Anderson wrote:
>>>>
>>>>>> + The first lane in the group. Lanes are numbered based on the register
>>>>>> + offsets, not the I/O ports. This corresponds to the letter-based
>>>>>> + ("Lane A") naming scheme, and not the number-based ("Lane 0") naming
>>>>>> + scheme. On most SoCs, "Lane A" is "Lane 0", but not always.
>>>>>> + minimum: 0
>>>>>> + maximum: 7
>>>>>> + - description: |
>>>>>> + Last lane. For single-lane protocols, this should be the same as the
>>>>>> + first lane.
>>>>>> + minimum: 0
>>>>>> + maximum: 7
>>>>>> +
>>>>>> + compatible:
>>>>>> + enum:
>>>>>> + - fsl,ls1046a-serdes-1
>>>>>> + - fsl,ls1046a-serdes-2
>>>>>
>>>>> Does not look like proper compatible and your explanation from commit
>>>>> msg did not help me. What "1" and "2" stand for? Usually compatibles
>>>>> cannot have some arbitrary properties encoded.
>>>>
>>>> Each serdes has a different set of supported protocols for each lane. This is encoded
>>>> in the driver data associated with the compatible
>>>
>>> Implementation does not matter.
>>
>> Of *course* implementation matters. Devicetree bindings do not happen in a vacuum. They
>> describe the hardware, but only in service to the implementation.
>
> This is so not true. > Bindings do not service implementation. Bindings
> happen in vacuum
Where are all the bindings for hardware without drivers?
Why don't device trees describe the entire hardware before any drivers are written?
Actually, I have seen some device trees written like that (baked into the chip's ROM),
and they cannot be used because the bindings
- Do not fully describe the hardware (e.g. clocks, resets, interrupts, and other things)
- Do not describe the hardware in a compatible way (e.g. using different names for
registers and clocks, or ordering fields differently).
- Contain typos and errors (since they were never used)
These same issues apply to any new binding documentation. Claiming that bindings happen
in a vacuum is de facto untrue, and would be unsound practice if it wasn't.
> because they are used by different implementations:
> Linux, u-Boot, BSD and several other quite different systems.
U-Boot doesn't use devicetree for this device (and if it did the port would likely be
based on the Linux driver). BSD doesn't support this hardware at all. We are the first
to create a driver for this device, so we get to choose the binding.
> Any references to implemention from the bindings is questionable,
> although of course not always wrong.
>
> Building bindings per specific implementation is as well usually not
> correct.
Sure, but there are of course many ways to create bindings, even for the same hardware.
As an example, pinctrl bindings can be written like
pinctrl@cafebabe {
uart-tx {
function = "uart-tx";
pins = "5";
};
};
or
pinctrl@deadbeef {
uart-tx {
pinmux = <SOME_MACRO(5, UART_TX)>;
};
};
or
pinctrl@d00dfeed {
uart-tx {
pinmux = <SOME_MACRO(5, FUNC3)>;
};
};
and which one to use depends both on the structure of the hardware, as well as the
driver. These bindings require a different driver style under the hood, and using
the wrong binding can unnecessarily complicate the driver for no reason.
To further beat home the point, someone might use a "fixed-clock" to describe a clock
and then later change to a more detailed implementation. They could use "simple-pinctrl"
and then later move to a device-specific driver.
If the devicetree author is smart, then they will create a binding like
clock {
compatible = "vendor,my-clock", "fixed-clock";
...
};
so that better support might be added in the future. In fact, that is *exactly* what I
am suggesting here.
>>
>>>> , along with the appropriate values
>>>> to plug into the protocol control registers. Because each serdes has a different set
>>>> of supported protocols
>>>
>>> Another way is to express it with a property.
>>>
>>>> and register configuration,
>>>
>>> What does it mean exactly? The same protocols have different programming
>>> model on the instances?
>>
>> (In the below paragraph, when I say "register" I mean "register or field within a
>> register")
>>
>> Yes. Every serdes instance has a different way to program protocols into lanes. While
>> there is a little bit of orthogonality (the same registers are typically used for the
>> same protocols), each serdes is different. The values programmed into the registers are
>> unique to the serdes, and the lane which they apply to is also unique (e.g. the same
>> register may be used to program a different lane with a different protocol).
>
> That's not answering the point here, but I'll respond to the later
> paragraph.
>
>>
>>>> adding support for a new SoC will
>>>> require adding the appropriate configuration to the driver, and adding a new compatible
>>>> string. Although most of the driver is generic, this critical portion is shared only
>>>> between closely-related SoCs (such as variants with differing numbers of cores).
>>>>
>>>
>>> Again implementation - we do not talk here about driver, but the bindings.
>>>
>>>> The 1 and 2 stand for the number of the SerDes on that SoC. e.g. the documentation will
>>>> refer to SerDes1 and SerDes2.
>>>>
>>>> So e.g. other compatibles might be
>>>>
>>>> - fsl,ls1043a-serdes-1 # There's only one serdes on this SoC
>>>> - fsl,t4042-serdes-1 # This SoC has four serdes
>>>> - fsl,t4042-serdes-2
>>>> - fsl,t4042-serdes-3
>>>> - fsl,t4042-serdes-4
>>>
>>> If the devices are really different - there is no common parts in the
>>> programming model (registers) - then please find some descriptive
>>> compatible. However if the programming model of common part is
>>> consistent and the differences are only for different protocols (kind of
>>> expected), this should be rather a property describing which protocols
>>> are supported.
>>>
>>
>> I do not want to complicate the driver by attempting to encode such information in the
>> bindings. Storing the information in the driver is extremely common. Please refer to e.g.
>
> Yes, quirks are even more common, more flexible and are in general
> recommended for more complicated cases. Yet you talk about driver
> implementation, which I barely care.
>
>>
>> - mvebu_comphy_cp110_modes in drivers/phy/marvell/phy-mvebu-cp110-comphy.c
>> - mvebu_a3700_comphy_modes in drivers/phy/marvell/phy-mvebu-a3700-comphy.c
>> - icm_matrix in drivers/phy/xilinx/phy-zynqmp.c
>> - samsung_usb2_phy_config in drivers/phy/samsung/
>
> This one is a good example - where do you see there compatibles with
> arbitrary numbers attached?
samsung_usb2_phy_of_match in drivers/phy/samsung/phy-samsung-usb2.c
There is a different compatible for each SoC variant. Each compatible selects a struct
containing
- A list of phys, each with custom power on and off functions
- A function which converts a rate to an arbitrary value to program into a register
This is further documented in Documentation/driver-api/phy/samsung-usb2.rst
>> - qmp_phy_init_tbl in drivers/phy/qualcomm/phy-qcom-qmp.c
>>
>> All of these drivers (and there are more)
>>
>> - Use a driver-internal struct to encode information specific to different device models.
>> - Select that struct based on the compatible
>
> Driver implementation. You can do it in many different ways. Does not
> matter for the bindings.
And because this both describes the hardware and is convenient to the implementation,
I have chosen this way.
>>
>> The other thing is that while the LS1046A SerDes are fairly generic, other SerDes of this
>> type have particular restructions on the clocks. E.g. on some SoCs, certain protocols
>> cannot be used together (even if they would otherwise be legal), and some protocols must
>> use particular PLLs (whereas in general there is no such restriction). There are also
>> some register fields which are required to program on some SoCs, and which are reserved
>> on others.
>
> Just to be clear, because you are quite unspecific here ("some
> protocols") - we talk about the same protocol programmed on two of these
> serdes (serdes-1 and serdes-2 how you call it). Does it use different
> registers?
Yes.
> Are some registers - for the same protocol - reserved in one version?
Yes.
For example, I excerpt part of the documentation for PCCR2 on the T4240:
> XFIa Configuration:
> XFIA_CFG Default value set by RCW configuration.
> This field must be 0 for SerDes 3 & 4
> All settings not shown are reserved
>
> 00 Disabled
> 01 x1 on Lane 3 to FM2 MAC 9
And here is part of the documentation for PCCR2 on the LS1046A:
> SATAa Configuration
> All others reserved
> NOTE: This field is not supported in every instance. The following table includes only
> supported registers.
> Field supported in Field not supported in
> SerDes1_PCCR2 —
> — SerDes2_PCCR2
>
> 000b - Disabled
> 001b - x1 on Lane 3 (SerDes #2 only)
And here is part of the documentation for PCCRB on the LS1046A:
> XFIa Configuration
> All others reserved Default value set by RCW configuration.
>
> 000b - Disabled
> 010b - x1 on Lane 1 to XGMIIa (Serdes #1 only)
You may notice that
- For some SerDes on the same SoC, these fields are reserved
- Between different SoCs, different protocols may be configured in different registers
- The same registers may be used for different protocols in different SoCs (though
generally there are several general layouts)
- Fields have particular values which must be programmed
In addition, the documentation also says
> Reserved registers and fields must be preserved on writes.
All of these combined issues make it so that we need detailed, serdes-specific
configuration. The easiest way to store this configuration is in the driver. This
is consistent with *many* existing phy implementations. I would like to write a
standard phy driver, not one twisted by unusual device tree requirements.
>>
>> There is, frankly, a large amount of variation between devices as implemented on different
>> SoCs.
>
> This I don't get. You mean different SoCs have entirely different
> Serdes? Sure, no problem. We talk here only about this SoC, this
> serdes-1 and serdes-2.
>
>> Especially because (AIUI) drivers must remain compatible with old devicetrees, I
>> think using a specific compatible string is especially appropriate here.
>
> This argument does not make any sense in case of new bindings and new
> drivers, unless you build on top of existing implementation. Anyway no
> one asks you to break existing bindings...
When there is a bug in the bindings how do you fix it? If I were to follow your suggested method, it would be difficult to determine the particular devices
>> It will give us
>> the ability to correct any implementation quirks as they are discovered (and I anticipate
>> that there will be) rather than having to determine everything up front.
>
> All the quirks can be also chosen by respective properties.
Quirks are *exactly* the sort of implementation-specific details that you were opposed to above.
> Anyway, "serdes-1" and "serdes-2" are not correct compatibles,
The compatibles suggested were "fsl,ls1046-serdes-1" and -2. As noted above, these are separate
devices which, while having many similarities, have different register layouts and protocol
support. They are *not* 100% compatible with each other. Would you require that clock drivers
for different SoCs use the same compatibles just because they had the same registers, even though
the clocks themselves had different functions and hierarchy?
--Sean
> so my NAK
> stays. These might be separate compatibles, although that would require
> proper naming and proper justification (as you did not answer my actual
> questions about differences when using same protocols). Judging by the
> bindings and your current description (implementation does not matter),
> this also looks like a property.
>
>
> Best regards,
> Krzysztof
>
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH net-next 01/28] dt-bindings: phy: Add QorIQ SerDes binding
2022-06-20 17:19 ` Sean Anderson
@ 2022-06-20 18:21 ` Krzysztof Kozlowski
2022-06-20 18:51 ` Sean Anderson
0 siblings, 1 reply; 25+ messages in thread
From: Krzysztof Kozlowski @ 2022-06-20 18:21 UTC (permalink / raw)
To: Sean Anderson, David S . Miller, Jakub Kicinski, Madalin Bucur,
netdev
Cc: linux-kernel, linux-arm-kernel, Paolo Abeni, Russell King,
Eric Dumazet, Kishon Vijay Abraham I, Krzysztof Kozlowski,
Rob Herring, Vinod Koul, devicetree, linux-phy
On 20/06/2022 19:19, Sean Anderson wrote:
>
>
> On 6/20/22 6:54 AM, Krzysztof Kozlowski wrote:
>> On 19/06/2022 17:53, Sean Anderson wrote:
>>>>>
>>>>>>> + The first lane in the group. Lanes are numbered based on the register
>>>>>>> + offsets, not the I/O ports. This corresponds to the letter-based
>>>>>>> + ("Lane A") naming scheme, and not the number-based ("Lane 0") naming
>>>>>>> + scheme. On most SoCs, "Lane A" is "Lane 0", but not always.
>>>>>>> + minimum: 0
>>>>>>> + maximum: 7
>>>>>>> + - description: |
>>>>>>> + Last lane. For single-lane protocols, this should be the same as the
>>>>>>> + first lane.
>>>>>>> + minimum: 0
>>>>>>> + maximum: 7
>>>>>>> +
>>>>>>> + compatible:
>>>>>>> + enum:
>>>>>>> + - fsl,ls1046a-serdes-1
>>>>>>> + - fsl,ls1046a-serdes-2
>>>>>>
>>>>>> Does not look like proper compatible and your explanation from commit
>>>>>> msg did not help me. What "1" and "2" stand for? Usually compatibles
>>>>>> cannot have some arbitrary properties encoded.
>>>>>
>>>>> Each serdes has a different set of supported protocols for each lane. This is encoded
>>>>> in the driver data associated with the compatible
>>>>
>>>> Implementation does not matter.
>>>
>>> Of *course* implementation matters. Devicetree bindings do not happen in a vacuum. They
>>> describe the hardware, but only in service to the implementation.
>>
>> This is so not true. > Bindings do not service implementation. Bindings
>> happen in vacuum
>
> Where are all the bindings for hardware without drivers?
>
> Why don't device trees describe the entire hardware before any drivers are written?
>
> Actually, I have seen some device trees written like that (baked into the chip's ROM),
> and they cannot be used because the bindings
>
> - Do not fully describe the hardware (e.g. clocks, resets, interrupts, and other things)
> - Do not describe the hardware in a compatible way (e.g. using different names for
> registers and clocks, or ordering fields differently).
> - Contain typos and errors (since they were never used)
>
> These same issues apply to any new binding documentation. Claiming that bindings happen
> in a vacuum is de facto untrue, and would be unsound practice if it wasn't.
>
>> because they are used by different implementations:
>> Linux, u-Boot, BSD and several other quite different systems.
>
> U-Boot doesn't use devicetree for this device (and if it did the port would likely be
> based on the Linux driver). BSD doesn't support this hardware at all. We are the first
> to create a driver for this device, so we get to choose the binding.
You choose the binding in respect to the guidelines. You cannot choose
some random weirdness just because you are first. It does not matter
that there are no other implementations in that way - you must choose
reasonable bindings.
>
>> Any references to implemention from the bindings is questionable,
>> although of course not always wrong.
>>
>> Building bindings per specific implementation is as well usually not
>> correct.
>
> Sure, but there are of course many ways to create bindings, even for the same hardware.
> As an example, pinctrl bindings can be written like
>
> pinctrl@cafebabe {
> uart-tx {
> function = "uart-tx";
> pins = "5";
> };
> };
>
> or
>
> pinctrl@deadbeef {
> uart-tx {
> pinmux = <SOME_MACRO(5, UART_TX)>;
> };
> };
>
> or
>
> pinctrl@d00dfeed {
> uart-tx {
> pinmux = <SOME_MACRO(5, FUNC3)>;
> };
> };
>
> and which one to use depends both on the structure of the hardware, as well as the
> driver. These bindings require a different driver style under the hood, and using
> the wrong binding can unnecessarily complicate the driver for no reason.
>
> To further beat home the point, someone might use a "fixed-clock" to describe a clock
> and then later change to a more detailed implementation. They could use "simple-pinctrl"
> and then later move to a device-specific driver.
>
> If the devicetree author is smart, then they will create a binding like
>
> clock {
> compatible = "vendor,my-clock", "fixed-clock";
> ...
> };
>
> so that better support might be added in the future. In fact, that is *exactly* what I
> am suggesting here.
>
>>>
>>>>> , along with the appropriate values
>>>>> to plug into the protocol control registers. Because each serdes has a different set
>>>>> of supported protocols
>>>>
>>>> Another way is to express it with a property.
>>>>
>>>>> and register configuration,
>>>>
>>>> What does it mean exactly? The same protocols have different programming
>>>> model on the instances?
>>>
>>> (In the below paragraph, when I say "register" I mean "register or field within a
>>> register")
>>>
>>> Yes. Every serdes instance has a different way to program protocols into lanes. While
>>> there is a little bit of orthogonality (the same registers are typically used for the
>>> same protocols), each serdes is different. The values programmed into the registers are
>>> unique to the serdes, and the lane which they apply to is also unique (e.g. the same
>>> register may be used to program a different lane with a different protocol).
>>
>> That's not answering the point here, but I'll respond to the later
>> paragraph.
>>
>>>
>>>>> adding support for a new SoC will
>>>>> require adding the appropriate configuration to the driver, and adding a new compatible
>>>>> string. Although most of the driver is generic, this critical portion is shared only
>>>>> between closely-related SoCs (such as variants with differing numbers of cores).
>>>>>
>>>>
>>>> Again implementation - we do not talk here about driver, but the bindings.
>>>>
>>>>> The 1 and 2 stand for the number of the SerDes on that SoC. e.g. the documentation will
>>>>> refer to SerDes1 and SerDes2.
>>>>>
>>>>> So e.g. other compatibles might be
>>>>>
>>>>> - fsl,ls1043a-serdes-1 # There's only one serdes on this SoC
>>>>> - fsl,t4042-serdes-1 # This SoC has four serdes
>>>>> - fsl,t4042-serdes-2
>>>>> - fsl,t4042-serdes-3
>>>>> - fsl,t4042-serdes-4
>>>>
>>>> If the devices are really different - there is no common parts in the
>>>> programming model (registers) - then please find some descriptive
>>>> compatible. However if the programming model of common part is
>>>> consistent and the differences are only for different protocols (kind of
>>>> expected), this should be rather a property describing which protocols
>>>> are supported.
>>>>
>>>
>>> I do not want to complicate the driver by attempting to encode such information in the
>>> bindings. Storing the information in the driver is extremely common. Please refer to e.g.
>>
>> Yes, quirks are even more common, more flexible and are in general
>> recommended for more complicated cases. Yet you talk about driver
>> implementation, which I barely care.
>>
>>>
>>> - mvebu_comphy_cp110_modes in drivers/phy/marvell/phy-mvebu-cp110-comphy.c
>>> - mvebu_a3700_comphy_modes in drivers/phy/marvell/phy-mvebu-a3700-comphy.c
>>> - icm_matrix in drivers/phy/xilinx/phy-zynqmp.c
>>> - samsung_usb2_phy_config in drivers/phy/samsung/
>>
>> This one is a good example - where do you see there compatibles with
>> arbitrary numbers attached?
>
> samsung_usb2_phy_of_match in drivers/phy/samsung/phy-samsung-usb2.c
>
> There is a different compatible for each SoC variant. Each compatible selects a struct
> containing
>
> - A list of phys, each with custom power on and off functions
> - A function which converts a rate to an arbitrary value to program into a register
>
> This is further documented in Documentation/driver-api/phy/samsung-usb2.rst
Exactly, please follow this approach. Compatible is per different
device, e.g. different SoC variant. Of course you could have different
devices on same SoC, but "1" and "2" are not different devices.
>
>>> - qmp_phy_init_tbl in drivers/phy/qualcomm/phy-qcom-qmp.c
>>>
>>> All of these drivers (and there are more)
>>>
>>> - Use a driver-internal struct to encode information specific to different device models.
>>> - Select that struct based on the compatible
>>
>> Driver implementation. You can do it in many different ways. Does not
>> matter for the bindings.
>
> And because this both describes the hardware and is convenient to the implementation,
> I have chosen this way.
>
>>>
>>> The other thing is that while the LS1046A SerDes are fairly generic, other SerDes of this
>>> type have particular restructions on the clocks. E.g. on some SoCs, certain protocols
>>> cannot be used together (even if they would otherwise be legal), and some protocols must
>>> use particular PLLs (whereas in general there is no such restriction). There are also
>>> some register fields which are required to program on some SoCs, and which are reserved
>>> on others.
>>
>> Just to be clear, because you are quite unspecific here ("some
>> protocols") - we talk about the same protocol programmed on two of these
>> serdes (serdes-1 and serdes-2 how you call it). Does it use different
>> registers?
>
> Yes.
>
>> Are some registers - for the same protocol - reserved in one version?
>
> Yes.
>
> For example, I excerpt part of the documentation for PCCR2 on the T4240:
>
>> XFIa Configuration:
>> XFIA_CFG Default value set by RCW configuration.
>> This field must be 0 for SerDes 3 & 4
>> All settings not shown are reserved
>>
>> 00 Disabled
>> 01 x1 on Lane 3 to FM2 MAC 9
>
> And here is part of the documentation for PCCR2 on the LS1046A:
>
>> SATAa Configuration
>> All others reserved
>> NOTE: This field is not supported in every instance. The following table includes only
>> supported registers.
>> Field supported in Field not supported in
>> SerDes1_PCCR2 —
>> — SerDes2_PCCR2
>>
>> 000b - Disabled
>> 001b - x1 on Lane 3 (SerDes #2 only)
>
> And here is part of the documentation for PCCRB on the LS1046A:
>
>> XFIa Configuration
>> All others reserved Default value set by RCW configuration.
>>
>> 000b - Disabled
>> 010b - x1 on Lane 1 to XGMIIa (Serdes #1 only)
> You may notice that
>
> - For some SerDes on the same SoC, these fields are reserved
That all sounds like quite different devices, which indeed usually is
described with different compatibles. Still "xxx-1" and "xxx-2" are not
valid compatibles. You need to come with some more reasonable name
describing them. Maybe the block has revision or different model/vendor.
> - Between different SoCs, different protocols may be configured in different registers
> - The same registers may be used for different protocols in different SoCs (though
> generally there are several general layouts)
Different SoCs give you different compatibles, so problem is solved and
that's not exactly argument for this case.
> - Fields have particular values which must be programmed
>
> In addition, the documentation also says
>
>> Reserved registers and fields must be preserved on writes.
>
> All of these combined issues make it so that we need detailed, serdes-specific
> configuration. The easiest way to store this configuration is in the driver. This
> is consistent with *many* existing phy implementations. I would like to write a
> standard phy driver, not one twisted by unusual device tree requirements.
Sure.
>
>>>
>>> There is, frankly, a large amount of variation between devices as implemented on different
>>> SoCs.
>>
>> This I don't get. You mean different SoCs have entirely different
>> Serdes? Sure, no problem. We talk here only about this SoC, this
>> serdes-1 and serdes-2.
>>
>>> Especially because (AIUI) drivers must remain compatible with old devicetrees, I
>>> think using a specific compatible string is especially appropriate here.
>>
>> This argument does not make any sense in case of new bindings and new
>> drivers, unless you build on top of existing implementation. Anyway no
>> one asks you to break existing bindings...
>
> When there is a bug in the bindings how do you fix it? If I were to follow your suggested method, it would be difficult to determine the particular devices
>
>>> It will give us
>>> the ability to correct any implementation quirks as they are discovered (and I anticipate
>>> that there will be) rather than having to determine everything up front.
>>
>> All the quirks can be also chosen by respective properties.
>
> Quirks are *exactly* the sort of implementation-specific details that you were opposed to above.
>
>> Anyway, "serdes-1" and "serdes-2" are not correct compatibles,
>
> The compatibles suggested were "fsl,ls1046-serdes-1" and -2. As noted above, these are separate
> devices which, while having many similarities, have different register layouts and protocol
> support. They are *not* 100% compatible with each other. Would you require that clock drivers
> for different SoCs use the same compatibles just because they had the same registers, even though
> the clocks themselves had different functions and hierarchy?
You miss the point. Clock controllers on same SoC have different names
used in compatibles. We do not describe them as "vendor,aa-clk-1" and
"vendor,aa-clk-2".
Come with proper naming and entire discussion might be not valid
(although with not perfect naming Rob might come with questions). I
cannot propose the name because I don't know these hardware blocks and I
do not have access to datasheet.
Other way, if any reasonable naming is not possible, could be also to
describe the meaning of "-1" suffix, e.g. that it does not mean some
index but a variant from specification.
>
> --Sean
>
>> so my NAK
>> stays. These might be separate compatibles, although that would require
>> proper naming and proper justification (as you did not answer my actual
>> questions about differences when using same protocols). Judging by the
>> bindings and your current description (implementation does not matter),
>> this also looks like a property.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH net-next 01/28] dt-bindings: phy: Add QorIQ SerDes binding
2022-06-20 18:21 ` Krzysztof Kozlowski
@ 2022-06-20 18:51 ` Sean Anderson
2022-06-21 7:12 ` Krzysztof Kozlowski
0 siblings, 1 reply; 25+ messages in thread
From: Sean Anderson @ 2022-06-20 18:51 UTC (permalink / raw)
To: Krzysztof Kozlowski, David S . Miller, Jakub Kicinski,
Madalin Bucur, netdev
Cc: linux-kernel, linux-arm-kernel, Paolo Abeni, Russell King,
Eric Dumazet, Kishon Vijay Abraham I, Krzysztof Kozlowski,
Rob Herring, Vinod Koul, devicetree, linux-phy, Ioana Ciornei
On 6/20/22 2:21 PM, Krzysztof Kozlowski wrote:
>>>> - samsung_usb2_phy_config in drivers/phy/samsung/
>>>
>>> This one is a good example - where do you see there compatibles with
>>> arbitrary numbers attached?
>>
>> samsung_usb2_phy_of_match in drivers/phy/samsung/phy-samsung-usb2.c
>>
>> There is a different compatible for each SoC variant. Each compatible selects a struct
>> containing
>>
>> - A list of phys, each with custom power on and off functions
>> - A function which converts a rate to an arbitrary value to program into a register
>>
>> This is further documented in Documentation/driver-api/phy/samsung-usb2.rst
>
> Exactly, please follow this approach. Compatible is per different
> device, e.g. different SoC variant. Of course you could have different
> devices on same SoC, but "1" and "2" are not different devices.
(in this case they are)
>>
>>>> - qmp_phy_init_tbl in drivers/phy/qualcomm/phy-qcom-qmp.c
>>>>
>>>> All of these drivers (and there are more)
>>>>
>>>> - Use a driver-internal struct to encode information specific to different device models.
>>>> - Select that struct based on the compatible
>>>
>>> Driver implementation. You can do it in many different ways. Does not
>>> matter for the bindings.
>>
>> And because this both describes the hardware and is convenient to the implementation,
>> I have chosen this way.
>>
>>>>
>>>> The other thing is that while the LS1046A SerDes are fairly generic, other SerDes of this
>>>> type have particular restructions on the clocks. E.g. on some SoCs, certain protocols
>>>> cannot be used together (even if they would otherwise be legal), and some protocols must
>>>> use particular PLLs (whereas in general there is no such restriction). There are also
>>>> some register fields which are required to program on some SoCs, and which are reserved
>>>> on others.
>>>
>>> Just to be clear, because you are quite unspecific here ("some
>>> protocols") - we talk about the same protocol programmed on two of these
>>> serdes (serdes-1 and serdes-2 how you call it). Does it use different
>>> registers?
>>
>> Yes.
>>
>>> Are some registers - for the same protocol - reserved in one version?
>>
>> Yes.
>>
>> For example, I excerpt part of the documentation for PCCR2 on the T4240:
>>
>>> XFIa Configuration:
>>> XFIA_CFG Default value set by RCW configuration.
>>> This field must be 0 for SerDes 3 & 4
>>> All settings not shown are reserved
>>>
>>> 00 Disabled
>>> 01 x1 on Lane 3 to FM2 MAC 9
>>
>> And here is part of the documentation for PCCR2 on the LS1046A:
>>
>>> SATAa Configuration
>>> All others reserved
>>> NOTE: This field is not supported in every instance. The following table includes only
>>> supported registers.
>>> Field supported in Field not supported in
>>> SerDes1_PCCR2 —
>>> — SerDes2_PCCR2
>>>
>>> 000b - Disabled
>>> 001b - x1 on Lane 3 (SerDes #2 only)
>>
>> And here is part of the documentation for PCCRB on the LS1046A:
>>
>>> XFIa Configuration
>>> All others reserved Default value set by RCW configuration.
>>>
>>> 000b - Disabled
>>> 010b - x1 on Lane 1 to XGMIIa (Serdes #1 only)
>> You may notice that
>>
>> - For some SerDes on the same SoC, these fields are reserved
>
> That all sounds like quite different devices, which indeed usually is
> described with different compatibles. Still "xxx-1" and "xxx-2" are not
> valid compatibles. You need to come with some more reasonable name
> describing them. Maybe the block has revision or different model/vendor.
There is none AFAIK. Maybe someone from NXP can comment (since there are many
undocumented registers).
>> - Between different SoCs, different protocols may be configured in different registers
>> - The same registers may be used for different protocols in different SoCs (though
>> generally there are several general layouts)
>
> Different SoCs give you different compatibles, so problem is solved and
> that's not exactly argument for this case.
>
>> - Fields have particular values which must be programmed
>>
>> In addition, the documentation also says
>>
>>> Reserved registers and fields must be preserved on writes.
>>
>> All of these combined issues make it so that we need detailed, serdes-specific
>> configuration. The easiest way to store this configuration is in the driver. This
>> is consistent with *many* existing phy implementations. I would like to write a
>> standard phy driver, not one twisted by unusual device tree requirements.
>
> Sure.
>
>>
>>>>
>>>> There is, frankly, a large amount of variation between devices as implemented on different
>>>> SoCs.
>>>
>>> This I don't get. You mean different SoCs have entirely different
>>> Serdes? Sure, no problem. We talk here only about this SoC, this
>>> serdes-1 and serdes-2.
>>>
>>>> Especially because (AIUI) drivers must remain compatible with old devicetrees, I
>>>> think using a specific compatible string is especially appropriate here.
>>>
>>> This argument does not make any sense in case of new bindings and new
>>> drivers, unless you build on top of existing implementation. Anyway no
>>> one asks you to break existing bindings...
>>
>> When there is a bug in the bindings how do you fix it? If I were to follow your suggested method, it would be difficult to determine the particular devices
>>
>>>> It will give us
>>>> the ability to correct any implementation quirks as they are discovered (and I anticipate
>>>> that there will be) rather than having to determine everything up front.
>>>
>>> All the quirks can be also chosen by respective properties.
>>
>> Quirks are *exactly* the sort of implementation-specific details that you were opposed to above.
>>
>>> Anyway, "serdes-1" and "serdes-2" are not correct compatibles,
>>
>> The compatibles suggested were "fsl,ls1046-serdes-1" and -2. As noted above, these are separate
>> devices which, while having many similarities, have different register layouts and protocol
>> support. They are *not* 100% compatible with each other. Would you require that clock drivers
>> for different SoCs use the same compatibles just because they had the same registers, even though
>> the clocks themselves had different functions and hierarchy?
>
> You miss the point. Clock controllers on same SoC have different names
> used in compatibles. We do not describe them as "vendor,aa-clk-1" and
> "vendor,aa-clk-2".
>
> Come with proper naming and entire discussion might be not valid
> (although with not perfect naming Rob might come with questions). I
> cannot propose the name because I don't know these hardware blocks and I
> do not have access to datasheet.
>
> Other way, if any reasonable naming is not possible, could be also to
> describe the meaning of "-1" suffix, e.g. that it does not mean some
> index but a variant from specification.
The documentation refers to these devices as "SerDes1", "SerDes2", etc.
Wold you prefer something like
serdes0: phy@1ea0000 {
compatible = "fsl,ls1046a-serdes";
variant = <0>;
};
?
--Sean
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH net-next 03/28] phy: fsl: Add QorIQ SerDes driver
2022-06-18 15:52 ` Sean Anderson
@ 2022-06-20 18:53 ` Sean Anderson
0 siblings, 0 replies; 25+ messages in thread
From: Sean Anderson @ 2022-06-20 18:53 UTC (permalink / raw)
To: Ioana Ciornei, David S . Miller, Jakub Kicinski, Madalin Bucur,
netdev@vger.kernel.org
Cc: linux-kernel@vger.kernel.org,
linux-arm-kernel@lists.infradead.org, Paolo Abeni, Russell King,
Eric Dumazet, Jonathan Corbet, Kishon Vijay Abraham I,
Krzysztof Kozlowski, Rob Herring, Vinod Koul,
devicetree@vger.kernel.org, linux-phy@lists.infradead.org
On 6/18/22 11:52 AM, Sean Anderson wrote:
> Hi Ioana,
>
> On 6/18/22 8:39 AM, Ioana Ciornei wrote:
>>>> Subject: [PATCH net-next 03/28] phy: fsl: Add QorIQ SerDes driver
>>>>
>>
>> Sorry for the previous HTML formatted email...
>>
>>>
>>> Hi Sean,
>>>
>>> I am very much interested in giving this driver a go on other SoCs as well
>>> but at the moment I am in vacation until mid next week.
>
> Please let me know your results. I have documented how to add support for
> additional SoCs, so hopefully it should be fairly straightforward.
>
>>>> This adds support for the "SerDes" devices found on various NXP QorIQ SoCs.
>>>> There may be up to four SerDes devices on each SoC, each supporting up to
>>>> eight lanes. Protocol support for each SerDes is highly heterogeneous, with
>>>> each SoC typically having a totally different selection of supported
>>>> protocols for each lane. Additionally, the SerDes devices on each SoC also
>>>> have differing support. One SerDes will typically support Ethernet on most
>>>> lanes, while the other will typically support PCIe on most lanes.
>>>>
>>>> There is wide hardware support for this SerDes. I have not done extensive
>>>> digging, but it seems to be used on almost every QorIQ device, including
>>>> the AMP and Layerscape series. Because each SoC typically has specific
>>>> instructions and exceptions for its SerDes, I have limited the initial
>>>> scope of this module to just the LS1046A. Additionally, I have only added
>>>> support for Ethernet protocols. There is not a great need for dynamic
>>>> reconfiguration for other protocols (SATA and PCIe handle rate changes in
>>>> hardware), so support for them may never be added.>
>>>> Nevertheless, I have tried to provide an obvious path for adding support
>>>> for other SoCs as well as other protocols. SATA just needs support for
>>>> configuring LNmSSCR0. PCIe may need to configure the equalization
>>>> registers. It also uses multiple lanes. I have tried to write the driver
>>>> with multi-lane support in mind, so there should not need to be any large
>>>> changes. Although there are 6 protocols supported, I have only tested SGMII
>>>> and XFI. The rest have been implemented as described in the datasheet.
>>>>
>>>> The PLLs are modeled as clocks proper. This lets us take advantage of the
>>>> existing clock infrastructure. I have not given the same treatment to the
>>>> lane "clocks" (dividers) because they need to be programmed in-concert with
>>>> the rest of the lane settings. One tricky thing is that the VCO (pll) rate
>>>> exceeds 2^32 (maxing out at around 5GHz). This will be a problem on 32-bit
>>>> platforms, since clock rates are stored as unsigned longs. To work around
>>>> this, the pll clock rate is generally treated in units of kHz.>
>>>> The PLLs are configured rather interestingly. Instead of the usual direct
>>>> programming of the appropriate divisors, the input and output clock rates
>>>> are selected directly. Generally, the only restriction is that the input
>>>> and output must be integer multiples of each other. This suggests some kind
>>>> of internal look-up table. The datasheets generally list out the supported
>>>> combinations explicitly, and not all input/output combinations are
>>>> documented. I'm not sure if this is due to lack of support, or due to an
>>>> oversight. If this becomes an issue, then some combinations can be
>>>> blacklisted (or whitelisted). This may also be necessary for other SoCs
>>>> which have more stringent clock requirements.
>>>
>>>
>>> I didn't get a change to go through the driver like I would like, but are you
>>> changing the PLL's rate at runtime?
>
> Yes.
>
>>> Do you take into consideration that a PLL might still be used by a PCIe or SATA
>>> lane (which is not described in the DTS) and deny its rate reconfiguration
>>> if this happens?
>
> Yes.
>
> When the device is probed, we go through the PCCRs and reserve any lane which is in
> use for a protocol we don't support (PCIe, SATA). We also get both PLL's rates
> exclusively and mark them as enabled.
>
>>> I am asking this because when I added support for the Lynx 28G SerDes block what
>>> I did in order to support rate change depending of the plugged SFP module was
>>> just to change the PLL used by the lane, not the PLL rate itself.
>>> This is because I was afraid of causing more harm then needed for all the
>>> non-Ethernet lanes.
>
> Yes. Since There is not much need for dynamic reconfiguration for other protocols,
> I suspect that non-ethernet support will not be added soon (or perhaps ever).
>
>>>>
>>>> The general API call list for this PHY is documented under the driver-api
>>>> docs. I think this is rather standard, except that most driverts configure
>>>> the mode (protocol) at xlate-time. Unlike some other phys where e.g. PCIe
>>>> x4 will use 4 separate phys all configured for PCIe, this driver uses one
>>>> phy configured to use 4 lanes. This is because while the individual lanes
>>>> may be configured individually, the protocol selection acts on all lanes at
>>>> once. Additionally, the order which lanes should be configured in is
>>>> specified by the datasheet. To coordinate this, lanes are reserved in
>>>> phy_init, and released in phy_exit.
>>>>
>>>> When getting a phy, if a phy already exists for those lanes, it is reused.
>>>> This is to make things like QSGMII work. Four MACs will all want to ensure
>>>> that the lane is configured properly, and we need to ensure they can all
>>>> call phy_init, etc. There is refcounting for phy_init and phy_power_on, so
>>>> the phy will only be powered on once. However, there is no refcounting for
>>>> phy_set_mode. A "rogue" MAC could set the mode to something non-QSGMII and
>>>> break the other MACs. Perhaps there is an opportunity for future
>>>> enhancement here.
>>>>
>>>> This driver was written with reference to the LS1046A reference manual.
>>>> However, it was informed by reference manuals for all processors with
>>>> MEMACs, especially the T4240 (which appears to have a "maxed-out"
>>>> configuration).
>>>>
>>>> Signed-off-by: Sean Anderson <sean.anderson@seco.com>
>>>> ---
>>>> This appears to be the same underlying hardware as the Lynx 28G phy
>>>> added in 8f73b37cf3fb ("phy: add support for the Layerscape SerDes
>>>> 28G").
>>>
>>> The SerDes block used on L1046A (and a lot of other SoCs) is not the same
>>> one as the Lynx 28G that I submitted. The Lynx 28G block is only included
>>> on the LX2160A SoC and its variants.
>
> OK. I looked over it quickly and it seemed to share many of the same registers.
I looked at the LX2160ARM today and it seems like the 28g phy is mostly a superset
of the 10g phy. With some careful attention to detail, I think these drivers could
be merged. At the very least, I think it should be possible to create some helper
functions for programming the common registers.
--Sean
>>> The SerDes block that you are adding a driver for is the Lynx 10G SerDes,
>>> which is why I would suggest renaming it to phy-fsl-lynx-10g.c.
>
> Ah, thanks. Is this documented anywhere?
>
> --Sean
>
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH net-next 01/28] dt-bindings: phy: Add QorIQ SerDes binding
2022-06-20 18:51 ` Sean Anderson
@ 2022-06-21 7:12 ` Krzysztof Kozlowski
0 siblings, 0 replies; 25+ messages in thread
From: Krzysztof Kozlowski @ 2022-06-21 7:12 UTC (permalink / raw)
To: Sean Anderson, David S . Miller, Jakub Kicinski, Madalin Bucur,
netdev
Cc: linux-kernel, linux-arm-kernel, Paolo Abeni, Russell King,
Eric Dumazet, Kishon Vijay Abraham I, Krzysztof Kozlowski,
Rob Herring, Vinod Koul, devicetree, linux-phy, Ioana Ciornei
On 20/06/2022 20:51, Sean Anderson wrote:
> On 6/20/22 2:21 PM, Krzysztof Kozlowski wrote:
>>>>> - samsung_usb2_phy_config in drivers/phy/samsung/
>>>>
>>>> This one is a good example - where do you see there compatibles with
>>>> arbitrary numbers attached?
>>>
>>> samsung_usb2_phy_of_match in drivers/phy/samsung/phy-samsung-usb2.c
>>>
>>> There is a different compatible for each SoC variant. Each compatible selects a struct
>>> containing
>>>
>>> - A list of phys, each with custom power on and off functions
>>> - A function which converts a rate to an arbitrary value to program into a register
>>>
>>> This is further documented in Documentation/driver-api/phy/samsung-usb2.rst
>>
>> Exactly, please follow this approach. Compatible is per different
>> device, e.g. different SoC variant. Of course you could have different
>> devices on same SoC, but "1" and "2" are not different devices.
>
> (in this case they are)
In a meaning of descriptive compatible - it's not.
>>>
>>> - For some SerDes on the same SoC, these fields are reserved
>>
>> That all sounds like quite different devices, which indeed usually is
>> described with different compatibles. Still "xxx-1" and "xxx-2" are not
>> valid compatibles. You need to come with some more reasonable name
>> describing them. Maybe the block has revision or different model/vendor.
>
> There is none AFAIK. Maybe someone from NXP can comment (since there are many
> undocumented registers).
Maybe it's also possible to invent some reasonable name based on
protocols supported? If nothing comes then please add a one-liner
comment explaining logic behind 1/2 suffix.
>>> The compatibles suggested were "fsl,ls1046-serdes-1" and -2. As noted above, these are separate
>>> devices which, while having many similarities, have different register layouts and protocol
>>> support. They are *not* 100% compatible with each other. Would you require that clock drivers
>>> for different SoCs use the same compatibles just because they had the same registers, even though
>>> the clocks themselves had different functions and hierarchy?
>>
>> You miss the point. Clock controllers on same SoC have different names
>> used in compatibles. We do not describe them as "vendor,aa-clk-1" and
>> "vendor,aa-clk-2".
>>
>> Come with proper naming and entire discussion might be not valid
>> (although with not perfect naming Rob might come with questions). I
>> cannot propose the name because I don't know these hardware blocks and I
>> do not have access to datasheet.
>>
>> Other way, if any reasonable naming is not possible, could be also to
>> describe the meaning of "-1" suffix, e.g. that it does not mean some
>> index but a variant from specification.
>
> The documentation refers to these devices as "SerDes1", "SerDes2", etc.
>
> Wold you prefer something like
>
> serdes0: phy@1ea0000 {
> compatible = "fsl,ls1046a-serdes";
> variant = <0>;
> };
No, it's the same problem, just embeds compatible in different property.
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH net-next 02/28] dt-bindings: net: fman: Add additional interface properties
2022-06-19 10:33 ` Krzysztof Kozlowski
@ 2022-06-27 23:05 ` Rob Herring
0 siblings, 0 replies; 25+ messages in thread
From: Rob Herring @ 2022-06-27 23:05 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Sean Anderson, David S . Miller, Jakub Kicinski, Madalin Bucur,
netdev, linux-kernel, linux-arm-kernel, Paolo Abeni, Russell King,
Eric Dumazet, Krzysztof Kozlowski, devicetree
On Sun, Jun 19, 2022 at 12:33:22PM +0200, Krzysztof Kozlowski wrote:
> On 18/06/2022 17:55, Sean Anderson wrote:
> > Hi Krzysztof,
> >
> > On 6/17/22 9:16 PM, Krzysztof Kozlowski wrote:
> >> On 17/06/2022 13:32, Sean Anderson wrote:
> >>> At the moment, MEMACs are configured almost completely based on the
> >>> phy-connection-type. That is, if the phy interface is RGMII, it assumed
> >>> that RGMII is supported. For some interfaces, it is assumed that the
> >>> RCW/bootloader has set up the SerDes properly. The actual link state is
> >>> never reported.
> >>>
> >>> To address these shortcomings, the driver will need additional
> >>> information. First, it needs to know how to access the PCS/PMAs (in
> >>> order to configure them and get the link status). The SGMII PCS/PMA is
> >>> the only currently-described PCS/PMA. Add the XFI and QSGMII PCS/PMAs as
> >>> well. The XFI (and 1GBase-KR) PCS/PMA is a c45 "phy" which sits on the
> >>> same MDIO bus as SGMII PCS/PMA. By default they will have conflicting
> >>> addresses, but they are also not enabled at the same time by default.
> >>> Therefore, we can let the default address for the XFI PCS/PMA be the
> >>> same as for SGMII. This will allow for backwards-compatibility.
> >>>
> >>> QSGMII, however, cannot work with the current binding. This is because
> >>> the QSGMII PCS/PMAs are only present on one MAC's MDIO bus. At the
> >>> moment this is worked around by having every MAC write to the PCS/PMA
> >>> addresses (without checking if they are present). This only works if
> >>> each MAC has the same configuration, and only if we don't need to know
> >>> the status. Because the QSGMII PCS/PMA will typically be located on a
> >>> different MDIO bus than the MAC's SGMII PCS/PMA, there is no fallback
> >>> for the QSGMII PCS/PMA.
> >>>
> >>> MEMACs (across all SoCs) support the following protocols:
> >>>
> >>> - MII
> >>> - RGMII
> >>> - SGMII, 1000Base-X, and 1000Base-KX
> >>> - 2500Base-X (aka 2.5G SGMII)
> >>> - QSGMII
> >>> - 10GBase-R (aka XFI) and 10GBase-KR
> >>> - XAUI and HiGig
> >>>
> >>> Each line documents a set of orthogonal protocols (e.g. XAUI is
> >>> supported if and only if HiGig is supported). Additionally,
> >>>
> >>> - XAUI implies support for 10GBase-R
> >>> - 10GBase-R is supported if and only if RGMII is not supported
> >>> - 2500Base-X implies support for 1000Base-X
> >>> - MII implies support for RGMII
> >>>
> >>> To switch between different protocols, we must reconfigure the SerDes.
> >>> This is done by using the standard phys property. We can also use it to
> >>> validate whether different protocols are supported (e.g. using
> >>> phy_validate). This will work for serial protocols, but not RGMII or
> >>> MII. Additionally, we still need to be compatible when there is no
> >>> SerDes.
> >>>
> >>> While we can detect 10G support by examining the port speed (as set by
> >>> fsl,fman-10g-port), we cannot determine support for any of the other
> >>> protocols based on the existing binding. In fact, the binding works
> >>> against us in some respects, because pcsphy-handle is required even if
> >>> there is no possible PCS/PMA for that MAC. To allow for backwards-
> >>> compatibility, we use a boolean-style property for RGMII (instead of
> >>> presence/absence-style). When the property for RGMII is missing, we will
> >>> assume that it is supported. The exception is MII, since no existing
> >>> device trees use it (as far as I could tell).
> >>>
> >>> Unfortunately, QSGMII support will be broken for old device trees. There
> >>> is nothing we can do about this because of the PCS/PMA situation (as
> >>> described above).
> >>>
> >>> Signed-off-by: Sean Anderson <sean.anderson@seco.com>
> >>
> >> Thanks for the patch but you add too many new properties. The file
> >> should be converted to YAML/DT schema first.
> >
> > Perhaps. However, conversion to yaml is a non-trivial task, especially for
> > a complicated binding such as this one. I am more than happy to rework this
> > patch to be based on a yaml conversion, but I do not have the bandwidth to
> > do so myself.
>
> I understand. Although since 2020 - since when we expect the bindings
> to be in YAML - this file grew by 6 properties, because each person
> extends it instead of converting. Each person uses the same excuse...
>
> You add here 5 more, so it would be 11 new properties in total.
>
> >
> > If you have any comments on the binding changes themselves, that would be
> > much appreciated.
>
> Maybe Rob will ack it, but for me the change is too big to be accepted
> in TXT, so no from me.
Above my threshold for not first converting too. Really, I'm pretty
close to saying no .txt file changes at all. Maybe compatible string
updates only, people should be rewarded for not changing their h/w.
Rob
^ permalink raw reply [flat|nested] 25+ messages in thread
end of thread, other threads:[~2022-06-27 23:05 UTC | newest]
Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-06-17 20:32 [PATCH net-next 00/28] [RFC] net: dpaa: Convert to phylink Sean Anderson
2022-06-17 20:32 ` [PATCH net-next 01/28] dt-bindings: phy: Add QorIQ SerDes binding Sean Anderson
2022-06-17 23:27 ` Rob Herring
2022-06-18 1:15 ` Krzysztof Kozlowski
2022-06-18 3:38 ` Sean Anderson
2022-06-19 11:24 ` Krzysztof Kozlowski
2022-06-19 15:53 ` Sean Anderson
2022-06-20 10:54 ` Krzysztof Kozlowski
2022-06-20 17:19 ` Sean Anderson
2022-06-20 18:21 ` Krzysztof Kozlowski
2022-06-20 18:51 ` Sean Anderson
2022-06-21 7:12 ` Krzysztof Kozlowski
2022-06-17 20:32 ` [PATCH net-next 02/28] dt-bindings: net: fman: Add additional interface properties Sean Anderson
2022-06-18 1:16 ` Krzysztof Kozlowski
2022-06-18 15:55 ` Sean Anderson
2022-06-19 10:33 ` Krzysztof Kozlowski
2022-06-27 23:05 ` Rob Herring
2022-06-17 20:32 ` [PATCH net-next 03/28] phy: fsl: Add QorIQ SerDes driver Sean Anderson
2022-06-18 3:02 ` kernel test robot
[not found] ` <GV1PR04MB905598703F5E9A0989662EFDE0AE9@GV1PR04MB9055.eurprd04.prod.outlook.com>
2022-06-18 12:39 ` Ioana Ciornei
2022-06-18 15:52 ` Sean Anderson
2022-06-20 18:53 ` Sean Anderson
2022-06-17 20:33 ` [PATCH net-next 26/28] arm64: dts: ls1046ardb: Add serdes bindings Sean Anderson
2022-06-17 20:33 ` [PATCH net-next 27/28] arm64: dts: ls1046a: Add SerDes bindings Sean Anderson
2022-06-17 20:33 ` [PATCH net-next 28/28] arm64: dts: ls1046a: Specify which MACs support RGMII Sean Anderson
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).