nb/intel/haswell: Use DEVEN to disable devices

This allows devices to be properly disabled when they are set to `off`
in the devicetree, or when a device has its `enabled` property set to
false.

A message is printed stating that a device is being disabled, even if
it was already disabled via DEVEN. However, it could be useful to have
this information, so such messages are kept.

The device 00:04.0 is a thermal sensor on the Acer C720, but it has not
been named as such in this patch. This is because the public datasheets
never formally acknowledge what the device is, and how it might differ
across platforms.

Tested on a Supermicro X10SLM+-F. The Mini-HD audio is disabled now,
silencing a warning from Linux.

Also tested on an Acer C720 (Google Peppy). Disabling "device 4" from
devicetree.cb works.

Also tested on an ASRock H81M-HDS. For this device, and all other test
devices, there were no regressions observed.

Change-Id: If1504e620967449a09f113a7c771a1ec30380644
Signed-off-by: Tristan Corrick <tristan@corrick.kiwi>
Reviewed-on: https://review.coreboot.org/c/30270
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-by: Patrick Rudolph <siro@das-labor.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Tristan Corrick 2018-12-17 22:09:50 +13:00 committed by Patrick Georgi
parent 78824238b9
commit bc896cd8a9
1 changed files with 46 additions and 0 deletions

View File

@ -14,6 +14,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
#include <commonlib/helpers.h>
#include <console/console.h> #include <console/console.h>
#include <arch/acpi.h> #include <arch/acpi.h>
#include <arch/io.h> #include <arch/io.h>
@ -22,7 +23,9 @@
#include <cpu/intel/haswell/haswell.h> #include <cpu/intel/haswell/haswell.h>
#include <device/device.h> #include <device/device.h>
#include <device/pci.h> #include <device/pci.h>
#include <device/pci_def.h>
#include <device/pci_ids.h> #include <device/pci_ids.h>
#include <device/pci_ops.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <cpu/x86/smm.h> #include <cpu/x86/smm.h>
@ -423,6 +426,47 @@ static void mc_read_resources(struct device *dev)
mc_add_dram_resources(dev, &index); mc_add_dram_resources(dev, &index);
} }
/*
* The Mini-HD audio device is disabled whenever the IGD is. This is
* because it provides audio over the integrated graphics port(s), which
* requires the IGD to be functional.
*/
static void disable_devices(void)
{
static const struct {
const unsigned int devfn;
const u32 mask;
const char *const name;
} nb_devs[] = {
{ PCI_DEVFN(1, 2), DEVEN_D1F2EN, "PEG12" },
{ PCI_DEVFN(1, 1), DEVEN_D1F1EN, "PEG11" },
{ PCI_DEVFN(1, 0), DEVEN_D1F0EN, "PEG10" },
{ PCI_DEVFN(2, 0), DEVEN_D2EN | DEVEN_D3EN, "IGD" },
{ PCI_DEVFN(3, 0), DEVEN_D3EN, "Mini-HD audio" },
{ PCI_DEVFN(4, 0), DEVEN_D4EN, "\"device 4\"" },
{ PCI_DEVFN(7, 0), DEVEN_D7EN, "\"device 7\"" },
};
struct device *host_dev = dev_find_slot(0, PCI_DEVFN(0, 0));
u32 deven;
size_t i;
if (!host_dev)
return;
deven = pci_read_config32(host_dev, DEVEN);
for (i = 0; i < ARRAY_SIZE(nb_devs); i++) {
struct device *dev = dev_find_slot(0, nb_devs[i].devfn);
if (!dev || !dev->enabled) {
printk(BIOS_DEBUG, "Disabling %s.\n", nb_devs[i].name);
deven &= ~nb_devs[i].mask;
}
}
pci_write_config32(host_dev, DEVEN, deven);
}
static void intel_set_subsystem(struct device *dev, unsigned int vendor, static void intel_set_subsystem(struct device *dev, unsigned int vendor,
unsigned int device) unsigned int device)
{ {
@ -445,6 +489,8 @@ static void northbridge_init(struct device *dev)
pair |= 0x4; /* Fixed Priority */ pair |= 0x4; /* Fixed Priority */
MCHBAR8(0x5418) = pair; MCHBAR8(0x5418) = pair;
disable_devices();
/* /*
* Set bits 0+1 of BIOS_RESET_CPL to indicate to the CPU * Set bits 0+1 of BIOS_RESET_CPL to indicate to the CPU
* that BIOS has initialized memory and power management * that BIOS has initialized memory and power management