summaryrefslogtreecommitdiffstats
path: root/src/northbridge/intel/haswell/northbridge.c
diff options
context:
space:
mode:
authorAngel Pons <th3fanbus@gmail.com>2020-07-23 02:32:27 +0200
committerAngel Pons <th3fanbus@gmail.com>2020-10-24 15:44:14 +0000
commit76b8bc220122efd3774b0bddf5d2f229401fac46 (patch)
tree09d8396d159a2e9b19163bc4b3cbf420cb6feede /src/northbridge/intel/haswell/northbridge.c
parent72f4dda6b7d1de5eef1df1d32be4595067c4a15d (diff)
downloadcoreboot-76b8bc220122efd3774b0bddf5d2f229401fac46.tar.gz
coreboot-76b8bc220122efd3774b0bddf5d2f229401fac46.tar.bz2
coreboot-76b8bc220122efd3774b0bddf5d2f229401fac46.zip
nb/intel/haswell: Set up Root Complex topology
System BIOS must program some of the Root Complex Topology Capability Structure registers located in configuration space, specs say. So do it. Tested on Asrock B85M Pro4, still boots. Change-Id: Ia2a61706a127bf2b817004a8ec6a723da9826aad Signed-off-by: Angel Pons <th3fanbus@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/43744 Reviewed-by: Arthur Heymans <arthur@aheymans.xyz> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/northbridge/intel/haswell/northbridge.c')
-rw-r--r--src/northbridge/intel/haswell/northbridge.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/src/northbridge/intel/haswell/northbridge.c b/src/northbridge/intel/haswell/northbridge.c
index 5619d95728b6..9cf564f4747e 100644
--- a/src/northbridge/intel/haswell/northbridge.c
+++ b/src/northbridge/intel/haswell/northbridge.c
@@ -498,12 +498,77 @@ static void northbridge_dmi_init(void)
}
}
+static void northbridge_topology_init(void)
+{
+ const u32 eple_a[3] = { EPLE2A, EPLE3A, EPLE4A };
+ const u32 eple_d[3] = { EPLE2D, EPLE3D, EPLE4D };
+
+ u32 reg32;
+
+ /* Set the CID1 Egress Port 0 Root Topology */
+ reg32 = EPBAR32(EPESD);
+ reg32 &= ~(0xff << 16);
+ reg32 |= 1 << 16;
+ EPBAR32(EPESD) = reg32;
+
+ reg32 = EPBAR32(EPLE1D);
+ reg32 &= ~(0xff << 16);
+ reg32 |= 1 | (1 << 16);
+ EPBAR32(EPLE1D) = reg32;
+ EPBAR64(EPLE1A) = (uintptr_t)DEFAULT_DMIBAR;
+
+ for (unsigned int i = 0; i <= 2; i++) {
+ const struct device *const dev = pcidev_on_root(1, i);
+
+ if (!dev || !dev->enabled)
+ continue;
+
+ EPBAR64(eple_a[i]) = (u64)PCI_DEV(0, 1, i);
+
+ reg32 = EPBAR32(eple_d[i]);
+ reg32 &= ~(0xff << 16);
+ reg32 |= 1 | (1 << 16);
+ EPBAR32(eple_d[i]) = reg32;
+
+ pci_update_config32(dev, PEG_ESD, ~(0xff << 16), (1 << 16));
+ pci_write_config32(dev, PEG_LE1A, (uintptr_t)DEFAULT_EPBAR);
+ pci_write_config32(dev, PEG_LE1A + 4, 0);
+ pci_update_config32(dev, PEG_LE1D, ~(0xff << 16), (1 << 16) | 1);
+
+ /* Read and write to lock register */
+ pci_or_config32(dev, PEG_DCAP2, 0);
+ }
+
+ /* Set the CID1 DMI Port Root Topology */
+ reg32 = DMIBAR32(DMIESD);
+ reg32 &= ~(0xff << 16);
+ reg32 |= 1 << 16;
+ DMIBAR32(DMIESD) = reg32;
+
+ reg32 = DMIBAR32(DMILE1D);
+ reg32 &= ~(0xffff << 16);
+ reg32 |= 1 | (2 << 16);
+ DMIBAR32(DMILE1D) = reg32;
+ DMIBAR64(DMILE1A) = (uintptr_t)DEFAULT_RCBA;
+
+ DMIBAR64(DMILE2A) = (uintptr_t)DEFAULT_EPBAR;
+ reg32 = DMIBAR32(DMILE2D);
+ reg32 &= ~(0xff << 16);
+ reg32 |= 1 | (1 << 16);
+ DMIBAR32(DMILE2D) = reg32;
+
+ /* Program RO and Write-Once Registers */
+ DMIBAR32(DMIPVCCAP1) = DMIBAR32(DMIPVCCAP1);
+ DMIBAR32(DMILCAP) = DMIBAR32(DMILCAP);
+}
+
static void northbridge_init(struct device *dev)
{
u8 bios_reset_cpl, pair;
init_egress();
northbridge_dmi_init();
+ northbridge_topology_init();
/* Enable Power Aware Interrupt Routing. */
pair = MCHBAR8(INTRDIRCTL);