I've been experimenting with some UEFI/Kernel code and am working on the various PCI-Express elements. I have obtained the MCFG ACPI table, Enumerated all PCI devices into my own structures and have access to all the devices MMIO regions and the full 4kb configuration space.
For this specific PCIe device which I have identified I have followed the configuration space as follows:
Test capability list bit, assuming it is set, use offset 0x34, follow the pointers until I find a PCI Express configuration capability (ID = 0x10).
From here register 0x0c (Link capabilities) specifies the max link width as x16 and the max link speed as 3 (which is an index into the supported link speed vector and equates to 8.0 GT/s or Gen3 speed which the device is capable of).
The link status register is showing that the negotiated link width is x16, however the link speed is 1 (2.5 GT/s).
What I've tried is using the Link Control 2 Register to set the Target Speed to 3 then set Bit 5 on the Link Control Register to trigger a re-training. I also disable the autonomous link speed to ensure the device remains at the selected speed.
I then wait a small duration (1 second for testing) then poll the Link Status register checking for the Link Training bit to clear. This seems to clear immediately regardless of the above delay and when checking the Link Status register again the link speed is still 1.
I have checked several of the registers for error notifications and haven't spotted anything yet.
Clearly I need to find the correct process to establish a new link speed on the device, possibly configure de-emphasis values or apply the same link speed settings to upstream devices/bridges.
Any advice would be hugely appreciated.