[net-next,v8,1/2] dt-bindings: net: x-powers: add AC200/AC300 EPHY packages

Message ID 20260813-submit-acx00-of-dynamic-v1-v8-1-d2f1c52e87b4@gmail.com (mailing list archive)
State New
Headers
Series net: phy: add X-Powers AC200/AC300 EPHY support |

Commit Message

James Hilliard Aug. 13, 2026, 9:53 p.m. UTC
The AC200 and AC300 contain compatible Fast Ethernet link PHYs which
report the same Clause 22 identifier and use the same link-side register
layout. Their package control paths differ: AC200 control registers are
accessed through the I2C register interface of the companion IC, while
the AC300 control range is at a second Clause 22 address fixed at 16 plus
the link address.

Describe both variants as Ethernet PHY packages. The package reg value is
the link PHY base address and the child supplies the documented PHY ID,
because the identification registers cannot be read until package setup
has completed. The AC300 driver reaches its control range with the PHY
package offset helpers. The AC200 package instead references the
companion IC whose I2C interface provides access to the package controls.

Give fixed hardware variant-specific compatibles. Also provide an ACx00
compatible for systems which can contain either package, with one packed
NVMEM field containing calibration in bits 3 through 0, the AC300 selector
in bit 8 and its low-calibration selector in bit 9. Such a description
contains the potential resources for both backends; the driver consumes
only those selected by the configuration field.

Describe the package clock, supply and optional xMII receive-clock
inversion needed by some integrations. A fixed AC200 package may omit the
NVMEM field and use its internal calibration copy. Limit AC300-capable link
addresses to 0 through 7 so the control address remains in the documented
range 16 through 23.

Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
---
 .../bindings/net/x-powers,acx00-ephy-package.yaml  | 154 +++++++++++++++++++++
 1 file changed, 154 insertions(+)
  

Comments

Jakub Kicinski Aug. 18, 2026, 1:24 a.m. UTC | #1
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
---
dt-bindings: net: x-powers: add AC200/AC300 EPHY packages

This adds a new binding describing the X-Powers AC200 and AC300 Ethernet
PHY packages, with separate compatibles for each fixed variant plus an
ACx00 compatible for boards that can carry either part. It documents the
package clock, supply, packed NVMEM configuration field and the phandle
used to reach the AC200 companion IC.

> diff --git a/Documentation/devicetree/bindings/net/x-powers,acx00-ephy-package.yaml b/Documentation/devicetree/bindings/net/x-powers,acx00-ephy-package.yaml
> new file mode 100644
> index 0000000000000..afe57bd163dd7
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/x-powers,acx00-ephy-package.yaml
> @@ -0,0 +1,154 @@

[ ... ]

> +  x-powers,ac200:
> +    $ref: /schemas/types.yaml#/definitions/phandle
> +    description:
> +      Phandle to the AC200 companion IC providing I2C access to the package
> +      control registers used to power and configure the Ethernet PHY.

[Severity: Low]
Is there a binding for the node this phandle is supposed to point at?

A case-insensitive grep for ac200 under Documentation/devicetree/bindings at
the end of this series matches only this new file; the x-powers mfd directory
contains just x-powers,ac100.yaml and x-powers,axp152.yaml. So the
compatible, bus position (I2C child) and properties of the phandle target
appear to be undocumented, and any device tree using the ac200 or acx00
compatibles would carry a node that dtbs_check reports as undocumented.

The same gap seems to exist on the driver side. ac200_ephy_ctl_create() in
drivers/net/phy/xpowers/ac200.c resolves the phandle and then needs a bound
I2C client with a regmap and a clock:

  client = of_find_i2c_device_by_node(ac200_node);
  ...
  device_lock(&client->dev);
  if (device_is_bound(&client->dev))
          priv->regmap = dev_get_regmap(&client->dev, NULL);
  device_unlock(&client->dev);
  if (!priv->regmap) {
          ret = dev_err_probe(dev, -EPROBE_DEFER, "AC200 driver is not ready\n");

A grep for ac200 in drivers/mfd returns nothing at the end of this series,
so is there any in-tree driver that can bind such an I2C device and provide
that regmap and clock? If not, this path can only ever return -EPROBE_DEFER,
and the AC200/ACx00 half of the new ABI, including the packed NVMEM bit
layout consumed only through that path, cannot be exercised or validated by
a conforming device tree.

Could the companion IC binding be added (or referenced) alongside this file?

> +
> +  x-powers,xmii-rx-clock-inverted:
> +    type: boolean
> +    description:
> +      Invert the xMII receive clock inside the PHY. This is required by some
> +      SoC integrations, including the Allwinner H6 AC200 connection.
> +
> +patternProperties:
> +  ^ethernet-phy@[a-f0-9]+$:
> +    $ref: ethernet-phy.yaml#
> +    properties:
> +      compatible:
> +        const: ethernet-phy-id0044.1400
> +    required:
> +      - compatible
> +    unevaluatedProperties: false

[Severity: Low]
This isn't a bug, but should the child node's reg be constrained here too?

The child schema overrides only compatible, so the link PHY's reg keeps
ethernet-phy.yaml's 0..31 range. The description in this same file says "The
package and child use the same base address", and the ac300/acx00
conditionals below limit the package reg to 7, but neither constraint reaches
the child. A tree like:

  ethernet-phy-package@0 {
          reg = <0>;
          ethernet-phy@1f {
                  reg = <0x1f>;
          };
  };

passes dt_binding_check, as does an AC300 child above address 7.

Nothing is misprogrammed at runtime: acx00_ephy_init_package() in
drivers/net/phy/xpowers/acx00.c rejects the mismatch before joining the
package,

  ret = of_property_read_u32(package_node, "reg", &base_addr);
  if (ret || base_addr != phydev->mdio.addr) {
          ret = dev_err_probe(dev, -EINVAL,
                              "package and link PHY addresses differ\n");

and ac300_ephy_ctl_create() in drivers/net/phy/xpowers/ac300.c rejects
addresses above 7 before any control-range access:

  if (phydev->mdio.addr > FIELD_MAX(AC300_PACKAGE_PHY_ADDR_MASK))
          return ERR_PTR(dev_err_probe(dev, -EINVAL,
                                       "link address is outside the package range\n"));

So the only effect is that an invalid tree fails PHY probe instead of failing
schema validation. Bounding the child reg per variant in the added
patternProperties block would move that detection to dt_binding_check. Note
the existing package binding qcom,qca807x.yaml adds no child-address
constraints either, so the omission matches current convention.

> +
> +required:
> +  - compatible
> +  - vcc-supply

[ ... ]

> +  - if:
> +      properties:
> +        compatible:
> +          const: x-powers,acx00-ephy-package
> +    then:
> +      properties:
> +        reg:
> +          maximum: 7
> +      required:
> +        - clocks
> +        - nvmem-cells
> +        - nvmem-cell-names
> +        - x-powers,ac200

[ ... ]
  

Patch

diff --git a/Documentation/devicetree/bindings/net/x-powers,acx00-ephy-package.yaml b/Documentation/devicetree/bindings/net/x-powers,acx00-ephy-package.yaml
new file mode 100644
index 000000000000..afe57bd163dd
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/x-powers,acx00-ephy-package.yaml
@@ -0,0 +1,154 @@ 
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/net/x-powers,acx00-ephy-package.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: X-Powers AC200 and AC300 Ethernet PHY packages
+
+maintainers:
+  - James Hilliard <james.hilliard1@gmail.com>
+
+description:
+  The AC200 and AC300 contain compatible Fast Ethernet PHY blocks which report
+  the same Clause 22 PHY ID and use the same link-side register layout. The
+  package control paths differ. AC200 package control registers are accessed
+  through the companion IC's I2C register interface, while AC300 control
+  registers occupy a second Clause 22 address fixed at 16 plus the link PHY
+  address.
+
+  Systems with a known package use the corresponding AC200 or AC300 compatible.
+  Systems which can contain either package use the ACx00 compatible and a
+  packed NVMEM configuration field to select the backend at runtime.
+
+  The link PHY cannot report its ID until the package control sequence has
+  completed, so its child node supplies the documented PHY ID. The package and
+  child use the same base address. The AC200 driver programs that address into
+  the package, while the AC300 driver derives its control address from it.
+
+properties:
+  compatible:
+    enum:
+      - x-powers,ac200-ephy-package
+      - x-powers,ac300-ephy-package
+      - x-powers,acx00-ephy-package
+
+  reg:
+    maximum: 31
+
+  clocks:
+    maxItems: 1
+    description: AC300 input clock, running at 24, 25, or 27 MHz
+
+  vcc-supply:
+    description:
+      3.3 V package supply. This is connected to EPHY_VCC on AC200 and VCC1
+      on AC300.
+
+  nvmem-cells:
+    maxItems: 1
+    description:
+      Packed EPHY configuration field. Bits 3 through 0 contain the analog
+      calibration code, bits 7 through 4 are reserved, bit 8 selects AC300
+      when set and AC200 when clear, and bit 9 requests the AC300
+      low-calibration tuning sequence. A fixed AC200 package may provide only
+      the low calibration bits or omit the cell and use its internal eFuse
+      copy instead.
+
+  nvmem-cell-names:
+    const: configuration
+
+  x-powers,ac200:
+    $ref: /schemas/types.yaml#/definitions/phandle
+    description:
+      Phandle to the AC200 companion IC providing I2C access to the package
+      control registers used to power and configure the Ethernet PHY.
+
+  x-powers,xmii-rx-clock-inverted:
+    type: boolean
+    description:
+      Invert the xMII receive clock inside the PHY. This is required by some
+      SoC integrations, including the Allwinner H6 AC200 connection.
+
+patternProperties:
+  ^ethernet-phy@[a-f0-9]+$:
+    $ref: ethernet-phy.yaml#
+    properties:
+      compatible:
+        const: ethernet-phy-id0044.1400
+    required:
+      - compatible
+    unevaluatedProperties: false
+
+required:
+  - compatible
+  - vcc-supply
+
+dependentRequired:
+  nvmem-cells: [ nvmem-cell-names ]
+
+allOf:
+  - $ref: ethernet-phy-package.yaml#
+  - if:
+      properties:
+        compatible:
+          const: x-powers,ac200-ephy-package
+    then:
+      properties:
+        clocks: false
+      required:
+        - x-powers,ac200
+  - if:
+      properties:
+        compatible:
+          const: x-powers,ac300-ephy-package
+    then:
+      properties:
+        reg:
+          maximum: 7
+        x-powers,ac200: false
+      required:
+        - clocks
+        - nvmem-cells
+        - nvmem-cell-names
+  - if:
+      properties:
+        compatible:
+          const: x-powers,acx00-ephy-package
+    then:
+      properties:
+        reg:
+          maximum: 7
+      required:
+        - clocks
+        - nvmem-cells
+        - nvmem-cell-names
+        - x-powers,ac200
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    mdio {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        ethernet-phy-package@0 {
+            compatible = "x-powers,acx00-ephy-package";
+            reg = <0>;
+            #address-cells = <1>;
+            #size-cells = <0>;
+            clocks = <&pwm 5>;
+            vcc-supply = <&reg_3v3>;
+            nvmem-cells = <&ephy_configuration>;
+            nvmem-cell-names = "configuration";
+            x-powers,ac200 = <&ac200>;
+
+            ethernet-phy@0 {
+                compatible = "ethernet-phy-id0044.1400";
+                reg = <0>;
+            };
+        };
+    };
+
+...