Zynq Ultrascale MPSOC Linux SIOU driver

Zynq Ultrascale MPSOC Linux SIOU driver

Table of Contents

Introduction

ZynqMP SoC has a SerDes/SIOU (Serial Input and Output block) module that provides a high-speed physical interface
for the high-speed peripherals present in the SoC.

  1. USB (2 controllers)

  2. SATA (1 controller with two lanes)

  3. DisplayPort (1 controller with two lanes)

  4. SGMII (4 controllers)

  5. PCIe (1 controller with four lanes)

The inputs to SerDes are PIPE interfaces, and the outputs are four high-speed serial lanes. PHY provides 4 output lanes only for 14 PIPE inputs (as mentioned above: 2 + 2 + 4 + 2 + 4 = 14). All inputs are routed to PHY output lanes with a mux (interconnect matrix). Only some combinations are valid; for example, USB1 cannot be assigned to lane 0. The PHY driver validates DTS entries for the correct combination of controller and SerDes lanes.

Note:

Due to the new driver introduced in the upstream flow, kernel and devicetree configurations are based on the release:

  • Support till 2020.2 release

  • Support from 2021.1 release

HW/IP Features

The ZynqMP PS shall incorporate a quad GT. Features include:

  • A quad transceiver

  • Support for PCIe, SATA, USB 3.0, SGMII, and DisplayPort requirements

    • 1, 2, or 4-lane PCIe support at 2.5 or 5.0 Gbps

    • 1 or 2-lane DisplayPort (TX only) at 1.62, 2.7, or 5.4 Gbps

    • 1-2 SATA channels at 1.5, 3.0, or 6.0 Gbps

    • 1-2 USB 3.0 channels at 5.0 Gbps

    • 1-4 Ethernet SGMII channels at 1.25 Gbps

  • Supports SGMII for data only (no clock, or clock optional)

  • Supports any 4 of the standards simultaneously

  • Provides flexible host-programmable multiplexing for connecting the GT resources to the PS masters (DisplayPort, PCIe, SATA, GEM).

Kernel Configuration

Support till 2020.2 release:

Device Drivers------> Phy Subsystem--> <*> Xilinx ZynqMP phy driver

By enabling the above, the following Kconfig parameter should be enabled:
CONFIG_PHY_XILINX_ZYNQMP=y

Support from 2021.1 release:

Device Drivers------> Phy Subsystem--> -*- PHY Core -*- Xilinx ZynqMP PHY driver

By enabling the above, the following Kconfig parameter should be enabled:

CONFIG_PHY_XILINX_ZYNQMP=y

Devicetree

Support till 2020.2 release:

Device nodes should specify the required configuration in their "phys" property, containing a phandle to the PHY port node and a device type.
The phys property should be as mentioned below:

phys = <PHANDLE CONTROLLER_TYPE CONTROLLER_INSTANCE LANE_NUM LANE_FREQ>;
PHANDLE can be any of &lane0, &lane1, &lane2, or &lane3.
CONTROLLER_TYPE can be any of PHY_TYPE_PCIE, PHY_TYPE_SATA, PHY_TYPE_USB, PHY_TYPE_DP, or PHY_TYPE_SGMII.
CONTROLLER_INSTANCE depends on the controller type used and can be any of the following:

  • PHY_TYPE_PCIE: 0 or 1 or 2 or 3
    PHY_TYPE_SATA: 0 or 1
    PHY_TYPE_USB: 0 or 1
    PHY_TYPE_DP: 0 or 1
    PHY_TYPE_SGMII: 0 or 1 or 2 or 3

LANE_NUM depends on which lane clock is used as refclk and can be 0, 1, 2, or 3.
LANE_FREQ is the frequency at which the controller can operate and can be any of 19.2 MHz, 20 MHz, 24 MHz, 26 MHz, 27 MHz, 28.4 MHz, 40 MHz, 52 MHz, 100 MHz, 108 MHz, 125 MHz, 135 MHz, or 150 MHz.

Example
The code below is required for probing the SerDes driver. This should be added in zynqmp.dtsi.

serdes: zynqmp_phy@fd400000 { compatible = "xlnx,zynqmp-psgtr"; status = "okay"; reg = <0x0 0xfd400000 0x0 0x40000>, <0x0 0xfd3d0000 0x0 0x1000>, <0x0 0xfd1a0000 0x0 0x1000>, <0x0 0xff5e0000 0x0 0x1000>; reg-names = "serdes", "siou", "fpd", "lpd"; xlnx,tx_termination_fix; lane0: lane@0 { #phy-cells = <4>; }; lane1: lane@1 { #phy-cells = <4>; }; lane2: lane@2 { #phy-cells = <4>; }; lane3: lane@3 { #phy-cells = <4>; }; };

The code below configures USB instance 0 to use lane 2 and get a 26 MHz lane refclk from lane 2.

usb@fe200000 { ... phys = <&lane2 PHY_TYPE_USB3 0 2 26000000>; ... };

The code below configures SATA instance 1 to use lane 3 and get a 125 MHz lane refclk from lane 1.

ahci@fd0c0000 { ... phys = <&lane3 PHY_TYPE_SATA 1 1 125000000>; ... };

Support from 2021.1 release:

In the new upstream flow, the following changes need to be added:

phys = <PHANDLE LANE_NUM CONTROLLER_TYPE CONTROLLER_INSTANCE LANE_FREQ>;

PHANDLE = &psgtr

LANE_NUM = 0, 1, 2, 3

CONTROLLER_TYPE = PHY_TYPE_PCIE, PHY_TYPE_SATA, PHY_TYPE_USB, PHY_TYPE_DP, or PHY_TYPE_SGMII

CONTROLLER_INSTANCE depends on the controller type used and can be any of the following:

PHY_TYPE_PCIE: 0 or 1 or 2 or 3
PHY_TYPE_SATA: 0 or 1
PHY_TYPE_USB: 0 or 1
PHY_TYPE_DP: 0 or 1
PHY_TYPE_SGMII: 0 or 1 or 2 or 3

LANE_FREQ = refclk number that has the desired frequency

Example:

PSGTR changes:

refclk4:psgtr_dp_clock { compatible = "fixed-clock"; #clock-cells = <0x00>; clock-frequency = <27000000>; }; refclk3:psgtr_usb_clock { compatible = "fixed-clock"; #clock-cells = <0x00>; clock-frequency = <26000000>; }; refclk2:psgtr_sata_clock { compatible = "fixed-clock"; #clock-cells = <0x00>; clock-frequency = <125000000>; }; refclk1:psgtr_pcie_clock { compatible = "fixed-clock"; #clock-cells = <0x00>; clock-frequency = <150000000>; }; psgtr: phy@fd400000 { compatible = "xlnx,zynqmp-psgtr-v1.1"; reg = <0x00 0xfd400000 0x00 0x40000 0x00 0xfd3d0000 0x00 0x1000>; reg-names = "serdes\0siou"; #clock-cells = <0x01>; clocks = <&refclk1 &refclk2 &refclk3 &refclk4>; /* refclk instances used per lane */ clock-names = "ref0\0ref1\0ref2\0ref3"; #phy-cells = <0x04>; status = "okay"; };

SATA instance 1 using lane 3 refclk 125 MHz:

ahci@fd0c0000 { compatible = "ceva,ahci-1v84"; status = "okay"; reg = <0x00 0xfd0c0000 0x00 0x2000>; ..... /* psgtr_phandle....lane number... controller_type...instance....refclk */ phys = <&psgtr 0x3 PHY_TYPE_SATA 0x01 0x1>; reset-names = "sata_rst"; resets = <0x1a 0x10>; };

USB instance 0 using lane 2 refclk 26 MHz:

usb0@ff9d0000 { #address-cells = <0x02>; #size-cells = <0x02>; status = "okay"; compatible = "xlnx,zynqmp-dwc3"; reg = <0x00 0xff9d0000 0x00 0x100>; clock-names = "bus_clk\0ref_clk"; .... resets = <0x1a 0x3b 0x1a 0x3d 0x1a 0x3f>; reset-names = "usb_crst\0usb_hibrst\0usb_apbrst"; ...... dwc3@fe200000 { compatible = "snps,dwc3"; status = "okay"; reg = <0x00 0xfe200000 0x00 0x40000>; interrupt-parent = <0x04>; interrupt-names = "dwc_usb3\0otg\0hiber"; interrupts = <0x00 0x41 0x04 0x00 0x45 0x04 0x00 0x4b 0x04>; #stream-id-cells = <0x01>; ..... dr_mode = "host"; maximum-speed = "super-speed"; phy-names = "usb3-phy"; /* psgtr_phandle....lane number... controller_type...instance....refclk */ phys = <&psgtr 0x2 PHY_TYPE_USB 0x00 0x02>; }; };

Test Procedure

As this driver is used by SATA, USB, PCIe, SGMII, and DP protocols, testing the functionality of any of those protocols will automatically test this IP.

Expected Output

Once Linux is booted, type "dmesg | grep gtr" and check whether PLL lock is happening. The output below is expected:

root@Xilinx-ZCU102-2016_3:~# dmesg | grep gtr [ 6.575387] xilinx-psgtr fd400000.zynqmp_phy: Lane:3 type:3 protocol:2 pll_locked:yes [ 6.808627] xilinx-psgtr fd400000.zynqmp_phy: Lane:2 type:0 protocol:3 pll_locked:yes [ 7.570858] xilinx-psgtr fd400000.zynqmp_phy: Lane:1 type:8 protocol:4 pll_locked:yes

Mainline Status

The current driver available in the Xilinx Linux git is in sync (except one suspend/resume fix for USB) with the open-source kernel.

Change log

2026.1

  • Kernel upgrade to 6.18, fix USB enumeration failure on suspend/resume.

  • a743371c36f2 phy: zynqmp: keep SERDES scrambler and 8b/10b enabled for USB

  • 066fd30275f9 phy: zynqmp: use read-modify-write for SERDES scrambler bypass

  • af1f75b10e07 phy: zynqmp: fix L0_TM_DISABLE_SCRAMBLE_ENCODER mask

2025.2

  • None

2025.1

  • Kernel upgrade to 6.12

2024.2

  • phy: xilinx: phy-zynqmp: Fix SGMII linkup failure on resume 4dd8383fcbe1

2024.1

  • Kernel upgrade to 6.6

2023.2

  • None

2023.1

  • Kernel upgrade to 6.1

  • Updated comment description: SGMII is validated on SOM KR260. 7f2f1a1

2022.2

  • None

2022.1

  • Kernel upgrade to 5.15

  • Fix bus width setting for SGMII 5d691d

2021.2

  • None

2021.1

  • ZynqMP: Add PHY driver for the Xilinx ZynqMP Gigabit Transceiver

  • Fix unused-function compiler warning

  • Handle the clock enable/disable properly

  • Skip PHY initialization and PLL lock for USB

Note: This new PSGTR configuration is applicable from Xilinx 2021.1 release onward.

Related Links