summaryrefslogtreecommitdiffstats
path: root/arch/x86/cpu/ivybridge
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/cpu/ivybridge')
-rw-r--r--arch/x86/cpu/ivybridge/Kconfig27
-rw-r--r--arch/x86/cpu/ivybridge/Makefile4
-rw-r--r--arch/x86/cpu/ivybridge/bd82x6x.c17
-rw-r--r--arch/x86/cpu/ivybridge/car.S241
-rw-r--r--arch/x86/cpu/ivybridge/cpu.c96
-rw-r--r--arch/x86/cpu/ivybridge/early_me.c31
-rw-r--r--arch/x86/cpu/ivybridge/gma.c7
-rw-r--r--arch/x86/cpu/ivybridge/lpc.c77
-rw-r--r--arch/x86/cpu/ivybridge/me_status.c195
-rw-r--r--arch/x86/cpu/ivybridge/microcode_intel.c166
-rw-r--r--arch/x86/cpu/ivybridge/model_206ax.c8
-rw-r--r--arch/x86/cpu/ivybridge/northbridge.c5
-rw-r--r--arch/x86/cpu/ivybridge/report_platform.c90
-rw-r--r--arch/x86/cpu/ivybridge/sata.c51
-rw-r--r--arch/x86/cpu/ivybridge/sdram.c404
15 files changed, 142 insertions, 1277 deletions
diff --git a/arch/x86/cpu/ivybridge/Kconfig b/arch/x86/cpu/ivybridge/Kconfig
index 0819347b59..e23d01a08f 100644
--- a/arch/x86/cpu/ivybridge/Kconfig
+++ b/arch/x86/cpu/ivybridge/Kconfig
@@ -7,43 +7,18 @@
config NORTHBRIDGE_INTEL_IVYBRIDGE
bool
- select CACHE_MRC_BIN
+ select CACHE_MRC_BIN if HAVE_MRC
if NORTHBRIDGE_INTEL_IVYBRIDGE
-config CACHE_MRC_BIN
- bool
- default n
-
-config CACHE_MRC_SIZE_KB
- int
- default 512
-
config DCACHE_RAM_BASE
- hex
default 0xff7e0000
config DCACHE_RAM_SIZE
- hex
default 0x20000
-config HAVE_MRC
- bool "Add a System Agent binary"
- help
- Select this option to add a System Agent binary to
- the resulting U-Boot image. MRC stands for Memory Reference Code.
- It is a binary blob which U-Boot uses to set up SDRAM.
-
- Note: Without this binary U-Boot will not be able to set up its
- SDRAM so will not boot.
-
config DCACHE_RAM_MRC_VAR_SIZE
- hex
default 0x4000
- help
- This is the amount of CAR (Cache as RAM) reserved for use by the
- memory reference code. This should be set to 16KB (0x4000 hex)
- so that MRC has enough space to run.
config CPU_SPECIFIC_OPTIONS
def_bool y
diff --git a/arch/x86/cpu/ivybridge/Makefile b/arch/x86/cpu/ivybridge/Makefile
index 9203219f31..9cdb07bdf2 100644
--- a/arch/x86/cpu/ivybridge/Makefile
+++ b/arch/x86/cpu/ivybridge/Makefile
@@ -7,16 +7,12 @@
ifdef CONFIG_HAVE_FSP
obj-y += fsp_configs.o ivybridge.o
else
-obj-y += car.o
obj-y += cpu.o
obj-y += early_me.o
obj-y += gma.o
obj-y += lpc.o
-obj-y += me_status.o
obj-y += model_206ax.o
-obj-y += microcode_intel.o
obj-y += northbridge.o
-obj-y += report_platform.o
obj-y += sata.o
obj-y += sdram.o
endif
diff --git a/arch/x86/cpu/ivybridge/bd82x6x.c b/arch/x86/cpu/ivybridge/bd82x6x.c
index 9972b0ae7f..4c039ac9c6 100644
--- a/arch/x86/cpu/ivybridge/bd82x6x.c
+++ b/arch/x86/cpu/ivybridge/bd82x6x.c
@@ -11,8 +11,10 @@
#include <pch.h>
#include <syscon.h>
#include <asm/cpu.h>
+#include <asm/intel_regs.h>
#include <asm/io.h>
#include <asm/lapic.h>
+#include <asm/lpc_common.h>
#include <asm/pci.h>
#include <asm/arch/bd82x6x.h>
#include <asm/arch/model_206ax.h>
@@ -187,20 +189,7 @@ static int bd82x6x_pch_get_spi_base(struct udevice *dev, ulong *sbasep)
static int bd82x6x_set_spi_protect(struct udevice *dev, bool protect)
{
- uint8_t bios_cntl;
-
- /* Adjust the BIOS write protect and SMM BIOS Write Protect Disable */
- dm_pci_read_config8(dev, BIOS_CTRL, &bios_cntl);
- if (protect) {
- bios_cntl &= ~BIOS_CTRL_BIOSWE;
- bios_cntl |= BIT(5);
- } else {
- bios_cntl |= BIOS_CTRL_BIOSWE;
- bios_cntl &= ~BIT(5);
- }
- dm_pci_write_config8(dev, BIOS_CTRL, bios_cntl);
-
- return 0;
+ return lpc_set_spi_protect(dev, BIOS_CTRL, protect);
}
static int bd82x6x_get_gpio_base(struct udevice *dev, u32 *gbasep)
diff --git a/arch/x86/cpu/ivybridge/car.S b/arch/x86/cpu/ivybridge/car.S
deleted file mode 100644
index 1defabf91f..0000000000
--- a/arch/x86/cpu/ivybridge/car.S
+++ /dev/null
@@ -1,241 +0,0 @@
-/*
- * Copyright (c) 2014 Google, Inc
- *
- * From Coreboot file cpu/intel/model_206ax/cache_as_ram.inc
- *
- * Copyright (C) 2000,2007 Ronald G. Minnich <rminnich@gmail.com>
- * Copyright (C) 2005 Tyan (written by Yinghai Lu for Tyan)
- * Copyright (C) 2007-2008 coresystems GmbH
- * Copyright (C) 2012 Kyösti Mälkki <kyosti.malkki@gmail.com>
- *
- * SPDX-License-Identifier: GPL-2.0
- */
-
-#include <common.h>
-#include <asm/msr-index.h>
-#include <asm/mtrr.h>
-#include <asm/post.h>
-#include <asm/processor.h>
-#include <asm/processor-flags.h>
-#include <asm/arch/microcode.h>
-
-#define MTRR_PHYS_BASE_MSR(reg) (0x200 + 2 * (reg))
-#define MTRR_PHYS_MASK_MSR(reg) (0x200 + 2 * (reg) + 1)
-
-#define CACHE_AS_RAM_SIZE CONFIG_DCACHE_RAM_SIZE
-#define CACHE_AS_RAM_BASE CONFIG_DCACHE_RAM_BASE
-
-/* Cache 4GB - MRC_SIZE_KB for MRC */
-#define CACHE_MRC_BYTES ((CONFIG_CACHE_MRC_SIZE_KB << 10) - 1)
-#define CACHE_MRC_BASE (0xFFFFFFFF - CACHE_MRC_BYTES)
-#define CACHE_MRC_MASK (~CACHE_MRC_BYTES)
-
-#define CPU_PHYSMASK_HI (1 << (CONFIG_CPU_ADDR_BITS - 32) - 1)
-
-#define NOEVICTMOD_MSR 0x2e0
-
- /*
- * Note: ebp must not be touched in this code as it holds the BIST
- * value (built-in self test). We preserve this value until it can
- * be written to global_data when CAR is ready for use.
- */
-.globl car_init
-car_init:
- post_code(POST_CAR_START)
-
- /* Send INIT IPI to all excluding ourself */
- movl $0x000C4500, %eax
- movl $0xFEE00300, %esi
- movl %eax, (%esi)
-
- /* TODO: Load microcode later - the 'no eviction' mode breaks this */
- movl $MSR_IA32_UCODE_WRITE, %ecx
- xorl %edx, %edx
- movl $_dt_ucode_base_size, %eax
- movl (%eax), %eax
- addl $UCODE_HEADER_LEN, %eax
- wrmsr
-
- post_code(POST_CAR_SIPI)
- /* Zero out all fixed range and variable range MTRRs */
- movl $mtrr_table, %esi
- movl $((mtrr_table_end - mtrr_table) / 2), %edi
- xorl %eax, %eax
- xorl %edx, %edx
-clear_mtrrs:
- movw (%esi), %bx
- movzx %bx, %ecx
- wrmsr
- add $2, %esi
- dec %edi
- jnz clear_mtrrs
-
- post_code(POST_CAR_MTRR)
- /* Configure the default memory type to uncacheable */
- movl $MTRR_DEF_TYPE_MSR, %ecx
- rdmsr
- andl $(~0x00000cff), %eax
- wrmsr
-
- post_code(POST_CAR_UNCACHEABLE)
- /* Set Cache-as-RAM base address */
- movl $(MTRR_PHYS_BASE_MSR(0)), %ecx
- movl $(CACHE_AS_RAM_BASE | MTRR_TYPE_WRBACK), %eax
- xorl %edx, %edx
- wrmsr
-
- post_code(POST_CAR_BASE_ADDRESS)
- /* Set Cache-as-RAM mask */
- movl $(MTRR_PHYS_MASK_MSR(0)), %ecx
- movl $(~(CACHE_AS_RAM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
- movl $CPU_PHYSMASK_HI, %edx
- wrmsr
-
- post_code(POST_CAR_MASK)
-
- /* Enable MTRR */
- movl $MTRR_DEF_TYPE_MSR, %ecx
- rdmsr
- orl $MTRR_DEF_TYPE_EN, %eax
- wrmsr
-
- /* Enable cache (CR0.CD = 0, CR0.NW = 0) */
- movl %cr0, %eax
- andl $(~(X86_CR0_CD | X86_CR0_NW)), %eax
- invd
- movl %eax, %cr0
-
- /* enable the 'no eviction' mode */
- movl $NOEVICTMOD_MSR, %ecx
- rdmsr
- orl $1, %eax
- andl $~2, %eax
- wrmsr
-
- /* Clear the cache memory region. This will also fill up the cache */
- movl $CACHE_AS_RAM_BASE, %esi
- movl %esi, %edi
- movl $(CACHE_AS_RAM_SIZE / 4), %ecx
- xorl %eax, %eax
- rep stosl
-
- /* enable the 'no eviction run' state */
- movl $NOEVICTMOD_MSR, %ecx
- rdmsr
- orl $3, %eax
- wrmsr
-
- post_code(POST_CAR_FILL)
- /* Enable Cache-as-RAM mode by disabling cache */
- movl %cr0, %eax
- orl $X86_CR0_CD, %eax
- movl %eax, %cr0
-
- /* Enable cache for our code in Flash because we do XIP here */
- movl $MTRR_PHYS_BASE_MSR(1), %ecx
- xorl %edx, %edx
- movl $car_init_ret, %eax
- andl $(~(CONFIG_XIP_ROM_SIZE - 1)), %eax
- orl $MTRR_TYPE_WRPROT, %eax
- wrmsr
-
- movl $MTRR_PHYS_MASK_MSR(1), %ecx
- movl $CPU_PHYSMASK_HI, %edx
- movl $(~(CONFIG_XIP_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
- wrmsr
-
- post_code(POST_CAR_ROM_CACHE)
-#ifdef CONFIG_CACHE_MRC_BIN
- /* Enable caching for ram init code to run faster */
- movl $MTRR_PHYS_BASE_MSR(2), %ecx
- movl $(CACHE_MRC_BASE | MTRR_TYPE_WRPROT), %eax
- xorl %edx, %edx
- wrmsr
- movl $MTRR_PHYS_MASK_MSR(2), %ecx
- movl $(CACHE_MRC_MASK | MTRR_PHYS_MASK_VALID), %eax
- movl $CPU_PHYSMASK_HI, %edx
- wrmsr
-#endif
-
- post_code(POST_CAR_MRC_CACHE)
- /* Enable cache */
- movl %cr0, %eax
- andl $(~(X86_CR0_CD | X86_CR0_NW)), %eax
- movl %eax, %cr0
-
- post_code(POST_CAR_CPU_CACHE)
-
- /* All CPUs need to be in Wait for SIPI state */
-wait_for_sipi:
- movl (%esi), %eax
- bt $12, %eax
- jc wait_for_sipi
-
- /* return */
- jmp car_init_ret
-
-.globl car_uninit
-car_uninit:
- /* Disable cache */
- movl %cr0, %eax
- orl $X86_CR0_CD, %eax
- movl %eax, %cr0
-
- /* Disable MTRRs */
- movl $MTRR_DEF_TYPE_MSR, %ecx
- rdmsr
- andl $(~MTRR_DEF_TYPE_EN), %eax
- wrmsr
-
- /* Disable the no-eviction run state */
- movl $NOEVICTMOD_MSR, %ecx
- rdmsr
- andl $~2, %eax
- wrmsr
-
- invd
-
- /* Disable the no-eviction mode */
- rdmsr
- andl $~1, %eax
- wrmsr
-
-#ifdef CONFIG_CACHE_MRC_BIN
- /* Clear the MTRR that was used to cache MRC */
- xorl %eax, %eax
- xorl %edx, %edx
- movl $MTRR_PHYS_BASE_MSR(2), %ecx
- wrmsr
- movl $MTRR_PHYS_MASK_MSR(2), %ecx
- wrmsr
-#endif
-
- /* Enable MTRRs */
- movl $MTRR_DEF_TYPE_MSR, %ecx
- rdmsr
- orl $MTRR_DEF_TYPE_EN, %eax
- wrmsr
-
- invd
-
- ret
-
-mtrr_table:
- /* Fixed MTRRs */
- .word 0x250, 0x258, 0x259
- .word 0x268, 0x269, 0x26A
- .word 0x26B, 0x26C, 0x26D
- .word 0x26E, 0x26F
- /* Variable MTRRs */
- .word 0x200, 0x201, 0x202, 0x203
- .word 0x204, 0x205, 0x206, 0x207
- .word 0x208, 0x209, 0x20A, 0x20B
- .word 0x20C, 0x20D, 0x20E, 0x20F
- .word 0x210, 0x211, 0x212, 0x213
-mtrr_table_end:
-
- .align 4
-_dt_ucode_base_size:
- /* These next two fields are filled in by ifdtool */
- .long 0 /* microcode base */
- .long 0 /* microcode size */
diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c
index 948833c028..0f9390517f 100644
--- a/arch/x86/cpu/ivybridge/cpu.c
+++ b/arch/x86/cpu/ivybridge/cpu.c
@@ -17,15 +17,18 @@
#include <fdtdec.h>
#include <pch.h>
#include <asm/cpu.h>
+#include <asm/cpu_common.h>
+#include <asm/intel_regs.h>
#include <asm/io.h>
#include <asm/lapic.h>
+#include <asm/lpc_common.h>
+#include <asm/microcode.h>
#include <asm/msr.h>
#include <asm/mtrr.h>
#include <asm/pci.h>
#include <asm/post.h>
#include <asm/processor.h>
#include <asm/arch/model_206ax.h>
-#include <asm/arch/microcode.h>
#include <asm/arch/pch.h>
#include <asm/arch/sandybridge.h>
@@ -33,51 +36,11 @@ DECLARE_GLOBAL_DATA_PTR;
static int set_flex_ratio_to_tdp_nominal(void)
{
- msr_t flex_ratio, msr;
- u8 nominal_ratio;
-
/* Minimum CPU revision for configurable TDP support */
if (cpuid_eax(1) < IVB_CONFIG_TDP_MIN_CPUID)
return -EINVAL;
- /* Check for Flex Ratio support */
- flex_ratio = msr_read(MSR_FLEX_RATIO);
- if (!(flex_ratio.lo & FLEX_RATIO_EN))
- return -EINVAL;
-
- /* Check for >0 configurable TDPs */
- msr = msr_read(MSR_PLATFORM_INFO);
- if (((msr.hi >> 1) & 3) == 0)
- return -EINVAL;
-
- /* Use nominal TDP ratio for flex ratio */
- msr = msr_read(MSR_CONFIG_TDP_NOMINAL);
- nominal_ratio = msr.lo & 0xff;
-
- /* See if flex ratio is already set to nominal TDP ratio */
- if (((flex_ratio.lo >> 8) & 0xff) == nominal_ratio)
- return 0;
-
- /* Set flex ratio to nominal TDP ratio */
- flex_ratio.lo &= ~0xff00;
- flex_ratio.lo |= nominal_ratio << 8;
- flex_ratio.lo |= FLEX_RATIO_LOCK;
- msr_write(MSR_FLEX_RATIO, flex_ratio);
-
- /* Set flex ratio in soft reset data register bits 11:6 */
- clrsetbits_le32(RCB_REG(SOFT_RESET_DATA), 0x3f << 6,
- (nominal_ratio & 0x3f) << 6);
-
- /* Set soft reset control to use register value */
- setbits_le32(RCB_REG(SOFT_RESET_CTRL), 1);
-
- /* Issue warm reset, will be "CPU only" due to soft reset data */
- outb(0x0, PORT_RESET);
- outb(SYS_RST | RST_CPU, PORT_RESET);
- cpu_hlt();
-
- /* Not reached */
- return -EINVAL;
+ return cpu_set_flex_ratio_to_tdp_nominal();
}
int arch_cpu_init(void)
@@ -104,9 +67,9 @@ int arch_cpu_init_dm(void)
/* TODO(sjg@chromium.org): Get rid of gd->hose */
gd->hose = hose;
- ret = uclass_first_device(UCLASS_LPC, &dev);
- if (!dev)
- return -ENODEV;
+ ret = uclass_first_device_err(UCLASS_LPC, &dev);
+ if (ret)
+ return ret;
/*
* We should do as little as possible before the serial console is
@@ -162,17 +125,6 @@ static void enable_usb_bar(struct udevice *bus)
pci_bus_write_config(bus, usb3, PCI_COMMAND, cmd, PCI_SIZE_32);
}
-static int report_bist_failure(void)
-{
- if (gd->arch.bist != 0) {
- post_code(POST_BIST_FAILURE);
- printf("BIST failed: %08x\n", gd->arch.bist);
- return -EFAULT;
- }
-
- return 0;
-}
-
int print_cpuinfo(void)
{
enum pei_boot_mode_t boot_mode = PEI_BOOT_NONE;
@@ -183,20 +135,6 @@ int print_cpuinfo(void)
uint16_t pm1_sts;
int ret;
- /* Halt if there was a built in self test failure */
- ret = report_bist_failure();
- if (ret)
- return ret;
-
- enable_lapic();
-
- ret = microcode_update_intel();
- if (ret)
- return ret;
-
- /* Enable upper 128bytes of CMOS */
- writel(1 << 2, RCB_REG(RC));
-
/* TODO: cmos_post_init() */
if (readl(MCHBAR_REG(SSKPD)) == 0xCAFE) {
debug("soft reset detected\n");
@@ -207,17 +145,9 @@ int print_cpuinfo(void)
reset_cpu(0);
}
- /* Early chipset init required before RAM init can work */
- uclass_first_device(UCLASS_NORTHBRIDGE, &dev);
-
- ret = uclass_first_device(UCLASS_LPC, &lpc);
+ ret = cpu_common_init();
if (ret)
return ret;
- if (!dev)
- return -ENODEV;
-
- /* Cause the SATA device to do its early init */
- uclass_first_device(UCLASS_DISK, &dev);
/* Check PM1_STS[15] to see if we are waking from Sx */
pm1_sts = inw(DEFAULT_PMBASE + PM1_STS);
@@ -236,15 +166,15 @@ int print_cpuinfo(void)
post_code(POST_EARLY_INIT);
/* Enable SPD ROMs and DDR-III DRAM */
- ret = uclass_first_device(UCLASS_I2C, &dev);
+ ret = uclass_first_device_err(UCLASS_I2C, &dev);
if (ret)
return ret;
- if (!dev)
- return -ENODEV;
/* Prepare USB controller early in S3 resume */
- if (boot_mode == PEI_BOOT_RESUME)
+ if (boot_mode == PEI_BOOT_RESUME) {
+ uclass_first_device(UCLASS_LPC, &lpc);
enable_usb_bar(pci_get_controller(lpc->parent));
+ }
gd->arch.pei_boot_mode = boot_mode;
diff --git a/arch/x86/cpu/ivybridge/early_me.c b/arch/x86/cpu/ivybridge/early_me.c
index b1df77d571..cda96ab398 100644
--- a/arch/x86/cpu/ivybridge/early_me.c
+++ b/arch/x86/cpu/ivybridge/early_me.c
@@ -27,35 +27,6 @@ static const char *const me_ack_values[] = {
[ME_HFS_ACK_CONTINUE] = "Continue to boot"
};
-static inline void pci_read_dword_ptr(struct udevice *me_dev, void *ptr,
- int offset)
-{
- u32 dword;
-
- dm_pci_read_config32(me_dev, offset, &dword);
- memcpy(ptr, &dword, sizeof(dword));
-}
-
-static inline void pci_write_dword_ptr(struct udevice *me_dev, void *ptr,
- int offset)
-{
- u32 dword = 0;
-
- memcpy(&dword, ptr, sizeof(dword));
- dm_pci_write_config32(me_dev, offset, dword);
-}
-
-void intel_early_me_status(struct udevice *me_dev)
-{
- struct me_hfs hfs;
- struct me_gmes gmes;
-
- pci_read_dword_ptr(me_dev, &hfs, PCI_ME_HFS);
- pci_read_dword_ptr(me_dev, &gmes, PCI_ME_GMES);
-
- intel_me_status(&hfs, &gmes);
-}
-
int intel_early_me_init(struct udevice *me_dev)
{
int count;
@@ -159,7 +130,7 @@ int intel_early_me_init_done(struct udevice *dev, struct udevice *me_dev,
debug("ME: Requested BIOS Action: %s\n", me_ack_values[hfs.ack_data]);
/* Check status after acknowledgement */
- intel_early_me_status(me_dev);
+ intel_me_status(me_dev);
switch (hfs.ack_data) {
case ME_HFS_ACK_CONTINUE:
diff --git a/arch/x86/cpu/ivybridge/gma.c b/arch/x86/cpu/ivybridge/gma.c
index 3b6291e905..37e2e6ead8 100644
--- a/arch/x86/cpu/ivybridge/gma.c
+++ b/arch/x86/cpu/ivybridge/gma.c
@@ -12,6 +12,7 @@
#include <errno.h>
#include <fdtdec.h>
#include <pci_rom.h>
+#include <asm/intel_regs.h>
#include <asm/io.h>
#include <asm/mtrr.h>
#include <asm/pci.h>
@@ -812,9 +813,9 @@ int gma_func0_init(struct udevice *dev)
writew(0x0010, RCB_REG(DISPBDF));
setbits_le32(RCB_REG(FD2), PCH_ENABLE_DBDF);
- ret = uclass_first_device(UCLASS_NORTHBRIDGE, &nbridge);
- if (!nbridge)
- return -ENODEV;
+ ret = uclass_first_device_err(UCLASS_NORTHBRIDGE, &nbridge);
+ if (ret)
+ return ret;
rev = bridge_silicon_revision(nbridge);
sandybridge_setup_graphics(nbridge, dev);
diff --git a/arch/x86/cpu/ivybridge/lpc.c b/arch/x86/cpu/ivybridge/lpc.c
index 9ab5ed3ff9..88ab7973fd 100644
--- a/arch/x86/cpu/ivybridge/lpc.c
+++ b/arch/x86/cpu/ivybridge/lpc.c
@@ -13,9 +13,11 @@
#include <rtc.h>
#include <pci.h>
#include <asm/acpi.h>
+#include <asm/intel_regs.h>
#include <asm/interrupt.h>
#include <asm/io.h>
#include <asm/ioapic.h>
+#include <asm/lpc_common.h>
#include <asm/pci.h>
#include <asm/arch/pch.h>
@@ -404,26 +406,6 @@ static void pch_fixups(struct udevice *pch)
setbits_le32(RCB_REG(0x21a8), 0x3);
}
-/*
- * Enable Prefetching and Caching.
- */
-static void enable_spi_prefetch(struct udevice *pch)
-{
- u8 reg8;
-
- dm_pci_read_config8(pch, 0xdc, &reg8);
- reg8 &= ~(3 << 2);
- reg8 |= (2 << 2); /* Prefetching and Caching Enabled */
- dm_pci_write_config8(pch, 0xdc, reg8);
-}
-
-static void enable_port80_on_lpc(struct udevice *pch)
-{
- /* Enable port 80 POST on LPC */
- dm_pci_write_config32(pch, PCH_RCBA_BASE, DEFAULT_RCBA | 1);
- clrbits_le32(RCB_REG(GCS), 4);
-}
-
static void set_spi_speed(void)
{
u32 fdod;
@@ -440,54 +422,6 @@ static void set_spi_speed(void)
clrsetbits_8(RCB_REG(SPI_FREQ_SWSEQ), 7, fdod);
}
-/**
- * lpc_early_init() - set up LPC serial ports and other early things
- *
- * @dev: LPC device
- * @return 0 if OK, -ve on error
- */
-static int lpc_early_init(struct udevice *dev)
-{
- struct reg_info {
- u32 base;
- u32 size;
- } values[4], *ptr;
- int count;
- int i;
-
- count = fdtdec_get_int_array_count(gd->fdt_blob, dev->of_offset,
- "intel,gen-dec", (u32 *)values,
- sizeof(values) / sizeof(u32));
- if (count < 0)
- return -EINVAL;
-
- /* Set COM1/COM2 decode range */
- dm_pci_write_config16(dev->parent, LPC_IO_DEC, 0x0010);
-
- /* Enable PS/2 Keyboard/Mouse, EC areas and COM1 */
- dm_pci_write_config16(dev->parent, LPC_EN, KBC_LPC_EN | MC_LPC_EN |
- GAMEL_LPC_EN | COMA_LPC_EN);
-
- /* Write all registers but use 0 if we run out of data */
- count = count * sizeof(u32) / sizeof(values[0]);
- for (i = 0, ptr = values; i < ARRAY_SIZE(values); i++, ptr++) {
- u32 reg = 0;
-
- if (i < count)
- reg = ptr->base | PCI_COMMAND_IO | (ptr->size << 16);
- dm_pci_write_config32(dev->parent, LPC_GENX_DEC(i), reg);
- }
-
- enable_spi_prefetch(dev->parent);
-
- /* This is already done in start.S, but let's do it in C */
- enable_port80_on_lpc(dev->parent);
-
- set_spi_speed();
-
- return 0;
-}
-
static int lpc_init_extra(struct udevice *dev)
{
struct udevice *pch = dev->parent;
@@ -550,9 +484,12 @@ static int lpc_init_extra(struct udevice *dev)
static int bd82x6x_lpc_early_init(struct udevice *dev)
{
+ set_spi_speed();
+
/* Setting up Southbridge. In the northbridge code. */
debug("Setting up static southbridge registers\n");
- dm_pci_write_config32(dev->parent, PCH_RCBA_BASE, DEFAULT_RCBA | 1);
+ dm_pci_write_config32(dev->parent, PCH_RCBA_BASE,
+ RCB_BASE_ADDRESS | 1);
dm_pci_write_config32(dev->parent, PMBASE, DEFAULT_PMBASE | 1);
/* Enable ACPI BAR */
@@ -573,7 +510,7 @@ static int bd82x6x_lpc_probe(struct udevice *dev)
int ret;
if (!(gd->flags & GD_FLG_RELOC)) {
- ret = lpc_early_init(dev);
+ ret = lpc_common_early_init(dev);
if (ret) {
debug("%s: lpc_early_init() failed\n", __func__);
return ret;
diff --git a/arch/x86/cpu/ivybridge/me_status.c b/arch/x86/cpu/ivybridge/me_status.c
deleted file mode 100644
index 15cf69f40e..0000000000
--- a/arch/x86/cpu/ivybridge/me_status.c
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * From Coreboot src/southbridge/intel/bd82x6x/me_status.c
- *
- * Copyright (C) 2011 The Chromium OS Authors. All rights reserved.
- *
- * SPDX-License-Identifier: GPL-2.0
- */
-
-#include <common.h>
-#include <asm/arch/me.h>
-
-/* HFS1[3:0] Current Working State Values */
-static const char *const me_cws_values[] = {
- [ME_HFS_CWS_RESET] = "Reset",
- [ME_HFS_CWS_INIT] = "Initializing",
- [ME_HFS_CWS_REC] = "Recovery",
- [ME_HFS_CWS_NORMAL] = "Normal",
- [ME_HFS_CWS_WAIT] = "Platform Disable Wait",
- [ME_HFS_CWS_TRANS] = "OP State Transition",
- [ME_HFS_CWS_INVALID] = "Invalid CPU Plugged In"
-};
-
-/* HFS1[8:6] Current Operation State Values */
-static const char *const me_opstate_values[] = {
- [ME_HFS_STATE_PREBOOT] = "Preboot",
- [ME_HFS_STATE_M0_UMA] = "M0 with UMA",
- [ME_HFS_STATE_M3] = "M3 without UMA",
- [ME_HFS_STATE_M0] = "M0 without UMA",
- [ME_HFS_STATE_BRINGUP] = "Bring up",
- [ME_HFS_STATE_ERROR] = "M0 without UMA but with error"
-};
-
-/* HFS[19:16] Current Operation Mode Values */
-static const char *const me_opmode_values[] = {
- [ME_HFS_MODE_NORMAL] = "Normal",
- [ME_HFS_MODE_DEBUG] = "Debug",
- [ME_HFS_MODE_DIS] = "Soft Temporary Disable",
- [ME_HFS_MODE_OVER_JMPR] = "Security Override via Jumper",
- [ME_HFS_MODE_OVER_MEI] = "Security Override via MEI Message"
-};
-
-/* HFS[15:12] Error Code Values */
-static const char *const me_error_values[] = {
- [ME_HFS_ERROR_NONE] = "No Error",
- [ME_HFS_ERROR_UNCAT] = "Uncategorized Failure",
- [ME_HFS_ERROR_IMAGE] = "Image Failure",
- [ME_HFS_ERROR_DEBUG] = "Debug Failure"
-};
-
-/* GMES[31:28] ME Progress Code */
-static const char *const me_progress_values[] = {
- [ME_GMES_PHASE_ROM] = "ROM Phase",
- [ME_GMES_PHASE_BUP] = "BUP Phase",
- [ME_GMES_PHASE_UKERNEL] = "uKernel Phase",
- [ME_GMES_PHASE_POLICY] = "Policy Module",
- [ME_GMES_PHASE_MODULE] = "Module Loading",
- [ME_GMES_PHASE_UNKNOWN] = "Unknown",
- [ME_GMES_PHASE_HOST] = "Host Communication"
-};
-
-/* GMES[27:24] Power Management Event */
-static const char *const me_pmevent_values[] = {
- [0x00] = "Clean Moff->Mx wake",
- [0x01] = "Moff->Mx wake after an error",
- [0x02] = "Clean global reset",
- [0x03] = "Global reset after an error",
- [0x04] = "Clean Intel ME reset",
- [0x05] = "Intel ME reset due to exception",
- [0x06] = "Pseudo-global reset",
- [0x07] = "S0/M0->Sx/M3",
- [0x08] = "Sx/M3->S0/M0",
- [0x09] = "Non-power cycle reset",
- [0x0a] = "Power cycle reset through M3",
- [0x0b] = "Power cycle reset through Moff",
- [0x0c] = "Sx/Mx->Sx/Moff"
-};
-
-/* Progress Code 0 states */
-static const char *const me_progress_rom_values[] = {
- [0x00] = "BEGIN",
- [0x06] = "DISABLE"
-};
-
-/* Progress Code 1 states */
-static const char *const me_progress_bup_values[] = {
- [0x00] = "Initialization starts",
- [0x01] = "Disable the host wake event",
- [0x04] = "Flow determination start process",
- [0x08] = "Error reading/matching the VSCC table in the descriptor",
- [0x0a] = "Check to see if straps say ME DISABLED",
- [0x0b] = "Timeout waiting for PWROK",
- [0x0d] = "Possibly handle BUP manufacturing override strap",
- [0x11] = "Bringup in M3",
- [0x12] = "Bringup in M0",
- [0x13] = "Flow detection error",
- [0x15] = "M3 clock switching error",
- [0x18] = "M3 kernel load",
- [0x1c] = "T34 missing - cannot program ICC",
- [0x1f] = "Waiting for DID BIOS message",
- [0x20] = "Waiting for DID BIOS message failure",
- [0x21] = "DID reported an error",
- [0x22] = "Enabling UMA",
- [0x23] = "Enabling UMA error",
- [0x24] = "Sending DID Ack to BIOS",
- [0x25] = "Sending DID Ack to BIOS error",
- [0x26] = "Switching clocks in M0",
- [0x27] = "Switching clocks in M0 error",
- [0x28] = "ME in temp disable",
- [0x32] = "M0 kernel load",
-};
-
-/* Progress Code 3 states */
-static const char *const me_progress_policy_values[] = {
- [0x00] = "Entery into Policy Module",
- [0x03] = "Received S3 entry",
- [0x04] = "Received S4 entry",
- [0x05] = "Received S5 entry",
- [0x06] = "Received UPD entry",
- [0x07] = "Received PCR entry",
- [0x08] = "Received NPCR entry",
- [0x09] = "Received host wake",
- [0x0a] = "Received AC<>DC switch",
- [0x0b] = "Received DRAM Init Done",
- [0x0c] = "VSCC Data not found for flash device",
- [0x0d] = "VSCC Table is not valid",
- [0x0e] = "Flash Partition Boundary is outside address space",
- [0x0f] = "ME cannot access the chipset descriptor region",
- [0x10] = "Required VSCC values for flash parts do not match",
-};
-
-void intel_me_status(struct me_hfs *hfs, struct me_gmes *gmes)
-{
- /* Check Current States */
- debug("ME: FW Partition Table : %s\n",
- hfs->fpt_bad ? "BAD" : "OK");
- debug("ME: Bringup Loader Failure : %s\n",
- hfs->ft_bup_ld_flr ? "YES" : "NO");
- debug("ME: Firmware Init Complete : %s\n",
- hfs->fw_init_complete ? "YES" : "NO");
- debug("ME: Manufacturing Mode : %s\n",
- hfs->mfg_mode ? "YES" : "NO");
- debug("ME: Boot Options Present : %s\n",
- hfs->boot_options_present ? "YES" : "NO");
- debug("ME: Update In Progress : %s\n",
- hfs->update_in_progress ? "YES" : "NO");
- debug("ME: Current Working State : %s\n",
- me_cws_values[hfs->working_state]);
- debug("ME: Current Operation State : %s\n",
- me_opstate_values[hfs->operation_state]);
- debug("ME: Current Operation Mode : %s\n",
- me_opmode_values[hfs->operation_mode]);
- debug("ME: Error Code : %s\n",
- me_error_values[hfs->error_code]);
- debug("ME: Progress Phase : %s\n",
- me_progress_values[gmes->progress_code]);
- debug("ME: Power Management Event : %s\n",
- me_pmevent_values[gmes->current_pmevent]);
-
- debug("ME: Progress Phase State : ");
- switch (gmes->progress_code) {
- case ME_GMES_PHASE_ROM: /* ROM Phase */
- debug("%s", me_progress_rom_values[gmes->current_state]);
- break;
-
- case ME_GMES_PHASE_BUP: /* Bringup Phase */
- if (gmes->current_state < ARRAY_SIZE(me_progress_bup_values) &&
- me_progress_bup_values[gmes->current_state])
- debug("%s",
- me_progress_bup_values[gmes->current_state]);
- else
- debug("0x%02x", gmes->current_state);
- break;
-
- case ME_GMES_PHASE_POLICY: /* Policy Module Phase */
- if (gmes->current_state <
- ARRAY_SIZE(me_progress_policy_values) &&
- me_progress_policy_values[gmes->current_state])
- debug("%s",
- me_progress_policy_values[gmes->current_state]);
- else
- debug("0x%02x", gmes->current_state);
- break;
-
- case ME_GMES_PHASE_HOST: /* Host Communication Phase */
- if (!gmes->current_state)
- debug("Host communication established");
- else
- debug("0x%02x", gmes->current_state);
- break;
-
- default:
- debug("Unknown 0x%02x", gmes->current_state);
- }
- debug("\n");
-}
diff --git a/arch/x86/cpu/ivybridge/microcode_intel.c b/arch/x86/cpu/ivybridge/microcode_intel.c
deleted file mode 100644
index 2440a97c48..0000000000
--- a/arch/x86/cpu/ivybridge/microcode_intel.c
+++ /dev/null
@@ -1,166 +0,0 @@
-/*
- * Copyright (c) 2014 Google, Inc
- * Copyright (C) 2000 Ronald G. Minnich
- *
- * Microcode update for Intel PIII and later CPUs
- *
- * SPDX-License-Identifier: GPL-2.0
- */
-
-#include <common.h>
-#include <errno.h>
-#include <fdtdec.h>
-#include <libfdt.h>
-#include <asm/cpu.h>
-#include <asm/msr.h>
-#include <asm/msr-index.h>
-#include <asm/processor.h>
-#include <asm/arch/microcode.h>
-
-/**
- * struct microcode_update - standard microcode header from Intel
- *
- * We read this information out of the device tree and use it to determine
- * whether the update is applicable or not. We also use the same structure
- * to read information from the CPU.
- */
-struct microcode_update {
- uint header_version;
- uint update_revision;
- uint date_code;
- uint processor_signature;
- uint checksum;
- uint loader_revision;
- uint processor_flags;
- const void *data;
- int size;
-};
-
-static int microcode_decode_node(const void *blob, int node,
- struct microcode_update *update)
-{
- update->data = fdt_getprop(blob, node, "data", &update->size);
- if (!update->data)
- return -EINVAL;
- update->data += UCODE_HEADER_LEN;
- update->size -= UCODE_HEADER_LEN;
-
- update->header_version = fdtdec_get_int(blob, node,
- "intel,header-version", 0);
- update->update_revision = fdtdec_get_int(blob, node,
- "intel,update-revision", 0);
- update->date_code = fdtdec_get_int(blob, node,
- "intel,date-code", 0);
- update->processor_signature = fdtdec_get_int(blob, node,
- "intel,processor-signature", 0);
- update->checksum = fdtdec_get_int(blob, node, "intel,checksum", 0);
- update->loader_revision = fdtdec_get_int(blob, node,
- "intel,loader-revision", 0);
- update->processor_flags = fdtdec_get_int(blob, node,
- "intel,processor-flags", 0);
-
- return 0;
-}
-
-static inline uint32_t microcode_read_rev(void)
-{
- /*
- * Some Intel CPUs can be very finicky about the CPUID sequence used.
- * So this is implemented in assembly so that it works reliably.
- */
- uint32_t low, high;
-
- asm volatile (
- "xorl %%eax, %%eax\n"
- "xorl %%edx, %%edx\n"
- "movl %2, %%ecx\n"
- "wrmsr\n"
- "movl $0x01, %%eax\n"
- "cpuid\n"
- "movl %2, %%ecx\n"
- "rdmsr\n"
- : /* outputs */
- "=a" (low), "=d" (high)
- : /* inputs */
- "i" (MSR_IA32_UCODE_REV)
- : /* clobbers */
- "ebx", "ecx"
- );
-
- return high;
-}
-
-static void microcode_read_cpu(struct microcode_update *cpu)
-{
- /* CPUID sets MSR 0x8B iff a microcode update has been loaded. */
- unsigned int x86_model, x86_family;
- struct cpuid_result result;
- uint32_t low, high;
-
- wrmsr(MSR_IA32_UCODE_REV, 0, 0);
- result = cpuid(1);
- rdmsr(MSR_IA32_UCODE_REV, low, cpu->update_revision);
- x86_model = (result.eax >> 4) & 0x0f;
- x86_family = (result.eax >> 8) & 0x0f;
- cpu->processor_signature = result.eax;
-
- cpu->processor_flags = 0;
- if ((x86_model >= 5) || (x86_family > 6)) {
- rdmsr(0x17, low, high);
- cpu->processor_flags = 1 << ((high >> 18) & 7);
- }
- debug("microcode: sig=%#x pf=%#x revision=%#x\n",
- cpu->processor_signature, cpu->processor_flags,
- cpu->update_revision);
-}
-
-/* Get a microcode update from the device tree and apply it */
-int microcode_update_intel(void)
-{
- struct microcode_update cpu, update;
- const void *blob = gd->fdt_blob;
- int skipped;
- int count;
- int node;
- int ret;
- int rev;
-
- microcode_read_cpu(&cpu);
- node = 0;
- count = 0;
- skipped = 0;
- do {
- node = fdtdec_next_compatible(blob, node,
- COMPAT_INTEL_MICROCODE);
- if (node < 0) {
- debug("%s: Found %d updates\n", __func__, count);
- return count ? 0 : skipped ? -EEXIST : -ENOENT;
- }
-
- ret = microcode_decode_node(blob, node, &update);
- if (ret) {
- debug("%s: Unable to decode update: %d\n", __func__,
- ret);
- return ret;
- }
- if (!(update.processor_signature == cpu.processor_signature &&
- (update.processor_flags & cpu.processor_flags))) {
- debug("%s: Skipping non-matching update, sig=%x, pf=%x\n",
- __func__, update.processor_signature,
- update.processor_flags);
- skipped++;
- continue;
- }
- wrmsr(MSR_IA32_UCODE_WRITE, (ulong)update.data, 0);
- rev = microcode_read_rev();
- debug("microcode: updated to revision 0x%x date=%04x-%02x-%02x\n",
- rev, update.date_code & 0xffff,
- (update.date_code >> 24) & 0xff,
- (update.date_code >> 16) & 0xff);
- if (update.update_revision != rev) {
- printf("Microcode update failed\n");
- return -EFAULT;
- }
- count++;
- } while (1);
-}
diff --git a/arch/x86/cpu/ivybridge/model_206ax.c b/arch/x86/cpu/ivybridge/model_206ax.c
index 9654600cf1..cef425669c 100644
--- a/arch/x86/cpu/ivybridge/model_206ax.c
+++ b/arch/x86/cpu/ivybridge/model_206ax.c
@@ -17,6 +17,7 @@
#include <asm/cpu_x86.h>
#include <asm/lapic.h>
#include <asm/msr.h>
+#include <asm/msr-index.h>
#include <asm/mtrr.h>
#include <asm/processor.h>
#include <asm/speedstep.h>
@@ -363,7 +364,7 @@ static void set_max_ratio(void)
msr = msr_read(MSR_PLATFORM_INFO);
perf_ctl.lo = msr.lo & 0xff00;
}
- msr_write(IA32_PERF_CTL, perf_ctl);
+ msr_write(MSR_IA32_PERF_CTL, perf_ctl);
debug("model_x06ax: frequency set to %d\n",
((perf_ctl.lo >> 8) & 0xff) * SANDYBRIDGE_BCLK);
@@ -455,9 +456,10 @@ static int model_206ax_get_info(struct udevice *dev, struct cpu_info *info)
{
msr_t msr;
- msr = msr_read(IA32_PERF_CTL);
+ msr = msr_read(MSR_IA32_PERF_CTL);
info->cpu_freq = ((msr.lo >> 8) & 0xff) * SANDYBRIDGE_BCLK * 1000000;
- info->features = 1 << CPU_FEAT_L1_CACHE | 1 << CPU_FEAT_MMU;
+ info->features = 1 << CPU_FEAT_L1_CACHE | 1 << CPU_FEAT_MMU |
+ 1 << CPU_FEAT_UCODE;
return 0;
}
diff --git a/arch/x86/cpu/ivybridge/northbridge.c b/arch/x86/cpu/ivybridge/northbridge.c
index a066607a18..f7e0bc3f18 100644
--- a/arch/x86/cpu/ivybridge/northbridge.c
+++ b/arch/x86/cpu/ivybridge/northbridge.c
@@ -12,6 +12,7 @@
#include <asm/msr.h>
#include <asm/acpi.h>
#include <asm/cpu.h>
+#include <asm/intel_regs.h>
#include <asm/io.h>
#include <asm/pci.h>
#include <asm/processor.h>
@@ -167,8 +168,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,
diff --git a/arch/x86/cpu/ivybridge/report_platform.c b/arch/x86/cpu/ivybridge/report_platform.c
deleted file mode 100644
index c78322aef9..0000000000
--- a/arch/x86/cpu/ivybridge/report_platform.c
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * From Coreboot src/northbridge/intel/sandybridge/report_platform.c
- *
- * Copyright (C) 2012 Google Inc.
- *
- * SPDX-License-Identifier: GPL-2.0
- */
-
-#include <common.h>
-#include <asm/cpu.h>
-#include <asm/pci.h>
-#include <asm/arch/pch.h>
-#include <asm/arch/sandybridge.h>
-
-static void report_cpu_info(void)
-{
- char cpu_string[CPU_MAX_NAME_LEN], *cpu_name;
- const char *mode[] = {"NOT ", ""};
- struct cpuid_result cpuidr;
- int vt, txt, aes;
- u32 index;
-
- index = 0x80000000;
- cpuidr = cpuid(index);
- if (cpuidr.eax < 0x80000004) {
- strcpy(cpu_string, "Platform info not available");
- cpu_name = cpu_string;
- } else {
- cpu_name = cpu_get_name(cpu_string);
- }
-
- cpuidr = cpuid(1);
- debug("CPU id(%x): %s\n", cpuidr.eax, cpu_name);
- aes = (cpuidr.ecx & (1 << 25)) ? 1 : 0;
- txt = (cpuidr.ecx & (1 << 6)) ? 1 : 0;
- vt = (cpuidr.ecx & (1 << 5)) ? 1 : 0;
- debug("AES %ssupported, TXT %ssupported, VT %ssupported\n",
- mode[aes], mode[txt], mode[vt]);
-}
-
-/* The PCI id name match comes from Intel document 472178 */
-static struct {
- u16 dev_id;
- const char *dev_name;
-} pch_table[] = {
- {0x1E41, "Desktop Sample"},
- {0x1E42, "Mobile Sample"},
- {0x1E43, "SFF Sample"},
- {0x1E44, "Z77"},
- {0x1E45, "H71"},
- {0x1E46, "Z75"},
- {0x1E47, "Q77"},
- {0x1E48, "Q75"},
- {0x1E49, "B75"},
- {0x1E4A, "H77"},
- {0x1E53, "C216"},
- {0x1E55, "QM77"},
- {0x1E56, "QS77"},
- {0x1E58, "UM77"},
- {0x1E57, "HM77"},
- {0x1E59, "HM76"},
- {0x1E5D, "HM75"},
- {0x1E5E, "HM70"},
- {0x1E5F, "NM70"},
-};
-
-static void report_pch_info(struct udevice *dev)
-{
- const char *pch_type = "Unknown";
- int i;
- u16 dev_id;
- uint8_t rev_id;
-
- dm_pci_read_config16(dev, 2, &dev_id);
- for (i = 0; i < ARRAY_SIZE(pch_table); i++) {
- if (pch_table[i].dev_id == dev_id) {
- pch_type = pch_table[i].dev_name;
- break;
- }
- }
- dm_pci_read_config8(dev, 8, &rev_id);
- debug("PCH type: %s, device id: %x, rev id %x\n", pch_type, dev_id,
- rev_id);
-}
-
-void report_platform_info(struct udevice *dev)
-{
- report_cpu_info();
- report_pch_info(dev);
-}
diff --git a/arch/x86/cpu/ivybridge/sata.c b/arch/x86/cpu/ivybridge/sata.c
index a59d9edce5..c3d1057c29 100644
--- a/arch/x86/cpu/ivybridge/sata.c
+++ b/arch/x86/cpu/ivybridge/sata.c
@@ -9,28 +9,13 @@
#include <dm.h>
#include <fdtdec.h>
#include <asm/io.h>
+#include <asm/pch_common.h>
#include <asm/pci.h>
#include <asm/arch/pch.h>
#include <asm/arch/bd82x6x.h>
DECLARE_GLOBAL_DATA_PTR;
-static inline u32 sir_read(struct udevice *dev, int idx)
-{
- u32 data;
-
- dm_pci_write_config32(dev, SATA_SIRI, idx);
- dm_pci_read_config32(dev, SATA_SIRD, &data);
-
- return data;
-}
-
-static inline void sir_write(struct udevice *dev, int idx, u32 value)
-{
- dm_pci_write_config32(dev, SATA_SIRI, idx);
- dm_pci_write_config32(dev, SATA_SIRD, value);
-}
-
static void common_sata_init(struct udevice *dev, unsigned int port_map)
{
u32 reg32;
@@ -177,27 +162,27 @@ static void bd82x6x_sata_init(struct udevice *dev, struct udevice *pch)
pch_iobp_update(pch, SATA_IOBP_SP1G3IR, 0, port_tx);
/* Additional Programming Requirements */
- sir_write(dev, 0x04, 0x00001600);
- sir_write(dev, 0x28, 0xa0000033);
- reg32 = sir_read(dev, 0x54);
+ pch_common_sir_write(dev, 0x04, 0x00001600);
+ pch_common_sir_write(dev, 0x28, 0xa0000033);
+ reg32 = pch_common_sir_read(dev, 0x54);
reg32 &= 0xff000000;
reg32 |= 0x5555aa;
- sir_write(dev, 0x54, reg32);
- sir_write(dev, 0x64, 0xcccc8484);
- reg32 = sir_read(dev, 0x68);
+ pch_common_sir_write(dev, 0x54, reg32);
+ pch_common_sir_write(dev, 0x64, 0xcccc8484);
+ reg32 = pch_common_sir_read(dev, 0x68);
reg32 &= 0xffff0000;
reg32 |= 0xcccc;
- sir_write(dev, 0x68, reg32);
- reg32 = sir_read(dev, 0x78);
+ pch_common_sir_write(dev, 0x68, reg32);
+ reg32 = pch_common_sir_read(dev, 0x78);
reg32 &= 0x0000ffff;
reg32 |= 0x88880000;
- sir_write(dev, 0x78, reg32);
- sir_write(dev, 0x84, 0x001c7000);
- sir_write(dev, 0x88, 0x88338822);
- sir_write(dev, 0xa0, 0x001c7000);
- sir_write(dev, 0xc4, 0x0c0c0c0c);
- sir_write(dev, 0xc8, 0x0c0c0c0c);
- sir_write(dev, 0xd4, 0x10000000);
+ pch_common_sir_write(dev, 0x78, reg32);
+ pch_common_sir_write(dev, 0x84, 0x001c7000);
+ pch_common_sir_write(dev, 0x88, 0x88338822);
+ pch_common_sir_write(dev, 0xa0, 0x001c7000);
+ pch_common_sir_write(dev, 0xc4, 0x0c0c0c0c);
+ pch_common_sir_write(dev, 0xc8, 0x0c0c0c0c);
+ pch_common_sir_write(dev, 0xd4, 0x10000000);
pch_iobp_update(pch, 0xea004001, 0x3fffffff, 0xc0000000);
pch_iobp_update(pch, 0xea00408a, 0xfffffcff, 0x00000100);
@@ -229,11 +214,9 @@ static int bd82x6x_sata_probe(struct udevice *dev)
struct udevice *pch;
int ret;
- ret = uclass_first_device(UCLASS_PCH, &pch);
+ ret = uclass_first_device_err(UCLASS_PCH, &pch);
if (ret)
return ret;
- if (!pch)
- return -ENODEV;
if (!(gd->flags & GD_FLG_RELOC))
bd82x6x_sata_enable(dev);
diff --git a/arch/x86/cpu/ivybridge/sdram.c b/arch/x86/cpu/ivybridge/sdram.c
index e23c422cd0..e35e543c3e 100644
--- a/arch/x86/cpu/ivybridge/sdram.c
+++ b/arch/x86/cpu/ivybridge/sdram.c
@@ -23,9 +23,12 @@
#include <asm/processor.h>
#include <asm/gpio.h>
#include <asm/global_data.h>
+#include <asm/intel_regs.h>
#include <asm/mrccache.h>
+#include <asm/mrc_common.h>
#include <asm/mtrr.h>
#include <asm/pci.h>
+#include <asm/report_platform.h>
#include <asm/arch/me.h>
#include <asm/arch/pei_data.h>
#include <asm/arch/pch.h>
@@ -38,57 +41,14 @@ DECLARE_GLOBAL_DATA_PTR;
#define CMOS_OFFSET_MRC_SEED_S3 156
#define CMOS_OFFSET_MRC_SEED_CHK 160
-/*
- * This function looks for the highest region of memory lower than 4GB which
- * has enough space for U-Boot where U-Boot is aligned on a page boundary.
- * It overrides the default implementation found elsewhere which simply
- * picks the end of ram, wherever that may be. The location of the stack,
- * the relocation address, and how far U-Boot is moved by relocation are
- * set in the global data structure.
- */
ulong board_get_usable_ram_top(ulong total_size)
{
- struct memory_info *info = &gd->arch.meminfo;
- uintptr_t dest_addr = 0;
- struct memory_area *largest = NULL;
- int i;
-
- /* Find largest area of memory below 4GB */
-
- for (i = 0; i < info->num_areas; i++) {
- struct memory_area *area = &info->area[i];
-
- if (area->start >= 1ULL << 32)
- continue;
- if (!largest || area->size > largest->size)
- largest = area;
- }
-
- /* If no suitable area was found, return an error. */
- assert(largest);
- if (!largest || largest->size < (2 << 20))
- panic("No available memory found for relocation");
-
- dest_addr = largest->start + largest->size;
-
- return (ulong)dest_addr;
+ return mrc_common_board_get_usable_ram_top(total_size);
}
void dram_init_banksize(void)
{
- struct memory_info *info = &gd->arch.meminfo;
- int num_banks;
- int i;
-
- for (i = 0, num_banks = 0; i < info->num_areas; i++) {
- struct memory_area *area = &info->area[i];
-
- if (area->start >= 1ULL << 32)
- continue;
- gd->bd->bi_dram[num_banks].start = area->start;
- gd->bd->bi_dram[num_banks].size = area->size;
- num_banks++;
- }
+ mrc_common_dram_init_banksize();
}
static int read_seed_from_cmos(struct pei_data *pei_data)
@@ -215,164 +175,10 @@ int misc_init_r(void)
return 0;
}
-static const char *const ecc_decoder[] = {
- "inactive",
- "active on IO",
- "disabled on IO",
- "active"
-};
-
-/*
- * Dump in the log memory controller configuration as read from the memory
- * controller registers.
- */
-static void report_memory_config(void)
+static void post_system_agent_init(struct udevice *dev, struct udevice *me_dev,
+ struct pei_data *pei_data)
{
- u32 addr_decoder_common, addr_decode_ch[2];
- int i;
-
- addr_decoder_common = readl(MCHBAR_REG(0x5000));
- addr_decode_ch[0] = readl(MCHBAR_REG(0x5004));
- addr_decode_ch[1] = readl(MCHBAR_REG(0x5008));
-
- debug("memcfg DDR3 clock %d MHz\n",
- (readl(MCHBAR_REG(0x5e04)) * 13333 * 2 + 50) / 100);
- debug("memcfg channel assignment: A: %d, B % d, C % d\n",
- addr_decoder_common & 3,
- (addr_decoder_common >> 2) & 3,
- (addr_decoder_common >> 4) & 3);
-
- for (i = 0; i < ARRAY_SIZE(addr_decode_ch); i++) {
- u32 ch_conf = addr_decode_ch[i];
- debug("memcfg channel[%d] config (%8.8x):\n", i, ch_conf);
- debug(" ECC %s\n", ecc_decoder[(ch_conf >> 24) & 3]);
- debug(" enhanced interleave mode %s\n",
- ((ch_conf >> 22) & 1) ? "on" : "off");
- debug(" rank interleave %s\n",
- ((ch_conf >> 21) & 1) ? "on" : "off");
- debug(" DIMMA %d MB width x%d %s rank%s\n",
- ((ch_conf >> 0) & 0xff) * 256,
- ((ch_conf >> 19) & 1) ? 16 : 8,
- ((ch_conf >> 17) & 1) ? "dual" : "single",
- ((ch_conf >> 16) & 1) ? "" : ", selected");
- debug(" DIMMB %d MB width x%d %s rank%s\n",
- ((ch_conf >> 8) & 0xff) * 256,
- ((ch_conf >> 20) & 1) ? 16 : 8,
- ((ch_conf >> 18) & 1) ? "dual" : "single",
- ((ch_conf >> 16) & 1) ? ", selected" : "");
- }
-}
-
-static void post_system_agent_init(struct pei_data *pei_data)
-{
- /* If PCIe init is skipped, set the PEG clock gating */
- if (!pei_data->pcie_init)
- setbits_le32(MCHBAR_REG(0x7010), 1);
-}
-
-static asmlinkage void console_tx_byte(unsigned char byte)
-{
-#ifdef DEBUG
- putc(byte);
-#endif
-}
-
-static int recovery_mode_enabled(void)
-{
- return false;
-}
-
-/**
- * Find the PEI executable in the ROM and execute it.
- *
- * @dev: Northbridge device
- * @pei_data: configuration data for UEFI PEI reference code
- */
-int sdram_initialise(struct udevice *dev, struct udevice *me_dev,
- struct pei_data *pei_data)
-{
- unsigned version;
- const char *data;
uint16_t done;
- int ret;
-
- report_platform_info(dev);
-
- /* Wait for ME to be ready */
- ret = intel_early_me_init(me_dev);
- if (ret)
- return ret;
- ret = intel_early_me_uma_size(me_dev);
- if (ret < 0)
- return ret;
-
- debug("Starting UEFI PEI System Agent\n");
-
- /*
- * Do not pass MRC data in for recovery mode boot,
- * Always pass it in for S3 resume.
- */
- if (!recovery_mode_enabled() ||
- pei_data->boot_mode == PEI_BOOT_RESUME) {
- ret = prepare_mrc_cache(pei_data);
- if (ret)
- debug("prepare_mrc_cache failed: %d\n", ret);
- }
-
- /* If MRC data is not found we cannot continue S3 resume. */
- if (pei_data->boot_mode == PEI_BOOT_RESUME && !pei_data->mrc_input) {
- debug("Giving up in sdram_initialize: No MRC data\n");
- reset_cpu(0);
- }
-
- /* Pass console handler in pei_data */
- pei_data->tx_byte = console_tx_byte;
-
- debug("PEI data at %p, size %x:\n", pei_data, sizeof(*pei_data));
-
- data = (char *)CONFIG_X86_MRC_ADDR;
- if (data) {
- int rv;
- int (*func)(struct pei_data *);
- ulong start;
-
- debug("Calling MRC at %p\n", data);
- post_code(POST_PRE_MRC);
- start = get_timer(0);
- func = (int (*)(struct pei_data *))data;
- rv = func(pei_data);
- post_code(POST_MRC);
- if (rv) {
- switch (rv) {
- case -1:
- printf("PEI version mismatch.\n");
- break;
- case -2:
- printf("Invalid memory frequency.\n");
- break;
- default:
- printf("MRC returned %x.\n", rv);
- }
- printf("Nonzero MRC return value.\n");
- return -EFAULT;
- }
- debug("MRC execution time %lu ms\n", get_timer(start));
- } else {
- printf("UEFI PEI System Agent not found.\n");
- return -ENOSYS;
- }
-
-#if CONFIG_USBDEBUG
- /* mrc.bin reconfigures USB, so reinit it to have debug */
- early_usbdebug_init();
-#endif
-
- version = readl(MCHBAR_REG(0x5034));
- debug("System Agent Version %d.%d.%d Build %d\n",
- version >> 24 , (version >> 16) & 0xff,
- (version >> 8) & 0xff, version & 0xff);
- debug("MRC output data length %#x at %p\n", pei_data->mrc_output_len,
- pei_data->mrc_output);
/*
* Send ME init done for SandyBridge here. This is done inside the
@@ -383,25 +189,16 @@ int sdram_initialise(struct udevice *dev, struct udevice *me_dev,
if (BASE_REV_SNB == done)
intel_early_me_init_done(dev, me_dev, ME_INIT_STATUS_SUCCESS);
else
- intel_early_me_status(me_dev);
-
- post_system_agent_init(pei_data);
- report_memory_config();
+ intel_me_status(me_dev);
- /* S3 resume: don't save scrambler seed or MRC data */
- if (pei_data->boot_mode != PEI_BOOT_RESUME) {
- /*
- * This will be copied to SDRAM in reserve_arch(), then written
- * to SPI flash in mrccache_save()
- */
- gd->arch.mrc_output = (char *)pei_data->mrc_output;
- gd->arch.mrc_output_len = pei_data->mrc_output_len;
- ret = write_seeds_to_cmos(pei_data);
- if (ret)
- debug("Failed to write seeds to CMOS: %d\n", ret);
- }
+ /* If PCIe init is skipped, set the PEG clock gating */
+ if (!pei_data->pcie_init)
+ setbits_le32(MCHBAR_REG(0x7010), 1);
+}
- return 0;
+static int recovery_mode_enabled(void)
+{
+ return false;
}
int reserve_arch(void)
@@ -409,87 +206,16 @@ int reserve_arch(void)
return mrccache_reserve();
}
-static int copy_spd(struct pei_data *peid)
+static int copy_spd(struct udevice *dev, struct pei_data *peid)
{
- const int gpio_vector[] = {41, 42, 43, 10, -1};
- int spd_index;
- const void *blob = gd->fdt_blob;
- int node, spd_node;
- int ret, i;
-
- for (i = 0; ; i++) {
- if (gpio_vector[i] == -1)
- break;
- ret = gpio_requestf(gpio_vector[i], "spd_id%d", i);
- if (ret) {
- debug("%s: Could not request gpio %d\n", __func__,
- gpio_vector[i]);
- return ret;
- }
- }
- spd_index = gpio_get_values_as_int(gpio_vector);
- debug("spd index %d\n", spd_index);
- node = fdtdec_next_compatible(blob, 0, COMPAT_MEMORY_SPD);
- if (node < 0) {
- printf("SPD data not found.\n");
- return -ENOENT;
- }
-
- for (spd_node = fdt_first_subnode(blob, node);
- spd_node > 0;
- spd_node = fdt_next_subnode(blob, spd_node)) {
- const char *data;
- int len;
-
- if (fdtdec_get_int(blob, spd_node, "reg", -1) != spd_index)
- continue;
- data = fdt_getprop(blob, spd_node, "data", &len);
- if (len < sizeof(peid->spd_data[0])) {
- printf("Missing SPD data\n");
- return -EINVAL;
- }
-
- debug("Using SDRAM SPD data for '%s'\n",
- fdt_get_name(blob, spd_node, NULL));
- memcpy(peid->spd_data[0], data, sizeof(peid->spd_data[0]));
- break;
- }
-
- if (spd_node < 0) {
- printf("No SPD data found for index %d\n", spd_index);
- return -ENOENT;
- }
+ const void *data;
+ int ret;
- return 0;
-}
+ ret = mrc_locate_spd(dev, sizeof(peid->spd_data[0]), &data);
+ if (ret)
+ return ret;
-/**
- * add_memory_area() - Add a new usable memory area to our list
- *
- * Note: @start and @end must not span the first 4GB boundary
- *
- * @info: Place to store memory info
- * @start: Start of this memory area
- * @end: End of this memory area + 1
- */
-static int add_memory_area(struct memory_info *info,
- uint64_t start, uint64_t end)
-{
- struct memory_area *ptr;
-
- if (info->num_areas == CONFIG_NR_DRAM_BANKS)
- return -ENOSPC;
-
- ptr = &info->area[info->num_areas];
- ptr->start = start;
- ptr->size = end - start;
- info->total_memory += ptr->size;
- if (ptr->start < (1ULL << 32))
- info->total_32bit_memory += ptr->size;
- debug("%d: memory %llx size %llx, total now %llx / %llx\n",
- info->num_areas, ptr->start, ptr->size,
- info->total_32bit_memory, info->total_memory);
- info->num_areas++;
+ memcpy(peid->spd_data[0], data, sizeof(peid->spd_data[0]));
return 0;
}
@@ -608,10 +334,10 @@ static int sdram_find(struct udevice *dev)
debug("Available memory below 4GB: %lluM\n", tomk >> 10);
/* Report the memory regions */
- add_memory_area(info, 1 << 20, 2 << 28);
- add_memory_area(info, (2 << 28) + (2 << 20), 4 << 28);
- add_memory_area(info, (4 << 28) + (2 << 20), tseg_base);
- add_memory_area(info, 1ULL << 32, touud);
+ mrc_add_memory_area(info, 1 << 20, 2 << 28);
+ mrc_add_memory_area(info, (2 << 28) + (2 << 20), 4 << 28);
+ mrc_add_memory_area(info, (4 << 28) + (2 << 20), tseg_base);
+ mrc_add_memory_area(info, 1ULL << 32, touud);
/* Add MTRRs for memory */
mtrr_add_request(MTRR_TYPE_WRBACK, 0, 2ULL << 30);
@@ -680,9 +406,9 @@ static void rcba_config(void)
int dram_init(void)
{
- struct pei_data pei_data __aligned(8) = {
+ struct pei_data _pei_data __aligned(8) = {
.pei_version = PEI_VERSION,
- .mchbar = DEFAULT_MCHBAR,
+ .mchbar = MCH_BASE_ADDRESS,
.dmibar = DEFAULT_DMIBAR,
.epbar = DEFAULT_EPBAR,
.pciexbar = CONFIG_PCIE_ECAM_BASE,
@@ -733,38 +459,84 @@ int dram_init(void)
{ 0, 4, 0x0000 }, /* P13= Empty */
},
};
+ struct pei_data *pei_data = &_pei_data;
struct udevice *dev, *me_dev;
int ret;
- ret = uclass_first_device(UCLASS_NORTHBRIDGE, &dev);
+ ret = uclass_first_device_err(UCLASS_NORTHBRIDGE, &dev);
if (ret)
return ret;
- if (!dev)
- return -ENODEV;
ret = syscon_get_by_driver_data(X86_SYSCON_ME, &me_dev);
if (ret)
return ret;
- debug("Boot mode %d\n", gd->arch.pei_boot_mode);
- debug("mrc_input %p\n", pei_data.mrc_input);
- pei_data.boot_mode = gd->arch.pei_boot_mode;
- ret = copy_spd(&pei_data);
- if (!ret)
- ret = sdram_initialise(dev, me_dev, &pei_data);
+ ret = copy_spd(dev, pei_data);
if (ret)
return ret;
+ pei_data->boot_mode = gd->arch.pei_boot_mode;
+ debug("Boot mode %d\n", gd->arch.pei_boot_mode);
+ debug("mrc_input %p\n", pei_data->mrc_input);
- rcba_config();
- quick_ram_check();
+ /*
+ * Do not pass MRC data in for recovery mode boot,
+ * Always pass it in for S3 resume.
+ */
+ if (!recovery_mode_enabled() ||
+ pei_data->boot_mode == PEI_BOOT_RESUME) {
+ ret = prepare_mrc_cache(pei_data);
+ if (ret)
+ debug("prepare_mrc_cache failed: %d\n", ret);
+ }
- writew(0xCAFE, MCHBAR_REG(SSKPD));
+ /* If MRC data is not found we cannot continue S3 resume. */
+ if (pei_data->boot_mode == PEI_BOOT_RESUME && !pei_data->mrc_input) {
+ debug("Giving up in sdram_initialize: No MRC data\n");
+ reset_cpu(0);
+ }
- post_code(POST_DRAM);
+ /* Pass console handler in pei_data */
+ pei_data->tx_byte = sdram_console_tx_byte;
- ret = sdram_find(dev);
+ /* Wait for ME to be ready */
+ ret = intel_early_me_init(me_dev);
if (ret)
return ret;
+ ret = intel_early_me_uma_size(me_dev);
+ if (ret < 0)
+ return ret;
+ ret = mrc_common_init(dev, pei_data, false);
+ if (ret)
+ return ret;
+
+ ret = sdram_find(dev);
+ if (ret)
+ return ret;
gd->ram_size = gd->arch.meminfo.total_32bit_memory;
+ debug("MRC output data length %#x at %p\n", pei_data->mrc_output_len,
+ pei_data->mrc_output);
+
+ post_system_agent_init(dev, me_dev, pei_data);
+ report_memory_config();
+
+ /* S3 resume: don't save scrambler seed or MRC data */
+ if (pei_data->boot_mode != PEI_BOOT_RESUME) {
+ /*
+ * This will be copied to SDRAM in reserve_arch(), then written
+ * to SPI flash in mrccache_save()
+ */
+ gd->arch.mrc_output = (char *)pei_data->mrc_output;
+ gd->arch.mrc_output_len = pei_data->mrc_output_len;
+ ret = write_seeds_to_cmos(pei_data);
+ if (ret)
+ debug("Failed to write seeds to CMOS: %d\n", ret);
+ }
+
+ writew(0xCAFE, MCHBAR_REG(SSKPD));
+ if (ret)
+ return ret;
+
+ rcba_config();
+
return 0;
}
OpenPOWER on IntegriCloud