3.2.2.14. SERDES

3.2.2.14.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.14.2. Types of SERDES

The TI AM64x SoC has a 1 Lane SERDES.

1 Lane Serdes

                  ┌───────────────────┐
                  │                   │
                  │                   │
<-> Peripheral IP1│                   │   <-> RX0/TX0
──────────────────┤     1L SERDES     ├────────────────
                  │                   │
                  │                   │
                  └───────────────────┘

3.2.2.14.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.

Supported 1 Lane Serdes Configurations

The 1 Lane SERDES in AM64 SoC is 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 1 Lane SERDES are:

  • EDP

  • PCIe

  • QSGMII

  • SGMII

  • USB

  • USXGMII

3.2.2.14.4. SERDES Instances

AM64 SoC has a single instance of the 1 Lane Serdes.

3.2.2.14.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

                  ┌───────────────────┐
      PCIE0_LANE0/|                   │
           USBSS0 │     1L SERDES     │   <-> RX0/TX0
──────────────────┤                   ├────────────────
                  │                   │
                  └───────────────────┘

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 AM642 board file k3-am642-evm.dts contains the following Serdes Muxing by default:

&serdes_ln_ctrl {
    idle-states = <AM64_SERDES0_LANE0_PCIE0>;
};

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.14.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:

  1. 8Gbps for PCIe GEN3

  2. 5Gbps for PCIe GEN2

  3. 2.5Gbps for PCIe GEN1

  4. 5Gbps for USB3 SS

  5. 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.

1L SERDES Clocking Options

The following illustration shows the clocking options for the 1L SERDES.

                                           /|HFOSC0_CLKOUT
┌───────────────────────┐                 / ┌◄───────────────
│                       │                 │ │
│                       │                 │ │HFOSC1_CLKOUT
│      ┌─────────┐      │ core_refclk     │ ├◄───────────────
│      │  PLL0   │      │◄────────────────┤ │
│      │         │      │                 │ │MAIN_PLL0_HSDIV8_CLKOUT (100/125 MHz)
│      └─────────┘      │                 │ ├◄───────────────
│                       │                 │ │
│      ┌─────────┐      │                 │ │MAIN_PLL2_HSDIV4_CLKOUT (100 MHz)
│      │  PLL1   │      │                 \ ├◄───────────────
│      │         │      │                  \│
│      └─────────┘      │ cmn_refclk
│                       │◄─────────────────
│                       │
│      1L SERDES        │
│                       │
│                       │ ref_der_out_clock /
│                       │ refclk_out
│                       │─────────────────►
└───────────────────────┘

As seen in the figure above, 1L SERDES IP supports 2 clock inputs (core_refclk and cmn_refclk). core_refclk is the internal reference clock while the cmn_refclk is the external reference clock.

For the clock IDs corresponding to the 1 Lane SERDES instances, refer:

1 Lane SERDES0 Clock IDs for AM64

3.2.2.14.6.1. Internal Reference Clock

In order to use internal reference clock, core_refclk input to 1L 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 1 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@f000000 {
        compatible = "ti,am64-wiz-16g";
        .
        .
        assigned-clocks = <&k3_clks 162 1>;
        assigned-clock-parents = <&k3_clks 162 5>;
        .
        .
};

In the above example, the WIZ node corresponding to the 1 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 162 1>

which is the input-muxed clock corresponding to core_refclk. The value 162 corresponds to the AM64X_DEV_SERDES_10G0 device, while the value 1 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 162 5>

which indicates that the clock with clock ID 5 (DEV_SERDES_10G0_CORE_REF_CLK_PARENT_HSDIV4_16FFT_MAIN_2_HSDIVOUT4_CLK) which is the MAIN_PLL2_HSDIV4_CLKOUT clock, is used as the core_refclk, via the input-muxed clock.

3.2.2.14.6.2. External Reference Clock

The 1L 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-am64-main.dtsi) as shown below:

/ {
    serdes_refclk: serdes-refclk {
            #clock-cells = <0>;
            compatible = "fixed-clock";
            clock-frequency = <0>;
  };
  .
  .
  .
};

Note that “clock-frequency = <0>;” is set to “0” since the external clocks need not always be connected, based on the board design.

3.2.2.14.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-am64-main.dtsi SoC device-tree file:

serdes0: serdes@f000000 {
    compatible = "ti,j721e-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 162 1>,
                             <&k3_clks 162 1>,
                             <&k3_clks 162 1>;
    .
    .
    .
};

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>.