From 95b61752dbb56b9a7a2da439c5d21e30643661ef Mon Sep 17 00:00:00 2001 From: Shaunak Saha Date: Wed, 4 Oct 2017 23:08:40 -0700 Subject: soc/intel/cannonlake: Add support for C state and P state This patch adds the C state and P state configurations for cannonlake soc. TEST = Boot and test the CPU states for all the cores are present in "powertop" tool output. Change-Id: I4ba156354f87646b25d0f9114ebf0583eedf72df Signed-off-by: Shaunak Saha Reviewed-on: https://review.coreboot.org/21891 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: Aaron Durbin --- src/soc/intel/cannonlake/acpi.c | 134 +++++++++++++++++++++++++++++ src/soc/intel/cannonlake/chip.c | 1 + src/soc/intel/cannonlake/include/soc/cpu.h | 2 +- 3 files changed, 136 insertions(+), 1 deletion(-) diff --git a/src/soc/intel/cannonlake/acpi.c b/src/soc/intel/cannonlake/acpi.c index 4e2a02787f..9dcaa338c9 100644 --- a/src/soc/intel/cannonlake/acpi.c +++ b/src/soc/intel/cannonlake/acpi.c @@ -33,9 +33,143 @@ #include #include #include +#include #include #include +/* + * List of supported C-states in this processor. + */ +enum { + C_STATE_C0, /* 0 */ + C_STATE_C1, /* 1 */ + C_STATE_C1E, /* 2 */ + C_STATE_C6_SHORT_LAT, /* 3 */ + C_STATE_C6_LONG_LAT, /* 4 */ + C_STATE_C7_SHORT_LAT, /* 5 */ + C_STATE_C7_LONG_LAT, /* 6 */ + C_STATE_C7S_SHORT_LAT, /* 7 */ + C_STATE_C7S_LONG_LAT, /* 8 */ + C_STATE_C8, /* 9 */ + C_STATE_C9, /* 10 */ + C_STATE_C10, /* 11 */ + NUM_C_STATES +}; + +#define MWAIT_RES(state, sub_state) \ + { \ + .addrl = (((state) << 4) | (sub_state)), \ + .space_id = ACPI_ADDRESS_SPACE_FIXED, \ + .bit_width = ACPI_FFIXEDHW_VENDOR_INTEL, \ + .bit_offset = ACPI_FFIXEDHW_CLASS_MWAIT, \ + .access_size = ACPI_FFIXEDHW_FLAG_HW_COORD, \ + } + +static const acpi_cstate_t cstate_map[NUM_C_STATES] = { + [C_STATE_C0] = {}, + [C_STATE_C1] = { + .latency = 0, + .power = C1_POWER, + .resource = MWAIT_RES(0, 0), + }, + [C_STATE_C1E] = { + .latency = 0, + .power = C1_POWER, + .resource = MWAIT_RES(0, 1), + }, + [C_STATE_C6_SHORT_LAT] = { + .latency = C_STATE_LATENCY_FROM_LAT_REG(0), + .power = C6_POWER, + .resource = MWAIT_RES(2, 0), + }, + [C_STATE_C6_LONG_LAT] = { + .latency = C_STATE_LATENCY_FROM_LAT_REG(0), + .power = C6_POWER, + .resource = MWAIT_RES(2, 1), + }, + [C_STATE_C7_SHORT_LAT] = { + .latency = C_STATE_LATENCY_FROM_LAT_REG(0), + .power = C7_POWER, + .resource = MWAIT_RES(3, 0), + }, + [C_STATE_C7_LONG_LAT] = { + .latency = C_STATE_LATENCY_FROM_LAT_REG(0), + .power = C7_POWER, + .resource = MWAIT_RES(3, 1), + }, + [C_STATE_C7S_SHORT_LAT] = { + .latency = C_STATE_LATENCY_FROM_LAT_REG(0), + .power = C7_POWER, + .resource = MWAIT_RES(3, 2), + }, + [C_STATE_C7S_LONG_LAT] = { + .latency = C_STATE_LATENCY_FROM_LAT_REG(0), + .power = C7_POWER, + .resource = MWAIT_RES(3, 3), + }, + [C_STATE_C8] = { + .latency = C_STATE_LATENCY_FROM_LAT_REG(0), + .power = C8_POWER, + .resource = MWAIT_RES(4, 0), + }, + [C_STATE_C9] = { + .latency = C_STATE_LATENCY_FROM_LAT_REG(0), + .power = C9_POWER, + .resource = MWAIT_RES(5, 0), + }, + [C_STATE_C10] = { + .latency = C_STATE_LATENCY_FROM_LAT_REG(0), + .power = C10_POWER, + .resource = MWAIT_RES(6, 0), + }, +}; + +static int cstate_set_s0ix[] = { + C_STATE_C1E, + C_STATE_C6_LONG_LAT, + C_STATE_C7S_LONG_LAT +}; + +static int cstate_set_non_s0ix[] = { + C_STATE_C1E, + C_STATE_C7S_LONG_LAT, + C_STATE_C10 +}; + +acpi_cstate_t *soc_get_cstate_map(size_t *entries) +{ + static acpi_cstate_t map[MAX(ARRAY_SIZE(cstate_set_s0ix), + ARRAY_SIZE(cstate_set_non_s0ix))]; + int *set; + int i; + device_t dev = SA_DEV_ROOT; + config_t *config = dev->chip_info; + int is_s0ix_enable = config->s0ix_enable; + + if (is_s0ix_enable) { + *entries = ARRAY_SIZE(cstate_set_s0ix); + set = cstate_set_s0ix; + } else { + *entries = ARRAY_SIZE(cstate_set_non_s0ix); + set = cstate_set_non_s0ix; + } + + for (i = 0; i < *entries; i++) { + memcpy(&map[i], &cstate_map[set[i]], sizeof(acpi_cstate_t)); + map[i].ctype = i + 1; + } + return map; +} + +void soc_power_states_generation(int core_id, int cores_per_package) +{ + device_t dev = SA_DEV_ROOT; + config_t *config = dev->chip_info; + if (config->eist_enable) + /* Generate P-state tables */ + generate_p_state_entries(core_id, cores_per_package); +} + void soc_fill_fadt(acpi_fadt_t *fadt) { const uint16_t pmbase = ACPI_BASE_ADDRESS; diff --git a/src/soc/intel/cannonlake/chip.c b/src/soc/intel/cannonlake/chip.c index 23e6fffbe8..2810ed11f5 100644 --- a/src/soc/intel/cannonlake/chip.c +++ b/src/soc/intel/cannonlake/chip.c @@ -154,6 +154,7 @@ static struct device_operations cpu_bus_ops = { .set_resources = DEVICE_NOOP, .enable_resources = DEVICE_NOOP, .init = DEVICE_NOOP, + .acpi_fill_ssdt_generator = generate_cpu_entries, }; static void soc_enable(device_t dev) diff --git a/src/soc/intel/cannonlake/include/soc/cpu.h b/src/soc/intel/cannonlake/include/soc/cpu.h index 866f7588d2..bd9db37848 100644 --- a/src/soc/intel/cannonlake/include/soc/cpu.h +++ b/src/soc/intel/cannonlake/include/soc/cpu.h @@ -19,6 +19,7 @@ #include #include +#include /* Supported CPUIDs */ #define CPUID_CANNONLAKE_A0 0x60660 @@ -35,7 +36,6 @@ /* Power in units of mW */ #define C1_POWER 0x3e8 -#define C3_POWER 0x1f4 #define C6_POWER 0x15e #define C7_POWER 0xc8 #define C8_POWER 0xc8 -- cgit v1.2.3