Thread (19 messages) 19 messages, 4 authors, 2025-05-16

Re: [PATCH net-next v5 0/5] Add PCS support for Qualcomm IPQ9574 SoC

From: <hidden>
Date: 2025-05-12 22:56:39
Also in: linux-arm-msm, linux-devicetree, lkml

On 2/19/25 4:46 AM, Lei Wei wrote:
On 2/12/2025 6:19 PM, Russell King (Oracle) wrote:
quoted
On Tue, Feb 11, 2025 at 07:59:34PM -0800, Jakub Kicinski wrote:
quoted
On Fri, 7 Feb 2025 23:53:11 +0800 Lei Wei wrote:
quoted
The 'UNIPHY' PCS block in the Qualcomm IPQ9574 SoC provides Ethernet
PCS and SerDes functions. It supports 1Gbps mode PCS and 10-Gigabit
mode PCS (XPCS) functions, and supports various interface modes for
the connectivity between the Ethernet MAC and the external PHYs/Switch.
There are three UNIPHY (PCS) instances in IPQ9574, supporting the six
Ethernet ports.

This patch series adds base driver support for initializing the PCS,
and PCS phylink ops for managing the PCS modes/states. Support for
SGMII/QSGMII (PCS) and USXGMII (XPCS) modes is being added initially.

The Ethernet driver which handles the MAC operations will create the
PCS instances and phylink for the MAC, by utilizing the API exported
by this driver.

While support is being added initially for IPQ9574, the driver is
expected to be easily extendable later for other SoCs in the IPQ
family such as IPQ5332.
Could someone with PHY, or even, dare I say, phylink expertise
take a look here?
I've not had the time, sorry. Looking at it now, I have lots of
questions over this.

1) clocks.

- Patch 2 provides clocks from this driver which are exported to the
   NSCCC block that are then used to provide the MII clocks.
- Patch 3 consumes clocks from the NSCCC block for use with each PCS.

Surely this leads to a circular dependency, where the MSCCC driver
can't get the clocks it needs until this driver has initialised, but
this driver can't get the clocks it needs for each PCS from the NSCCC
because the MSCCC driver needs this driver to initialise.
Sorry for the delay in response. Below is a description of the 
dependencies between the PCS/NSSCC drivers during initialization time 
and how the clock relationships are set up. Based on this, there should 
not any issue due to circular dependency, but please let me know if any 
improvement is possible here given the hardware clock dependency. The 
module loading order is as follows:

Step 1.) NSCC driver module
Step 2.) PCS driver module
Step 3.) Ethernet driver module

The 'UNIPHY' PCS clocks (from Serdes to NSSCC) are not needed to be 
available at the time of registration of PCS MII clocks (NSSCC to PCS 
MII) by the NSSCC driver (Step 1). The PCS MII clocks is registered 
before 'UNIPHY' PCS clock is registered, since by default the parent is 
initialized to 'xo' clock. Below is the output of clock tree on the 
board before the PCS driver is loaded.

xo-board-clk
     nss_cc_port1_rx_clk_src
         nss_cc_port1_rx_div_clk_src
             nss_cc_uniphy_port1_rx_clk
             nss_cc_port1_rx_clk

The 'UNIPHY' PCS clock is later configured as a parent to the PCS MII 
clock at the time when the Ethernet and PCS drivers are enabled (step3) 
and the MAC links up. At link up time, the NSSCC driver sets the NSSCC 
port clock rate (by configuring the divider) based on the link speed, 
during which time the NSSCC port clock's parent is switched to 'UNIPHY' 
PCS clock. Below is the clock tree dump after this step.

7a00000.ethernet-pcs::rx_clk
     nss_cc_port1_rx_clk_src
         nss_cc_port1_rx_div_clk_src
             nss_cc_uniphy_port1_rx_clk
             nss_cc_port1_rx_clk
I tried this PCS driver, and I am seeing a circular dependency in the 
clock init. If the clock tree is:
     GCC -> NSSCC -> PCS(uniphy) -> NSSCC -> PCS(mii)

The way I understand it, the UNIPHY probe depends on the MII probe. If 
MII .probe() returns -EPROBE_DEFER, then so will the UNIPHY .probe(). 
But the MII cannot probe until the UNIPHY is done, due to the clock 
dependency. How is it supposed to work?

The way I found to resolve this is to move the probing of the MII clocks 
to ipq_pcs_get().

This is the kernel log that I see:

[   12.008754] platform 39b00000.clock-controller: deferred probe 
pending: platform: supplier 7a00000.ethernet-pcs not ready
[   12.008788] mdio_bus 90000.mdio-1:18: deferred probe pending: 
mdio_bus: supplier 7a20000.ethernet-pcs not ready
[   12.018704] mdio_bus 90000.mdio-1:00: deferred probe pending: 
mdio_bus: supplier 90000.mdio-1:18 not ready
[   12.028588] mdio_bus 90000.mdio-1:01: deferred probe pending: 
mdio_bus: supplier 90000.mdio-1:18 not ready
[   12.038310] mdio_bus 90000.mdio-1:02: deferred probe pending: 
mdio_bus: supplier 90000.mdio-1:18 not ready
[   12.047943] mdio_bus 90000.mdio-1:03: deferred probe pending: 
mdio_bus: supplier 90000.mdio-1:18 not ready
[   12.057579] platform 7a00000.ethernet-pcs: deferred probe pending: 
ipq9574_pcs: Failed to get MII 0 RX clock
[   12.067209] platform 7a20000.ethernet-pcs: deferred probe pending: 
ipq9574_pcs: Failed to get MII 0 RX clock
[   12.077200] platform 3a000000.qcom-ppe: deferred probe pending: 
platform: supplier 39b00000.clock-controller not ready


PHY:
&mdio {
	qca8k_nsscc: clock-controller@18 {
		compatible = "qcom,qca8084-nsscc";
		...
	};

	ethernet-phy-package@0 {
		compatible = "qcom,qca8084-package";
		...

		qca8084_0: ethernet-phy@0 {
			compatible = "ethernet-phy-id004d.d180";
			reg = <0>;
			clocks = <&qca8k_nsscc NSS_CC_GEPHY0_SYS_CLK>;
			resets = <&qca8k_nsscc NSS_CC_GEPHY0_SYS_ARES>;
		};
		qca8084_1: ethernet-phy@1 {
			compatible = "ethernet-phy-id004d.d180";
			reg = <1>;
			clocks = <&qca8k_nsscc NSS_CC_GEPHY1_SYS_CLK>;
			resets = <&qca8k_nsscc NSS_CC_GEPHY1_SYS_ARES>;
		};
		qca8084_2: ethernet-phy@2 {
			compatible = "ethernet-phy-id004d.d180";
			reg = <2>;
			clocks = <&qca8k_nsscc NSS_CC_GEPHY2_SYS_CLK>;
			resets = <&qca8k_nsscc NSS_CC_GEPHY2_SYS_ARES>;
		};
		qca8084_3: ethernet-phy@3 {
			compatible = "ethernet-phy-id004d.d180";
			reg = <3>;
			clocks = <&qca8k_nsscc NSS_CC_GEPHY3_SYS_CLK>;
			resets = <&qca8k_nsscc NSS_CC_GEPHY3_SYS_ARES>;
		};
	};

	qca8081_12: ethernet-phy@12 {
		reset-gpios = <&tlmm 36 GPIO_ACTIVE_LOW>;
		reg = <12>;
	};

PCS:
	pcs_uniphy0: ethernet-pcs@7a00000 {
		compatible = "qcom,ipq9574-pcs";
		...
		pcsuniphy0_ch0: pcs-mii@0 {
			reg = <0>;
			clocks = <&nsscc NSS_CC_UNIPHY_PORT1_RX_CLK>,
				 <&nsscc NSS_CC_UNIPHY_PORT1_TX_CLK>;
			clock-names = "rx",
				      "tx";
		};
		...

MAC:
		port@1 {
			reg = <1>;
			phy-mode = "usxgmii";
			managed = "in-band-status";
			phy-handle = <&qca8084_0>;
			pcs-handle = <&pcsuniphy0_ch0>;
			...
		};
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help