blob: 05f5f327cc6148c8aafbea7646e1dfa40b7bcad1 [file] [log] [blame]
Angel Ponsf23ae0b2020-04-02 23:48:12 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Stefan Reinauer1a08f582009-10-28 16:52:48 +00002
3#include <console/console.h>
4#include <device/device.h>
Stefan Reinauer1a08f582009-10-28 16:52:48 +00005#include <cpu/cpu.h>
Stefan Reinauer1a08f582009-10-28 16:52:48 +00006#include <cpu/x86/msr.h>
Stefan Reinauer2a27b202010-12-11 22:14:44 +00007#include <cpu/intel/speedstep.h>
Stefan Reinauer1a08f582009-10-28 16:52:48 +00008#include <cpu/x86/cache.h>
Uwe Hermannaac8f662010-09-29 09:54:16 +00009#include <cpu/x86/name.h>
Stefan Reinauer1a08f582009-10-28 16:52:48 +000010
Stefan Reinauer1a08f582009-10-28 16:52:48 +000011#define HIGHEST_CLEVEL 3
12static void configure_c_states(void)
13{
14 msr_t msr;
15
Elyes HAOUAS4e6b7902018-10-02 08:44:47 +020016 msr = rdmsr(MSR_PKG_CST_CONFIG_CONTROL);
Stefan Reinauer1a08f582009-10-28 16:52:48 +000017 msr.lo |= (1 << 15); // Lock configuration
Lee Leahycdc50482017-03-15 18:26:18 -070018 msr.lo |= (1 << 10); // redirect IO-based CState transition requests to
19 // MWAIT
Stefan Reinauer1a08f582009-10-28 16:52:48 +000020 msr.lo &= ~(1 << 9); // Issue a single stop grant cycle upon stpclk
21 msr.lo &= ~7; msr.lo |= HIGHEST_CLEVEL; // support at most C3
22 // TODO Do we want Deep C4 and Dynamic L2 shrinking?
Elyes HAOUAS4e6b7902018-10-02 08:44:47 +020023 wrmsr(MSR_PKG_CST_CONFIG_CONTROL, msr);
Stefan Reinauer1a08f582009-10-28 16:52:48 +000024
Stefan Reinauerdfeb04d2010-12-12 00:37:41 +000025 /* Set Processor MWAIT IO BASE (P_BLK) */
26 msr.hi = 0;
27 // TODO Do we want PM1_BASE? Needs SMM?
Lee Leahycdc50482017-03-15 18:26:18 -070028 //msr.lo = ((PMB0_BASE + 4) & 0xffff) | (((PMB1_BASE + 9) & 0xffff)
29 // << 16);
Stefan Reinauerdfeb04d2010-12-12 00:37:41 +000030 msr.lo = ((PMB0_BASE + 4) & 0xffff);
Patrick Georgi644e83b2013-02-09 15:35:30 +010031 wrmsr(MSR_PMG_IO_BASE_ADDR, msr);
Stefan Reinauer1a08f582009-10-28 16:52:48 +000032
Stefan Reinauerdfeb04d2010-12-12 00:37:41 +000033 /* set C_LVL controls */
34 msr.hi = 0;
Lee Leahycdc50482017-03-15 18:26:18 -070035 // -2 because LVL0+1 aren't counted
36 msr.lo = (PMB0_BASE + 4) | ((HIGHEST_CLEVEL - 2) << 16);
Patrick Georgi644e83b2013-02-09 15:35:30 +010037 wrmsr(MSR_PMG_IO_CAPTURE_ADDR, msr);
Stefan Reinauer1a08f582009-10-28 16:52:48 +000038}
39
Stefan Reinauer1a08f582009-10-28 16:52:48 +000040static void configure_misc(void)
41{
42 msr_t msr;
43
44 msr = rdmsr(IA32_MISC_ENABLE);
Lee Leahy7b5f12b92017-03-15 17:16:59 -070045 msr.lo |= (1 << 3); /* TM1 enable */
Stefan Reinauer1a08f582009-10-28 16:52:48 +000046 msr.lo |= (1 << 13); /* TM2 enable */
47 msr.lo |= (1 << 17); /* Bidirectional PROCHOT# */
48
49 msr.lo |= (1 << 10); /* FERR# multiplexing */
50
51 // TODO: Only if IA32_PLATFORM_ID[17] = 0 and IA32_PLATFORM_ID[50] = 1
52 msr.lo |= (1 << 16); /* Enhanced SpeedStep Enable */
53
54 // TODO Do we want Deep C4 and Dynamic L2 shrinking?
55 wrmsr(IA32_MISC_ENABLE, msr);
56
57 msr.lo |= (1 << 20); /* Lock Enhanced SpeedStep Enable */
58 wrmsr(IA32_MISC_ENABLE, msr);
59}
60
Edward O'Callaghan2c9d2cf2014-10-27 23:29:29 +110061static void model_106cx_init(struct device *cpu)
Stefan Reinauer1a08f582009-10-28 16:52:48 +000062{
63 char processor_name[49];
64
Stefan Reinauer1a08f582009-10-28 16:52:48 +000065 /* Print processor name */
66 fill_processor_name(processor_name);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000067 printk(BIOS_INFO, "CPU: %s.\n", processor_name);
Stefan Reinauer1a08f582009-10-28 16:52:48 +000068
Stefan Reinauer1a08f582009-10-28 16:52:48 +000069 /* Configure C States */
70 configure_c_states();
71
72 /* Configure Enhanced SpeedStep and Thermal Sensors */
73 configure_misc();
74
75 /* TODO: PIC thermal sensor control */
Stefan Reinauer1a08f582009-10-28 16:52:48 +000076}
77
78static struct device_operations cpu_dev_ops = {
Stefan Reinauer5fc7f982009-11-04 12:18:44 +000079 .init = model_106cx_init,
Stefan Reinauer1a08f582009-10-28 16:52:48 +000080};
81
Jonathan Neuschäfer8f06ce32017-11-20 01:56:44 +010082static const struct cpu_device_id cpu_table[] = {
Felix Held6a6ac1e2023-02-06 15:19:11 +010083 { X86_VENDOR_INTEL, 0x106c0, CPUID_EXACT_MATCH_MASK }, /* Intel Atom 230 */
84 { X86_VENDOR_INTEL, 0x106ca, CPUID_EXACT_MATCH_MASK }, /* Intel Atom D5xx */
Felix Held1e781652023-02-08 11:39:16 +010085 CPU_TABLE_END
Stefan Reinauer1a08f582009-10-28 16:52:48 +000086};
87
88static const struct cpu_driver driver __cpu_driver = {
89 .ops = &cpu_dev_ops,
90 .id_table = cpu_table,
91};