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.

[FAQ] AM68, AM67, J722S, J721S2, J784S4, TDA4VM, TDA4VL, TDA4VH, DRA821: How to retrain PCIe link speed between Gen1 (2.5GT/s), Gen2 (5.0GT/s), and Gen3 (8.0GT/s) speeds

Part Number: AM69
Other Parts Discussed in Thread: AM67, AM68, , DRA821, TDA4VH, TDA4VM, TDA4VL,

Tool/software:

For troubleshooting and debugging, I would like to manually configure link speeds to a value different from default. How can I do this for AM69 or other devices (such as AM68, AM67, J722S, J721S2, J784S4, TDA4VM, TDA4VL, TDA4VH, DRA821)?

  • The following sequence will retrain link for different speeds within Linux. Do note that below instruction is using the device enumerated as 0000:00:00.0 (usually the first PCIe controller instance on the Jacinto SoC), but should be changed if wanting to change speeds for other devices.

    • setpci -s 0000:00:00.0 CAP_EXP+0x30.W=0x1
      • This changes target link speed to gen 1 speeds (2.5GT/s) by setting link control 2 register. Instead of 0x1, can use 0x2 or 0x3 for Gen2 and Gen3 speeds respectively
    • setpci -s 0000:00:00.0 CAP_EXP+0x10.W=0x20
      • This retrains the link by setting link control register's bit 5
    • lspci -vv -s 0000:00:00.0 | grep -i speed
      • This prints the target speed along with the speed that is actually set

    Below are some example logs for reference, generated using SK-AM69 board with 9.2 Linux SDK. However, these instructions should be applicable for all other Jacinto/Sitara devices running Linux.

    # Print all the devices connected
    root@am69a-sk:/opt/edgeai-gst-apps# lspci
    0000:00:00.0 PCI bridge: Texas Instruments Device b00d
    0000:01:00.0 Non-Volatile memory controller: Samsung Electronics Co Ltd NVMe SSD Controller SM9
    0001:00:00.0 PCI bridge: Texas Instruments Device b013
    0002:00:00.0 PCI bridge: Texas Instruments Device b00d
    
    # Printing what speed is negotiated by default
    root@am69a-sk:/opt/edgeai-gst-apps# lspci -vv -s 0000:00:00.0 | grep -i speed
                    LnkCap: Port #0, Speed 8GT/s, Width x8, ASPM L1, Exit Latency L1 <8us
                    LnkSta: Speed 8GT/s (ok), Width x4 (downgraded)
                    LnkCap2: Supported Link Speeds: 2.5-8GT/s, Crosslink- Retimer- 2Retimers- DRS-
                    LnkCtl2: Target Link Speed: 8GT/s, EnterCompliance- SpeedDis-
                    
    # Setting the "Target Link Speed" to 0x1 (gen 1 speed of 2.5GT/s)
    root@am69a-sk:/opt/edgeai-gst-apps# setpci -s 0000:00:00.0 CAP_EXP+0x30.W=0x1
    root@am69a-sk:/opt/edgeai-gst-apps# lspci -vv -s 0000:00:00.0 | grep -i speed
                    LnkCap: Port #0, Speed 8GT/s, Width x8, ASPM L1, Exit Latency L1 <8us
                    LnkSta: Speed 8GT/s (ok), Width x4 (downgraded)
                    LnkCap2: Supported Link Speeds: 2.5-8GT/s, Crosslink- Retimer- 2Retimers- DRS-
                    LnkCtl2: Target Link Speed: 2.5GT/s, EnterCompliance- SpeedDis-
    
    # Setting the Retrain Link bit (bit 5) of link control register. This initiates link training and sets link status to reflect target link speed.
    root@am69a-sk:/opt/edgeai-gst-apps# setpci -s 0000:00:00.0 CAP_EXP+0x10.W=0x20
    root@am69a-sk:/opt/edgeai-gst-apps# lspci -vv -s 0000:00:00.0 | grep -i speed
                    LnkCap: Port #0, Speed 8GT/s, Width x8, ASPM L1, Exit Latency L1 <8us
                    LnkSta: Speed 2.5GT/s (downgraded), Width x4 (downgraded)
                    LnkCap2: Supported Link Speeds: 2.5-8GT/s, Crosslink- Retimer- 2Retimers- DRS-
                    LnkCtl2: Target Link Speed: 2.5GT/s, EnterCompliance- SpeedDis-
    
    
    

    If wanting to set the max link speed to a lower value than what is capable, and if wanting to have this change persist over boot cycles, then the devicetree's max-link-speed property may be changed: https://git.ti.com/cgit/ti-linux-kernel/ti-linux-kernel/tree/arch/arm64/boot/dts/ti/k3-j784s4-main.dtsi?h=ti-linux-6.1.y#n1351

    Example diff below:

    https://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-files/791/0001_2D00_Set_2D00_max_2D00_link_2D00_speed_2D00_to_2D00_gen_2D00_2_2D00_5.0GT_2D00_s_2D00_for_2D00_PCIe0_2D00_port.patch

    And example logs where "Target Link Speed" is now set to 5.0GT/s by default.

    root@am69a-sk:/opt/edgeai-gst-apps# lspci -vv -s 0000:00:00.0 | grep -i speed
                    LnkCap: Port #0, Speed 5GT/s, Width x8, ASPM L1, Exit Latency L1 <8us
                    LnkSta: Speed 5GT/s (ok), Width x4 (downgraded)
                    LnkCap2: Supported Link Speeds: 2.5-5GT/s, Crosslink- Retimer- 2Retimers- DRS-
                    LnkCtl2: Target Link Speed: 5GT/s, EnterCompliance- SpeedDis-
    root@am69a-sk:/opt/edgeai-gst-apps#
    
    

    As a warning, above devicetree patch only sets the max-link-speed/Target Link Speed. This does not guarantee that link will come up at the max-link-speed. The behavior of PCIe is that it will negotiate up to the highest speed that both sides of the PCIe connection can support. So, although PCIe controller's max-link-speed is set to 5.0GT/s (gen 2 speeds) in the patch, if connected device can only support 2.5GT/s (gen 1 speeds), then both sides will negotiate to 2.5GT/s. There are exceptions where link training may fail (for example, when trying to negotiate to gen 3 speeds, link equalization failing), which could cause downgrade in speed negotiated.

    Regards,

    Takuma