+// SPDX-License-Identifier: GPL-2.0
/*
* From Coreboot file of same name
*
* Copyright (C) 2007-2009 coresystems GmbH
* Copyright (C) 2011 The Chromium Authors
- *
- * SPDX-License-Identifier: GPL-2.0
*/
#include <common.h>
#include <cpu.h>
#include <dm.h>
#include <fdtdec.h>
+#include <log.h>
#include <malloc.h>
-#include <asm/acpi.h>
#include <asm/cpu.h>
+#include <asm/cpu_common.h>
#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>
#include <asm/turbo.h>
-#include <asm/arch/bd82x6x.h>
#include <asm/arch/model_206ax.h>
+DECLARE_GLOBAL_DATA_PTR;
+
static void enable_vmx(void)
{
struct cpuid_result regs;
[0x11] = 128,
};
-int cpu_config_tdp_levels(void)
+bool cpu_ivybridge_config_tdp_levels(void)
{
struct cpuid_result result;
- msr_t platform_info;
/* Minimum CPU revision */
result = cpuid(1);
if (result.eax < IVB_CONFIG_TDP_MIN_CPUID)
- return 0;
+ return false;
- /* Bits 34:33 indicate how many levels supported */
- platform_info = msr_read(MSR_PLATFORM_INFO);
- return (platform_info.hi >> 1) & 3;
+ return cpu_config_tdp_levels();
}
/*
msr_write(MSR_PKG_POWER_LIMIT, limit);
/* Use nominal TDP values for CPUs with configurable TDP */
- if (cpu_config_tdp_levels()) {
+ if (cpu_ivybridge_config_tdp_levels()) {
msr = msr_read(MSR_CONFIG_TDP_NOMINAL);
limit.hi = 0;
limit.lo = msr.lo & 0xff;
msr_write(MSR_PP1_CURRENT_CONFIG, msr);
}
-static int configure_thermal_target(void)
-{
- int tcc_offset;
- msr_t msr;
- int node;
-
- /* Find pointer to CPU configuration */
- node = fdtdec_next_compatible(gd->fdt_blob, 0,
- COMPAT_INTEL_MODEL_206AX);
- if (node < 0)
- return -ENOENT;
- tcc_offset = fdtdec_get_int(gd->fdt_blob, node, "tcc-offset", 0);
-
- /* Set TCC activaiton offset if supported */
- msr = msr_read(MSR_PLATFORM_INFO);
- if ((msr.lo & (1 << 30)) && tcc_offset) {
- msr = msr_read(MSR_TEMPERATURE_TARGET);
- msr.lo &= ~(0xf << 24); /* Bits 27:24 */
- msr.lo |= (tcc_offset & 0xf) << 24;
- msr_write(MSR_TEMPERATURE_TARGET, msr);
- }
-
- return 0;
-}
-
static void configure_misc(void)
{
msr_t msr;
static void set_max_ratio(void)
{
- msr_t msr, perf_ctl;
-
- perf_ctl.hi = 0;
+ msr_t msr;
+ uint ratio;
/* Check for configurable TDP option */
- if (cpu_config_tdp_levels()) {
+ if (cpu_ivybridge_config_tdp_levels()) {
/* Set to nominal TDP ratio */
msr = msr_read(MSR_CONFIG_TDP_NOMINAL);
- perf_ctl.lo = (msr.lo & 0xff) << 8;
+ ratio = msr.lo & 0xff;
} else {
/* Platform Info bits 15:8 give max ratio */
msr = msr_read(MSR_PLATFORM_INFO);
- perf_ctl.lo = msr.lo & 0xff00;
+ ratio = (msr.lo & 0xff00) >> 8;
}
- msr_write(IA32_PERF_CTL, perf_ctl);
-
- debug("model_x06ax: frequency set to %d\n",
- ((perf_ctl.lo >> 8) & 0xff) * SANDYBRIDGE_BCLK);
+ cpu_set_perf_control(ratio);
}
static void set_energy_perf_bias(u8 policy)
msr_write(IA32_MC0_STATUS + (i * 4), msr);
}
-#if CONFIG_USBDEBUG
-static unsigned ehci_debug_addr;
-#endif
-
-int model_206ax_init(struct x86_cpu_priv *cpu)
+static int model_206ax_init(struct udevice *dev)
{
int ret;
/* Clear out pending MCEs */
configure_mca();
-#if CONFIG_USBDEBUG
- /* Is this caution really needed? */
- if (!ehci_debug_addr)
- ehci_debug_addr = get_ehci_debug();
- set_ehci_debug(0);
-#endif
-
- /* Setup MTRRs based on physical address size */
-#if 0 /* TODO: Implement this */
- struct cpuid_result cpuid_regs;
-
- cpuid_regs = cpuid(0x80000008);
- x86_setup_fixed_mtrrs();
- x86_setup_var_mtrrs(cpuid_regs.eax & 0xff, 2);
- x86_mtrr_check();
-#endif
-
-#if CONFIG_USBDEBUG
- set_ehci_debug(ehci_debug_addr);
-#endif
-
/* Enable the local cpu apics */
enable_lapic_tpr();
- lapic_setup();
/* Enable virtualization if enabled in CMOS */
enable_vmx();
configure_misc();
/* Thermal throttle activation offset */
- ret = configure_thermal_target();
+ ret = cpu_configure_thermal_target(dev);
if (ret) {
debug("Cannot set thermal target\n");
- return ret;
+ if (ret != -ENOENT)
+ return ret;
}
/* Enable Direct Cache Access */
static int model_206ax_get_info(struct udevice *dev, struct cpu_info *info)
{
- info->features = 1 << CPU_FEAT_L1_CACHE | 1 << CPU_FEAT_MMU;
+ return cpu_intel_get_info(info, INTEL_BCLK_MHZ);
return 0;
}
static int cpu_x86_model_206ax_probe(struct udevice *dev)
{
+ if (dev->seq == 0)
+ model_206ax_init(dev);
+
return 0;
}
.get_desc = cpu_x86_get_desc,
.get_info = model_206ax_get_info,
.get_count = model_206ax_get_count,
+ .get_vendor = cpu_x86_get_vendor,
};
static const struct udevice_id cpu_x86_model_206ax_ids[] = {
.bind = cpu_x86_bind,
.probe = cpu_x86_model_206ax_probe,
.ops = &cpu_x86_model_206ax_ops,
+ .flags = DM_FLAG_PRE_RELOC,
};