Matt Delco has uploaded this change for review.

View Change

soc/intel/skylake: add CPPC support

ACPI defines a method _CPC for "Continuous Performance Control" (CPPC).
Linux has a driver that enables features like speed shift without
consulting ACPI. Other OSes instead rely on this information and need a
_CPC present. Prior to this change performance in Win10 never exceeds
80% and MSR 0x770 is 0, while with this change higher speeds can be achieved
and the MSR value is now 1.

Rather than add a large package to each processor I have the code add one
global instance and each processor has a method that references that instance.
I'm open to suggestions on a different place to place the package.

Change-Id: Ib7e0ae13f4b664b51e42f963e53c71f8832be062
Signed-off-by: Matt Delco <delco@chromium.org>
---
M src/soc/intel/skylake/acpi.c
1 file changed, 152 insertions(+), 2 deletions(-)

git pull ssh://review.coreboot.org:29418/coreboot refs/changes/73/27673/1
diff --git a/src/soc/intel/skylake/acpi.c b/src/soc/intel/skylake/acpi.c
index 5bed118..d2d41c9 100644
--- a/src/soc/intel/skylake/acpi.c
+++ b/src/soc/intel/skylake/acpi.c
@@ -501,6 +501,151 @@
acpigen_pop_len();
}

+#define CPPC_PACKAGE_NAME "\\GCPC"
+
+static void generate_CPPC_method(void)
+{
+ acpigen_write_method("_CPC", 0);
+ acpigen_emit_byte(RETURN_OP);
+ acpigen_emit_namestring(CPPC_PACKAGE_NAME);
+ acpigen_pop_len();
+}
+
+static void generate_CPPC_package(bool version2)
+{
+ acpi_addr_t msr = {
+ .space_id = ACPI_ADDRESS_SPACE_FIXED,
+ .bit_width = 8,
+ .bit_offset = 0,
+ {
+ .access_size = 4
+ },
+ .addrl = 0,
+ .addrh = 0,
+ };
+ static const acpi_addr_t unsupported = {
+ .space_id = ACPI_ADDRESS_SPACE_MEMORY,
+ .bit_width = 0,
+ .bit_offset = 0,
+ {
+ .resv = 0
+ },
+ .addrl = 0,
+ .addrh = 0,
+ };
+
+ acpigen_write_name(CPPC_PACKAGE_NAME);
+ acpigen_write_package(version2 ? 21 : 17);
+
+ acpigen_write_dword(version2 ? 21 : 17);
+ acpigen_write_byte(version2 ? 2 : 1);
+
+ // 0x771 is IA32_HWP_CAPABILITIES (RO)
+ msr.addrl = 0x771;
+
+ // Highest Performance:
+ // ResourceTemplate(){Register(FFixedHW, 0x08, 0x00, 0x771, 0x04,)},
+ acpigen_write_register_resource(&msr);
+
+ // Nominal Performance -> Guaranteed Performance:
+ // ResourceTemplate(){Register(FFixedHW, 0x08, 0x08, 0x771, 0x04,)},
+ msr.bit_offset = 8;
+ acpigen_write_register_resource(&msr);
+
+ // Lowest Nonlinear Performance -> Most Efficient Performance:
+ // ResourceTemplate(){Register(FFixedHW, 0x08, 0x10, 0x771, 0x04,)},
+ msr.bit_offset = 16;
+ acpigen_write_register_resource(&msr);
+
+ // Lowest Performance:
+ // ResourceTemplate(){Register(FFixedHW, 0x08, 0x18, 0x771, 0x04,)},
+ msr.bit_offset = 24;
+ acpigen_write_register_resource(&msr);
+
+ // Guaranteed Performance Register:
+ // ResourceTemplate(){Register(FFixedHW, 0x08, 0x08, 0x771, 0x04,)},
+ msr.bit_offset = 8;
+ acpigen_write_register_resource(&msr);
+
+ // 0x774 is IA32_HWP_REQUEST (RW)
+ msr.addrl = 0x774;
+
+ // Desired Performance Register:
+ // ResourceTemplate(){Register(FFixedHW, 0x08, 0x10, 0x774, 0x04,)},
+ msr.bit_offset = 16;
+ acpigen_write_register_resource(&msr);
+
+ // Minimum Performance Register:
+ // ResourceTemplate(){Register(FFixedHW, 0x08, 0x00, 0x774, 0x04,)},
+ msr.bit_offset = 0;
+ acpigen_write_register_resource(&msr);
+
+ // Maximum Performance Register:
+ // ResourceTemplate(){Register(FFixedHW, 0x08, 0x08, 0x774, 0x04,)},
+ msr.bit_offset = 8;
+ acpigen_write_register_resource(&msr);
+
+ // Performance Reduction Tolerance Register:
+ // ResourceTemplate(){Register(SystemMemory, 0x00, 0x00, 0x0,,)},
+ acpigen_write_register_resource(&unsupported);
+
+ // Time Window Register:
+ // ResourceTemplate(){Register(SystemMemory, 0x00, 0x00, 0x0,,)},
+ acpigen_write_register_resource(&unsupported);
+
+ // Counter Wraparound Time:
+ // ResourceTemplate(){Register(SystemMemory, 0x00, 0x00, 0x0,,)},
+ acpigen_write_register_resource(&unsupported);
+
+ // 0xE7 is IA32_MPERF
+ msr.addrl = 0xe7;
+
+ // Reference Performance Counter Register:
+ // ResourceTemplate(){Register(FFixedHW, 0x40, 0x00, 0x0E7, 0x04,)},
+ msr.bit_width = 64;
+ msr.bit_offset = 0;
+ acpigen_write_register_resource(&msr);
+
+ // 0xE8 is IA32_APERF
+ msr.addrl = 0xe8;
+
+ // Delivered Performance Counter Register:
+ // ResourceTemplate(){Register(FFixedHW, 0x40, 0x00, 0x0E8, 0x04,)},
+ acpigen_write_register_resource(&msr);
+
+ // 0x777 is IA32_HWP_STATUS
+ msr.addrl = 0x777;
+
+ // Performance Limited Register:
+ // ResourceTemplate(){Register(FFixedHW, 0x01, 0x02, 0x777, 0x04,)},
+ msr.bit_width = 1;
+ msr.bit_offset = 2;
+ acpigen_write_register_resource(&msr);
+
+ // 0x770 is IA32_PM_ENABLE
+ msr.addrl = 0x770;
+
+ // CPPC Enable Register:
+ // ResourceTemplate(){Register(FFixedHW, 0x01, 0x00, 0x770, 0x04,)},
+ msr.bit_offset = 0;
+ acpigen_write_register_resource(&msr);
+
+ if (version2) {
+ // Autonomous Selection Enable = 1
+ acpigen_write_dword(1);
+
+ // Autonomous Activity Window Register
+ acpigen_write_register_resource(&unsupported);
+
+ // Energy Performance Preference Register
+ acpigen_write_register_resource(&unsupported);
+
+ // Reference Performance
+ acpigen_write_register_resource(&unsupported);
+ }
+ acpigen_pop_len();
+}
+
void generate_cpu_entries(struct device *device)
{
int core_id, cpu_id, pcontrol_blk = ACPI_BASE_ADDRESS, plen = 6;
@@ -520,6 +665,9 @@
printk(BIOS_DEBUG, "Found %d CPU(s) with %d core(s) each.\n",
numcpus, cores_per_package);

+ if (config->eist_enable && config->speed_shift_enable)
+ generate_CPPC_package(TRUE);
+
for (cpu_id = 0; cpu_id < numcpus; cpu_id++) {
for (core_id = 0; core_id < cores_per_package; core_id++) {
if (core_id > 0) {
@@ -535,11 +683,13 @@
generate_c_state_entries(is_s0ix_enable,
max_c_state);

- if (config->eist_enable)
+ if (config->eist_enable) {
/* Generate P-state tables */
generate_p_state_entries(core_id,
cores_per_package);
-
+ if (config->speed_shift_enable)
+ generate_CPPC_method();
+ }
acpigen_pop_len();
}
}

To view, visit change 27673. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ib7e0ae13f4b664b51e42f963e53c71f8832be062
Gerrit-Change-Number: 27673
Gerrit-PatchSet: 1
Gerrit-Owner: Matt Delco <delco@chromium.org>