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>
This commit is contained in:
committed by
Aaron Durbin
parent
af896d071b
commit
bd427803ab
@@ -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)
|
||||
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),
|
||||
}
|
||||
};
|
||||
|
||||
uint32_t soc_read_sci_irq_select(void)
|
||||
{
|
||||
/* 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;
|
||||
uintptr_t pmc_bar = soc_read_pmc_base();
|
||||
return read32((void *)pmc_bar + IRQ_REG);
|
||||
}
|
||||
|
||||
static int acpi_sci_irq(void)
|
||||
acpi_cstate_t *soc_get_cstate_map(size_t *entries)
|
||||
{
|
||||
int sci_irq = 9;
|
||||
return sci_irq;
|
||||
*entries = ARRAY_SIZE(cstate_map);
|
||||
return cstate_map;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void acpi_fill_fadt(acpi_fadt_t *fadt)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
unsigned long southbridge_write_acpi_tables(device_t device,
|
||||
unsigned long current,
|
||||
struct acpi_rsdp *rsdp)
|
||||
{
|
||||
return acpi_write_hpet(device, current, rsdp);
|
||||
}
|
||||
|
||||
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];
|
||||
|
||||
return GPE0_REG_MAX;
|
||||
generic_pm1_en |= WAK_STS | RTC_EN | PWRBTN_EN;
|
||||
return generic_pm1_en;
|
||||
}
|
||||
|
||||
void southbridge_inject_dsdt(device_t device)
|
||||
int soc_madt_sci_irq_polarity(int sci)
|
||||
{
|
||||
struct global_nvs_t *gnvs;
|
||||
|
||||
gnvs = cbmem_find(CBMEM_ID_ACPI_GNVS);
|
||||
|
||||
if (gnvs) {
|
||||
acpi_create_gnvs(gnvs);
|
||||
acpi_save_gnvs((uintptr_t)gnvs);
|
||||
/* And tell SMI about it */
|
||||
smm_setup_structures(gnvs, NULL, NULL);
|
||||
|
||||
/* 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),
|
||||
}
|
||||
};
|
||||
|
||||
acpi_cstate_t *soc_get_cstate_map(int *entries)
|
||||
{
|
||||
*entries = ARRAY_SIZE(cstate_map);
|
||||
return cstate_map;
|
||||
return MP_IRQ_POLARITY_LOW;
|
||||
}
|
||||
|
||||
uint16_t soc_get_acpi_base_address(void)
|
||||
void soc_fill_fadt(acpi_fadt_t *fadt)
|
||||
{
|
||||
return ACPI_BASE_ADDRESS;
|
||||
fadt->pm_tmr_blk = ACPI_BASE_ADDRESS + PM1_TMR;
|
||||
|
||||
fadt->p_lvl2_lat = ACPI_FADT_C2_NOT_SUPPORTED;
|
||||
fadt->p_lvl3_lat = ACPI_FADT_C3_NOT_SUPPORTED;
|
||||
|
||||
fadt->pm_tmr_len = 4;
|
||||
fadt->duty_width = 3;
|
||||
|
||||
fadt->iapc_boot_arch = ACPI_FADT_LEGACY_DEVICES | ACPI_FADT_8042;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void soc_power_states_generation(int core_id, int cores_per_package)
|
||||
{
|
||||
/* 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);
|
||||
|
||||
|
Reference in New Issue
Block a user