diff --git a/src/cpu/intel/haswell/haswell.h b/src/cpu/intel/haswell/haswell.h index 1625329b37..b8cc98a570 100644 --- a/src/cpu/intel/haswell/haswell.h +++ b/src/cpu/intel/haswell/haswell.h @@ -192,4 +192,27 @@ static inline bool haswell_is_ult(void) return CONFIG(INTEL_LYNXPOINT_LP); } +static inline bool cpu_is_haswell(void) +{ + switch (cpu_family_model()) { + case HASWELL_FAMILY_TRAD: + case HASWELL_FAMILY_ULT: + case CRYSTALWELL_FAMILY: + return true; + default: + return false; + } +} + +static inline bool cpu_is_broadwell(void) +{ + switch (cpu_family_model()) { + case BROADWELL_FAMILY_TRAD: + case BROADWELL_FAMILY_ULT: + return true; + default: + return false; + } +} + #endif diff --git a/src/northbridge/intel/haswell/early_init.c b/src/northbridge/intel/haswell/early_init.c index d52a9d1b85..1b5059adb8 100644 --- a/src/northbridge/intel/haswell/early_init.c +++ b/src/northbridge/intel/haswell/early_init.c @@ -1,10 +1,11 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include #include +#include #include #include #include +#include #include "haswell.h" @@ -80,10 +81,9 @@ static void haswell_setup_misc(void) mchbar_write32(INTRDIRCTL, reg32); } -static void haswell_setup_iommu(void) +static void northbridge_setup_iommu(void) { const u32 capid0_a = pci_read_config32(HOST_BRIDGE, CAPID0_A); - if (capid0_a & VTD_DISABLE) return; @@ -93,17 +93,37 @@ static void haswell_setup_iommu(void) mchbar_write32(VTVC0BAR + 4, VTVC0_BASE_ADDRESS >> 32); mchbar_write32(VTVC0BAR + 0, VTVC0_BASE_ADDRESS | 1); - /* Set L3HIT2PEND_DIS, lock GFXVTBAR policy config registers */ - u32 reg32; - reg32 = read32p(GFXVT_BASE_ADDRESS + ARCHDIS); - write32p(GFXVT_BASE_ADDRESS + ARCHDIS, reg32 | DMAR_LCKDN | L3HIT2PEND_DIS); + if (cpu_is_haswell()) { + /* + * Intel Document 492662 (Haswell System Agent BIOS Spec), Rev 1.6.0 + * Section 11.3 - DMA Remapping Engine Configuration + */ + const u32 gfxvt_archdis = 0x02100000 | DMAR_LCKDN; + write32p(GFXVT_BASE_ADDRESS + ARCHDIS, gfxvt_archdis); - /* Clear SPCAPCTRL */ - reg32 = read32p(VTVC0_BASE_ADDRESS + ARCHDIS) & ~SPCAPCTRL; + clrsetbits32p(VTVC0_BASE_ADDRESS + 0xf04, 0xf << 15, 1 << 15); - /* Set GLBIOTLBINV, GLBCTXTINV; lock VTVC0BAR policy config registers */ - write32p(VTVC0_BASE_ADDRESS + ARCHDIS, - reg32 | DMAR_LCKDN | GLBIOTLBINV | GLBCTXTINV); + u32 vtvc0_archdis = 0x000a5003 | DMAR_LCKDN; + if (pci_read_config16(PCI_DEV(0, 2, 0), PCI_DEVICE_ID) == 0xffff) { + vtvc0_archdis |= SPCAPCTRL; + } + write32p(VTVC0_BASE_ADDRESS + ARCHDIS, vtvc0_archdis); + } + if (cpu_is_broadwell()) { + /* + * Intel Document 535094 (Broadwell BIOS Spec), Rev 2.2.0 + * Section 17.3 - DMA Remapping Engine Configuration + */ + + /* TODO: For steppings <= D0 (pre-production), also clear bit 0 */ + setbits32p(GFXVT_BASE_ADDRESS + ARCHDIS, DMAR_LCKDN | PRSCAPDIS); + + write32p(GFXVT_BASE_ADDRESS + 0x100, 0x50a); + + clrsetbits32p(VTVC0_BASE_ADDRESS + 0xf04, 0xf << 15, 1 << 15); + + setbits32p(VTVC0_BASE_ADDRESS + ARCHDIS, DMAR_LCKDN); + } } void haswell_early_initialization(void) @@ -112,7 +132,7 @@ void haswell_early_initialization(void) haswell_setup_bars(); /* Setup IOMMU BARs */ - haswell_setup_iommu(); + northbridge_setup_iommu(); if (!CONFIG(INTEL_LYNXPOINT_LP)) northbridge_setup_peg(); diff --git a/src/northbridge/intel/haswell/haswell.h b/src/northbridge/intel/haswell/haswell.h index aeedd421e1..4d2da01788 100644 --- a/src/northbridge/intel/haswell/haswell.h +++ b/src/northbridge/intel/haswell/haswell.h @@ -28,10 +28,7 @@ #define ARCHDIS 0xff0 /* DMA Remap Engine Policy Control */ #define DMAR_LCKDN (1 << 31) #define SPCAPCTRL (1 << 25) -#define L3HIT2PEND_DIS (1 << 20) #define PRSCAPDIS (1 << 2) -#define GLBIOTLBINV (1 << 1) -#define GLBCTXTINV (1 << 0) void mb_late_romstage_setup(void); /* optional */