Angel Pons has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/44155 )
Change subject: sb/intel/lynxpoint: Consider root ports being disabled by strap ......................................................................
sb/intel/lynxpoint: Consider root ports being disabled by strap
PCIe RPC (Root Port Configuration) straps will force-disable some root port functions if some root ports have a width greater than x1. In two cases, this affects the last function. The PCIe init code will never finish configuring the root ports if that is the case: it assumes that the last function will eventually run through the code, but it doesn't.
If PCIe initialization does not complete, pressing the power button will not power off the board, unless it is held for about five seconds. Also, Windows 10 will show a BSOD about MACHINE CHECK EXCEPTION, and lock up instead of rebooting. Depending on the microcode version, the BSOD may not be visible. This happens even when the root port is not populated.
Use the strap fuse configuration value to know which configuration the PCH is strapped to. If needed, update the number of ports accordingly. In addition, print the updated value to ease debugging PCIe init code.
Tested on Asrock B85M Pro4, PCIe initialization completes successfully.
Change-Id: Id6da3a1f45467f00002a5ed41df8650f4a74eeba Signed-off-by: Angel Pons th3fanbus@gmail.com --- M src/southbridge/intel/lynxpoint/pcie.c 1 file changed, 34 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/55/44155/1
diff --git a/src/southbridge/intel/lynxpoint/pcie.c b/src/southbridge/intel/lynxpoint/pcie.c index d2950e7..5323e74 100644 --- a/src/southbridge/intel/lynxpoint/pcie.c +++ b/src/southbridge/intel/lynxpoint/pcie.c @@ -100,6 +100,36 @@ } }
+static void update_num_ports(void) +{ + /* + * The last visible function depends on the strapped root port width: + * + * +-----+----+----+----+----+ + * | RPC | #5 | #6 | #7 | #8 | + * +-----+----+----+----+----+ + * | 0 | x1 | x1 | x1 | x1 | + * | 1 | x2 | | x1 | x1 | + * | 2 | x2 | | x2 | | + * | 3 | x4 | | | | + * +-----+----+----+----+----+ + */ + switch ((rpc.strpfusecfg2 >> 14) & 0x3) { + case 0: + case 1: + break; + case 2: + rpc.num_ports = MIN(rpc.num_ports, 7); + break; + case 3: + rpc.num_ports = MIN(rpc.num_ports, 5); + break; + } + + printk(BIOS_DEBUG, "Adjusted number of PCIe root ports to %d as per strpfusecfg2\n", + rpc.num_ports); +} + static void root_port_init_config(struct device *dev) { int rp; @@ -137,6 +167,10 @@ case 5: rpc.strpfusecfg2 = pci_read_config32(dev, 0xfc); rpc.b0d28f4_32c = pci_read_config32(dev, 0x32c); + + if (!pch_is_lp()) + update_num_ports(); + break; case 6: rpc.b0d28f5_32c = pci_read_config32(dev, 0x32c);