Patrick Rudolph (siro@das-labor.org) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/18193
-gerrit
commit f4dc5b8dd2a115619caf2679d8428e9f0dc31f43 Author: Patrick Rudolph siro@das-labor.org Date: Sat Jan 21 10:33:20 2017 +0100
nb/intel/gm45/nb: Move DEVEN device hiding
Move and improve DEVEN device hiding.
Instead of relying only on devicetree, allow the PCI code to scan for devices, and invoke custom PCI driver functions. Therefore the code has been moved to PCI init function.
Add support for disabling IGD.
Fixes a crash in GNU Linux: In case the IGD is disabled by romstage, Linux still detects the IGD, but as it doesn't have resources assigned, it causes a crash in drm kernel module.
Change-Id: I03578d358f31b605f300a67f5b078eff834e070c Signed-off-by: Patrick Rudolph siro@das-labor.org --- src/northbridge/intel/gm45/northbridge.c | 79 +++++++++++++++----------------- 1 file changed, 38 insertions(+), 41 deletions(-)
diff --git a/src/northbridge/intel/gm45/northbridge.c b/src/northbridge/intel/gm45/northbridge.c index 3cb7d11..65e2052 100644 --- a/src/northbridge/intel/gm45/northbridge.c +++ b/src/northbridge/intel/gm45/northbridge.c @@ -180,14 +180,49 @@ static void mch_domain_set_resources(device_t dev) assign_resources(dev->link_list); }
-static void mch_domain_init(device_t dev) +static void mch_domain_init(device_t d0f0) { + u32 deven = pci_read_config32(d0f0, D0F0_DEVEN); + device_t dev; u32 reg32;
/* Enable SERR */ - reg32 = pci_read_config32(dev, PCI_COMMAND); + reg32 = pci_read_config32(d0f0, PCI_COMMAND); reg32 |= PCI_COMMAND_SERR; - pci_write_config32(dev, PCI_COMMAND, reg32); + pci_write_config32(d0f0, PCI_COMMAND, reg32); + + /* Hide internal functions on bus 0. */ + printk(BIOS_INFO, "mch_domain_init: Hiding "); + + dev = dev_find_slot(0, PCI_DEVFN(3, 3)); + if (dev && !dev->enabled) { + printk(BIOS_INFO, "ME "); + deven &= ~(1 << 9); + } + + dev = dev_find_slot(0, PCI_DEVFN(2, 1)); + if (dev && !dev->enabled) { + printk(BIOS_INFO, "IGD_DC "); + deven &= ~(1 << 4); + } + + dev = dev_find_slot(0, PCI_DEVFN(2, 0)); + if (dev && !dev->enabled) { + printk(BIOS_INFO, "IGD "); + deven &= ~(1 << 3); + } + + dev = dev_find_slot(0, PCI_DEVFN(1, 0)); + if (dev && !dev->enabled) { + printk(BIOS_INFO, "PEG "); + deven &= ~(1 << 1); + } + printk(BIOS_INFO, "\n"); + + if (!(deven & (0xf << 6))) + deven &= ~(1 << 14); + + pci_write_config32(d0f0, D0F0_DEVEN, deven); }
static struct device_operations pci_domain_ops = { @@ -225,45 +260,7 @@ static void enable_dev(device_t dev) } }
-static void gm45_init(void *const chip_info) -{ - int dev, fn, bit_base; - - struct device *const d0f0 = dev_find_slot(0, 0); - - /* Hide internal functions based on devicetree info. */ - for (dev = 3; dev > 0; --dev) { - switch (dev) { - case 3: /* ME */ - fn = 3; - bit_base = 6; - break; - case 2: /* IGD */ - fn = 1; - bit_base = 3; - break; - case 1: /* PEG */ - fn = 0; - bit_base = 1; - break; - } - for (; fn >= 0; --fn) { - const struct device *const d = - dev_find_slot(0, PCI_DEVFN(dev, fn)); - if (!d || d->enabled) continue; - const u32 deven = pci_read_config32(d0f0, D0F0_DEVEN); - pci_write_config32(d0f0, D0F0_DEVEN, - deven & ~(1 << (bit_base + fn))); - } - } - - const u32 deven = pci_read_config32(d0f0, D0F0_DEVEN); - if (!(deven & (0xf << 6))) - pci_write_config32(d0f0, D0F0_DEVEN, deven & ~(1 << 14)); -} - struct chip_operations northbridge_intel_gm45_ops = { CHIP_NAME("Intel GM45 Northbridge") .enable_dev = enable_dev, - .init = gm45_init, };