The 28G Lynx SerDes is instantiated 3 times in the NXP LX2160A SoC and twice in the NXP LX2162A. All these instances share the same register map, but the number of lanes and the protocols supported by each lane differs in a way that isn't detectable by the programming model. Going by the generic "fsl,lynx-28g" compatible string and expecting all SerDes instantiations to use it was a mistake that needs to be fixed. The two major options considered are (a) encode the SoC and the SerDes instance in the compatible string, everything else is the responsibility of the driver to derive based on this sufficient information (b) add sufficient device tree properties to describe the per-lane differences, as well as the different lane count Another important consideration is that any decision made here should be consistent with the decisions taken for the yet-to-be-introduced 10G Lynx SerDes (older generation for older SoCs), because of how similar they are. I've seen option (b) at play in this unmerged patch set for the 10G Lynx here, and I didn't like it: https://lore.kernel.org/linux-phy/20230413160607.4128315-3-sean.anderson@seco.com/ This is because there, we have a higher degree of variability in the PCCR register values that need to be written per protocol. This makes that approach more drawn-out and more prone to errors, compared to (a) which is more succinct and obviously correct. So I've chosen option (a) through elimination, and this also reflects how the SoC reference manual provides different tables with protocol combinations for each SerDes. NXP clearly documents these as not identical, and refers to them as such (SerDes 1, 2, etc). The per-SoC compatible string is prepended to the "fsl,lynx-28g" generic compatible, which is left there for compatibility with old kernels. An exception would be LX2160A SerDes #3, which at the time of writing is not described in fsl-lx2160a.dtsi, and is a non-networking SerDes, so the existing Linux driver is useless for it. So there is no practical reason to put the "fsl,lynx-28g" fallback for "fsl,lx2160a-serdes3". The specific compatible strings give us the opportunity to express more constraints in the schema that we weren't able to express before: - We allow #phy-cells in the top-level SerDes node only for compatibility with old kernels that don't know how to translate "phys = <&serdes_1_lane_a>" to a PHY. We don't need that feature for the not-yet-introduced LX2160A SerDes #3, so make the presence of #phy-cells at the top level be dependent on the presence of the "fsl,lynx-28g" fallback compatible. - The modernization of the compatible string should come together with per-lane OF nodes. - LX2162A SerDes 1 has fewer lanes than the others, and trying to use lanes 0-3 would be a mistake that could be caught by the schema. Cc: Rob Herring Cc: Krzysztof Kozlowski Cc: Conor Dooley Cc: devicetree@vger.kernel.org Signed-off-by: Vladimir Oltean --- part 1 -> part 2: - drop everything having to do with constraints (on #phy-cells, #address-cells, #size-cells) based on new compatible strings. Patch made its last appearance in v4 from part 1: https://lore.kernel.org/linux-phy/20251110092241.1306838-16-vladimir.oltean@nxp.com/ v3->v4: - OF nodes per lane broken out as a separate "[PATCH v4 phy 01/16] dt-bindings: phy: lynx-28g: permit lane OF PHY providers" - rewritten commit message - s|"^phy@[0-9a-f]+$"|"^phy@[0-7]$"|g in patternProperties - define "#address-cells" and "#size-cells" as part of common properties, only leave the part which marks them required in the allOf constraints area v2->v3: - re-add "fsl,lynx-28g" as fallback compatible, and #phy-cells = <1> in top-level "serdes" node - drop useless description texts - fix text formatting - schema is more lax to allow overlaying old and new required properties v1->v2: - drop the usage of "fsl,lynx-28g" as a fallback compatible - mark "fsl,lynx-28g" as deprecated - implement Josua's request for per-lane OF nodes for the new compatible strings .../devicetree/bindings/phy/fsl,lynx-28g.yaml | 33 +++++++++++++++++-- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/phy/fsl,lynx-28g.yaml b/Documentation/devicetree/bindings/phy/fsl,lynx-28g.yaml index e96229c2f8fb..8375bca810cc 100644 --- a/Documentation/devicetree/bindings/phy/fsl,lynx-28g.yaml +++ b/Documentation/devicetree/bindings/phy/fsl,lynx-28g.yaml @@ -9,10 +9,37 @@ title: Freescale Lynx 28G SerDes PHY maintainers: - Ioana Ciornei +description: + The Lynx 28G is a multi-lane, multi-protocol SerDes (PCIe, SATA, Ethernet) + present in multiple instances on NXP LX2160A and LX2162A SoCs. All instances + share a common register map and programming model, however they differ in + supported protocols per lane in a way that is not detectable by said + programming model without prior knowledge. The distinction is made through + the compatible string. + properties: compatible: - enum: - - fsl,lynx-28g + oneOf: + - const: fsl,lynx-28g + deprecated: true + description: + Legacy compatibility string for Lynx 28G SerDes. Any assumption + regarding whether a certain lane supports a certain protocol may + be incorrect. Deprecated except when used as a fallback. Use + device-specific strings instead. + - items: + - const: fsl,lx2160a-serdes1 + - const: fsl,lynx-28g + - items: + - const: fsl,lx2160a-serdes2 + - const: fsl,lynx-28g + - items: + - const: fsl,lx2162a-serdes1 + - const: fsl,lynx-28g + - items: + - const: fsl,lx2162a-serdes2 + - const: fsl,lynx-28g + - const: fsl,lx2160a-serdes3 reg: maxItems: 1 @@ -60,7 +87,7 @@ examples: #size-cells = <2>; serdes@1ea0000 { - compatible = "fsl,lynx-28g"; + compatible = "fsl,lx2160a-serdes1", "fsl,lynx-28g"; reg = <0x0 0x1ea0000 0x0 0x1e30>; #address-cells = <1>; #size-cells = <0>; -- 2.34.1