x86: Move common CPU code to its own place
authorSimon Glass <sjg@chromium.org>
Sat, 12 Mar 2016 05:06:58 +0000 (22:06 -0700)
committerBin Meng <bmeng.cn@gmail.com>
Thu, 17 Mar 2016 02:27:24 +0000 (10:27 +0800)
Some of the Intel CPU code is common to several Intel CPUs. Move it into a
common location along with required declarations.

Signed-off-by: Simon Glass <sjg@chromium.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
arch/x86/cpu/intel_common/Makefile
arch/x86/cpu/intel_common/cpu.c [new file with mode: 0644]
arch/x86/cpu/ivybridge/cpu.c
arch/x86/include/asm/arch-ivybridge/pch.h
arch/x86/include/asm/cpu_common.h [new file with mode: 0644]
arch/x86/include/asm/intel_regs.h

index 74b005a4966cf2a270ed9917c0d0b0c9d53eef9f..06de964cc8fd2641d5e46fdb9570318da7502c44 100644 (file)
@@ -5,6 +5,7 @@
 #
 
 obj-$(CONFIG_HAVE_MRC) += car.o
+obj-y += cpu.o
 obj-y += lpc.o
 ifndef CONFIG_TARGET_EFI
 obj-y += microcode.o
diff --git a/arch/x86/cpu/intel_common/cpu.c b/arch/x86/cpu/intel_common/cpu.c
new file mode 100644 (file)
index 0000000..1210943
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <asm/cpu_common.h>
+#include <asm/intel_regs.h>
+#include <asm/lapic.h>
+#include <asm/lpc_common.h>
+#include <asm/msr.h>
+#include <asm/mtrr.h>
+#include <asm/post.h>
+#include <asm/microcode.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+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 cpu_common_init(void)
+{
+       struct udevice *dev, *lpc;
+       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 && ret != -EEXIST)
+               return ret;
+
+       /* Enable upper 128bytes of CMOS */
+       writel(1 << 2, RCB_REG(RC));
+
+       /* Early chipset init required before RAM init can work */
+       uclass_first_device(UCLASS_NORTHBRIDGE, &dev);
+
+       ret = uclass_first_device(UCLASS_LPC, &lpc);
+       if (ret)
+               return ret;
+       if (!lpc)
+               return -ENODEV;
+
+       /* Cause the SATA device to do its early init */
+       uclass_first_device(UCLASS_DISK, &dev);
+
+       return 0;
+}
+
+int cpu_set_flex_ratio_to_tdp_nominal(void)
+{
+       msr_t flex_ratio, msr;
+       u8 nominal_ratio;
+
+       /* 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);
+
+       debug("CPU: Soft reset to set up flex ratio\n");
+
+       /* 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;
+}
index 796771c021f74000660529d95f0da4b4cbb255a8..bb720ba938aabf119e5a80fdd9692b8ccc338085 100644 (file)
@@ -17,6 +17,7 @@
 #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>
@@ -34,51 +35,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)
@@ -163,17 +124,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;
@@ -184,20 +134,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");
@@ -208,16 +144,10 @@ 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_err(UCLASS_LPC, &lpc);
+       ret = cpu_common_init();
        if (ret)
                return ret;
 
-       /* 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);
 
@@ -240,8 +170,10 @@ int print_cpuinfo(void)
                return ret;
 
        /* 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;
 
index f96dc2bb97372260ff67fd73145646eaa33f1f22..e72ff2afc93f708ca12a5a09856927abb437a257 100644 (file)
 #define SPI_FREQ_SWSEQ 0x3893
 #define SPI_DESC_COMP0 0x38b0
 #define SPI_FREQ_WR_ERA        0x38b4
-#define SOFT_RESET_CTRL 0x38f4
-#define SOFT_RESET_DATA 0x38f8
 
 #define DIR_ROUTE(a, b, c, d) \
                (((d) << DIR_IDR) | ((c) << DIR_ICR) | \
diff --git a/arch/x86/include/asm/cpu_common.h b/arch/x86/include/asm/cpu_common.h
new file mode 100644 (file)
index 0000000..562de3e
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2016 Google, Inc
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ */
+
+#ifndef __ASM_CPU_COMMON_H
+#define __ASM_CPU_COMMON_H
+
+#define IA32_PERF_CTL                  0x199
+
+/**
+ * cpu_common_init() - Set up common CPU init
+ *
+ * This reports BIST failure, enables the LAPIC, updates microcode, enables
+ * the upper 128-bytes of CROM RAM, probes the northbridge, PCH, LPC and SATA.
+ *
+ * @return 0 if OK, -ve on error
+ */
+int cpu_common_init(void);
+
+/**
+ * cpu_set_flex_ratio_to_tdp_nominal() - Set up the maximum non-turbo rate
+ *
+ * If a change is needed, this function will do a soft reset so it takes
+ * effect.
+ *
+ * Some details are available here:
+ * http://forum.hwbot.org/showthread.php?t=76092
+ *
+ * @return 0 if OK, -ve on error
+ */
+int cpu_set_flex_ratio_to_tdp_nominal(void);
+
+#endif
index 961d2bda1ebde3cc12f7717d9f40989600e07204..d2a6d2690e6f2395c958bd70c6c76c1b158f959b 100644 (file)
 #define MCH_BASE_SIZE          0x8000
 #define MCHBAR_REG(reg)                (MCH_BASE_ADDRESS + (reg))
 
+#define MCHBAR_PEI_VERSION     0x5034
+#define MCH_PKG_POWER_LIMIT_LO 0x59a0
+#define MCH_PKG_POWER_LIMIT_HI 0x59a4
+#define MCH_DDR_POWER_LIMIT_LO 0x58e0
+#define MCH_DDR_POWER_LIMIT_HI 0x58e4
+
 /* Access the Root Complex Register Block */
 #define RCB_BASE_ADDRESS       0xfed1c000
 #define RCB_REG(reg)           (RCB_BASE_ADDRESS + (reg))
 
+#define SOFT_RESET_CTRL                0x38f4
+#define SOFT_RESET_DATA                0x38f8
+
 #endif