diff options
author | Shaunak Saha <shaunak.saha@intel.com> | 2017-07-18 00:19:33 -0700 |
---|---|---|
committer | Aaron Durbin <adurbin@chromium.org> | 2017-09-08 19:01:04 +0000 |
commit | bd427803ab18576462c2c179c94ec0fec819221c (patch) | |
tree | a441902068336e7d83bd2ad94efc2153e00bd1a1 /src/soc/intel/apollolake | |
parent | af896d071b5d0c6ffabc1f4a5cda1429fb6754b6 (diff) |
soc/intel/common/block: Common ACPI
This patch adds the common acpi code.ACPI code is very similar
accross different intel chipsets.This patch is an effort to
move those code in common place so that it can be shared accross
different intel platforms instead of duplicating for each platform.
We are removing the common acpi files in src/soc/intel/common.
This removes the acpi.c file which was previously in
src/soc/common/acpi. The config for common acpi is
SOC_INTEL_COMMON_BLOCK_ACPI which can be defined in SOC's
Kconfig file in order to use the common ACPI code. This patch also
includes the changes in APL platform to use the common ACPI block.
TEST= Tested the patch as below:
1.Builds and system boots up with the patch.
2.Check all the ACPI tables are present in
/sys/firmware/acpi/tables
3.Check SCI's are properly working as we are
modifying the function to override madt.
4.Extract acpi tables like DSDT,APIC, FACP, FACS
and decompile the by iasl and compare with good
known tables.
5.Execute the extracted tables in aciexec to check
acpi methods are working properly.
Change-Id: Ib6eb6fd5366e6e28fd81bc22d050b0efa05a2e5d
Signed-off-by: Shaunak Saha <shaunak.saha@intel.com>
Reviewed-on: https://review.coreboot.org/20630
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-by: Sumeet R Pawnikar <sumeet.r.pawnikar@intel.com>
Diffstat (limited to 'src/soc/intel/apollolake')
-rw-r--r-- | src/soc/intel/apollolake/Kconfig | 2 | ||||
-rw-r--r-- | src/soc/intel/apollolake/acpi.c | 232 | ||||
-rw-r--r-- | src/soc/intel/apollolake/include/soc/acpi.h | 28 | ||||
-rw-r--r-- | src/soc/intel/apollolake/include/soc/pm.h | 17 |
4 files changed, 78 insertions, 201 deletions
diff --git a/src/soc/intel/apollolake/Kconfig b/src/soc/intel/apollolake/Kconfig index a3b458d489..29483f4985 100644 --- a/src/soc/intel/apollolake/Kconfig +++ b/src/soc/intel/apollolake/Kconfig @@ -59,9 +59,9 @@ config CPU_SPECIFIC_OPTIONS select SMM_TSEG select SA_ENABLE_IMR select SOC_INTEL_COMMON - select SOC_INTEL_COMMON_ACPI select SOC_INTEL_COMMON_ACPI_WAKE_SOURCE select SOC_INTEL_COMMON_BLOCK + select SOC_INTEL_COMMON_BLOCK_ACPI select SOC_INTEL_COMMON_BLOCK_CPU select SOC_INTEL_COMMON_BLOCK_FAST_SPI select SOC_INTEL_COMMON_BLOCK_GPIO diff --git a/src/soc/intel/apollolake/acpi.c b/src/soc/intel/apollolake/acpi.c index 1826b48458..e4846e4d05 100644 --- a/src/soc/intel/apollolake/acpi.c +++ b/src/soc/intel/apollolake/acpi.c @@ -17,20 +17,20 @@ #include <arch/acpi.h> #include <arch/acpigen.h> +#include <arch/io.h> #include <arch/ioapic.h> #include <arch/smp/mpspec.h> #include <cbmem.h> #include <cpu/x86/smm.h> #include <cpu/cpu.h> -#include <soc/acpi.h> -#include <soc/intel/common/acpi.h> +#include <gpio.h> +#include <intelblocks/acpi.h> +#include <intelblocks/pmclib.h> #include <soc/iomap.h> #include <soc/pm.h> #include <soc/nvs.h> #include <soc/pci_devs.h> #include <string.h> -#include <soc/gpio.h> -#include <gpio.h> #include "chip.h" #define CSTATE_RES(address_space, width, offset, address) \ @@ -41,116 +41,41 @@ .addrl = address, \ } -unsigned long acpi_fill_mcfg(unsigned long current) -{ - /* PCI Segment Group 0, Start Bus Number 0, End Bus Number is 255 */ - current += acpi_create_mcfg_mmconfig((void *) current, - CONFIG_MMCONF_BASE_ADDRESS, 0, 0, - 255); - return current; -} - -static int acpi_sci_irq(void) -{ - int sci_irq = 9; - return sci_irq; -} - -static unsigned long acpi_madt_irq_overrides(unsigned long current) -{ - int sci = acpi_sci_irq(); - uint16_t flags = MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_LOW; - - /* INT_SRC_OVR */ - current += acpi_create_madt_irqoverride((void *)current, 0, 0, 2, 0); - - /* SCI */ - current += acpi_create_madt_irqoverride((void *)current, 0, sci, sci, - flags); - - return current; -} - -unsigned long acpi_fill_madt(unsigned long current) -{ - /* Local APICs */ - current = acpi_create_madt_lapics(current); - - /* IOAPIC */ - current += acpi_create_madt_ioapic((void *) current, - 2, IO_APIC_ADDR, 0); - - return acpi_madt_irq_overrides(current); -} +static acpi_cstate_t cstate_map[] = { + { + /* C1 */ + .ctype = 1, /* ACPI C1 */ + .latency = 1, + .power = 1000, + .resource = CSTATE_RES(ACPI_ADDRESS_SPACE_FIXED, 0, 0, 0), + }, + { + .ctype = 2, /* ACPI C2 */ + .latency = 50, + .power = 10, + .resource = CSTATE_RES(ACPI_ADDRESS_SPACE_IO, 8, 0, 0x415), + }, + { + .ctype = 3, /* ACPI C3 */ + .latency = 150, + .power = 10, + .resource = CSTATE_RES(ACPI_ADDRESS_SPACE_IO, 8, 0, 0x419), + } +}; -void acpi_fill_fadt(acpi_fadt_t *fadt) +uint32_t soc_read_sci_irq_select(void) { - const uint16_t pmbase = ACPI_BASE_ADDRESS; - - /* Use ACPI 3.0 revision. */ - fadt->header.revision = ACPI_FADT_REV_ACPI_3_0; - - fadt->sci_int = acpi_sci_irq(); - fadt->smi_cmd = APM_CNT; - fadt->acpi_enable = APM_CNT_ACPI_ENABLE; - fadt->acpi_disable = APM_CNT_ACPI_DISABLE; - - fadt->pm1a_evt_blk = pmbase + PM1_STS; - fadt->pm1a_cnt_blk = pmbase + PM1_CNT; - fadt->pm_tmr_blk = pmbase + PM1_TMR; - fadt->gpe0_blk = pmbase + GPE0_STS(0); - - fadt->pm1_evt_len = 4; - fadt->pm1_cnt_len = 2; - fadt->pm_tmr_len = 4; - /* There are 4 GPE0 STS/EN pairs each 32 bits wide. */ - fadt->gpe0_blk_len = 2 * GPE0_REG_MAX * sizeof(uint32_t); - fadt->p_lvl2_lat = ACPI_FADT_C2_NOT_SUPPORTED; - fadt->p_lvl3_lat = ACPI_FADT_C3_NOT_SUPPORTED; - fadt->flush_size = 0x400; /* twice of cache size*/ - fadt->flush_stride = 0x10; /* Cache line width */ - fadt->duty_offset = 1; - fadt->duty_width = 3; - fadt->day_alrm = 0xd; - fadt->iapc_boot_arch = ACPI_FADT_LEGACY_DEVICES | ACPI_FADT_8042; - - fadt->flags = ACPI_FADT_WBINVD | ACPI_FADT_C1_SUPPORTED | - ACPI_FADT_C2_MP_SUPPORTED | ACPI_FADT_SLEEP_BUTTON | - ACPI_FADT_RESET_REGISTER | ACPI_FADT_SEALED_CASE | - ACPI_FADT_S4_RTC_WAKE | ACPI_FADT_PLATFORM_CLOCK; - - fadt->reset_reg.space_id = 1; - fadt->reset_reg.bit_width = 8; - fadt->reset_reg.addrl = 0xcf9; - fadt->reset_value = 6; - - fadt->x_pm1a_evt_blk.space_id = 1; - fadt->x_pm1a_evt_blk.bit_width = fadt->pm1_evt_len * 8; - fadt->x_pm1a_evt_blk.addrl = pmbase + PM1_STS; - - fadt->x_pm1b_evt_blk.space_id = 1; - - fadt->x_pm1a_cnt_blk.space_id = 1; - fadt->x_pm1a_cnt_blk.bit_width = fadt->pm1_cnt_len * 8; - fadt->x_pm1a_cnt_blk.addrl = pmbase + PM1_CNT; - - fadt->x_pm1b_cnt_blk.space_id = 1; - - fadt->x_pm_tmr_blk.space_id = 1; - fadt->x_pm_tmr_blk.bit_width = fadt->pm_tmr_len * 8; - fadt->x_pm_tmr_blk.addrl = pmbase + PM1_TMR; - - fadt->x_gpe1_blk.space_id = 1; + uintptr_t pmc_bar = soc_read_pmc_base(); + return read32((void *)pmc_bar + IRQ_REG); } -unsigned long southbridge_write_acpi_tables(device_t device, - unsigned long current, - struct acpi_rsdp *rsdp) +acpi_cstate_t *soc_get_cstate_map(size_t *entries) { - return acpi_write_hpet(device, current, rsdp); + *entries = ARRAY_SIZE(cstate_map); + return cstate_map; } -static void acpi_create_gnvs(struct global_nvs_t *gnvs) +void acpi_create_gnvs(struct global_nvs_t *gnvs) { struct soc_intel_apollolake_config *cfg; struct device *dev = SA_DEV_ROOT; @@ -159,7 +84,7 @@ static void acpi_create_gnvs(struct global_nvs_t *gnvs) memset(gnvs, 0, sizeof(*gnvs)); if (IS_ENABLED(CONFIG_CONSOLE_CBMEM)) - gnvs->cbmc = (uintptr_t)cbmem_find(CBMEM_ID_CONSOLE); + gnvs->cbmc = (uintptr_t) cbmem_find(CBMEM_ID_CONSOLE); if (IS_ENABLED(CONFIG_CHROMEOS)) { /* Initialize Verified Boot data */ @@ -184,7 +109,7 @@ static void acpi_create_gnvs(struct global_nvs_t *gnvs) /* Assign address of PERST_0 if GPIO is defined in devicetree */ if (cfg->prt0_gpio != GPIO_PRT0_UDEF) - gnvs->prt0 = (uintptr_t)gpio_dwx_address(cfg->prt0_gpio); + gnvs->prt0 = (uintptr_t) gpio_dwx_address(cfg->prt0_gpio); /* Get sdcard cd GPIO portid if GPIO is defined in devicetree. * Get offset of sdcard cd pin. @@ -195,87 +120,50 @@ static void acpi_create_gnvs(struct global_nvs_t *gnvs) } } -/* Save wake source information for calculating ACPI _SWS values */ -int soc_fill_acpi_wake(uint32_t *pm1, uint32_t **gpe0) +uint32_t acpi_fill_soc_wake(uint32_t generic_pm1_en, + const struct chipset_power_state *ps) { - struct chipset_power_state *ps; - static uint32_t gpe0_sts[GPE0_REG_MAX]; - uint32_t pm1_en; - int i; - - ps = cbmem_find(CBMEM_ID_POWER_STATE); - if (ps == NULL) - return -1; - /* - * PM1_EN to check the basic wake events which can happen through - * powerbtn or any other wake source like lidopen, key board press etc. * WAK_STS bit is set when the system is in one of the sleep states * (via the SLP_EN bit) and an enabled wake event occurs. Upon setting * this bit, the PMC will transition the system to the ON state and * can only be set by hardware and can only be cleared by writing a one * to this bit position. */ - pm1_en = ps->pm1_en | WAK_STS | RTC_EN | PWRBTN_EN; - *pm1 = ps->pm1_sts & pm1_en; - /* Mask off GPE0 status bits that are not enabled */ - *gpe0 = &gpe0_sts[0]; - for (i = 0; i < GPE0_REG_MAX; i++) - gpe0_sts[i] = ps->gpe0_sts[i] & ps->gpe0_en[i]; + generic_pm1_en |= WAK_STS | RTC_EN | PWRBTN_EN; + return generic_pm1_en; +} - return GPE0_REG_MAX; +int soc_madt_sci_irq_polarity(int sci) +{ + return MP_IRQ_POLARITY_LOW; } -void southbridge_inject_dsdt(device_t device) +void soc_fill_fadt(acpi_fadt_t *fadt) { - struct global_nvs_t *gnvs; + fadt->pm_tmr_blk = ACPI_BASE_ADDRESS + PM1_TMR; - gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS); + fadt->p_lvl2_lat = ACPI_FADT_C2_NOT_SUPPORTED; + fadt->p_lvl3_lat = ACPI_FADT_C3_NOT_SUPPORTED; - if (gnvs) { - acpi_create_gnvs(gnvs); - acpi_save_gnvs((uintptr_t)gnvs); - /* And tell SMI about it */ - smm_setup_structures(gnvs, NULL, NULL); + fadt->pm_tmr_len = 4; + fadt->duty_width = 3; - /* Add it to DSDT. */ - acpigen_write_scope("\\"); - acpigen_write_name_dword("NVSA", (uintptr_t)gnvs); - acpigen_pop_len(); - } -} -static acpi_cstate_t cstate_map[] = { - { - /* C1 */ - .ctype = 1, /* ACPI C1 */ - .latency = 1, - .power = 1000, - .resource = CSTATE_RES(ACPI_ADDRESS_SPACE_FIXED, 0, 0, 0), - }, - { - .ctype = 2, /* ACPI C2 */ - .latency = 50, - .power = 10, - .resource = CSTATE_RES(ACPI_ADDRESS_SPACE_IO, 8, 0, 0x415), - }, - { - .ctype = 3, /* ACPI C3 */ - .latency = 150, - .power = 10, - .resource = CSTATE_RES(ACPI_ADDRESS_SPACE_IO, 8, 0, 0x419), - } -}; + fadt->iapc_boot_arch = ACPI_FADT_LEGACY_DEVICES | ACPI_FADT_8042; -acpi_cstate_t *soc_get_cstate_map(int *entries) -{ - *entries = ARRAY_SIZE(cstate_map); - return cstate_map; + fadt->x_pm_tmr_blk.space_id = 1; + fadt->x_pm_tmr_blk.bit_width = fadt->pm_tmr_len * 8; + fadt->x_pm_tmr_blk.addrl = ACPI_BASE_ADDRESS + PM1_TMR; } -uint16_t soc_get_acpi_base_address(void) +void soc_power_states_generation(int core_id, int cores_per_package) { - return ACPI_BASE_ADDRESS; + /* Generate P-state tables */ + generate_p_state_entries(core_id, cores_per_package); + + /* Generate T-state tables */ + generate_t_state_entries(core_id, cores_per_package); } static void acpigen_soc_get_dw0_in_local5(uintptr_t addr) @@ -294,7 +182,7 @@ static void acpigen_soc_get_dw0_in_local5(uintptr_t addr) static int acpigen_soc_get_gpio_val(unsigned int gpio_num, uint32_t mask) { assert(gpio_num < TOTAL_PADS); - uintptr_t addr = (uintptr_t)gpio_dwx_address(gpio_num); + uintptr_t addr = (uintptr_t) gpio_dwx_address(gpio_num); acpigen_soc_get_dw0_in_local5(addr); @@ -320,7 +208,7 @@ static int acpigen_soc_get_gpio_val(unsigned int gpio_num, uint32_t mask) static int acpigen_soc_set_gpio_val(unsigned int gpio_num, uint32_t val) { assert(gpio_num < TOTAL_PADS); - uintptr_t addr = (uintptr_t)gpio_dwx_address(gpio_num); + uintptr_t addr = (uintptr_t) gpio_dwx_address(gpio_num); acpigen_soc_get_dw0_in_local5(addr); diff --git a/src/soc/intel/apollolake/include/soc/acpi.h b/src/soc/intel/apollolake/include/soc/acpi.h deleted file mode 100644 index ba3b8fc9b5..0000000000 --- a/src/soc/intel/apollolake/include/soc/acpi.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2016 Intel Corp. - * (Written by Lance Zhao <lijian.zhao@intel.com> for Intel Corp.) - * - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -#ifndef _SOC_APOLLOLAKE_ACPI_H_ -#define _SOC_APOLLOLAKE_ACPI_H_ - -#include <arch/acpi.h> - -unsigned long southbridge_write_acpi_tables(device_t device, - unsigned long current, struct acpi_rsdp *rsdp); - -void southbridge_inject_dsdt(device_t device); - -#endif /* _SOC_APOLLOLAKE_ACPI_H_ */ diff --git a/src/soc/intel/apollolake/include/soc/pm.h b/src/soc/intel/apollolake/include/soc/pm.h index 3be39554ed..37e4cedc3e 100644 --- a/src/soc/intel/apollolake/include/soc/pm.h +++ b/src/soc/intel/apollolake/include/soc/pm.h @@ -202,6 +202,23 @@ #define PMC_GPE_W_31_0 9 #endif +#define IRQ_REG 0x106C +#define SCI_IRQ_ADJUST 24 +#define SCI_IRQ_SEL (255 << SCI_IRQ_ADJUST) +#define SCIS_IRQ9 9 +#define SCIS_IRQ10 10 +#define SCIS_IRQ11 11 +#define SCIS_IRQ20 20 +#define SCIS_IRQ21 21 +#define SCIS_IRQ22 22 +#define SCIS_IRQ23 23 + +/* P-state configuration */ +#define PSS_MAX_ENTRIES 8 +#define PSS_RATIO_STEP 2 +#define PSS_LATENCY_TRANSITION 10 +#define PSS_LATENCY_BUSMASTER 10 + /* Track power state from reset to log events. */ struct chipset_power_state { uint16_t pm1_sts; |