summaryrefslogtreecommitdiff
path: root/src/soc/intel/skylake
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/intel/skylake')
-rw-r--r--src/soc/intel/skylake/acpi.c22
-rw-r--r--src/soc/intel/skylake/chip.h1
-rw-r--r--src/soc/intel/skylake/finalize.c17
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();
}