This technical debugging session details the process of identifying a transient link failure issue while attempting a bare metal bring-up of the PCIe Gen 1 link on an STM32 MP257 application processor development board.
Initial signal integrity checks via eye patterns were inconclusive, but deep-memory captures revealed low-probability link instability (flapping at ~2.5 kHz). Protocol analysis showed the link successfully training to L0 (idle) before rapidly dropping to unrecoverable errors. Time Interval Error (TIE) analysis of the SerDes transmit signal exposed the critical fault: bursts of extreme jitter (+/- 200 ps, half a Unit Interval) coinciding precisely with the link drops. The root cause was determined to be the SerDes transmit PLL losing lock due to instability in its internally-derived 25 MHz reference clock. The problem was solved efficiently by configuring the SerDes to use an external, stable 100 MHz differential reference clock.
STM32 MP257 PCIe Link Debug using High-Speed Oscilloscopy
0:00 Bare Metal Goal: The aim is to run the STM32 MP257 application processor bare metal, avoiding the overhead of Linux, specifically to utilize PCIe for high-performance, low-pin count interfacing with an FPGA.
0:48 Initial Failure: The PCIe Gen 1 X1 link failed to link up (train).
1:17 Debug Setup: Debugging was performed using a Teledyne LeCroy WaveRunner 8404M-MS (4 GHz oscilloscope) connected via differential probes (D420 series) to the TX/RX lines, using a GPIO trigger from the firmware (since the scope lacks a necessary CDR trigger option, as far as I can tell).
3:41 Initial Signal Check: Waveform captures appeared generally clean. Eye patterns (5:00) showed the transmit signal (from the SoC) was wide open, but the receive signal (from the M.2 SSD) was likely "overequalized" for a much lossier Gen 3 motherboard, which I don't care about for Gen 1 link integrity. Signal integrity did not appear to be the root cause.
7:25 Link Flapping Identified: Using deep memory, analysis showed the link was successfully establishing (L0/logical idle) but quickly dropping to "garbage" (11:20) and re-entering the training state (TS1) approximately every 400 microseconds (~2.5 kHz flapping frequency).
15:55 Jitter Analysis Pinpoints Failure: Plotting the Time Interval Error (TIE) on the transmit line revealed the core problem. The signal showed stable jitter until sudden, massive, transient bursts of noise (+/- 200 picoseconds, or half a Unit Interval, 16:34). This effectively obliterated timing alignment.
17:42 Correlation: This TIE burst happened simultaneously with the protocol decode failures and the link dropping back into the training state, suggesting a clock malfunction rather than signal reflection or ISI.
20:57 Root Cause (SerDes PLL): The instability was determined to be the SerDes Transmit PLL losing lock. This loss of lock was likely caused by feeding the PLL an internally generated 25 MHz reference clock derived from another PLL (21:20). The datasheet suggests this configuration should work, but empirically, it clearly did not.
22:04 The Fix: The solution was efficient and direct: reconfigure the SerDes to utilize an external, stable 100 MHz differential reference clock input, bypassing the unreliable internal clock path.
22:56 Verification: After the firmware fix, the link immediately stabilized, the eye was wide open, and protocol decodes showed continuous, valid TLP (Transaction Layer Packet) flow control (23:05). Problem solved.