X-Git-Url: https://git.librecmc.org/?p=oweals%2Fu-boot.git;a=blobdiff_plain;f=arch%2Fx86%2Fcpu%2Fivybridge%2Fnorthbridge.c;h=b713fcb1cfe7d1a6f0a738b9ebc57b6645cd1727;hp=a066607a18d3d11a75f50c0848bf7de3738e1d78;hb=c27178ba3649f539c9f1890ea147f4c5415f63b5;hpb=cd85bec36d0e0d16fedb00e0c434ed070a9c6b37 diff --git a/arch/x86/cpu/ivybridge/northbridge.c b/arch/x86/cpu/ivybridge/northbridge.c index a066607a18..b713fcb1cf 100644 --- a/arch/x86/cpu/ivybridge/northbridge.c +++ b/arch/x86/cpu/ivybridge/northbridge.c @@ -1,23 +1,26 @@ +// SPDX-License-Identifier: GPL-2.0 /* * From Coreboot northbridge/intel/sandybridge/northbridge.c * * Copyright (C) 2007-2009 coresystems GmbH * Copyright (C) 2011 The Chromium Authors - * - * SPDX-License-Identifier: GPL-2.0 */ #include #include +#include #include -#include #include +#include #include #include #include #include #include #include +#include + +DECLARE_GLOBAL_DATA_PTR; int bridge_silicon_revision(struct udevice *dev) { @@ -32,16 +35,6 @@ int bridge_silicon_revision(struct udevice *dev) return bridge_id | stepping; } -/* - * Reserve everything between A segment and 1MB: - * - * 0xa0000 - 0xbffff: legacy VGA - * 0xc0000 - 0xcffff: VGA OPROM (needed by kernel) - * 0xe0000 - 0xfffff: SeaBIOS, if used, otherwise DMI - */ -static const int legacy_hole_base_k = 0xa0000 / 1024; -static const int legacy_hole_size_k = 384; - static int get_pcie_bar(struct udevice *dev, u32 *base, u32 *len) { u32 pciexbar_reg; @@ -150,7 +143,7 @@ static void northbridge_init(struct udevice *dev, int rev) * CPUs with configurable TDP also need power limits set * in MCHBAR. Use same values from MSR_PKG_POWER_LIMIT. */ - if (cpu_config_tdp_levels()) { + if (cpu_ivybridge_config_tdp_levels()) { msr_t msr = msr_read(MSR_PKG_POWER_LIMIT); writel(msr.lo, MCHBAR_REG(0x59A0)); @@ -167,8 +160,8 @@ static void sandybridge_setup_northbridge_bars(struct udevice *dev) debug("Setting up static registers\n"); dm_pci_write_config32(dev, EPBAR, DEFAULT_EPBAR | 1); dm_pci_write_config32(dev, EPBAR + 4, (0LL + DEFAULT_EPBAR) >> 32); - dm_pci_write_config32(dev, MCHBAR, DEFAULT_MCHBAR | 1); - dm_pci_write_config32(dev, MCHBAR + 4, (0LL + DEFAULT_MCHBAR) >> 32); + dm_pci_write_config32(dev, MCHBAR, MCH_BASE_ADDRESS | 1); + dm_pci_write_config32(dev, MCHBAR + 4, (0LL + MCH_BASE_ADDRESS) >> 32); /* 64MB - busses 0-63 */ dm_pci_write_config32(dev, PCIEXBAR, DEFAULT_PCIEXBAR | 5); dm_pci_write_config32(dev, PCIEXBAR + 4, @@ -186,6 +179,35 @@ static void sandybridge_setup_northbridge_bars(struct udevice *dev) dm_pci_write_config8(dev, PAM6, 0x33); } +/** + * sandybridge_init_iommu() - Set up IOMMU so that azalia can be used + * + * It is not obvious where these values come from. They may be undocumented. + */ +static void sandybridge_init_iommu(struct udevice *dev) +{ + u32 capid0_a; + + dm_pci_read_config32(dev, 0xe4, &capid0_a); + if (capid0_a & (1 << 23)) { + log_debug("capid0_a not needed\n"); + return; + } + + /* setup BARs */ + writel(IOMMU_BASE1 >> 32, MCHBAR_REG(0x5404)); + writel(IOMMU_BASE1 | 1, MCHBAR_REG(0x5400)); + writel(IOMMU_BASE2 >> 32, MCHBAR_REG(0x5414)); + writel(IOMMU_BASE2 | 1, MCHBAR_REG(0x5410)); + + /* lock policies */ + writel(0x80000000, IOMMU_BASE1 + 0xff0); + + /* Enable azalia sound */ + writel(0x20000000, IOMMU_BASE2 + 0xff0); + writel(0xa0000000, IOMMU_BASE2 + 0xff0); +} + static int bd82x6x_northbridge_early_init(struct udevice *dev) { const int chipset_type = SANDYBRIDGE_MOBILE; @@ -206,6 +228,9 @@ static int bd82x6x_northbridge_early_init(struct udevice *dev) sandybridge_setup_northbridge_bars(dev); + /* Setup IOMMU BARs */ + sandybridge_init_iommu(dev); + /* Device Enable */ dm_pci_write_config32(dev, DEVEN, DEVEN_HOST | DEVEN_IGD);