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>
This commit is contained in:
parent
72f4dda6b7
commit
76b8bc2201
|
@ -20,6 +20,14 @@
|
||||||
|
|
||||||
#include "registers/host_bridge.h"
|
#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) */
|
/* Device 0:2.0 PCI configuration space (Graphics Device) */
|
||||||
|
|
||||||
#define MSAC 0x62 /* Multi Size Aperture Control */
|
#define MSAC 0x62 /* Multi Size Aperture Control */
|
||||||
|
@ -59,6 +67,7 @@
|
||||||
#define EPBAR8(x) *((volatile u8 *)(DEFAULT_EPBAR + (x)))
|
#define EPBAR8(x) *((volatile u8 *)(DEFAULT_EPBAR + (x)))
|
||||||
#define EPBAR16(x) *((volatile u16 *)(DEFAULT_EPBAR + (x)))
|
#define EPBAR16(x) *((volatile u16 *)(DEFAULT_EPBAR + (x)))
|
||||||
#define EPBAR32(x) *((volatile u32 *)(DEFAULT_EPBAR + (x)))
|
#define EPBAR32(x) *((volatile u32 *)(DEFAULT_EPBAR + (x)))
|
||||||
|
#define EPBAR64(x) *((volatile u64 *)(DEFAULT_EPBAR + (x)))
|
||||||
|
|
||||||
#include "registers/epbar.h"
|
#include "registers/epbar.h"
|
||||||
|
|
||||||
|
@ -69,6 +78,7 @@
|
||||||
#define DMIBAR8(x) *((volatile u8 *)(DEFAULT_DMIBAR + (x)))
|
#define DMIBAR8(x) *((volatile u8 *)(DEFAULT_DMIBAR + (x)))
|
||||||
#define DMIBAR16(x) *((volatile u16 *)(DEFAULT_DMIBAR + (x)))
|
#define DMIBAR16(x) *((volatile u16 *)(DEFAULT_DMIBAR + (x)))
|
||||||
#define DMIBAR32(x) *((volatile u32 *)(DEFAULT_DMIBAR + (x)))
|
#define DMIBAR32(x) *((volatile u32 *)(DEFAULT_DMIBAR + (x)))
|
||||||
|
#define DMIBAR64(x) *((volatile u64 *)(DEFAULT_DMIBAR + (x)))
|
||||||
|
|
||||||
#include "registers/dmibar.h"
|
#include "registers/dmibar.h"
|
||||||
|
|
||||||
|
|
|
@ -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)
|
static void northbridge_init(struct device *dev)
|
||||||
{
|
{
|
||||||
u8 bios_reset_cpl, pair;
|
u8 bios_reset_cpl, pair;
|
||||||
|
|
||||||
init_egress();
|
init_egress();
|
||||||
northbridge_dmi_init();
|
northbridge_dmi_init();
|
||||||
|
northbridge_topology_init();
|
||||||
|
|
||||||
/* Enable Power Aware Interrupt Routing. */
|
/* Enable Power Aware Interrupt Routing. */
|
||||||
pair = MCHBAR8(INTRDIRCTL);
|
pair = MCHBAR8(INTRDIRCTL);
|
||||||
|
|
|
@ -20,5 +20,9 @@
|
||||||
#define EPLE1A 0x058 /* 64bit */
|
#define EPLE1A 0x058 /* 64bit */
|
||||||
#define EPLE2D 0x060 /* 32bit */
|
#define EPLE2D 0x060 /* 32bit */
|
||||||
#define EPLE2A 0x068 /* 64bit */
|
#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__ */
|
#endif /* __HASWELL_REGISTERS_EPBAR_H__ */
|
||||||
|
|
Loading…
Reference in New Issue