mbox series

[net-next,RFC,v3,0/8] net: phy: Support DT PHY package

Message ID 20231126015346.25208-1-ansuelsmth@gmail.com
Headers show
Series net: phy: Support DT PHY package | expand

Message

Christian Marangi Nov. 26, 2023, 1:53 a.m. UTC
This depends on another series for PHY package API change. [1]

Idea of this big series is to introduce the concept of PHY package in DT
and generalize the support of it by PHY driver.

The concept of PHY package is nothing new and is already a thing in the
kernel with the API phy_package_join/leave/read/write.

The main idea of those API is to permit the PHY to have a shared global
data and to run probe/config only once for the PHY package. There are
various example of this already in the kernel with the mscc, bcm54140
mediatek ge and micrle driver and they all follow the same pattern.

What is currently lacking is describing this in DT and better reference
the PHY in charge of global configuration of the PHY package. For the
already present PHY, the implementation is simple enough with only one
PHY having the required regs to apply global configuration.

This can be ok for simple PHY package but some Qcom PHY package on
""modern"" SoC have more complex implementation. One example is the PHY
for qca807x where some global regs are present in the so-called "combo"
port and everything about psgmii calibration is placed in a 5th port in
the PHY package.

Given these additional thing, the original phy_package API are extended
with support for multiple global PHY for configuration. Each PHY driver
will have an enum of the ID for the global PHY to reference and is
required to pass to the read/write function.

On top of this, it's added correct DT support for describing PHY
package.

One example is this:

        ethernet-phy-package@0 {
            compatible = "ethernet-phy-package";
            #address-cells = <1>;
            #size-cells = <0>;

            reg = <0>;
            qcom,package-mode = "qsgmii";

            ethernet-phy@1 {
              reg = <1>;
            };

            phy4: ethernet-phy@4 {
              reg = <4>;
            };
        };

The mdio parse functions are changed to address for this additional
special node, the function is changed to simply detect this node and
search also in this.

If this is detected phy core will join each PHY present in the node and
use (if defined) the additional info in the PHY driver to probe/config
once the PHY package.

I hope this implementation is clean enough as I expect more and more of
these configuration to appear in the future.

(For Andrew, we are looking intro making this in at803x PHY driver and see
what functions can be reused, idea is to move the driver to a dedicated
directory and create something like at803x-common.c as the at803x PHY
driver is too bloated and splitting it it's a better approach)

[1] https://patchwork.kernel.org/project/netdevbpf/patch/20231126003748.9600-1-ansuelsmth@gmail.com/

Changes v3:
- Add back compatible implementation
- Detach patch that can be handled separately (phy_package_mmd, 
  phy_package extended)
- Rework code to new simplified implementation with base addr + offset
- Improve documentation with additional info and description
Changes v2:
- Drop compatible "ethernet-phy-package", use node name prefix matching
  instead
- Improve DT example
- Add reg for ethernet-phy-package
- Drop phy-mode for ethernet-phy-package
- Drop patch for generalization of phy-mode
- Drop global-phy property (handle internally to the PHY driver)
- Rework OF phy package code and PHY driver to handle base address
- Fix missing of_node_put
- Add some missing docs for added variables in struct
- Move some define from dt-bindings include to PHY driver
- Handle qsgmii validation in PHY driver
- Fix wrong include for gpiolib
- Drop reduntant version.h include

Christian Marangi (6):
  dt-bindings: net: document ethernet PHY package nodes
  net: phy: add initial support for PHY package in DT
  net: phy: add support for shared priv data size for PHY package in DT
  net: phy: add support for driver specific PHY package probe/config
  dt-bindings: net: Document Qcom QCA807x PHY package
  net: phy: qca807x: Add support for configurable LED

Robert Marko (2):
  dt-bindings: net: add QCA807x PHY defines
  net: phy: add Qualcom QCA807x driver

 .../bindings/net/ethernet-phy-package.yaml    |   75 +
 .../devicetree/bindings/net/qcom,qca807x.yaml |  136 ++
 drivers/net/mdio/of_mdio.c                    |   68 +-
 drivers/net/phy/Kconfig                       |    7 +
 drivers/net/phy/Makefile                      |    1 +
 drivers/net/phy/mdio_bus.c                    |   35 +-
 drivers/net/phy/phy_device.c                  |   54 +
 drivers/net/phy/qca807x.c                     | 1315 +++++++++++++++++
 include/dt-bindings/net/qcom-qca807x.h        |   30 +
 include/linux/phy.h                           |   27 +
 10 files changed, 1719 insertions(+), 29 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/net/ethernet-phy-package.yaml
 create mode 100644 Documentation/devicetree/bindings/net/qcom,qca807x.yaml
 create mode 100644 drivers/net/phy/qca807x.c
 create mode 100644 include/dt-bindings/net/qcom-qca807x.h

Comments

Rob Herring (Arm) Nov. 27, 2023, 10:16 p.m. UTC | #1
On Sun, Nov 26, 2023 at 02:53:39AM +0100, Christian Marangi wrote:
> Document ethernet PHY package nodes used to describe PHY shipped in
> bundle of 4-5 PHY. The special node describe a container of PHY that
> share common properties. This is a generic schema and PHY package
> should create specialized version with the required additional shared
> properties.
> 
> Example are PHY package that have some regs only in one PHY of the
> package and will affect every other PHY in the package, for example
> related to PHY interface mode calibration or global PHY mode selection.
> 
> The PHY package node MUST declare the base address used by the PHY driver
> for global configuration by calculating the offsets of the global PHY
> based on the base address of the PHY package and declare the
> "ethrnet-phy-package" compatible.
> 
> Each reg of the PHY defined in the PHY package node is absolute and will
> reference the real address of the PHY on the bus.
> 
> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> ---
>  .../bindings/net/ethernet-phy-package.yaml    | 75 +++++++++++++++++++
>  1 file changed, 75 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/ethernet-phy-package.yaml
> 
> diff --git a/Documentation/devicetree/bindings/net/ethernet-phy-package.yaml b/Documentation/devicetree/bindings/net/ethernet-phy-package.yaml
> new file mode 100644
> index 000000000000..244d4bc29164
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/ethernet-phy-package.yaml
> @@ -0,0 +1,75 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/net/ethernet-phy-package.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Ethernet PHY Package Common Properties
> +
> +maintainers:
> +  - Christian Marangi <ansuelsmth@gmail.com>
> +
> +description:
> +  This schema describe PHY package as simple container for
> +  a bundle of PHYs that share the same properties and
> +  contains the PHYs of the package themself.
> +
> +  Each reg of the PHYs defined in the PHY package node is
> +  absolute and describe the real address of the PHY on the bus.
> +
> +properties:
> +  $nodename:
> +    pattern: "^ethernet-phy-package(@[a-f0-9]+)?$"
> +
> +  compatible:
> +    const: ethernet-phy-package

In case I wasn't clear, but that compatible is a NAK.

> +
> +  reg:
> +    minimum: 0
> +    maximum: 31

Pretty sure the bus binding already provides these constraints.

> +    description:
> +      The base ID number for the PHY package.
> +      Commonly the ID of the first PHY in the PHY package.
> +
> +      Some PHY in the PHY package might be not defined but
> +      still exist on the device (just not attached to anything).
> +      The reg defined in the PHY package node might differ and
> +      the related PHY might be not defined.
> +
> +  '#address-cells':
> +    const: 1
> +
> +  '#size-cells':
> +    const: 0

You are implementing a secondary MDIO bus within this node. It needs a 
$ref to mdio.yaml instead of defining the bus again implicitly.

> +
> +patternProperties:
> +  ^ethernet-phy(@[a-f0-9]+)?$:
> +    $ref: ethernet-phy.yaml#
> +
> +required:
> +  - compatible
> +  - reg
> +
> +additionalProperties: true
> +
> +examples:
> +  - |
> +    mdio {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        ethernet-phy-package@16 {
> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +            compatible = "ethernet-phy-package";
> +            reg = <0x16>;
> +
> +            ethernet-phy@16 {
> +              reg = <0x16>;
> +            };
> +
> +            phy4: ethernet-phy@1a {
> +              reg = <0x1a>;
> +            };

This example on its own doesn't make sense. It can't be fully validated 
because you allow any additional properties. Drop it.

> +        };
> +    };
> -- 
> 2.40.1
>
Rob Herring (Arm) Nov. 27, 2023, 10:36 p.m. UTC | #2
On Sun, Nov 26, 2023 at 02:53:43AM +0100, Christian Marangi wrote:
> From: Robert Marko <robert.marko@sartura.hr>
> 
> Add DT bindings defined for Qualcomm QCA807x PHY series related to
> calibration and DAC settings.
> 
> Signed-off-by: Robert Marko <robert.marko@sartura.hr>
> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> ---
>  include/dt-bindings/net/qcom-qca807x.h | 30 ++++++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
>  create mode 100644 include/dt-bindings/net/qcom-qca807x.h

How is this used? There's nothing in the binding about it. Binding 
headers go with the binding schema that define how they are used.

> 
> diff --git a/include/dt-bindings/net/qcom-qca807x.h b/include/dt-bindings/net/qcom-qca807x.h
> new file mode 100644
> index 000000000000..e7d4d09b7dd4
> --- /dev/null
> +++ b/include/dt-bindings/net/qcom-qca807x.h
> @@ -0,0 +1,30 @@
> +/* SPDX-License-Identifier: GPL-2.0-only OR MIT */
> +/*
> + * Device Tree constants for the Qualcomm QCA807X PHYs
> + */
> +
> +#ifndef _DT_BINDINGS_QCOM_QCA807X_H
> +#define _DT_BINDINGS_QCOM_QCA807X_H
> +
> +/* Full amplitude, full bias current */
> +#define QCA807X_CONTROL_DAC_FULL_VOLT_BIAS		0
> +/* Amplitude follow DSP (amplitude is adjusted based on cable length), half bias current */
> +#define QCA807X_CONTROL_DAC_DSP_VOLT_HALF_BIAS		1
> +/* Full amplitude, bias current follow DSP (bias current is adjusted based on cable length) */
> +#define QCA807X_CONTROL_DAC_FULL_VOLT_DSP_BIAS		2
> +/* Both amplitude and bias current follow DSP */
> +#define QCA807X_CONTROL_DAC_DSP_VOLT_BIAS		3
> +/* Full amplitude, half bias current */
> +#define QCA807X_CONTROL_DAC_FULL_VOLT_HALF_BIAS		4
> +/* Amplitude follow DSP setting; 1/4 bias current when cable<10m,
> + * otherwise half bias current
> + */
> +#define QCA807X_CONTROL_DAC_DSP_VOLT_QUARTER_BIAS	5
> +/* Full amplitude; same bias current setting with “010” and “011”,
> + * but half more bias is reduced when cable <10m
> + */
> +#define QCA807X_CONTROL_DAC_FULL_VOLT_HALF_BIAS_SHORT	6
> +/* Amplitude follow DSP; same bias current setting with “110”, default value */
> +#define QCA807X_CONTROL_DAC_DSP_VOLT_HALF_BIAS_SHORT	7
> +
> +#endif
> -- 
> 2.40.1
>
Sergey Ryazanov Jan. 7, 2024, 6 p.m. UTC | #3
Hi Christian and Robert,

thank you for this great work!

Let me ask a couple of questions regarding the phy package conception. 
Please find them below.

On 26.11.2023 03:53, Christian Marangi wrote:
> Document ethernet PHY package nodes used to describe PHY shipped in
> bundle of 4-5 PHY. The special node describe a container of PHY that
> share common properties. This is a generic schema and PHY package
> should create specialized version with the required additional shared
> properties.
> 
> Example are PHY package that have some regs only in one PHY of the
> package and will affect every other PHY in the package, for example
> related to PHY interface mode calibration or global PHY mode selection.
> 
> The PHY package node MUST declare the base address used by the PHY driver
> for global configuration by calculating the offsets of the global PHY
> based on the base address of the PHY package and declare the
> "ethrnet-phy-package" compatible.
> 
> Each reg of the PHY defined in the PHY package node is absolute and will
> reference the real address of the PHY on the bus.
> 
> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> ---
>   .../bindings/net/ethernet-phy-package.yaml    | 75 +++++++++++++++++++
>   1 file changed, 75 insertions(+)
>   create mode 100644 Documentation/devicetree/bindings/net/ethernet-phy-package.yaml
> 
> diff --git a/Documentation/devicetree/bindings/net/ethernet-phy-package.yaml b/Documentation/devicetree/bindings/net/ethernet-phy-package.yaml
> new file mode 100644
> index 000000000000..244d4bc29164
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/ethernet-phy-package.yaml
> @@ -0,0 +1,75 @@
> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/net/ethernet-phy-package.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Ethernet PHY Package Common Properties
> +
> +maintainers:
> +  - Christian Marangi <ansuelsmth@gmail.com>
> +
> +description:
> +  This schema describe PHY package as simple container for
> +  a bundle of PHYs that share the same properties and
> +  contains the PHYs of the package themself.
> +
> +  Each reg of the PHYs defined in the PHY package node is
> +  absolute and describe the real address of the PHY on the bus.
> +
> +properties:
> +  $nodename:
> +    pattern: "^ethernet-phy-package(@[a-f0-9]+)?$"
> +
> +  compatible:
> +    const: ethernet-phy-package
> +
> +  reg:
> +    minimum: 0
> +    maximum: 31
> +    description:
> +      The base ID number for the PHY package.
> +      Commonly the ID of the first PHY in the PHY package.
> +
> +      Some PHY in the PHY package might be not defined but
> +      still exist on the device (just not attached to anything).
> +      The reg defined in the PHY package node might differ and
> +      the related PHY might be not defined.
> +
> +  '#address-cells':
> +    const: 1
> +
> +  '#size-cells':
> +    const: 0
> +
> +patternProperties:
> +  ^ethernet-phy(@[a-f0-9]+)?$:
> +    $ref: ethernet-phy.yaml#
> +
> +required:
> +  - compatible
> +  - reg
> +
> +additionalProperties: true
> +
> +examples:
> +  - |
> +    mdio {
> +        #address-cells = <1>;
> +        #size-cells = <0>;
> +
> +        ethernet-phy-package@16 {
> +            #address-cells = <1>;
> +            #size-cells = <0>;
> +            compatible = "ethernet-phy-package";
> +            reg = <0x16>;
> +
> +            ethernet-phy@16 {
> +              reg = <0x16>;
> +            };
> +
> +            phy4: ethernet-phy@1a {
> +              reg = <0x1a>;
> +            };
> +        };
> +    };

So, we ended up on a design where we use the predefined compatible 
string 'ethernet-phy-package' to recognize a phy package inside the 
of_mdiobus_register() function. During the V1 discussion, Vladimir came 
up with the idea of 'ranges' property usage [1]. Can we use 'ranges' to 
recognize a phy package in of_mdiobus_register()? IMHO this will give us 
a clear DT solution. I mean 'ranges' clearly indicates that child nodes 
are in the same address range as the parent node. Also we can list all 
child addresses in 'reg' to mark them occupied.

   mdio {
     ...

     ethernet-phy-package@16 {
       compatible = "qcom,qca8075";
       reg = <0x16>, <0x17>, <0x18>, <0x19>, <0x1a>;
       ranges;
       ...

       ethernet-phy@16 {
         reg = <0x16>;
       };

       ethernet-phy@1a {
         reg = <0x1a>;
       };
     };
   };

Did you find some issues with the 'ranges' conception?


And I would like to ask you about another issue raised by Vladimir [1]. 
These phy chips become SoC with all these built-in PHYs, PCSs, clocks, 
interrupt controllers, etc. Should we address this now? Or should we go 
with the proposed solution for now and postpone modeling of other 
peripherals until we get a real hardware, as Andrew suggested?

I'm asking because it looks like we have got a real hardware. Luo 
currently trying to push QCA8084 (multi-phy/switch chip) support, and 
this chip exactly contains a huge clock/reset controller [2,3].


1. https://lore.kernel.org/lkml/20231124165923.p2iozsrnwlogjzua@skbuf // 
Re: [net-next RFC PATCH 03/14] dt-bindings: net: document ethernet PHY 
package nodes
2. 
https://lore.kernel.org/lkml/20231215074005.26976-1-quic_luoj@quicinc.com 
  // [PATCH v8 00/14] add qca8084 ethernet phy driver
3. 
https://lore.kernel.org/lkml/20231104034858.9159-1-quic_luoj@quicinc.com 
  // [PATCH v12 0/4] add clock controller of qca8386/qca8084

--
Sergey
Christian Marangi Jan. 7, 2024, 6:30 p.m. UTC | #4
On Sun, Jan 07, 2024 at 08:00:33PM +0200, Sergey Ryazanov wrote:
> Hi Christian and Robert,
> 
> thank you for this great work!
> 
> Let me ask a couple of questions regarding the phy package conception.
> Please find them below.
> 
> On 26.11.2023 03:53, Christian Marangi wrote:
> > Document ethernet PHY package nodes used to describe PHY shipped in
> > bundle of 4-5 PHY. The special node describe a container of PHY that
> > share common properties. This is a generic schema and PHY package
> > should create specialized version with the required additional shared
> > properties.
> > 
> > Example are PHY package that have some regs only in one PHY of the
> > package and will affect every other PHY in the package, for example
> > related to PHY interface mode calibration or global PHY mode selection.
> > 
> > The PHY package node MUST declare the base address used by the PHY driver
> > for global configuration by calculating the offsets of the global PHY
> > based on the base address of the PHY package and declare the
> > "ethrnet-phy-package" compatible.
> > 
> > Each reg of the PHY defined in the PHY package node is absolute and will
> > reference the real address of the PHY on the bus.
> > 
> > Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> > ---
> >   .../bindings/net/ethernet-phy-package.yaml    | 75 +++++++++++++++++++
> >   1 file changed, 75 insertions(+)
> >   create mode 100644 Documentation/devicetree/bindings/net/ethernet-phy-package.yaml
> > 
> > diff --git a/Documentation/devicetree/bindings/net/ethernet-phy-package.yaml b/Documentation/devicetree/bindings/net/ethernet-phy-package.yaml
> > new file mode 100644
> > index 000000000000..244d4bc29164
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/net/ethernet-phy-package.yaml
> > @@ -0,0 +1,75 @@
> > +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/net/ethernet-phy-package.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: Ethernet PHY Package Common Properties
> > +
> > +maintainers:
> > +  - Christian Marangi <ansuelsmth@gmail.com>
> > +
> > +description:
> > +  This schema describe PHY package as simple container for
> > +  a bundle of PHYs that share the same properties and
> > +  contains the PHYs of the package themself.
> > +
> > +  Each reg of the PHYs defined in the PHY package node is
> > +  absolute and describe the real address of the PHY on the bus.
> > +
> > +properties:
> > +  $nodename:
> > +    pattern: "^ethernet-phy-package(@[a-f0-9]+)?$"
> > +
> > +  compatible:
> > +    const: ethernet-phy-package
> > +
> > +  reg:
> > +    minimum: 0
> > +    maximum: 31
> > +    description:
> > +      The base ID number for the PHY package.
> > +      Commonly the ID of the first PHY in the PHY package.
> > +
> > +      Some PHY in the PHY package might be not defined but
> > +      still exist on the device (just not attached to anything).
> > +      The reg defined in the PHY package node might differ and
> > +      the related PHY might be not defined.
> > +
> > +  '#address-cells':
> > +    const: 1
> > +
> > +  '#size-cells':
> > +    const: 0
> > +
> > +patternProperties:
> > +  ^ethernet-phy(@[a-f0-9]+)?$:
> > +    $ref: ethernet-phy.yaml#
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +
> > +additionalProperties: true
> > +
> > +examples:
> > +  - |
> > +    mdio {
> > +        #address-cells = <1>;
> > +        #size-cells = <0>;
> > +
> > +        ethernet-phy-package@16 {
> > +            #address-cells = <1>;
> > +            #size-cells = <0>;
> > +            compatible = "ethernet-phy-package";
> > +            reg = <0x16>;
> > +
> > +            ethernet-phy@16 {
> > +              reg = <0x16>;
> > +            };
> > +
> > +            phy4: ethernet-phy@1a {
> > +              reg = <0x1a>;
> > +            };
> > +        };
> > +    };
> 
> So, we ended up on a design where we use the predefined compatible string
> 'ethernet-phy-package' to recognize a phy package inside the
> of_mdiobus_register() function. During the V1 discussion, Vladimir came up
> with the idea of 'ranges' property usage [1]. Can we use 'ranges' to
> recognize a phy package in of_mdiobus_register()? IMHO this will give us a
> clear DT solution. I mean 'ranges' clearly indicates that child nodes are in
> the same address range as the parent node. Also we can list all child
> addresses in 'reg' to mark them occupied.
> 
>   mdio {
>     ...
> 
>     ethernet-phy-package@16 {
>       compatible = "qcom,qca8075";
>       reg = <0x16>, <0x17>, <0x18>, <0x19>, <0x1a>;
>       ranges;
>       ...
> 
>       ethernet-phy@16 {
>         reg = <0x16>;
>       };
> 
>       ethernet-phy@1a {
>         reg = <0x1a>;
>       };
>     };
>   };
> 
> Did you find some issues with the 'ranges' conception?
>

Nope it's ok but it might pose some confusion with the idea that the
very first element MUST be THE STARTING ADDR of the PHY package. (people
might think that it's just the list of the PHYs in the package and
remove the hardware unconnected ones... but that would be fault of who
write the DT anyway.)

> 
> And I would like to ask you about another issue raised by Vladimir [1].
> These phy chips become SoC with all these built-in PHYs, PCSs, clocks,
> interrupt controllers, etc. Should we address this now? Or should we go with
> the proposed solution for now and postpone modeling of other peripherals
> until we get a real hardware, as Andrew suggested?
> 

Honestly I would postpone untile we have a clear idea of what is
actually part of the PHY and what can be handled externally... Example
setting the clock in gcc, writing a specific driver...

It's a random idea but maybe most of the stuff required for that PHY is
just when it's connected to a switch... In that case it would all be
handled in the switch driver (tobe extended qca8k) and all these extra
stuff would be placed in that node instead of bloating phy nodes with
all kind of clk and other stuff.

This series still require 2 more series (at803x splint and cleanup) to be
actually proposed so we have some time to better define this.

What do you think?

> I'm asking because it looks like we have got a real hardware. Luo currently
> trying to push QCA8084 (multi-phy/switch chip) support, and this chip
> exactly contains a huge clock/reset controller [2,3].
> 
> 
> 1. https://lore.kernel.org/lkml/20231124165923.p2iozsrnwlogjzua@skbuf // Re:
> [net-next RFC PATCH 03/14] dt-bindings: net: document ethernet PHY package
> nodes
> 2. https://lore.kernel.org/lkml/20231215074005.26976-1-quic_luoj@quicinc.com
> // [PATCH v8 00/14] add qca8084 ethernet phy driver
> 3. https://lore.kernel.org/lkml/20231104034858.9159-1-quic_luoj@quicinc.com
> // [PATCH v12 0/4] add clock controller of qca8386/qca8084
> 
> --
> Sergey
Andrew Lunn Jan. 7, 2024, 6:31 p.m. UTC | #5
> And I would like to ask you about another issue raised by Vladimir [1].
> These phy chips become SoC with all these built-in PHYs, PCSs, clocks,
> interrupt controllers, etc. Should we address this now? Or should we go with
> the proposed solution for now and postpone modeling of other peripherals
> until we get a real hardware, as Andrew suggested?
> 
> I'm asking because it looks like we have got a real hardware. Luo currently
> trying to push QCA8084 (multi-phy/switch chip) support, and this chip
> exactly contains a huge clock/reset controller [2,3].

Ideally the reset controller is modelled as a Linux reset
controller. The clock part of it is modelled using the common clock
framework. When done correctly, the PHY should not really care. All it
does is ask for its clock to be enabled, and its reset to be disabled.

Also, given how difficult it is proving to be to make any progress at
all, i want to get one little part correctly described, the pure
PHY. Once we have that, we can start on the next little part. So long
as we keep to the Linux architecture of blocks or hardware with
standard Linux drivers, and DT to glue them together, a small step by
step approach should work out.

     Andrew
Andrew Lunn Jan. 7, 2024, 6:44 p.m. UTC | #6
> Honestly I would postpone untile we have a clear idea of what is
> actually part of the PHY and what can be handled externally... Example
> setting the clock in gcc, writing a specific driver...

That is really core of the problem here. We have no reliable
description of the hardware. The datasheet often starts with a block
diagram of the PHY package. Sometimes there is a product brief with
the same diagram. We need that published. I'm not asking for the full
data sheet, just the introductory text which gives a high level
overview of what the hardware actually is. Then we can sketch out a
high level Linux architecture for the PHY package.

     Andrew
Christian Marangi Jan. 7, 2024, 9:45 p.m. UTC | #7
On Sun, Jan 07, 2024 at 11:49:12PM +0200, Sergey Ryazanov wrote:
> Hi Christian,
> 
> On 07.01.2024 20:30, Christian Marangi wrote:
> > On Sun, Jan 07, 2024 at 08:00:33PM +0200, Sergey Ryazanov wrote:
> > > On 26.11.2023 03:53, Christian Marangi wrote:
> > > > Document ethernet PHY package nodes used to describe PHY shipped in
> > > > bundle of 4-5 PHY. The special node describe a container of PHY that
> > > > share common properties. This is a generic schema and PHY package
> > > > should create specialized version with the required additional shared
> > > > properties.
> > > > 
> > > > Example are PHY package that have some regs only in one PHY of the
> > > > package and will affect every other PHY in the package, for example
> > > > related to PHY interface mode calibration or global PHY mode selection.
> > > > 
> > > > The PHY package node MUST declare the base address used by the PHY driver
> > > > for global configuration by calculating the offsets of the global PHY
> > > > based on the base address of the PHY package and declare the
> > > > "ethrnet-phy-package" compatible.
> > > > 
> > > > Each reg of the PHY defined in the PHY package node is absolute and will
> > > > reference the real address of the PHY on the bus.
> > > > 
> > > > Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> > > > ---
> > > >    .../bindings/net/ethernet-phy-package.yaml    | 75 +++++++++++++++++++
> > > >    1 file changed, 75 insertions(+)
> > > >    create mode 100644 Documentation/devicetree/bindings/net/ethernet-phy-package.yaml
> > > > 
> > > > diff --git a/Documentation/devicetree/bindings/net/ethernet-phy-package.yaml b/Documentation/devicetree/bindings/net/ethernet-phy-package.yaml
> > > > new file mode 100644
> > > > index 000000000000..244d4bc29164
> > > > --- /dev/null
> > > > +++ b/Documentation/devicetree/bindings/net/ethernet-phy-package.yaml
> > > > @@ -0,0 +1,75 @@
> > > > +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> > > > +%YAML 1.2
> > > > +---
> > > > +$id: http://devicetree.org/schemas/net/ethernet-phy-package.yaml#
> > > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > > +
> > > > +title: Ethernet PHY Package Common Properties
> > > > +
> > > > +maintainers:
> > > > +  - Christian Marangi <ansuelsmth@gmail.com>
> > > > +
> > > > +description:
> > > > +  This schema describe PHY package as simple container for
> > > > +  a bundle of PHYs that share the same properties and
> > > > +  contains the PHYs of the package themself.
> > > > +
> > > > +  Each reg of the PHYs defined in the PHY package node is
> > > > +  absolute and describe the real address of the PHY on the bus.
> > > > +
> > > > +properties:
> > > > +  $nodename:
> > > > +    pattern: "^ethernet-phy-package(@[a-f0-9]+)?$"
> > > > +
> > > > +  compatible:
> > > > +    const: ethernet-phy-package
> > > > +
> > > > +  reg:
> > > > +    minimum: 0
> > > > +    maximum: 31
> > > > +    description:
> > > > +      The base ID number for the PHY package.
> > > > +      Commonly the ID of the first PHY in the PHY package.
> > > > +
> > > > +      Some PHY in the PHY package might be not defined but
> > > > +      still exist on the device (just not attached to anything).
> > > > +      The reg defined in the PHY package node might differ and
> > > > +      the related PHY might be not defined.
> > > > +
> > > > +  '#address-cells':
> > > > +    const: 1
> > > > +
> > > > +  '#size-cells':
> > > > +    const: 0
> > > > +
> > > > +patternProperties:
> > > > +  ^ethernet-phy(@[a-f0-9]+)?$:
> > > > +    $ref: ethernet-phy.yaml#
> > > > +
> > > > +required:
> > > > +  - compatible
> > > > +  - reg
> > > > +
> > > > +additionalProperties: true
> > > > +
> > > > +examples:
> > > > +  - |
> > > > +    mdio {
> > > > +        #address-cells = <1>;
> > > > +        #size-cells = <0>;
> > > > +
> > > > +        ethernet-phy-package@16 {
> > > > +            #address-cells = <1>;
> > > > +            #size-cells = <0>;
> > > > +            compatible = "ethernet-phy-package";
> > > > +            reg = <0x16>;
> > > > +
> > > > +            ethernet-phy@16 {
> > > > +              reg = <0x16>;
> > > > +            };
> > > > +
> > > > +            phy4: ethernet-phy@1a {
> > > > +              reg = <0x1a>;
> > > > +            };
> > > > +        };
> > > > +    };
> > > 
> > > So, we ended up on a design where we use the predefined compatible string
> > > 'ethernet-phy-package' to recognize a phy package inside the
> > > of_mdiobus_register() function. During the V1 discussion, Vladimir came up
> > > with the idea of 'ranges' property usage [1]. Can we use 'ranges' to
> > > recognize a phy package in of_mdiobus_register()? IMHO this will give us a
> > > clear DT solution. I mean 'ranges' clearly indicates that child nodes are in
> > > the same address range as the parent node. Also we can list all child
> > > addresses in 'reg' to mark them occupied.
> > > 
> > >    mdio {
> > >      ...
> > > 
> > >      ethernet-phy-package@16 {
> > >        compatible = "qcom,qca8075";
> > >        reg = <0x16>, <0x17>, <0x18>, <0x19>, <0x1a>;
> > >        ranges;
> > >        ...
> > > 
> > >        ethernet-phy@16 {
> > >          reg = <0x16>;
> > >        };
> > > 
> > >        ethernet-phy@1a {
> > >          reg = <0x1a>;
> > >        };
> > >      };
> > >    };
> > > 
> > > Did you find some issues with the 'ranges' conception?
> > 
> > Nope it's ok but it might pose some confusion with the idea that the
> > very first element MUST be THE STARTING ADDR of the PHY package. (people
> > might think that it's just the list of the PHYs in the package and
> > remove the hardware unconnected ones... but that would be fault of who
> > write the DT anyway.)
> 
> Make sense. I do not insist on addresses listing. Mainly I'm thinking of a
> proper way to show that child nodes are accessible directly on the parent
> bus, and introducing the special compatibility string, while we already have
> the 'ranges' property.
> 
> But it's good to know Rob's opinion on whether it is conceptually right to
> use 'ranges' here.
>

I like the ideas of ranges and I will try to propose it... Another idea
might be declare something like <0x16 0x4> where the additional cell
would declare the amount of address occupiaed by the package. But I
think your way is much better and less ""custom"". Yes would also love
some feedback from Rob about this.

> > > And I would like to ask you about another issue raised by Vladimir [1].
> > > These phy chips become SoC with all these built-in PHYs, PCSs, clocks,
> > > interrupt controllers, etc. Should we address this now? Or should we go with
> > > the proposed solution for now and postpone modeling of other peripherals
> > > until we get a real hardware, as Andrew suggested?
> > 
> > Honestly I would postpone untile we have a clear idea of what is
> > actually part of the PHY and what can be handled externally... Example
> > setting the clock in gcc, writing a specific driver...
> > 
> > It's a random idea but maybe most of the stuff required for that PHY is
> > just when it's connected to a switch... In that case it would all be
> > handled in the switch driver (tobe extended qca8k) and all these extra
> > stuff would be placed in that node instead of bloating phy nodes with
> > all kind of clk and other stuff.
> > 
> > This series still require 2 more series (at803x splint and cleanup) to be
> > actually proposed so we have some time to better define this.
> > 
> > What do you think?
> 
> Fair enough! Let's postpone until we really need it. I noticed this
> PHY-like-SoC discussion in the V1 comments, and it was not finished there
> neither addressed in the latest patch comment. So I asked just to be sure
> that we were finished with this. Thank you for the clarification.
> 
> --
> Sergey
>
Sergey Ryazanov Jan. 7, 2024, 9:49 p.m. UTC | #8
Hi Christian,

On 07.01.2024 20:30, Christian Marangi wrote:
> On Sun, Jan 07, 2024 at 08:00:33PM +0200, Sergey Ryazanov wrote:
>> On 26.11.2023 03:53, Christian Marangi wrote:
>>> Document ethernet PHY package nodes used to describe PHY shipped in
>>> bundle of 4-5 PHY. The special node describe a container of PHY that
>>> share common properties. This is a generic schema and PHY package
>>> should create specialized version with the required additional shared
>>> properties.
>>>
>>> Example are PHY package that have some regs only in one PHY of the
>>> package and will affect every other PHY in the package, for example
>>> related to PHY interface mode calibration or global PHY mode selection.
>>>
>>> The PHY package node MUST declare the base address used by the PHY driver
>>> for global configuration by calculating the offsets of the global PHY
>>> based on the base address of the PHY package and declare the
>>> "ethrnet-phy-package" compatible.
>>>
>>> Each reg of the PHY defined in the PHY package node is absolute and will
>>> reference the real address of the PHY on the bus.
>>>
>>> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
>>> ---
>>>    .../bindings/net/ethernet-phy-package.yaml    | 75 +++++++++++++++++++
>>>    1 file changed, 75 insertions(+)
>>>    create mode 100644 Documentation/devicetree/bindings/net/ethernet-phy-package.yaml
>>>
>>> diff --git a/Documentation/devicetree/bindings/net/ethernet-phy-package.yaml b/Documentation/devicetree/bindings/net/ethernet-phy-package.yaml
>>> new file mode 100644
>>> index 000000000000..244d4bc29164
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/net/ethernet-phy-package.yaml
>>> @@ -0,0 +1,75 @@
>>> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
>>> +%YAML 1.2
>>> +---
>>> +$id: http://devicetree.org/schemas/net/ethernet-phy-package.yaml#
>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>> +
>>> +title: Ethernet PHY Package Common Properties
>>> +
>>> +maintainers:
>>> +  - Christian Marangi <ansuelsmth@gmail.com>
>>> +
>>> +description:
>>> +  This schema describe PHY package as simple container for
>>> +  a bundle of PHYs that share the same properties and
>>> +  contains the PHYs of the package themself.
>>> +
>>> +  Each reg of the PHYs defined in the PHY package node is
>>> +  absolute and describe the real address of the PHY on the bus.
>>> +
>>> +properties:
>>> +  $nodename:
>>> +    pattern: "^ethernet-phy-package(@[a-f0-9]+)?$"
>>> +
>>> +  compatible:
>>> +    const: ethernet-phy-package
>>> +
>>> +  reg:
>>> +    minimum: 0
>>> +    maximum: 31
>>> +    description:
>>> +      The base ID number for the PHY package.
>>> +      Commonly the ID of the first PHY in the PHY package.
>>> +
>>> +      Some PHY in the PHY package might be not defined but
>>> +      still exist on the device (just not attached to anything).
>>> +      The reg defined in the PHY package node might differ and
>>> +      the related PHY might be not defined.
>>> +
>>> +  '#address-cells':
>>> +    const: 1
>>> +
>>> +  '#size-cells':
>>> +    const: 0
>>> +
>>> +patternProperties:
>>> +  ^ethernet-phy(@[a-f0-9]+)?$:
>>> +    $ref: ethernet-phy.yaml#
>>> +
>>> +required:
>>> +  - compatible
>>> +  - reg
>>> +
>>> +additionalProperties: true
>>> +
>>> +examples:
>>> +  - |
>>> +    mdio {
>>> +        #address-cells = <1>;
>>> +        #size-cells = <0>;
>>> +
>>> +        ethernet-phy-package@16 {
>>> +            #address-cells = <1>;
>>> +            #size-cells = <0>;
>>> +            compatible = "ethernet-phy-package";
>>> +            reg = <0x16>;
>>> +
>>> +            ethernet-phy@16 {
>>> +              reg = <0x16>;
>>> +            };
>>> +
>>> +            phy4: ethernet-phy@1a {
>>> +              reg = <0x1a>;
>>> +            };
>>> +        };
>>> +    };
>>
>> So, we ended up on a design where we use the predefined compatible string
>> 'ethernet-phy-package' to recognize a phy package inside the
>> of_mdiobus_register() function. During the V1 discussion, Vladimir came up
>> with the idea of 'ranges' property usage [1]. Can we use 'ranges' to
>> recognize a phy package in of_mdiobus_register()? IMHO this will give us a
>> clear DT solution. I mean 'ranges' clearly indicates that child nodes are in
>> the same address range as the parent node. Also we can list all child
>> addresses in 'reg' to mark them occupied.
>>
>>    mdio {
>>      ...
>>
>>      ethernet-phy-package@16 {
>>        compatible = "qcom,qca8075";
>>        reg = <0x16>, <0x17>, <0x18>, <0x19>, <0x1a>;
>>        ranges;
>>        ...
>>
>>        ethernet-phy@16 {
>>          reg = <0x16>;
>>        };
>>
>>        ethernet-phy@1a {
>>          reg = <0x1a>;
>>        };
>>      };
>>    };
>>
>> Did you find some issues with the 'ranges' conception?
> 
> Nope it's ok but it might pose some confusion with the idea that the
> very first element MUST be THE STARTING ADDR of the PHY package. (people
> might think that it's just the list of the PHYs in the package and
> remove the hardware unconnected ones... but that would be fault of who
> write the DT anyway.)

Make sense. I do not insist on addresses listing. Mainly I'm thinking of 
a proper way to show that child nodes are accessible directly on the 
parent bus, and introducing the special compatibility string, while we 
already have the 'ranges' property.

But it's good to know Rob's opinion on whether it is conceptually right 
to use 'ranges' here.

>> And I would like to ask you about another issue raised by Vladimir [1].
>> These phy chips become SoC with all these built-in PHYs, PCSs, clocks,
>> interrupt controllers, etc. Should we address this now? Or should we go with
>> the proposed solution for now and postpone modeling of other peripherals
>> until we get a real hardware, as Andrew suggested?
> 
> Honestly I would postpone untile we have a clear idea of what is
> actually part of the PHY and what can be handled externally... Example
> setting the clock in gcc, writing a specific driver...
> 
> It's a random idea but maybe most of the stuff required for that PHY is
> just when it's connected to a switch... In that case it would all be
> handled in the switch driver (tobe extended qca8k) and all these extra
> stuff would be placed in that node instead of bloating phy nodes with
> all kind of clk and other stuff.
> 
> This series still require 2 more series (at803x splint and cleanup) to be
> actually proposed so we have some time to better define this.
> 
> What do you think?

Fair enough! Let's postpone until we really need it. I noticed this 
PHY-like-SoC discussion in the V1 comments, and it was not finished 
there neither addressed in the latest patch comment. So I asked just to 
be sure that we were finished with this. Thank you for the clarification.

--
Sergey
Sergey Ryazanov Jan. 7, 2024, 9:57 p.m. UTC | #9
Hi Andrew,

On 07.01.2024 20:44, Andrew Lunn wrote:
>> Honestly I would postpone untile we have a clear idea of what is
>> actually part of the PHY and what can be handled externally... Example
>> setting the clock in gcc, writing a specific driver...
> 
> That is really core of the problem here. We have no reliable
> description of the hardware. The datasheet often starts with a block
> diagram of the PHY package. Sometimes there is a product brief with
> the same diagram. We need that published. I'm not asking for the full
> data sheet, just the introductory text which gives a high level
> overview of what the hardware actually is. Then we can sketch out a
> high level Linux architecture for the PHY package.

True. I am with you on this. Can we put these words over a mailing list 
entrance door? It will save tons of time for both maintainers and 
submitters.

--
Sergey
Luo Jie Jan. 8, 2024, 11:13 a.m. UTC | #10
On 1/8/2024 2:31 AM, Andrew Lunn wrote:
>> And I would like to ask you about another issue raised by Vladimir [1].
>> These phy chips become SoC with all these built-in PHYs, PCSs, clocks,
>> interrupt controllers, etc. Should we address this now? Or should we go with
>> the proposed solution for now and postpone modeling of other peripherals
>> until we get a real hardware, as Andrew suggested?
>>
>> I'm asking because it looks like we have got a real hardware. Luo currently
>> trying to push QCA8084 (multi-phy/switch chip) support, and this chip
>> exactly contains a huge clock/reset controller [2,3].
> 
> Ideally the reset controller is modelled as a Linux reset
> controller. The clock part of it is modelled using the common clock
> framework. When done correctly, the PHY should not really care. All it
> does is ask for its clock to be enabled, and its reset to be disabled.
> 
> Also, given how difficult it is proving to be to make any progress at
> all, i want to get one little part correctly described, the pure
> PHY. Once we have that, we can start on the next little part. So long
> as we keep to the Linux architecture of blocks or hardware with
> standard Linux drivers, and DT to glue them together, a small step by
> step approach should work out.
> 
>       Andrew

Since qca8075 PHY is also multiple port PHY, which is same as qca8084,
but qca8084 also includes the integrated clock controller, this is the
first qcom PHY chip integrating the clock controller internally.
can we also consider designing the clocks and resets DT models in the
PHY package DT.

For qca8084 PURE PHY chip, which is the quad PHY chip and two PCSes,
it integrates the clock controller that generates the clocks to be used
by the link of PHYs, the integrated controller also provides the resets
to the PHY,  the clock controller(NSSCC) driver of qca8084 works at the
same way of the GCC of SoC(IPQ), qca8084 needs to be initialized with
the clocks and resets for the qca8084 PHY package, these clocks and
resets are generated by the NSSCC, even for PURE phy chip qca8084, there
is also some PHY package level clocks needs to be initialized.

here is the diagram of qca8084.
__| |_______________| |__
| PCS0 |          |PCS1 |
|______|          |_____|
|_________________      |
|                |      |
|     NSSCC      |      |
|________________|      |
|_______________________|
|     |     |     |     |
|PHY1 |PHY2 |PHY3 |PHY4 |
|_____|_____|_____|_____|

let me example the initial clocks and resets for the pure PHY chip 
qca8084 as below, the clocks and resets should be put into the first
MDIO node to be initialized firstly before qca8084 PHY will work.

ethernet-phy-package@0 { 

         #address-cells = <1>; 

         #size-cells = <0>; 

         compatible = "ethernet-phy-package"; 

         reg = <0>; 

 

         /* initial PHY package level clocks */ 

         clocks = <&qca8k_nsscc NSS_CC_APB_BRIDGE_CLK>, 

                <&qca8k_nsscc NSS_CC_AHB_CLK>, 

                <&qca8k_nsscc NSS_CC_SEC_CTRL_AHB_CLK>, 

                <&qca8k_nsscc NSS_CC_TLMM_CLK>, 

                <&qca8k_nsscc NSS_CC_TLMM_AHB_CLK>, 

                <&qca8k_nsscc NSS_CC_CNOC_AHB_CLK>, 

                <&qca8k_nsscc NSS_CC_MDIO_AHB_CLK>; 

         clock-names = "apb_bridge", 

                 "ahb", 

                 "sec_ctrl_ahb", 

                 "tlmm", 

                 "tlmm_ahb", 

                 "cnoc_ahb", 

                 "mdio_ahb"; 

 

         /* initial PHY package level reset */ 

         resets = <&qca8k_nsscc NSS_CC_DSP_ARES>; 

         reset-names = "gephy_dsp"; 

 

         /* initial clocks and resets for first phy */ 

         phy0 { 

                 reg = <0>; 

                 clocks = <&qca8k_nsscc NSS_CC_GEPHY0_SYS_CLK>; 

                 clock-names = "gephy0_sys"; 

                 resets = <&qca8k_nsscc NSS_CC_GEPHY0_SYS_ARES>, 

                        <&qca8k_nsscc NSS_CC_GEPHY0_ARES>; 

                 reset-names = "gephy0_sys", 

                         "gephy0_soft"; 

         }; 

 

         /* initial clocks and resets for second phy */ 

         phy1 { 

                 reg = <1>; 

                 clocks = <&qca8k_nsscc NSS_CC_GEPHY1_SYS_CLK>; 

                 clock-names = "gephy1_sys"; 

                 resets = <&qca8k_nsscc NSS_CC_GEPHY1_SYS_ARES>, 

                        <&qca8k_nsscc NSS_CC_GEPHY1_ARES>; 

                 reset-names = "gephy1_sys", 

                         "gephy1_soft"; 

         }; 

 

         /* initial clocks and resets for third phy */ 

         phy2 { 

                 reg = <2>; 

                 clocks = <&qca8k_nsscc NSS_CC_GEPHY2_SYS_CLK>; 

                 clock-names = "gephy2_sys";
                 resets = <&qca8k_nsscc NSS_CC_GEPHY2_SYS_ARES>, 

                        <&qca8k_nsscc NSS_CC_GEPHY2_ARES>; 

                 reset-names = "gephy2_sys", 

                         "gephy2_soft"; 

         }; 

 

         /* initial clocks and resets for fourth phy */ 

         phy3 { 

                 reg = <3>; 

                 clocks = <&qca8k_nsscc NSS_CC_GEPHY3_SYS_CLK>; 

                 clock-names = "gephy3_sys"; 

                 resets = <&qca8k_nsscc NSS_CC_GEPHY3_SYS_ARES>, 

                        <&qca8k_nsscc NSS_CC_GEPHY3_ARES>; 

                 reset-names = "gephy3_sys", 

                         "gephy3_soft"; 

         }; 

 

         /* initial clocks and resets for pcs0. */ 

         pcs0 { 

                 reg = <4>; 

                 clocks = <&qca8k_nsscc NSS_CC_SRDS0_SYS_CLK>; 

                 clock-names = "srds0_sys"; 

                 resets = <&qca8k_nsscc NSS_CC_SRDS0_SYS_ARES>; 

                 reset-names = "srds0_sys"; 

         }; 

 

         /* initial clocks and resets for pcs1. */ 

         pcs1 { 

                 reg = <5>; 

                 clocks = <&qca8k_nsscc NSS_CC_SRDS1_SYS_CLK>; 

                 clock-names = "srds1_sys"; 

                 resets = <&qca8k_nsscc NSS_CC_SRDS1_SYS_ARES>; 

                 reset-names = "srds1_sys"; 

         }; 
 

};

appreciated for the PHY package level DT model design.
Andrew Lunn Jan. 8, 2024, 1:19 p.m. UTC | #11
> Since qca8075 PHY is also multiple port PHY, which is same as qca8084,
> but qca8084 also includes the integrated clock controller, this is the
> first qcom PHY chip integrating the clock controller internally.
> can we also consider designing the clocks and resets DT models in the
> PHY package DT.
> 
> For qca8084 PURE PHY chip, which is the quad PHY chip and two PCSes,
> it integrates the clock controller that generates the clocks to be used
> by the link of PHYs, the integrated controller also provides the resets
> to the PHY,  the clock controller(NSSCC) driver of qca8084 works at the
> same way of the GCC of SoC(IPQ), qca8084 needs to be initialized with
> the clocks and resets for the qca8084 PHY package, these clocks and
> resets are generated by the NSSCC, even for PURE phy chip qca8084, there
> is also some PHY package level clocks needs to be initialized.
> 
> here is the diagram of qca8084.
> __| |_______________| |__
> | PCS0 |          |PCS1 |
> |______|          |_____|
> |_________________      |
> |                |      |
> |     NSSCC      |      |
> |________________|      |
> |_______________________|
> |     |     |     |     |
> |PHY1 |PHY2 |PHY3 |PHY4 |
> |_____|_____|_____|_____|

Please add to the diagram the external clocks and external resets.

Additionally, add the resets and clocks between the NSSCC and the
individual PHYs. Typically, the internal clocks and resets are not in
DT, at last not for a single PHY. For a quad PHY in a package, it
might make sense to add them. Before we can decide that, we need a
clear idea what the hardware looks like.

> let me example the initial clocks and resets for the pure PHY chip qca8084
> as below, the clocks and resets should be put into the first
> MDIO node to be initialized firstly before qca8084 PHY will work.
> 
> ethernet-phy-package@0 {
> 
>         #address-cells = <1>;
> 
>         #size-cells = <0>;
> 
>         compatible = "ethernet-phy-package";
> 
>         reg = <0>;
> 
> 
> 
>         /* initial PHY package level clocks */
> 
>         clocks = <&qca8k_nsscc NSS_CC_APB_BRIDGE_CLK>,
> 
>                <&qca8k_nsscc NSS_CC_AHB_CLK>,
> 
>                <&qca8k_nsscc NSS_CC_SEC_CTRL_AHB_CLK>,
> 
>                <&qca8k_nsscc NSS_CC_TLMM_CLK>,
> 
>                <&qca8k_nsscc NSS_CC_TLMM_AHB_CLK>,
> 
>                <&qca8k_nsscc NSS_CC_CNOC_AHB_CLK>,
> 
>                <&qca8k_nsscc NSS_CC_MDIO_AHB_CLK>;

Device tree effectively defined devices on bus, in a tree, and how
they interconnect. Does the NSSCC have its own address on the MDIO
bus? Or does it share an address with one of the PHYs? It could be we
want to describe the NSSCC as a DT node of its own within the
package. It is probably both a clock consumer, and a clock provider.
The individual PHYs are then clock consumers, of the clocks the NSSCC
exports. Same for resets.

> 
>         clock-names = "apb_bridge",
> 
>                 "ahb",
> 
>                 "sec_ctrl_ahb",
> 
>                 "tlmm",
> 
>                 "tlmm_ahb",
> 
>                 "cnoc_ahb",
> 
>                 "mdio_ahb";
> 
> 
> 
>         /* initial PHY package level reset */
> 
>         resets = <&qca8k_nsscc NSS_CC_DSP_ARES>;
> 
>         reset-names = "gephy_dsp";
> 
> 
> 
>         /* initial clocks and resets for first phy */
> 
>         phy0 {
> 
>                 reg = <0>;
> 
>                 clocks = <&qca8k_nsscc NSS_CC_GEPHY0_SYS_CLK>;
> 
>                 clock-names = "gephy0_sys";
> 
>                 resets = <&qca8k_nsscc NSS_CC_GEPHY0_SYS_ARES>,
> 
>                        <&qca8k_nsscc NSS_CC_GEPHY0_ARES>;
> 
>                 reset-names = "gephy0_sys",
> 
>                         "gephy0_soft";
> 
>         };
> 
> 
> 
>         /* initial clocks and resets for second phy */
> 
>         phy1 {
> 
>                 reg = <1>;
> 
>                 clocks = <&qca8k_nsscc NSS_CC_GEPHY1_SYS_CLK>;
> 
>                 clock-names = "gephy1_sys";
> 
>                 resets = <&qca8k_nsscc NSS_CC_GEPHY1_SYS_ARES>,
> 
>                        <&qca8k_nsscc NSS_CC_GEPHY1_ARES>;
> 
>                 reset-names = "gephy1_sys",
> 
>                         "gephy1_soft";
> 
>         };
> 
> 
> 
>         /* initial clocks and resets for third phy */
> 
>         phy2 {
> 
>                 reg = <2>;
> 
>                 clocks = <&qca8k_nsscc NSS_CC_GEPHY2_SYS_CLK>;
> 
>                 clock-names = "gephy2_sys";
>                 resets = <&qca8k_nsscc NSS_CC_GEPHY2_SYS_ARES>,
> 
>                        <&qca8k_nsscc NSS_CC_GEPHY2_ARES>;
> 
>                 reset-names = "gephy2_sys",
> 
>                         "gephy2_soft";
> 
>         };
> 
> 
> 
>         /* initial clocks and resets for fourth phy */
> 
>         phy3 {
> 
>                 reg = <3>;
> 
>                 clocks = <&qca8k_nsscc NSS_CC_GEPHY3_SYS_CLK>;
> 
>                 clock-names = "gephy3_sys";
> 
>                 resets = <&qca8k_nsscc NSS_CC_GEPHY3_SYS_ARES>,
> 
>                        <&qca8k_nsscc NSS_CC_GEPHY3_ARES>;
> 
>                 reset-names = "gephy3_sys",
> 
>                         "gephy3_soft";
> 
>         };

This is starting to look O.K.

>         /* initial clocks and resets for pcs0. */
> 
>         pcs0 {
> 
>                 reg = <4>;
> 
>                 clocks = <&qca8k_nsscc NSS_CC_SRDS0_SYS_CLK>;
> 
>                 clock-names = "srds0_sys";
> 
>                 resets = <&qca8k_nsscc NSS_CC_SRDS0_SYS_ARES>;
> 
>                 reset-names = "srds0_sys";
> 
>         };
> 
> 
> 
>         /* initial clocks and resets for pcs1. */
> 
>         pcs1 {
> 
>                 reg = <5>;
> 
>                 clocks = <&qca8k_nsscc NSS_CC_SRDS1_SYS_CLK>;
> 
>                 clock-names = "srds1_sys";
> 
>                 resets = <&qca8k_nsscc NSS_CC_SRDS1_SYS_ARES>;
> 
>                 reset-names = "srds1_sys";
> 
>         };

PCS will need further work and thinking about. Typically, they are not
described in DT for a PHY. In general, a PCS in a PHY does not have a
driver of its own, the firmware in the PHY mostly controls it, not
Linux. For the moment, lets leave them as they are, and we will come
back to them once we get the clocks and resets correctly described.

     Andrew
Christian Marangi Jan. 17, 2024, 12:36 a.m. UTC | #12
On Sun, Jan 07, 2024 at 11:49:12PM +0200, Sergey Ryazanov wrote:
> Hi Christian,
> 
> On 07.01.2024 20:30, Christian Marangi wrote:
> > On Sun, Jan 07, 2024 at 08:00:33PM +0200, Sergey Ryazanov wrote:
> > > On 26.11.2023 03:53, Christian Marangi wrote:
> > > > Document ethernet PHY package nodes used to describe PHY shipped in
> > > > bundle of 4-5 PHY. The special node describe a container of PHY that
> > > > share common properties. This is a generic schema and PHY package
> > > > should create specialized version with the required additional shared
> > > > properties.
> > > > 
> > > > Example are PHY package that have some regs only in one PHY of the
> > > > package and will affect every other PHY in the package, for example
> > > > related to PHY interface mode calibration or global PHY mode selection.
> > > > 
> > > > The PHY package node MUST declare the base address used by the PHY driver
> > > > for global configuration by calculating the offsets of the global PHY
> > > > based on the base address of the PHY package and declare the
> > > > "ethrnet-phy-package" compatible.
> > > > 
> > > > Each reg of the PHY defined in the PHY package node is absolute and will
> > > > reference the real address of the PHY on the bus.
> > > > 
> > > > Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> > > > ---
> > > >    .../bindings/net/ethernet-phy-package.yaml    | 75 +++++++++++++++++++
> > > >    1 file changed, 75 insertions(+)
> > > >    create mode 100644 Documentation/devicetree/bindings/net/ethernet-phy-package.yaml
> > > > 
> > > > diff --git a/Documentation/devicetree/bindings/net/ethernet-phy-package.yaml b/Documentation/devicetree/bindings/net/ethernet-phy-package.yaml
> > > > new file mode 100644
> > > > index 000000000000..244d4bc29164
> > > > --- /dev/null
> > > > +++ b/Documentation/devicetree/bindings/net/ethernet-phy-package.yaml
> > > > @@ -0,0 +1,75 @@
> > > > +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> > > > +%YAML 1.2
> > > > +---
> > > > +$id: http://devicetree.org/schemas/net/ethernet-phy-package.yaml#
> > > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > > +
> > > > +title: Ethernet PHY Package Common Properties
> > > > +
> > > > +maintainers:
> > > > +  - Christian Marangi <ansuelsmth@gmail.com>
> > > > +
> > > > +description:
> > > > +  This schema describe PHY package as simple container for
> > > > +  a bundle of PHYs that share the same properties and
> > > > +  contains the PHYs of the package themself.
> > > > +
> > > > +  Each reg of the PHYs defined in the PHY package node is
> > > > +  absolute and describe the real address of the PHY on the bus.
> > > > +
> > > > +properties:
> > > > +  $nodename:
> > > > +    pattern: "^ethernet-phy-package(@[a-f0-9]+)?$"
> > > > +
> > > > +  compatible:
> > > > +    const: ethernet-phy-package
> > > > +
> > > > +  reg:
> > > > +    minimum: 0
> > > > +    maximum: 31
> > > > +    description:
> > > > +      The base ID number for the PHY package.
> > > > +      Commonly the ID of the first PHY in the PHY package.
> > > > +
> > > > +      Some PHY in the PHY package might be not defined but
> > > > +      still exist on the device (just not attached to anything).
> > > > +      The reg defined in the PHY package node might differ and
> > > > +      the related PHY might be not defined.
> > > > +
> > > > +  '#address-cells':
> > > > +    const: 1
> > > > +
> > > > +  '#size-cells':
> > > > +    const: 0
> > > > +
> > > > +patternProperties:
> > > > +  ^ethernet-phy(@[a-f0-9]+)?$:
> > > > +    $ref: ethernet-phy.yaml#
> > > > +
> > > > +required:
> > > > +  - compatible
> > > > +  - reg
> > > > +
> > > > +additionalProperties: true
> > > > +
> > > > +examples:
> > > > +  - |
> > > > +    mdio {
> > > > +        #address-cells = <1>;
> > > > +        #size-cells = <0>;
> > > > +
> > > > +        ethernet-phy-package@16 {
> > > > +            #address-cells = <1>;
> > > > +            #size-cells = <0>;
> > > > +            compatible = "ethernet-phy-package";
> > > > +            reg = <0x16>;
> > > > +
> > > > +            ethernet-phy@16 {
> > > > +              reg = <0x16>;
> > > > +            };
> > > > +
> > > > +            phy4: ethernet-phy@1a {
> > > > +              reg = <0x1a>;
> > > > +            };
> > > > +        };
> > > > +    };
> > > 
> > > So, we ended up on a design where we use the predefined compatible string
> > > 'ethernet-phy-package' to recognize a phy package inside the
> > > of_mdiobus_register() function. During the V1 discussion, Vladimir came up
> > > with the idea of 'ranges' property usage [1]. Can we use 'ranges' to
> > > recognize a phy package in of_mdiobus_register()? IMHO this will give us a
> > > clear DT solution. I mean 'ranges' clearly indicates that child nodes are in
> > > the same address range as the parent node. Also we can list all child
> > > addresses in 'reg' to mark them occupied.
> > > 
> > >    mdio {
> > >      ...
> > > 
> > >      ethernet-phy-package@16 {
> > >        compatible = "qcom,qca8075";
> > >        reg = <0x16>, <0x17>, <0x18>, <0x19>, <0x1a>;
> > >        ranges;
> > >        ...
> > > 
> > >        ethernet-phy@16 {
> > >          reg = <0x16>;
> > >        };
> > > 
> > >        ethernet-phy@1a {
> > >          reg = <0x1a>;
> > >        };
> > >      };
> > >    };
> > > 
> > > Did you find some issues with the 'ranges' conception?
> > 
> > Nope it's ok but it might pose some confusion with the idea that the
> > very first element MUST be THE STARTING ADDR of the PHY package. (people
> > might think that it's just the list of the PHYs in the package and
> > remove the hardware unconnected ones... but that would be fault of who
> > write the DT anyway.)
> 
> Make sense. I do not insist on addresses listing. Mainly I'm thinking of a
> proper way to show that child nodes are accessible directly on the parent
> bus, and introducing the special compatibility string, while we already have
> the 'ranges' property.
> 
> But it's good to know Rob's opinion on whether it is conceptually right to
> use 'ranges' here.
>

I wonder if something like this might make sense... Thing is that with
the ranges property we would have the define the address in the PHY
Package node as offsets...

An example would be

    mdio {
        #address-cells = <1>;
        #size-cells = <0>;

        ethernet-phy-package@10 {
            #address-cells = <1>;
            #size-cells = <0>;
            compatible = "qcom,qca807x-package";
            reg = <0x10>; 
            ranges = <0x0 0x10 0x5>;

            qcom,package-mode = "qsgmii";

            ethernet-phy@0 {
                reg = <0>;

                leds {

		...

With a PHY Package at 0x10, that span 5 address and the child starts at
0x0 offset.

This way we would be very precise on describing the amount of address
used by the PHY Package without having to define the PHY not actually
connected.

PHY needs to be at an offset to make sense of the ranges first element
property (0x0). With a non offset way we would have to have something
like

ranges = <0x10 0x10 0x5>;

With the child and tha parent always matching.

(this is easy to handle in the parsing and probe as we will just
calculate the real address based on the base address of the PHY package
+ offset)

I hope Rob can give more feedback about this, is this what you were
thinking with the usage of ranges property?

(this has also the bonus point of introducing some validation in the PHY
core code to make sure the right amount of PHY are defined in the
package by checking if the number of PHY doesn't exceed the value set in
ranges.)

> > > And I would like to ask you about another issue raised by Vladimir [1].
> > > These phy chips become SoC with all these built-in PHYs, PCSs, clocks,
> > > interrupt controllers, etc. Should we address this now? Or should we go with
> > > the proposed solution for now and postpone modeling of other peripherals
> > > until we get a real hardware, as Andrew suggested?
> > 
> > Honestly I would postpone untile we have a clear idea of what is
> > actually part of the PHY and what can be handled externally... Example
> > setting the clock in gcc, writing a specific driver...
> > 
> > It's a random idea but maybe most of the stuff required for that PHY is
> > just when it's connected to a switch... In that case it would all be
> > handled in the switch driver (tobe extended qca8k) and all these extra
> > stuff would be placed in that node instead of bloating phy nodes with
> > all kind of clk and other stuff.
> > 
> > This series still require 2 more series (at803x splint and cleanup) to be
> > actually proposed so we have some time to better define this.
> > 
> > What do you think?
> 
> Fair enough! Let's postpone until we really need it. I noticed this
> PHY-like-SoC discussion in the V1 comments, and it was not finished there
> neither addressed in the latest patch comment. So I asked just to be sure
> that we were finished with this. Thank you for the clarification.
> 
> --
> Sergey
>
Sergey Ryazanov Jan. 17, 2024, 7:39 p.m. UTC | #13
Hi Christian,

On 17.01.2024 02:36, Christian Marangi wrote:
> On Sun, Jan 07, 2024 at 11:49:12PM +0200, Sergey Ryazanov wrote:
>> Hi Christian,
>>
>> On 07.01.2024 20:30, Christian Marangi wrote:
>>> On Sun, Jan 07, 2024 at 08:00:33PM +0200, Sergey Ryazanov wrote:
>>>> On 26.11.2023 03:53, Christian Marangi wrote:
>>>>> Document ethernet PHY package nodes used to describe PHY shipped in
>>>>> bundle of 4-5 PHY. The special node describe a container of PHY that
>>>>> share common properties. This is a generic schema and PHY package
>>>>> should create specialized version with the required additional shared
>>>>> properties.
>>>>>
>>>>> Example are PHY package that have some regs only in one PHY of the
>>>>> package and will affect every other PHY in the package, for example
>>>>> related to PHY interface mode calibration or global PHY mode selection.
>>>>>
>>>>> The PHY package node MUST declare the base address used by the PHY driver
>>>>> for global configuration by calculating the offsets of the global PHY
>>>>> based on the base address of the PHY package and declare the
>>>>> "ethrnet-phy-package" compatible.
>>>>>
>>>>> Each reg of the PHY defined in the PHY package node is absolute and will
>>>>> reference the real address of the PHY on the bus.
>>>>>
>>>>> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
>>>>> ---
>>>>>     .../bindings/net/ethernet-phy-package.yaml    | 75 +++++++++++++++++++
>>>>>     1 file changed, 75 insertions(+)
>>>>>     create mode 100644 Documentation/devicetree/bindings/net/ethernet-phy-package.yaml
>>>>>
>>>>> diff --git a/Documentation/devicetree/bindings/net/ethernet-phy-package.yaml b/Documentation/devicetree/bindings/net/ethernet-phy-package.yaml
>>>>> new file mode 100644
>>>>> index 000000000000..244d4bc29164
>>>>> --- /dev/null
>>>>> +++ b/Documentation/devicetree/bindings/net/ethernet-phy-package.yaml
>>>>> @@ -0,0 +1,75 @@
>>>>> +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
>>>>> +%YAML 1.2
>>>>> +---
>>>>> +$id: http://devicetree.org/schemas/net/ethernet-phy-package.yaml#
>>>>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>>>>> +
>>>>> +title: Ethernet PHY Package Common Properties
>>>>> +
>>>>> +maintainers:
>>>>> +  - Christian Marangi <ansuelsmth@gmail.com>
>>>>> +
>>>>> +description:
>>>>> +  This schema describe PHY package as simple container for
>>>>> +  a bundle of PHYs that share the same properties and
>>>>> +  contains the PHYs of the package themself.
>>>>> +
>>>>> +  Each reg of the PHYs defined in the PHY package node is
>>>>> +  absolute and describe the real address of the PHY on the bus.
>>>>> +
>>>>> +properties:
>>>>> +  $nodename:
>>>>> +    pattern: "^ethernet-phy-package(@[a-f0-9]+)?$"
>>>>> +
>>>>> +  compatible:
>>>>> +    const: ethernet-phy-package
>>>>> +
>>>>> +  reg:
>>>>> +    minimum: 0
>>>>> +    maximum: 31
>>>>> +    description:
>>>>> +      The base ID number for the PHY package.
>>>>> +      Commonly the ID of the first PHY in the PHY package.
>>>>> +
>>>>> +      Some PHY in the PHY package might be not defined but
>>>>> +      still exist on the device (just not attached to anything).
>>>>> +      The reg defined in the PHY package node might differ and
>>>>> +      the related PHY might be not defined.
>>>>> +
>>>>> +  '#address-cells':
>>>>> +    const: 1
>>>>> +
>>>>> +  '#size-cells':
>>>>> +    const: 0
>>>>> +
>>>>> +patternProperties:
>>>>> +  ^ethernet-phy(@[a-f0-9]+)?$:
>>>>> +    $ref: ethernet-phy.yaml#
>>>>> +
>>>>> +required:
>>>>> +  - compatible
>>>>> +  - reg
>>>>> +
>>>>> +additionalProperties: true
>>>>> +
>>>>> +examples:
>>>>> +  - |
>>>>> +    mdio {
>>>>> +        #address-cells = <1>;
>>>>> +        #size-cells = <0>;
>>>>> +
>>>>> +        ethernet-phy-package@16 {
>>>>> +            #address-cells = <1>;
>>>>> +            #size-cells = <0>;
>>>>> +            compatible = "ethernet-phy-package";
>>>>> +            reg = <0x16>;
>>>>> +
>>>>> +            ethernet-phy@16 {
>>>>> +              reg = <0x16>;
>>>>> +            };
>>>>> +
>>>>> +            phy4: ethernet-phy@1a {
>>>>> +              reg = <0x1a>;
>>>>> +            };
>>>>> +        };
>>>>> +    };
>>>>
>>>> So, we ended up on a design where we use the predefined compatible string
>>>> 'ethernet-phy-package' to recognize a phy package inside the
>>>> of_mdiobus_register() function. During the V1 discussion, Vladimir came up
>>>> with the idea of 'ranges' property usage [1]. Can we use 'ranges' to
>>>> recognize a phy package in of_mdiobus_register()? IMHO this will give us a
>>>> clear DT solution. I mean 'ranges' clearly indicates that child nodes are in
>>>> the same address range as the parent node. Also we can list all child
>>>> addresses in 'reg' to mark them occupied.
>>>>
>>>>     mdio {
>>>>       ...
>>>>
>>>>       ethernet-phy-package@16 {
>>>>         compatible = "qcom,qca8075";
>>>>         reg = <0x16>, <0x17>, <0x18>, <0x19>, <0x1a>;
>>>>         ranges;
>>>>         ...
>>>>
>>>>         ethernet-phy@16 {
>>>>           reg = <0x16>;
>>>>         };
>>>>
>>>>         ethernet-phy@1a {
>>>>           reg = <0x1a>;
>>>>         };
>>>>       };
>>>>     };
>>>>
>>>> Did you find some issues with the 'ranges' conception?
>>>
>>> Nope it's ok but it might pose some confusion with the idea that the
>>> very first element MUST be THE STARTING ADDR of the PHY package. (people
>>> might think that it's just the list of the PHYs in the package and
>>> remove the hardware unconnected ones... but that would be fault of who
>>> write the DT anyway.)
>>
>> Make sense. I do not insist on addresses listing. Mainly I'm thinking of a
>> proper way to show that child nodes are accessible directly on the parent
>> bus, and introducing the special compatibility string, while we already have
>> the 'ranges' property.
>>
>> But it's good to know Rob's opinion on whether it is conceptually right to
>> use 'ranges' here.
>>
> 
> I wonder if something like this might make sense... Thing is that with
> the ranges property we would have the define the address in the PHY
> Package node as offsets...
> 
> An example would be
> 
>      mdio {
>          #address-cells = <1>;
>          #size-cells = <0>;
> 
>          ethernet-phy-package@10 {
>              #address-cells = <1>;
>              #size-cells = <0>;
>              compatible = "qcom,qca807x-package";
>              reg = <0x10>;
>              ranges = <0x0 0x10 0x5>;
> 
>              qcom,package-mode = "qsgmii";
> 
>              ethernet-phy@0 {
>                  reg = <0>;
> 
>                  leds {
> 
> 		...
> 
> With a PHY Package at 0x10, that span 5 address and the child starts at
> 0x0 offset.
> 
> This way we would be very precise on describing the amount of address
> used by the PHY Package without having to define the PHY not actually
> connected.
> 
> PHY needs to be at an offset to make sense of the ranges first element
> property (0x0). With a non offset way we would have to have something
> like
> 
> ranges = <0x10 0x10 0x5>;
> 
> With the child and tha parent always matching.
> 
> (this is easy to handle in the parsing and probe as we will just
> calculate the real address based on the base address of the PHY package
> + offset)

On one hand it makes sense and looks useful for software development. On 
another, it looks like a violation of the main DT designing rule, when 
DT should be used to describe that hardware properties, which can not be 
learnt from other sources.

As far as I understand this specific chip, each of embedded PHYs has its 
own MDIO bus address and not an offset from a main common address. 
Correct me please, if I am got it wrong.

> I hope Rob can give more feedback about this, is this what you were
> thinking with the usage of ranges property?
> 
> (this has also the bonus point of introducing some validation in the PHY
> core code to make sure the right amount of PHY are defined in the
> package by checking if the number of PHY doesn't exceed the value set in
> ranges.)

Yep, I am also would like to hear some clarification from Rob regarding 
acceptable 'range' property usage and may be some advice on how to 
specify the size of occupied addresses. Rob?

--
Sergey
Christian Marangi Jan. 17, 2024, 8:03 p.m. UTC | #14
On Wed, Jan 17, 2024 at 09:39:25PM +0200, Sergey Ryazanov wrote:
> Hi Christian,
> 
> On 17.01.2024 02:36, Christian Marangi wrote:
> > On Sun, Jan 07, 2024 at 11:49:12PM +0200, Sergey Ryazanov wrote:
> > > Hi Christian,
> > > 
> > > On 07.01.2024 20:30, Christian Marangi wrote:
> > > > On Sun, Jan 07, 2024 at 08:00:33PM +0200, Sergey Ryazanov wrote:
> > > > > On 26.11.2023 03:53, Christian Marangi wrote:
> > > > > > Document ethernet PHY package nodes used to describe PHY shipped in
> > > > > > bundle of 4-5 PHY. The special node describe a container of PHY that
> > > > > > share common properties. This is a generic schema and PHY package
> > > > > > should create specialized version with the required additional shared
> > > > > > properties.
> > > > > > 
> > > > > > Example are PHY package that have some regs only in one PHY of the
> > > > > > package and will affect every other PHY in the package, for example
> > > > > > related to PHY interface mode calibration or global PHY mode selection.
> > > > > > 
> > > > > > The PHY package node MUST declare the base address used by the PHY driver
> > > > > > for global configuration by calculating the offsets of the global PHY
> > > > > > based on the base address of the PHY package and declare the
> > > > > > "ethrnet-phy-package" compatible.
> > > > > > 
> > > > > > Each reg of the PHY defined in the PHY package node is absolute and will
> > > > > > reference the real address of the PHY on the bus.
> > > > > > 
> > > > > > Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
> > > > > > ---
> > > > > >     .../bindings/net/ethernet-phy-package.yaml    | 75 +++++++++++++++++++
> > > > > >     1 file changed, 75 insertions(+)
> > > > > >     create mode 100644 Documentation/devicetree/bindings/net/ethernet-phy-package.yaml
> > > > > > 
> > > > > > diff --git a/Documentation/devicetree/bindings/net/ethernet-phy-package.yaml b/Documentation/devicetree/bindings/net/ethernet-phy-package.yaml
> > > > > > new file mode 100644
> > > > > > index 000000000000..244d4bc29164
> > > > > > --- /dev/null
> > > > > > +++ b/Documentation/devicetree/bindings/net/ethernet-phy-package.yaml
> > > > > > @@ -0,0 +1,75 @@
> > > > > > +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
> > > > > > +%YAML 1.2
> > > > > > +---
> > > > > > +$id: http://devicetree.org/schemas/net/ethernet-phy-package.yaml#
> > > > > > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > > > > > +
> > > > > > +title: Ethernet PHY Package Common Properties
> > > > > > +
> > > > > > +maintainers:
> > > > > > +  - Christian Marangi <ansuelsmth@gmail.com>
> > > > > > +
> > > > > > +description:
> > > > > > +  This schema describe PHY package as simple container for
> > > > > > +  a bundle of PHYs that share the same properties and
> > > > > > +  contains the PHYs of the package themself.
> > > > > > +
> > > > > > +  Each reg of the PHYs defined in the PHY package node is
> > > > > > +  absolute and describe the real address of the PHY on the bus.
> > > > > > +
> > > > > > +properties:
> > > > > > +  $nodename:
> > > > > > +    pattern: "^ethernet-phy-package(@[a-f0-9]+)?$"
> > > > > > +
> > > > > > +  compatible:
> > > > > > +    const: ethernet-phy-package
> > > > > > +
> > > > > > +  reg:
> > > > > > +    minimum: 0
> > > > > > +    maximum: 31
> > > > > > +    description:
> > > > > > +      The base ID number for the PHY package.
> > > > > > +      Commonly the ID of the first PHY in the PHY package.
> > > > > > +
> > > > > > +      Some PHY in the PHY package might be not defined but
> > > > > > +      still exist on the device (just not attached to anything).
> > > > > > +      The reg defined in the PHY package node might differ and
> > > > > > +      the related PHY might be not defined.
> > > > > > +
> > > > > > +  '#address-cells':
> > > > > > +    const: 1
> > > > > > +
> > > > > > +  '#size-cells':
> > > > > > +    const: 0
> > > > > > +
> > > > > > +patternProperties:
> > > > > > +  ^ethernet-phy(@[a-f0-9]+)?$:
> > > > > > +    $ref: ethernet-phy.yaml#
> > > > > > +
> > > > > > +required:
> > > > > > +  - compatible
> > > > > > +  - reg
> > > > > > +
> > > > > > +additionalProperties: true
> > > > > > +
> > > > > > +examples:
> > > > > > +  - |
> > > > > > +    mdio {
> > > > > > +        #address-cells = <1>;
> > > > > > +        #size-cells = <0>;
> > > > > > +
> > > > > > +        ethernet-phy-package@16 {
> > > > > > +            #address-cells = <1>;
> > > > > > +            #size-cells = <0>;
> > > > > > +            compatible = "ethernet-phy-package";
> > > > > > +            reg = <0x16>;
> > > > > > +
> > > > > > +            ethernet-phy@16 {
> > > > > > +              reg = <0x16>;
> > > > > > +            };
> > > > > > +
> > > > > > +            phy4: ethernet-phy@1a {
> > > > > > +              reg = <0x1a>;
> > > > > > +            };
> > > > > > +        };
> > > > > > +    };
> > > > > 
> > > > > So, we ended up on a design where we use the predefined compatible string
> > > > > 'ethernet-phy-package' to recognize a phy package inside the
> > > > > of_mdiobus_register() function. During the V1 discussion, Vladimir came up
> > > > > with the idea of 'ranges' property usage [1]. Can we use 'ranges' to
> > > > > recognize a phy package in of_mdiobus_register()? IMHO this will give us a
> > > > > clear DT solution. I mean 'ranges' clearly indicates that child nodes are in
> > > > > the same address range as the parent node. Also we can list all child
> > > > > addresses in 'reg' to mark them occupied.
> > > > > 
> > > > >     mdio {
> > > > >       ...
> > > > > 
> > > > >       ethernet-phy-package@16 {
> > > > >         compatible = "qcom,qca8075";
> > > > >         reg = <0x16>, <0x17>, <0x18>, <0x19>, <0x1a>;
> > > > >         ranges;
> > > > >         ...
> > > > > 
> > > > >         ethernet-phy@16 {
> > > > >           reg = <0x16>;
> > > > >         };
> > > > > 
> > > > >         ethernet-phy@1a {
> > > > >           reg = <0x1a>;
> > > > >         };
> > > > >       };
> > > > >     };
> > > > > 
> > > > > Did you find some issues with the 'ranges' conception?
> > > > 
> > > > Nope it's ok but it might pose some confusion with the idea that the
> > > > very first element MUST be THE STARTING ADDR of the PHY package. (people
> > > > might think that it's just the list of the PHYs in the package and
> > > > remove the hardware unconnected ones... but that would be fault of who
> > > > write the DT anyway.)
> > > 
> > > Make sense. I do not insist on addresses listing. Mainly I'm thinking of a
> > > proper way to show that child nodes are accessible directly on the parent
> > > bus, and introducing the special compatibility string, while we already have
> > > the 'ranges' property.
> > > 
> > > But it's good to know Rob's opinion on whether it is conceptually right to
> > > use 'ranges' here.
> > > 
> > 
> > I wonder if something like this might make sense... Thing is that with
> > the ranges property we would have the define the address in the PHY
> > Package node as offsets...
> > 
> > An example would be
> > 
> >      mdio {
> >          #address-cells = <1>;
> >          #size-cells = <0>;
> > 
> >          ethernet-phy-package@10 {
> >              #address-cells = <1>;
> >              #size-cells = <0>;
> >              compatible = "qcom,qca807x-package";
> >              reg = <0x10>;
> >              ranges = <0x0 0x10 0x5>;
> > 
> >              qcom,package-mode = "qsgmii";
> > 
> >              ethernet-phy@0 {
> >                  reg = <0>;
> > 
> >                  leds {
> > 
> > 		...
> > 
> > With a PHY Package at 0x10, that span 5 address and the child starts at
> > 0x0 offset.
> > 
> > This way we would be very precise on describing the amount of address
> > used by the PHY Package without having to define the PHY not actually
> > connected.
> > 
> > PHY needs to be at an offset to make sense of the ranges first element
> > property (0x0). With a non offset way we would have to have something
> > like
> > 
> > ranges = <0x10 0x10 0x5>;
> > 
> > With the child and tha parent always matching.
> > 
> > (this is easy to handle in the parsing and probe as we will just
> > calculate the real address based on the base address of the PHY package
> > + offset)
> 
> On one hand it makes sense and looks useful for software development. On
> another, it looks like a violation of the main DT designing rule, when DT
> should be used to describe that hardware properties, which can not be learnt
> from other sources.
> 
> As far as I understand this specific chip, each of embedded PHYs has its own
> MDIO bus address and not an offset from a main common address. Correct me
> please, if I am got it wrong.
>

Correct, it's a quad PHY but each PHY have it's own address and they
can't be changed (they are incremental from the base one)

We have lots of device that have this (it's present in 99% of the the
ipq40xx and ipq807x SoC) and the common setup is putting the quad PHY
and connect only some port to it. (the address are occupiaed anyway just
the ethernet port is not connected)

Honestly I don't think it's a violation, IMHO quite the opposite. If DT
is there to describe the hardware, defining each PHY of the package as a
separate one is wrong and actually cause confusion by dropping entirely
any description that they are indeed in a package and that on the BUS
there may be address used without anything connected.

I'm more convinced with the ranges property as we can't put a size to
the reg property. (due to mdio node having address-cell to 0, changing
this will affect also every other phy node and that is problematic)

> > I hope Rob can give more feedback about this, is this what you were
> > thinking with the usage of ranges property?
> > 
> > (this has also the bonus point of introducing some validation in the PHY
> > core code to make sure the right amount of PHY are defined in the
> > package by checking if the number of PHY doesn't exceed the value set in
> > ranges.)
> 
> Yep, I am also would like to hear some clarification from Rob regarding
> acceptable 'range' property usage and may be some advice on how to specify
> the size of occupied addresses. Rob?
> 
> --
> Sergey
Andrew Lunn Jan. 17, 2024, 8:05 p.m. UTC | #15
> On one hand it makes sense and looks useful for software development. On
> another, it looks like a violation of the main DT designing rule, when DT
> should be used to describe that hardware properties, which can not be learnt
> from other sources.
> 
> As far as I understand this specific chip, each of embedded PHYs has its own
> MDIO bus address and not an offset from a main common address. Correct me
> please, if I am got it wrong.

I don't have the datasheet for this specific PHY. But the concept of a
quad PHY in one package is well known. Take for example the
VSC8584. The datasheet is open on Microchips website. It has four
strapping pins to determine the addresses of the PHYs in the
package. The PHY number, 0 - 3 determine bits 0-1 of the MDIO
address. The 4 strapping pins then determine bit 2-5 of the address.

In theory, each PHY could have its own strapping pins, allowing it to
be set to any address, and two PHYs could even have the same
address. But i doubt anybody actually builds hardware like that. I
expect the base addresses is set at the package level, and then PHYs
are just offsets from this.

So to me, a range property does seem reasonable. However, I agree, we
need acceptance from the DT Maintainers.

     Andrew