diff options
Diffstat (limited to 'arch/x86/cpu/ivybridge/northbridge.c')
-rw-r--r-- | arch/x86/cpu/ivybridge/northbridge.c | 126 |
1 files changed, 96 insertions, 30 deletions
diff --git a/arch/x86/cpu/ivybridge/northbridge.c b/arch/x86/cpu/ivybridge/northbridge.c index e3d8c139df..a066607a18 100644 --- a/arch/x86/cpu/ivybridge/northbridge.c +++ b/arch/x86/cpu/ivybridge/northbridge.c @@ -8,6 +8,7 @@ */ #include <common.h> +#include <dm.h> #include <asm/msr.h> #include <asm/acpi.h> #include <asm/cpu.h> @@ -18,23 +19,17 @@ #include <asm/arch/model_206ax.h> #include <asm/arch/sandybridge.h> -static int bridge_revision_id = -1; - -int bridge_silicon_revision(void) +int bridge_silicon_revision(struct udevice *dev) { - if (bridge_revision_id < 0) { - struct cpuid_result result; - uint8_t stepping, bridge_id; - pci_dev_t dev; - - result = cpuid(1); - stepping = result.eax & 0xf; - dev = PCI_BDF(0, 0, 0); - bridge_id = x86_pci_read_config16(dev, PCI_DEVICE_ID) & 0xf0; - bridge_revision_id = bridge_id | stepping; - } - - return bridge_revision_id; + struct cpuid_result result; + u16 bridge_id; + u8 stepping; + + result = cpuid(1); + stepping = result.eax & 0xf; + dm_pci_read_config16(dev, PCI_DEVICE_ID, &bridge_id); + bridge_id &= 0xf0; + return bridge_id | stepping; } /* @@ -47,15 +42,14 @@ int bridge_silicon_revision(void) static const int legacy_hole_base_k = 0xa0000 / 1024; static const int legacy_hole_size_k = 384; -static int get_pcie_bar(u32 *base, u32 *len) +static int get_pcie_bar(struct udevice *dev, u32 *base, u32 *len) { - pci_dev_t dev = PCI_BDF(0, 0, 0); u32 pciexbar_reg; *base = 0; *len = 0; - pciexbar_reg = x86_pci_read_config32(dev, PCIEXBAR); + dm_pci_read_config32(dev, PCIEXBAR, &pciexbar_reg); if (!(pciexbar_reg & (1 << 0))) return 0; @@ -81,55 +75,55 @@ static int get_pcie_bar(u32 *base, u32 *len) return 0; } -static void add_fixed_resources(pci_dev_t dev, int index) +static void add_fixed_resources(struct udevice *dev, int index) { u32 pcie_config_base, pcie_config_size; - if (get_pcie_bar(&pcie_config_base, &pcie_config_size)) { + if (get_pcie_bar(dev, &pcie_config_base, &pcie_config_size)) { debug("Adding PCIe config bar base=0x%08x size=0x%x\n", pcie_config_base, pcie_config_size); } } -static void northbridge_dmi_init(pci_dev_t dev) +static void northbridge_dmi_init(struct udevice *dev, int rev) { /* Clear error status bits */ writel(0xffffffff, DMIBAR_REG(0x1c4)); writel(0xffffffff, DMIBAR_REG(0x1d0)); /* Steps prior to DMI ASPM */ - if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_SNB) { + if ((rev & BASE_REV_MASK) == BASE_REV_SNB) { clrsetbits_le32(DMIBAR_REG(0x250), (1 << 22) | (1 << 20), 1 << 21); } setbits_le32(DMIBAR_REG(0x238), 1 << 29); - if (bridge_silicon_revision() >= SNB_STEP_D0) { + if (rev >= SNB_STEP_D0) { setbits_le32(DMIBAR_REG(0x1f8), 1 << 16); - } else if (bridge_silicon_revision() >= SNB_STEP_D1) { + } else if (rev >= SNB_STEP_D1) { clrsetbits_le32(DMIBAR_REG(0x1f8), 1 << 26, 1 << 16); setbits_le32(DMIBAR_REG(0x1fc), (1 << 12) | (1 << 23)); } /* Enable ASPM on SNB link, should happen before PCH link */ - if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_SNB) + if ((rev & BASE_REV_MASK) == BASE_REV_SNB) setbits_le32(DMIBAR_REG(0xd04), 1 << 4); setbits_le32(DMIBAR_REG(0x88), (1 << 1) | (1 << 0)); } -void northbridge_init(pci_dev_t dev) +static void northbridge_init(struct udevice *dev, int rev) { u32 bridge_type; add_fixed_resources(dev, 6); - northbridge_dmi_init(dev); + northbridge_dmi_init(dev, rev); bridge_type = readl(MCHBAR_REG(0x5f10)); bridge_type &= ~0xff; - if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_IVB) { + if ((rev & BASE_REV_MASK) == BASE_REV_IVB) { /* Enable Power Aware Interrupt Routing - fixed priority */ clrsetbits_8(MCHBAR_REG(0x5418), 0xf, 0x4); @@ -167,6 +161,78 @@ void northbridge_init(pci_dev_t dev) writel(0x00100001, MCHBAR_REG(0x5500)); } -void northbridge_enable(pci_dev_t dev) +static void sandybridge_setup_northbridge_bars(struct udevice *dev) +{ + /* Set up all hardcoded northbridge BARs */ + 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); + /* 64MB - busses 0-63 */ + dm_pci_write_config32(dev, PCIEXBAR, DEFAULT_PCIEXBAR | 5); + dm_pci_write_config32(dev, PCIEXBAR + 4, + (0LL + DEFAULT_PCIEXBAR) >> 32); + dm_pci_write_config32(dev, DMIBAR, DEFAULT_DMIBAR | 1); + dm_pci_write_config32(dev, DMIBAR + 4, (0LL + DEFAULT_DMIBAR) >> 32); + + /* Set C0000-FFFFF to access RAM on both reads and writes */ + dm_pci_write_config8(dev, PAM0, 0x30); + dm_pci_write_config8(dev, PAM1, 0x33); + dm_pci_write_config8(dev, PAM2, 0x33); + dm_pci_write_config8(dev, PAM3, 0x33); + dm_pci_write_config8(dev, PAM4, 0x33); + dm_pci_write_config8(dev, PAM5, 0x33); + dm_pci_write_config8(dev, PAM6, 0x33); +} + +static int bd82x6x_northbridge_early_init(struct udevice *dev) +{ + const int chipset_type = SANDYBRIDGE_MOBILE; + u32 capid0_a; + u8 reg8; + + /* Device ID Override Enable should be done very early */ + dm_pci_read_config32(dev, 0xe4, &capid0_a); + if (capid0_a & (1 << 10)) { + dm_pci_read_config8(dev, 0xf3, ®8); + reg8 &= ~7; /* Clear 2:0 */ + + if (chipset_type == SANDYBRIDGE_MOBILE) + reg8 |= 1; /* Set bit 0 */ + + dm_pci_write_config8(dev, 0xf3, reg8); + } + + sandybridge_setup_northbridge_bars(dev); + + /* Device Enable */ + dm_pci_write_config32(dev, DEVEN, DEVEN_HOST | DEVEN_IGD); + + return 0; +} + +static int bd82x6x_northbridge_probe(struct udevice *dev) { + int rev; + + if (!(gd->flags & GD_FLG_RELOC)) + return bd82x6x_northbridge_early_init(dev); + + rev = bridge_silicon_revision(dev); + northbridge_init(dev, rev); + + return 0; } + +static const struct udevice_id bd82x6x_northbridge_ids[] = { + { .compatible = "intel,bd82x6x-northbridge" }, + { } +}; + +U_BOOT_DRIVER(bd82x6x_northbridge_drv) = { + .name = "bd82x6x_northbridge", + .id = UCLASS_NORTHBRIDGE, + .of_match = bd82x6x_northbridge_ids, + .probe = bd82x6x_northbridge_probe, +}; |