diff options
author | Lee Leahy <leroy.p.leahy@intel.com> | 2015-05-12 18:23:27 -0700 |
---|---|---|
committer | Leroy P Leahy <leroy.p.leahy@intel.com> | 2015-07-16 17:24:48 +0200 |
commit | 1d14b3e926c15027f9272f1e80b8913fef8cf25d (patch) | |
tree | b3d89ad4bb1b0ea5ac05d1d7dc6cbf26ec93e6c3 /src/soc/intel/skylake/acpi.c | |
parent | b000513741d330947bb832a5835378e35bdfb394 (diff) |
soc/intel: Add Skylake SOC support
Add the files to support the Skylake SOC.
Matches chromium tree at 927026db
BRANCH=none
BUG=None
TEST=Build and run on a Skylake platform
Change-Id: I80248f7e47eaf13b52e3c7ff951eb1976edbaa15
Signed-off-by: Lee Leahy <leroy.p.leahy@intel.com>
Reviewed-on: http://review.coreboot.org/10341
Tested-by: build bot (Jenkins)
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Diffstat (limited to 'src/soc/intel/skylake/acpi.c')
-rw-r--r-- | src/soc/intel/skylake/acpi.c | 337 |
1 files changed, 162 insertions, 175 deletions
diff --git a/src/soc/intel/skylake/acpi.c b/src/soc/intel/skylake/acpi.c index f038e87e5a..1b193c7308 100644 --- a/src/soc/intel/skylake/acpi.c +++ b/src/soc/intel/skylake/acpi.c @@ -3,6 +3,7 @@ * * Copyright (C) 2009 coresystems GmbH * Copyright (C) 2014 Google Inc. + * Copyright (C) 2015 Intel Corporation. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -15,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc. */ #include <arch/acpi.h> @@ -23,9 +24,10 @@ #include <arch/io.h> #include <arch/smp/mpspec.h> #include <cbmem.h> +#include <chip.h> #include <console/console.h> +#include <cpu/cpu.h> #include <cpu/x86/smm.h> -#include <console/console.h> #include <types.h> #include <string.h> #include <arch/cpu.h> @@ -41,36 +43,33 @@ #include <soc/msr.h> #include <soc/pci_devs.h> #include <soc/pm.h> -#include <soc/intel/broadwell/chip.h> /* - * List of supported C-states in this processor. Only the ULT parts support C8, - * C9, and C10. + * List of suported C-states in this processor. */ enum { - C_STATE_C0, /* 0 */ - C_STATE_C1, /* 1 */ - C_STATE_C1E, /* 2 */ - C_STATE_C3, /* 3 */ - C_STATE_C6_SHORT_LAT, /* 4 */ - C_STATE_C6_LONG_LAT, /* 5 */ - C_STATE_C7_SHORT_LAT, /* 6 */ - C_STATE_C7_LONG_LAT, /* 7 */ - C_STATE_C7S_SHORT_LAT, /* 8 */ - C_STATE_C7S_LONG_LAT, /* 9 */ - C_STATE_C8, /* 10 */ - C_STATE_C9, /* 11 */ - C_STATE_C10, /* 12 */ + C_STATE_C0, /* 0 */ + C_STATE_C1, /* 1 */ + C_STATE_C1E, /* 2 */ + C_STATE_C3, /* 3 */ + C_STATE_C6_SHORT_LAT, /* 4 */ + C_STATE_C6_LONG_LAT, /* 5 */ + C_STATE_C7_SHORT_LAT, /* 6 */ + C_STATE_C7_LONG_LAT, /* 7 */ + C_STATE_C7S_SHORT_LAT, /* 8 */ + C_STATE_C7S_LONG_LAT, /* 9 */ + C_STATE_C8, /* 10 */ + C_STATE_C9, /* 11 */ + C_STATE_C10, /* 12 */ 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, \ +#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 acpi_cstate_t cstate_map[NUM_C_STATES] = { @@ -78,75 +77,78 @@ static acpi_cstate_t cstate_map[NUM_C_STATES] = { [C_STATE_C1] = { .latency = 0, .power = 1000, - .resource = MWAIT_RES(0,0), + .resource = MWAIT_RES(0, 0), }, [C_STATE_C1E] = { .latency = 0, .power = 1000, - .resource = MWAIT_RES(0,1), + .resource = MWAIT_RES(0, 1), }, [C_STATE_C3] = { .latency = C_STATE_LATENCY_FROM_LAT_REG(0), - .power = 900, + .power = 500, .resource = MWAIT_RES(1, 0), }, [C_STATE_C6_SHORT_LAT] = { .latency = C_STATE_LATENCY_FROM_LAT_REG(1), - .power = 800, + .power = 350, .resource = MWAIT_RES(2, 0), }, [C_STATE_C6_LONG_LAT] = { .latency = C_STATE_LATENCY_FROM_LAT_REG(2), - .power = 800, + .power = 350, .resource = MWAIT_RES(2, 1), }, [C_STATE_C7_SHORT_LAT] = { .latency = C_STATE_LATENCY_FROM_LAT_REG(1), - .power = 700, + .power = 200, .resource = MWAIT_RES(3, 0), }, [C_STATE_C7_LONG_LAT] = { .latency = C_STATE_LATENCY_FROM_LAT_REG(2), - .power = 700, + .power = 200, .resource = MWAIT_RES(3, 1), }, [C_STATE_C7S_SHORT_LAT] = { .latency = C_STATE_LATENCY_FROM_LAT_REG(1), - .power = 700, + .power = 200, .resource = MWAIT_RES(3, 2), }, [C_STATE_C7S_LONG_LAT] = { .latency = C_STATE_LATENCY_FROM_LAT_REG(2), - .power = 700, + .power = 200, .resource = MWAIT_RES(3, 3), }, [C_STATE_C8] = { .latency = C_STATE_LATENCY_FROM_LAT_REG(3), - .power = 600, + .power = 200, .resource = MWAIT_RES(4, 0), }, [C_STATE_C9] = { .latency = C_STATE_LATENCY_FROM_LAT_REG(4), - .power = 500, + .power = 200, .resource = MWAIT_RES(5, 0), }, [C_STATE_C10] = { .latency = C_STATE_LATENCY_FROM_LAT_REG(5), - .power = 400, + .power = 200, .resource = MWAIT_RES(6, 0), }, }; -static int cstate_set_s0ix[3] = { +static int cstate_set_s0ix[] = { C_STATE_C1E, C_STATE_C7S_LONG_LAT, C_STATE_C10 }; -static int cstate_set_non_s0ix[3] = { +static int cstate_set_non_s0ix[] = { C_STATE_C1E, C_STATE_C3, - C_STATE_C7S_LONG_LAT + C_STATE_C7S_LONG_LAT, + C_STATE_C8, + C_STATE_C9, + C_STATE_C10 }; static int get_cores_per_package(void) @@ -173,15 +175,15 @@ void acpi_init_gnvs(global_nvs_t *gnvs) /* CPU core count */ gnvs->pcnt = dev_count_cpu(); -#if CONFIG_CONSOLE_CBMEM +#if IS_ENABLED(CONFIG_CONSOLE_CBMEM) /* Update the mem console pointer. */ gnvs->cbmc = (u32)cbmem_find(CBMEM_ID_CONSOLE); #endif -#if CONFIG_CHROMEOS +#if IS_ENABLED(CONFIG_CHROMEOS) /* Initialize Verified Boot data */ chromeos_init_vboot(&(gnvs->chromeos)); -#if CONFIG_EC_GOOGLE_CHROMEEC +#if IS_ENABLED(CONFIG_EC_GOOGLE_CHROMEEC) gnvs->chromeos.vbt2 = google_ec_running_ro() ? ACTIVE_ECFW_RO : ACTIVE_ECFW_RW; #endif @@ -189,37 +191,6 @@ void acpi_init_gnvs(global_nvs_t *gnvs) #endif } -void acpi_create_intel_hpet(acpi_hpet_t * hpet) -{ - acpi_header_t *header = &(hpet->header); - acpi_addr_t *addr = &(hpet->addr); - - memset((void *) hpet, 0, sizeof(acpi_hpet_t)); - - /* fill out header fields */ - memcpy(header->signature, "HPET", 4); - memcpy(header->oem_id, OEM_ID, 6); - memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8); - memcpy(header->asl_compiler_id, ASLC, 4); - - header->length = sizeof(acpi_hpet_t); - header->revision = 1; - - /* fill out HPET address */ - addr->space_id = 0; /* Memory */ - addr->bit_width = 64; - addr->bit_offset = 0; - addr->addrl = (unsigned long long)HPET_BASE_ADDRESS & 0xffffffff; - addr->addrh = (unsigned long long)HPET_BASE_ADDRESS >> 32; - - hpet->id = 0x8086a201; /* Intel */ - hpet->number = 0x00; - hpet->min_tick = 0x0080; - - header->checksum = - acpi_checksum((void *) hpet, sizeof(acpi_hpet_t)); -} - unsigned long acpi_fill_mcfg(unsigned long current) { current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *)current, @@ -336,82 +307,25 @@ void acpi_fill_in_fadt(acpi_fadt_t *fadt) fadt->x_gpe1_blk.addrh = 0x0; } -static acpi_tstate_t tss_table_fine[] = { - { 100, 1000, 0, 0x00, 0 }, - { 94, 940, 0, 0x1f, 0 }, - { 88, 880, 0, 0x1e, 0 }, - { 82, 820, 0, 0x1d, 0 }, - { 75, 760, 0, 0x1c, 0 }, - { 69, 700, 0, 0x1b, 0 }, - { 63, 640, 0, 0x1a, 0 }, - { 57, 580, 0, 0x19, 0 }, - { 50, 520, 0, 0x18, 0 }, - { 44, 460, 0, 0x17, 0 }, - { 38, 400, 0, 0x16, 0 }, - { 32, 340, 0, 0x15, 0 }, - { 25, 280, 0, 0x14, 0 }, - { 19, 220, 0, 0x13, 0 }, - { 13, 160, 0, 0x12, 0 }, -}; - -static acpi_tstate_t tss_table_coarse[] = { - { 100, 1000, 0, 0x00, 0 }, - { 88, 875, 0, 0x1f, 0 }, - { 75, 750, 0, 0x1e, 0 }, - { 63, 625, 0, 0x1d, 0 }, - { 50, 500, 0, 0x1c, 0 }, - { 38, 375, 0, 0x1b, 0 }, - { 25, 250, 0, 0x1a, 0 }, - { 13, 125, 0, 0x19, 0 }, -}; - -static int generate_T_state_entries(int core, int cores_per_package) +static void generate_c_state_entries(int s0ix_enable, int max_cstate) { - int len; - - /* Indicate SW_ALL coordination for T-states */ - len = acpigen_write_TSD_package(core, cores_per_package, SW_ALL); - - /* Indicate FFixedHW so OS will use MSR */ - len += acpigen_write_empty_PTC(); - - /* Set a T-state limit that can be modified in NVS */ - len += acpigen_write_TPC("\\TLVL"); - - /* - * CPUID.(EAX=6):EAX[5] indicates support - * for extended throttle levels. - */ - if (cpuid_eax(6) & (1 << 5)) - len += acpigen_write_TSS_package( - ARRAY_SIZE(tss_table_fine), tss_table_fine); - else - len += acpigen_write_TSS_package( - ARRAY_SIZE(tss_table_coarse), tss_table_coarse); - - return len; -} -static int generate_C_state_entries(void) -{ - device_t dev = SA_DEV_ROOT; - config_t *config = dev->chip_info; - acpi_cstate_t map[3]; + acpi_cstate_t map[max_cstate]; int *set; int i; - if (config->s0ix_enable) + if (s0ix_enable) set = cstate_set_s0ix; else set = cstate_set_non_s0ix; - for (i = 0; i < 3; i++) { + for (i = 0; i < max_cstate; i++) { memcpy(&map[i], &cstate_map[set[i]], sizeof(acpi_cstate_t)); map[i].ctype = i + 1; } /* Generate C-state tables */ - return acpigen_write_CST_package(map, ARRAY_SIZE(map)); + acpigen_write_CST_package(map, ARRAY_SIZE(map)); } static int calculate_power(int tdp, int p1_ratio, int ratio) @@ -435,7 +349,7 @@ static int calculate_power(int tdp, int p1_ratio, int ratio) return (int)power; } -static void generate_P_state_entries(int core, int cores_per_package) +static void generate_p_state_entries(int core, int cores_per_package) { int ratio_min, ratio_max, ratio_turbo, ratio_step; int coord_type, power_max, power_unit, num_entries; @@ -484,10 +398,10 @@ static void generate_P_state_entries(int core, int cores_per_package) /* Determine ratio points */ ratio_step = PSS_RATIO_STEP; - num_entries = (ratio_max - ratio_min) / ratio_step; - while (num_entries > PSS_MAX_ENTRIES-1) { - ratio_step <<= 1; - num_entries >>= 1; + num_entries = ((ratio_max - ratio_min) / ratio_step) + 1; + if (num_entries > PSS_MAX_ENTRIES) { + ratio_step += 1; + num_entries = ((ratio_max - ratio_min) / ratio_step) + 1; } /* P[T] is Turbo state if enabled */ @@ -500,12 +414,12 @@ static void generate_P_state_entries(int core, int cores_per_package) /* Add entry for Turbo ratio */ acpigen_write_PSS_package( - clock_max + 1, /*MHz*/ - power_max, /*mW*/ - PSS_LATENCY_TRANSITION, /*lat1*/ - PSS_LATENCY_BUSMASTER, /*lat2*/ - ratio_turbo << 8, /*control*/ - ratio_turbo << 8); /*status*/ + clock_max + 1, /* MHz */ + power_max, /* mW */ + PSS_LATENCY_TRANSITION, /* lat1 */ + PSS_LATENCY_BUSMASTER, /* lat2 */ + ratio_turbo << 8, /* control */ + ratio_turbo << 8); /* status */ } else { /* _PSS package count without Turbo */ acpigen_write_package(num_entries + 1); @@ -513,12 +427,12 @@ static void generate_P_state_entries(int core, int cores_per_package) /* First regular entry is max non-turbo ratio */ acpigen_write_PSS_package( - clock_max, /*MHz*/ - power_max, /*mW*/ - PSS_LATENCY_TRANSITION, /*lat1*/ - PSS_LATENCY_BUSMASTER, /*lat2*/ - ratio_max << 8, /*control*/ - ratio_max << 8); /*status*/ + clock_max, /* MHz */ + power_max, /* mW */ + PSS_LATENCY_TRANSITION, /* lat1 */ + PSS_LATENCY_BUSMASTER, /* lat2 */ + ratio_max << 8, /* control */ + ratio_max << 8); /* status */ /* Generate the remaining entries */ for (ratio = ratio_min + ((num_entries - 1) * ratio_step); @@ -529,50 +443,55 @@ static void generate_P_state_entries(int core, int cores_per_package) clock = ratio * CPU_BCLK; acpigen_write_PSS_package( - clock, /*MHz*/ - power, /*mW*/ - PSS_LATENCY_TRANSITION, /*lat1*/ - PSS_LATENCY_BUSMASTER, /*lat2*/ - ratio << 8, /*control*/ - ratio << 8); /*status*/ + clock, /* MHz */ + power, /* mW */ + PSS_LATENCY_TRANSITION, /* lat1 */ + PSS_LATENCY_BUSMASTER, /* lat2 */ + ratio << 8, /* control */ + ratio << 8); /* status */ } /* Fix package length */ acpigen_pop_len(); } -void generate_cpu_entries(void) +void generate_cpu_entries(device_t device) { - int coreID, cpuID, pcontrol_blk = ACPI_BASE_ADDRESS, plen = 6; + int core_id, cpu_id, pcontrol_blk = ACPI_BASE_ADDRESS, plen = 6; int totalcores = dev_count_cpu(); int cores_per_package = get_cores_per_package(); int numcpus = totalcores/cores_per_package; + device_t dev = SA_DEV_ROOT; + config_t *config = dev->chip_info; + int is_s0ix_enable = config->s0ix_enable; + int max_c_state; + + if (is_s0ix_enable) + max_c_state = ARRAY_SIZE(cstate_set_s0ix); + else + max_c_state = ARRAY_SIZE(cstate_set_non_s0ix); printk(BIOS_DEBUG, "Found %d CPU(s) with %d core(s) each.\n", numcpus, cores_per_package); - for (cpuID=1; cpuID <=numcpus; cpuID++) { - for (coreID=1; coreID<=cores_per_package; coreID++) { - if (coreID>1) { + for (cpu_id = 0; cpu_id < numcpus; cpu_id++) { + for (core_id = 0; core_id < cores_per_package; core_id++) { + if (core_id > 0) { pcontrol_blk = 0; plen = 0; } /* Generate processor \_PR.CPUx */ acpigen_write_processor( - (cpuID-1)*cores_per_package+coreID-1, + cpu_id*cores_per_package+core_id, pcontrol_blk, plen); - - /* Generate P-state tables */ - generate_P_state_entries( - coreID-1, cores_per_package); - /* Generate C-state tables */ - generate_C_state_entries(); + generate_c_state_entries(is_s0ix_enable, + max_c_state); - /* Generate T-state tables */ - generate_T_state_entries( - cpuID-1, cores_per_package); + /* Generate P-state tables */ + generate_p_state_entries(core_id, + cores_per_package); acpigen_pop_len(); } @@ -600,3 +519,71 @@ unsigned long acpi_madt_irq_overrides(unsigned long current) return current; } + +#define ALIGN_CURRENT current = (ALIGN(current, 16)) + +unsigned long southcluster_write_acpi_tables(device_t device, + unsigned long current, + struct acpi_rsdp *rsdp) +{ + acpi_header_t *ssdt2; + + current = acpi_write_hpet(device, current, rsdp); + ALIGN_CURRENT; + +#if CONFIG_GOP_SUPPORT + igd_opregion_t *opregion; + + printk(BIOS_DEBUG, "ACPI: * IGD OpRegion\n"); + opregion = (igd_opregion_t *)current; + init_igd_opregion(opregion); + current += sizeof(igd_opregion_t); + ALIGN_CURRENT; +#endif + + ssdt2 = (acpi_header_t *)current; + memset(ssdt2, 0, sizeof(acpi_header_t)); + acpi_create_serialio_ssdt(ssdt2); + if (ssdt2->length) { + current += ssdt2->length; + acpi_add_table(rsdp, ssdt2); + printk(BIOS_DEBUG, "ACPI: * SSDT2 @ %p Length %x\n",ssdt2, + ssdt2->length); + ALIGN_CURRENT; + } else { + ssdt2 = NULL; + printk(BIOS_DEBUG, "ACPI: * SSDT2 not generated.\n"); + } + + printk(BIOS_DEBUG, "current = %lx\n", current); + + return current; +} + +void southcluster_inject_dsdt(device_t device) +{ + global_nvs_t *gnvs; + + gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS); + if (!gnvs) { + gnvs = cbmem_add(CBMEM_ID_ACPI_GNVS, sizeof (*gnvs)); + if (gnvs) + memset(gnvs, 0, sizeof(*gnvs)); + } + + if (gnvs) { + acpi_create_gnvs(gnvs); + acpi_save_gnvs((unsigned long)gnvs); + /* And tell SMI about it */ + smm_setup_structures(gnvs, NULL, NULL); + + /* Add it to DSDT. */ + acpigen_write_scope("\\"); + acpigen_write_name_dword("NVSA", (u32) gnvs); + acpigen_pop_len(); + } +} + +__attribute__((weak)) void acpi_create_serialio_ssdt(acpi_header_t *ssdt) +{ +} |