summaryrefslogtreecommitdiff
path: root/src/southbridge/intel/lynxpoint/pcie.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/southbridge/intel/lynxpoint/pcie.c')
-rw-r--r--src/southbridge/intel/lynxpoint/pcie.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/src/southbridge/intel/lynxpoint/pcie.c b/src/southbridge/intel/lynxpoint/pcie.c
index d2950e7916..4e94f121c0 100644
--- a/src/southbridge/intel/lynxpoint/pcie.c
+++ b/src/southbridge/intel/lynxpoint/pcie.c
@@ -100,6 +100,38 @@ static void root_port_config_update_gbe_port(void)
}
}
+static void update_num_ports(void)
+{
+ /*
+ * According to existing code in 'root_port_check_disable()', which does
+ * not agree with the confusing information on the datasheets, the last
+ * visible function depends on the strapped root port width as follows:
+ *
+ * +-----+----+----+----+----+
+ * | 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 +169,10 @@ static void root_port_init_config(struct device *dev)
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);