summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/northbridge/intel/haswell/haswell.h10
-rw-r--r--src/northbridge/intel/haswell/northbridge.c65
-rw-r--r--src/northbridge/intel/haswell/registers/epbar.h4
3 files changed, 79 insertions, 0 deletions
diff --git a/src/northbridge/intel/haswell/haswell.h b/src/northbridge/intel/haswell/haswell.h
index 4bcaaa7728..b160f83876 100644
--- a/src/northbridge/intel/haswell/haswell.h
+++ b/src/northbridge/intel/haswell/haswell.h
@@ -20,6 +20,14 @@
#include "registers/host_bridge.h"
+/* Device 0:1.0 PCI configuration space (PCIe Graphics) */
+
+#define PEG_DCAP2 0xc4 /* 32bit */
+
+#define PEG_ESD 0x144 /* 32bit */
+#define PEG_LE1D 0x150 /* 32bit */
+#define PEG_LE1A 0x158 /* 64bit */
+
/* Device 0:2.0 PCI configuration space (Graphics Device) */
#define MSAC 0x62 /* Multi Size Aperture Control */
@@ -59,6 +67,7 @@
#define EPBAR8(x) *((volatile u8 *)(DEFAULT_EPBAR + (x)))
#define EPBAR16(x) *((volatile u16 *)(DEFAULT_EPBAR + (x)))
#define EPBAR32(x) *((volatile u32 *)(DEFAULT_EPBAR + (x)))
+#define EPBAR64(x) *((volatile u64 *)(DEFAULT_EPBAR + (x)))
#include "registers/epbar.h"
@@ -69,6 +78,7 @@
#define DMIBAR8(x) *((volatile u8 *)(DEFAULT_DMIBAR + (x)))
#define DMIBAR16(x) *((volatile u16 *)(DEFAULT_DMIBAR + (x)))
#define DMIBAR32(x) *((volatile u32 *)(DEFAULT_DMIBAR + (x)))
+#define DMIBAR64(x) *((volatile u64 *)(DEFAULT_DMIBAR + (x)))
#include "registers/dmibar.h"
diff --git a/src/northbridge/intel/haswell/northbridge.c b/src/northbridge/intel/haswell/northbridge.c
index 5619d95728..9cf564f474 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);
diff --git a/src/northbridge/intel/haswell/registers/epbar.h b/src/northbridge/intel/haswell/registers/epbar.h
index 963ceaddf4..699a2ba578 100644
--- a/src/northbridge/intel/haswell/registers/epbar.h
+++ b/src/northbridge/intel/haswell/registers/epbar.h
@@ -20,5 +20,9 @@
#define EPLE1A 0x058 /* 64bit */
#define EPLE2D 0x060 /* 32bit */
#define EPLE2A 0x068 /* 64bit */
+#define EPLE3D 0x070 /* 32bit */
+#define EPLE3A 0x078 /* 64bit */
+#define EPLE4D 0x080 /* 32bit */
+#define EPLE4A 0x088 /* 64bit */
#endif /* __HASWELL_REGISTERS_EPBAR_H__ */