nb/intel/haswell: Add HASWELL_HIDE_PEG_FROM_MRC option

The MRC will perform PCI enumeration, and if it detects a VGA device in
a PEG slot, it will disable the IGD and not reserve any memory for it.
Since the memory map is locked by the time MRC finishes, the IGD can not
be enabled afterwards. Changing this behavior requires patching the MRC.

Hiding the PEG devices from MRC allows the IGD to be used even when a
dedicated graphics card is present. However, MRC will not program the
PEG AFE settings as it should, which can cause stability problems at
higher PCIe link speeds. Thus, restrict this workaround to only run when
the HASWELL_HIDE_PEG_FROM_MRC option is enabled. This allows the IGD to
be disabled and the PEG AFE settings to be programmed when a dedicated
graphics card is to be enabled, which results in increased stability.

The most ideal way to fix this problem for good is to implement native
platform init. Native init is necessary to make Nvidia Optimus usable.

Tested on Asrock B85M Pro4, using the PEG slot with a dedicated graphics
card as well as without. Graphics in both situations function properly.

Change-Id: I4d825b1c41d8705bfafe28d8ecb0a511788901f0
Signed-off-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/45534
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Reviewed-by: Nico Huber <nico.h@gmx.de>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Angel Pons 2020-08-29 02:52:09 +02:00
parent 6c4028dd3d
commit 84641c8183
2 changed files with 26 additions and 6 deletions

View File

@ -78,6 +78,15 @@ config MRC_FILE
The path and filename of the file to use as System Agent The path and filename of the file to use as System Agent
binary. binary.
config HASWELL_HIDE_PEG_FROM_MRC
bool "Hide PEG devices from MRC to work around hardcoded MRC behavior"
default y
help
If set, hides all PEG devices from MRC. This allows the iGPU
to be used even when a dedicated graphics card is present.
However, it prevents MRC from programming PEG AFE registers,
which can make PEG devices unstable. When unsure, choose N.
config PRE_GRAPHICS_DELAY config PRE_GRAPHICS_DELAY
int "Graphics initialization delay in ms" int "Graphics initialization delay in ms"
default 0 default 0

View File

@ -84,13 +84,24 @@ static void start_peg2_link_training(const pci_devfn_t dev)
printk(BIOS_DEBUG, "Started PEG1%d link training.\n", PCI_FUNC(PCI_DEV2DEVFN(dev))); printk(BIOS_DEBUG, "Started PEG1%d link training.\n", PCI_FUNC(PCI_DEV2DEVFN(dev)));
/* /*
* Hide the PEG device while the MRC runs. This is because the MRC makes * The MRC will perform PCI enumeration, and if it detects a VGA
* configurations that are not ideal if it sees a VGA device in a PEG slot, * device in a PEG slot, it will disable the IGD and not reserve
* and it locks registers preventing changes to these configurations. * any memory for it. Since the memory map is locked by the time
* MRC finishes, the IGD can't be enabled afterwards. Wonderful.
*
* If one really wants to enable the Intel iGPU as primary, hide
* all PEG devices during MRC execution. This will trick the MRC
* into thinking there aren't any, and will enable the IGD. Note
* that PEG AFE settings will not be programmed, which may cause
* stability problems at higher PCIe link speeds. The most ideal
* way to fix this problem for good is to implement native init.
*/ */
pci_update_config32(HOST_BRIDGE, DEVEN, ~mask, 0); if (CONFIG(HASWELL_HIDE_PEG_FROM_MRC)) {
peg_hidden[PCI_FUNC(PCI_DEV2DEVFN(dev))] = true; pci_update_config32(HOST_BRIDGE, DEVEN, ~mask, 0);
printk(BIOS_DEBUG, "Temporarily hiding PEG1%d.\n", PCI_FUNC(PCI_DEV2DEVFN(dev))); peg_hidden[PCI_FUNC(PCI_DEV2DEVFN(dev))] = true;
printk(BIOS_DEBUG, "Temporarily hiding PEG1%d.\n",
PCI_FUNC(PCI_DEV2DEVFN(dev)));
}
} }
void haswell_unhide_peg(void) void haswell_unhide_peg(void)