3.2.2.16. SERDES
3.2.2.16.1. Introduction
SERDES converts device (SoC) parallel data into serialized data that can be output over a high-speed electrical interface. In the opposite direction, SerDes converts high-speed serial data into parallel data that can be processed by the device.
SERDES is used for transmitting/receiving data for PCIe, USB3, CPSW (QSGMII, SGMII, USXGMII, XFI), eDP in K3 SoC.
Note
The following documentation describes the different PHY types (data rates) supported by the SERDES. While the SERDES might support a given protocol, it does not imply that the peripheral is capable of utilizing it. Please refer to the Technical Reference Manual for verifying hardware support for the peripheral. Refer to the peripheral driver documentation for verifying software support for the peripheral.
3.2.2.16.2. Types of SERDES
The TI J784S4 SoC has a 4 Lane SERDES.
4 Lane Serdes
┌───────────────────┐
<-> Peripheral IP1│ │ <-> RX0/TX0
──────────────────┤ ├────────────────
│ │
│ │
<-> Peripheral IP2│ │ <-> RX1/TX1
──────────────────┤ ├────────────────
│ │
│ 4L SERDES │
<-> Peripheral IP3│ │ <-> RX2/TX2
──────────────────┤ ├────────────────
│ │
│ │
<-> Peripheral IP4│ │ <-> RX3/TX3
──────────────────┤ ├────────────────
│ │
│ │
└───────────────────┘
3.2.2.16.3. SERDES Configurations
This section lists the set of PHY types (data rates) that the SERDES can be configured in, from the perspective of the SERDES driver and SERDES hardware support. To enable the desired configuration, the SoC device-tree has to be modified based on the instructions mentioned in the SERDES Muxing section.
A single SERDES can support either one protocol (connects to one Peripheral IP) or two protocols (connects to multiple Peripheral IP) at the same time.
If a SERDES supports one protocol, it’s called a single link PHY and if a SERDES supports two protocols, it’s called multi-link PHY. Note that a single link PHY can comprise multiple lanes. For a multi-link PHY, the lanes can be split up in different ways but the only constraint is that the SERDES can support up to two protocols simultaneously.
It’s also not always necessary to use all the lanes of a SERDES and some lanes can be left unused.
Supported 4 Lane Serdes Configurations
The 4 Lane SERDES instances in J784S4 SoC are configured by the Torrent Serdes kernel driver:
drivers/phy/cadence/phy-cadence-torrent.c
The possible Peripheral IP configurations that can be configured on the 4 Lane SERDES are:
Single Protocol Configurations:
EDP
PCIe
QSGMII
SGMII
USB
USXGMII
Multi Protocol Configurations:
EDP + PCIe
EDP + USB
PCIe + QSGMII
PCIe + SGMII
PCIe + USB
PCIe + USXGMII
QSGMII + USB
QSGMII + USXGMII
SGMII + USB
SGMII + USXGMII
3.2.2.16.4. SERDES Instances
J784S4 SoC has four instances of the 4 Lane Serdes.
3.2.2.16.5. SERDES Muxing
SERDES Muxing refers to the process of selecting the mapping between the Peripheral Lanes and the SERDES Lanes. A valid mapping refers to the process of selecting a valid combination of Peripheral Lane and SERDES Lane based on the physical connections available to choose from. Listed below is the valid set of combinations for the SERDES instances.
SERDES 0
┌───────────────────┐
| │
PCIE1_LANE0/| │
HYPERLINK_LANE0 │ │ <-> RX0/TX0
──────────────────┤ ├────────────────
│ │
│ │
PCIE1_LANE1/| │
HYPERLINK_LANE1 │ │ <-> RX1/TX1
──────────────────┤ ├────────────────
│ │
│ 4L SERDES │
PCIE3_LANE0/| │
PCIE1_LANE2/│ │
HYPERLINK_LANE2 │ │ <-> RX2/TX2
──────────────────┤ ├────────────────
│ │
│ │
PCIE3_LANE1/| │
PCIE1_LANE3/│ │
USB3_0/│ │
HYPERLINK_LANE3 │ │ <-> RX3/TX3
──────────────────┤ ├────────────────
│ │
└───────────────────┘
SERDES 1
┌───────────────────┐
| │
CPSW0_Q/SGMII_LANE3/| │
PCIE0_LANE0 │ │ <-> RX0/TX0
──────────────────┤ ├────────────────
│ │
│ │
CPSW0_Q/SGMII_LANE4/| │
PCIE0_LANE1 │ │ <-> RX1/TX1
──────────────────┤ ├────────────────
│ │
│ 4L SERDES │
CPSW0_Q/SGMII_LANE1/│ │
PCIE0_LANE2/| │
PCIE2_LANE0 │ │ <-> RX2/TX2
──────────────────┤ ├────────────────
│ │
│ │
CPSW0_Q/SGMII_LANE2/│ │
PCIE0_LANE3/| │
PCIE2_LANE1 │ │ <-> RX3/TX3
──────────────────┤ ├────────────────
│ │
└───────────────────┘
SERDES 2
┌───────────────────┐
| │
CPSW0_Q/SGMII_LANE5 │ │ <-> RX0/TX0
──────────────────┤ ├────────────────
│ │
│ │
CPSW0_Q/SGMII_LANE6 │ │ <-> RX1/TX1
──────────────────┤ ├────────────────
│ │
│ 4L SERDES │
CPSW0_Q/SGMII_LANE7/| │
CPSW0_Q/SGMII_LANE1 │ │ <-> RX2/TX2
──────────────────┤ ├────────────────
│ │
│ │
CPSW0_Q/SGMII_LANE8/│ │
CPSW0_Q/SGMII_LANE2 │ │ <-> RX3/TX3
──────────────────┤ ├────────────────
│ │
└───────────────────┘
SERDES 4
┌───────────────────┐
EDP1_LANE0/| │
CPSW0_Q/SGMII_LANE5/| │
HYPERLINK_LANE0 │ │ <-> RX0/TX0
──────────────────┤ ├────────────────
│ │
EDP1_LANE1/| │
CPSW0_Q/SGMII_LANE6/| │
HYPERLINK_LANE1 │ │ <-> RX1/TX1
──────────────────┤ ├────────────────
│ 4L SERDES │
EDP1_LANE2/| │
CPSW0_Q/SGMII_LANE7/| │
HYPERLINK_LANE2 │ │ <-> RX2/TX2
──────────────────┤ ├────────────────
│ │
EDP1_LANE3/| │
CPSW0_Q/SGMII_LANE8/| │
USB3_0/| │
HYPERLINK_LANE0 │ │ <-> RX3/TX3
──────────────────┤ ├────────────────
│ │
└───────────────────┘
The Muxing configuration for each of the SERDES lanes can be described using device tree. The device tree node labelled serdes_ln_ctrl corresponds to the mux used to configure each of the SERDES lanes. The property “idle-states” inside the serdes_ln_ctrl mux is used to specify the mapping between the SERDES lane and the IP lane.
A valid mapping can be determined by referring to the SERDES muxing section above. To select a mapping, the following format has to be used:
<SoC_SERDESw_LANEx_IPa_LANEb>
where:
SoC is the name of the SoC,
‘w’ specifies the SERDES instance: SERDES0 for example,
‘x’ specifies the SERDES Lane: LANE0 for example,
IP specifies the peripheral IP: PCIE for example,
‘a’ specifies the instance of that peripheral IP: PCIE0 for example,
‘b’ specifies the peripheral IP’s Lane: LANE0 for example.
The mapping is interpret as follows:
For the SoC named: SoC, SERDESw LANEx should be mapped to IPa LANEb.
For unused Serdes lanes, indicate them using:
<SoC_SERDESw_LANEx_IPa_UNUSED>
Serdes Muxing Example
Consider an SoC named SoCX with one 1L SERDES, one 2L SERDES and one 4L SERDES, with the instances being SERDES0, SERDES1 and SERDES2. Additionally, let the SoC have PCIe instance PCIE1, EDP instance EDP0 and a CPSW instance using QSGMII.
Then, to configure:
SERDES0 Lane0 for PCIE1 Lane0
SERDES1 Lane0 for EDP0 Lane2
SERDES1 Lane1 for EDP0 Lane3
SERDES2 Lane0 for QSGMII Lane3
SERDES2 Lane1 for QSGMII Lane4
SERDES2 Lane2 for QSGMII Lane1
SERDES2 Lane3 for QSGMII Lane2
the device tree serdes_ln_ctrl node has to be defined as follows:
&serdes_ln_ctrl {
idle-states = <SoCX_SERDES0_LANE0_PCIE1_LANE0>, <SoCX_SERDES1_LANE0_EDP0_LANE2>,
<SoCX_SERDES1_LANE1_EDP0_LANE3>, <SoCX_SERDES2_LANE0_QSGMII_LANE3>,
<SoCX_SERDES2_LANE1_QSGMII_LANE4>, <SoCX_SERDES2_LANE2_QSGMII_LANE1>
<SoCX_SERDES2_LANE3_QSGMII_LANE2>;
};
Default Device Tree Muxing
The J784S4 board file k3-j784s4-evm.dts contains the following Serdes Muxing by default:
&serdes_ln_ctrl {
idle-states = <J784S4_SERDES0_LANE0_PCIE1_LANE0>, <J784S4_SERDES0_LANE1_PCIE1_LANE1>,
<J784S4_SERDES0_LANE2_IP3_UNUSED>, <J784S4_SERDES0_LANE3_USB>,
<J784S4_SERDES1_LANE0_PCIE0_LANE0>, <J784S4_SERDES1_LANE1_PCIE0_LANE1>,
<J784S4_SERDES1_LANE2_PCIE0_LANE2>, <J784S4_SERDES1_LANE3_PCIE0_LANE3>,
<J784S4_SERDES2_LANE2_QSGMII_LANE1>, <J784S4_SERDES2_LANE3_QSGMII_LANE2>;
};
The exact mux values to be programmed can be obtained from the dt-bindings include directory of the kernel repository:
include/dt-bindings/mux/ti-serdes.h
The serdes_ln_ctrl based configuration uses the mux framework of Linux. More information can be found in the Documentation of the kernel repository:
Documentation/devicetree/bindings/mux/mux-controller.yaml
3.2.2.16.6. SERDES Clocking Options
Each SERDES has PLLs inside it which have to be programmed to operate at different frequencies, based on the data rate required by the Peripheral IP connected to the SERDES.
For example, based on the specification, the data rates for some of the Peripheral IPs are:
8Gbps for PCIe GEN3
5Gbps for PCIe GEN2
2.5Gbps for PCIe GEN1
5Gbps for USB3 SS
5Gbps for QSGMII [CPSW Ethernet]
The input reference clocks connected to each SERDES are used to program the PLLs inside the SERDES. The details regarding the PLL frequencies and programming is abstracted from the user. The user only has to provide the reference clocks to be used by the SERDES for programming the PLLs, based on the data rates required by the Peripheral IPs being used.
4L SERDES Clocking Options
The following illustration shows the clocking options for the 4L SERDES.
/|HFOSC0_CLKOUT
┌───────────────────────┐ / ┌◄───────────────
│ │ │ │
│ │ │ │HFOSC1_CLKOUT
│ ┌─────────┐ │ core_refclk │ ├◄───────────────
│ │ PLL0 │ │◄────────────────┤ │
│ │ │ │ │ │MAIN_PLL3_HSDIV4_CLKOUT (100/125/156.25 MHz)
│ └─────────┘ │ │ ├◄───────────────
│ │ │ │
│ │ │ │MAIN_PLL2_HSDIV4_CLKOUT (100 MHz)
│ │ \ ├◄───────────────
│ ┌─────────┐ │ \│
│ │ PLL1 │ │
│ │ │ │ cmn_refclk
│ └─────────┘ │◄─────────────────
│ │
│ │
│ 4L SERDES │ refclk_out
│ │─────────────────►X Not Used
│ │
│ │
└───────────────────────┘
As seen in the figure above, 4L SERDES IP supports 2 clock inputs (core_refclk and cmn_refclk). The clock core_refclk is the internal reference clock while the clock cmn_refclk is the external reference clock. It also has an output reference clock which is not used (refclk_out).
For the clock IDs corresponding to the 4 Lane SERDES instances, refer:
3.2.2.16.6.1. Internal Reference Clock
In order to use internal reference clock, core_refclk input to the 4L SERDES should be used. core_refclk can use one of the four inputs provided to the input-muxed clock.
The WIZ wrapper allows selecting the input clock to be used for core_refclk. In the device-tree, within the WIZ parent node of the 4 Lane SERDES node, the following device-tree properties are used to configure the clocks:
“assigned-clocks” property is used to indicate the input-muxed clock corresponding to the core_refclk internal reference clock.
“assigned-clock-parents” property is used to indicate which of the 4 clock inputs to the input-muxed clock is to be selected and used for core_refclk.
serdes_wiz0: wiz@5060000 {
compatible = "ti,j784s4-wiz-10g";
.
.
assigned-clocks = <&k3_clks 404 6>;
assigned-clock-parents = <&k3_clks 404 10>;
.
.
};
In the above example, the WIZ node corresponding to the 4 Lane SERDES0 instance is shown. Within the WIZ node, using the “assigned-clocks” property, we are indicating that core_refclk receives its input from the clock identified by:
<k3_clks 404 6>
which is the input-muxed clock corresponding to core_refclk. The value 404 corresponds to the J784S4_DEV_SERDES_10G0 device, while the value 6 corresponds to DEV_SERDES_10G0_CORE_REF_CLK which is the input-muxed clock.
The value of the “assigned-clock-parents” property corresponding to core_refclk is:
<&k3_clks 404 10>
which indicates that the clock with clock ID 10 (DEV_SERDES_10G0_CORE_REF_CLK_PARENT_HSDIV4_16FFT_MAIN_2_HSDIVOUT4_CLK) which is the MAIN_PLL2_HSDIV4_CLKOUT clock has to be used as the core_refclk, via the input-muxed clock.
3.2.2.16.6.2. External Reference Clock
The 4L SERDES IP supports one external reference clock input cmn_refclk (named as serdes_refclk in the device-tree).
The external reference clock input is represented in the SoC device-tree file (k3-j784s4-main.dtsi) as shown below:
/ {
serdes_refclk: serdes-refclk {
#clock-cells = <0>;
compatible = "fixed-clock";
};
.
.
.
};
3.2.2.16.6.3. Selecting Between Internal and External Reference Clock
The WIZ wrapper allows selecting between the internal and external clock to be used as the input to PLL0 and PLL1 of the SERDES. Additionally, the reference clock to be used as input for the digital logic of the SERDES PHY and PMA can also be selected.
It is possible to choose between the internal and external reference clocks for PLL0, PLL1 and the digital reference clock. By default they are configured to use the internal reference clock in the k3-j7200-main.dtsi SoC device-tree file:
serdes0: serdes@5060000 {
compatible = "ti,j7200-serdes-10g";
.
.
.
assigned-clocks = <&serdes_wiz0 TI_WIZ_PLL0_REFCLK>,
<&serdes_wiz0 TI_WIZ_PLL1_REFCLK>,
<&serdes_wiz0 TI_WIZ_REFCLK_DIG>;
assigned-clock-parents = <&k3_clks 404 6>,
<&k3_clks 404 6>,
<&k3_clks 404 6>;
.
.
.
};
For the example above corresponding to SERDES0 instance, the “assigned-clocks” property is used to indicate the clocks for PLL0, PLL1 and the digital reference clock respectively.
The “assigned-clock-parents” property is used to indicate which of the clocks shall be used for each of PLL0, PLL1 and digital reference clocks as the input. Each of them have two reference clock inputs to choose from: internal clock (k3_clks) and external clock (serdes_refclk).
The “assigned-clock-parents” by default sets the clock to internal clocks.
For using the external reference clock, the “assigned-clock-parents” property has to be set to <&serdes_refclk>.