summaryrefslogtreecommitdiff
path: root/src/soc/intel/cannonlake
diff options
context:
space:
mode:
authorShaunak Saha <shaunak.saha@intel.com>2017-10-04 23:08:40 -0700
committerAaron Durbin <adurbin@chromium.org>2017-10-26 15:55:37 +0000
commit95b61752dbb56b9a7a2da439c5d21e30643661ef (patch)
treeb7856619ddeb70752c935f727a46f9779f8dae0d /src/soc/intel/cannonlake
parent66b5acc54bf75b186efea431dfac6eebce527403 (diff)
downloadcoreboot-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>
Diffstat (limited to 'src/soc/intel/cannonlake')
-rw-r--r--src/soc/intel/cannonlake/acpi.c134
-rw-r--r--src/soc/intel/cannonlake/chip.c1
-rw-r--r--src/soc/intel/cannonlake/include/soc/cpu.h2
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