This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

PROCESSOR-SDK-J721E: Share serdes2 between pcie and usb

Part Number: PROCESSOR-SDK-J721E

Hello.

We have a custom board, based on J821E, that has:

- a pcie bus wired to serdes2 lane0 - to be used with processor's pcie2 unit

- a usb bus wied to serdes2 lane1 - to be used with processor's usb1 unit

Setup with PCIE enabled but USB not enabled - works with this device tree fragment:

&serdes2 {
serdes2_pcie_link: link@0 {
reg = <0>;
cdns,num-lanes = <1>;
#phy-cells = <0>;
cdns,phy-type = <PHY_TYPE_PCIE>;
resets = <&serdes_wiz2 1>, <&serdes_wiz2 2>;
};
};
&pcie2_rc {
reset-gpios = <&main_gpio0 7 GPIO_ACTIVE_HIGH>;
phys = <&serdes2_pcie_link>;
phy-names = "pcie_phy";
num-lanes = <1>;
status = "okay";
};

Setup with USB enabled but PCIE not enabled - works with this device tree fragment:

&serdes2 {
serdes2_usb1_link: link@1 {
reg = <1>;
cdns,num-lanes = <1>;
#phy-cells = <0>;
cdns,phy-type = <PHY_TYPE_USB3>;
resets = <&serdes_wiz2 1>, <&serdes_wiz2 2>;
};
};
&usb1 {
dr_mode = "host";
maximum-speed = "super-speed";
phys = <&serdes2_usb1_link>;
phy-names = "cdns3,usb3-phy";
status = "okay";
};

Question is - how to make the two devices work at the same time.

It is not possible to use the above device tree snippets together because they conflict - both reference <&serdes_wiz2 1>, and <&serdes_wiz2 2>, this causes serdes2_wiz registeration to fail.

In the kernel sources, these "resets" are backed by wiz_phy_reset_assert() / wiz_phy_reset_deassert() in drivers/phy/ti/phy-j721e-wiz.c and physically control bits 31:30 of LANECTLn registers - that is "enable lane" / "force enable lane" fields.

One can assume that to control lane 0, it shal be enough to enable lane0 only (via resets = <&serdes_wiz2 1>), there shall be no need to enable lane 1.  And vice versa.

However, in practive, if leaving only resets = <&serdes_wiz2 1>, then pcie2 registration errors out with

[    4.335159] cdns-sierra-phy 5020000.serdes: PLL lock of lane failed 
[    4.341413] phy phy-5020000.serdes.3: phy poweron failed --> -110
[    4.347493] j721e-pcie 2920000.pcie: Failed to init phy

The first error is from cdns_sierra_phy_on() from drivers/phy/cadence/phy-cadence-sierra.c
The code there polls for non-zero value in bit 0 of PLLLNC_STATUS_PREG__PLLCTRL_STATUS_PREG_0 register, which is "PLLLN active high lock flag". Looks like PLL lock for lane 0 indeed never happens if only lane0 is enabled and lane1 is not.

I'm looking either for any help with this issue, or for functional documentation for the serdes unit (I believe it is an instance of 16G Multi-Protocol PHY from Cadence, https://ip.cadence.com/ipportfolio/ip-portfolio-overview/interface-ip/serdes-ip/16g-multi-protocol-phy) so I could look for a solution myself.