diff options
-rw-r--r-- | src/soc/intel/skylake/acpi.c | 22 | ||||
-rw-r--r-- | src/soc/intel/skylake/chip.h | 1 | ||||
-rw-r--r-- | src/soc/intel/skylake/finalize.c | 17 |
3 files changed, 32 insertions, 8 deletions
diff --git a/src/soc/intel/skylake/acpi.c b/src/soc/intel/skylake/acpi.c index c01066f7fb..678e0a9f3f 100644 --- a/src/soc/intel/skylake/acpi.c +++ b/src/soc/intel/skylake/acpi.c @@ -217,6 +217,8 @@ unsigned long acpi_fill_madt(unsigned long current) void acpi_fill_in_fadt(acpi_fadt_t *fadt) { const uint16_t pmbase = ACPI_BASE_ADDRESS; + const struct device *dev = dev_find_slot(0, PCH_DEVFN_LPC); + config_t *config = dev->chip_info; fadt->sci_int = acpi_sci_irq(); fadt->smi_cmd = APM_CNT; @@ -230,14 +232,16 @@ void acpi_fill_in_fadt(acpi_fadt_t *fadt) fadt->pm1a_cnt_blk = pmbase + PM1_CNT; fadt->pm1b_cnt_blk = 0x0; fadt->pm2_cnt_blk = pmbase + PM2_CNT; - fadt->pm_tmr_blk = pmbase + PM1_TMR; + if (config->PmTimerDisabled == 0) + fadt->pm_tmr_blk = pmbase + PM1_TMR; fadt->gpe0_blk = pmbase + GPE0_STS(0); fadt->gpe1_blk = 0; fadt->pm1_evt_len = 4; fadt->pm1_cnt_len = 2; fadt->pm2_cnt_len = 1; - fadt->pm_tmr_len = 4; + if (config->PmTimerDisabled == 0) + 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->gpe1_blk_len = 0; @@ -302,12 +306,14 @@ void acpi_fill_in_fadt(acpi_fadt_t *fadt) fadt->x_pm2_cnt_blk.addrl = pmbase + PM2_CNT; fadt->x_pm2_cnt_blk.addrh = 0x0; - 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.bit_offset = 0; - fadt->x_pm_tmr_blk.resv = 0; - fadt->x_pm_tmr_blk.addrl = pmbase + PM1_TMR; - fadt->x_pm_tmr_blk.addrh = 0x0; + if (config->PmTimerDisabled == 0) { + 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.bit_offset = 0; + fadt->x_pm_tmr_blk.resv = 0; + fadt->x_pm_tmr_blk.addrl = pmbase + PM1_TMR; + fadt->x_pm_tmr_blk.addrh = 0x0; + } fadt->x_gpe0_blk.space_id = 0; fadt->x_gpe0_blk.bit_width = 0; diff --git a/src/soc/intel/skylake/chip.h b/src/soc/intel/skylake/chip.h index 0390edaaea..0b87f2d08e 100644 --- a/src/soc/intel/skylake/chip.h +++ b/src/soc/intel/skylake/chip.h @@ -325,6 +325,7 @@ struct soc_intel_skylake_config { u8 HeciEnabled; /* PL2 Override value in Watts */ u32 tdp_pl2_override; + u8 PmTimerDisabled; }; typedef struct soc_intel_skylake_config config_t; diff --git a/src/soc/intel/skylake/finalize.c b/src/soc/intel/skylake/finalize.c index 13df7ccdaf..5eef66dbbb 100644 --- a/src/soc/intel/skylake/finalize.c +++ b/src/soc/intel/skylake/finalize.c @@ -38,6 +38,7 @@ #define PCH_P2SB_EPMASK(mask_number) PCH_P2SB_EPMASK0 + (mask_number * 4) #define PCH_P2SB_E0 0xE0 +#define PCH_PWRM_ACPI_TMR_CTL 0xFC static void pch_configure_endpoints(device_t dev, int epmask_id, uint32_t mask) { @@ -92,6 +93,7 @@ static void pch_finalize_script(void) uint8_t *pmcbase; config_t *config; u32 pmsyncreg; + u8 reg8; /* Set SPI opcode menu */ write16(spibar + SPIBAR_PREOP, SPI_OPPREFIX); @@ -126,6 +128,21 @@ static void pch_finalize_script(void) /* we should disable Heci1 based on the devicetree policy */ config = dev->chip_info; + + /* + * Disable ACPI PM timer based on dt policy + * + * Disabling ACPI PM timer is necessary for XTAL OSC shutdown. + * Disabling ACPI PM timer also switches off TCO + */ + + if (config->PmTimerDisabled) { + reg8 = read8(pmcbase + PCH_PWRM_ACPI_TMR_CTL); + reg8 |= (1 << 1); + write8(pmcbase + PCH_PWRM_ACPI_TMR_CTL, reg8); + } + + /* we should disable Heci1 based on the devicetree policy */ if (config->HeciEnabled == 0) pch_disable_heci(); } |