diff options
author | Shaunak Saha <shaunak.saha@intel.com> | 2017-10-04 23:08:40 -0700 |
---|---|---|
committer | Aaron Durbin <adurbin@chromium.org> | 2017-10-26 15:55:37 +0000 |
commit | 95b61752dbb56b9a7a2da439c5d21e30643661ef (patch) | |
tree | b7856619ddeb70752c935f727a46f9779f8dae0d | |
parent | 66b5acc54bf75b186efea431dfac6eebce527403 (diff) | |
download | coreboot-95b61752dbb56b9a7a2da439c5d21e30643661ef.tar.xz |
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 <shaunak.saha@intel.com>
Reviewed-on: https://review.coreboot.org/21891
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
-rw-r--r-- | src/soc/intel/cannonlake/acpi.c | 134 | ||||
-rw-r--r-- | src/soc/intel/cannonlake/chip.c | 1 | ||||
-rw-r--r-- | src/soc/intel/cannonlake/include/soc/cpu.h | 2 |
3 files changed, 136 insertions, 1 deletions
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 <soc/nvs.h> #include <soc/pci_devs.h> #include <soc/pm.h> +#include <string.h> #include <vendorcode/google/chromeos/gnvs.h> #include <wrdd.h> +/* + * 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 <arch/cpu.h> #include <device/device.h> +#include <intelblocks/msr.h> /* 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 |