summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/intel/apollolake/Kconfig1
-rw-r--r--src/soc/intel/common/block/pmc/Kconfig7
-rw-r--r--src/soc/intel/common/block/pmc/pmc.c17
3 files changed, 25 insertions, 0 deletions
diff --git a/src/soc/intel/apollolake/Kconfig b/src/soc/intel/apollolake/Kconfig
index b7f2dc92c4..a9f49dbbfd 100644
--- a/src/soc/intel/apollolake/Kconfig
+++ b/src/soc/intel/apollolake/Kconfig
@@ -57,6 +57,7 @@ config CPU_SPECIFIC_OPTIONS
select PCIEX_LENGTH_256MB
select POSTCAR_CONSOLE
select POSTCAR_STAGE
+ select PMC_INVALID_READ_AFTER_WRITE
select REG_SCRIPT
select RELOCATABLE_RAMSTAGE # Build fails if this is not selected
select RTC
diff --git a/src/soc/intel/common/block/pmc/Kconfig b/src/soc/intel/common/block/pmc/Kconfig
index cfd12d8f3e..46f134e3b1 100644
--- a/src/soc/intel/common/block/pmc/Kconfig
+++ b/src/soc/intel/common/block/pmc/Kconfig
@@ -30,3 +30,10 @@ config POWER_STATE_PREVIOUS_AFTER_FAILURE
power
endchoice
+
+config PMC_INVALID_READ_AFTER_WRITE
+ bool
+ default n
+ help
+ Enable this for PMC devices where a read back of ACPI BAR and
+ IO access bit does not return the previously written value.
diff --git a/src/soc/intel/common/block/pmc/pmc.c b/src/soc/intel/common/block/pmc/pmc.c
index a3c5c4216c..f9563302df 100644
--- a/src/soc/intel/common/block/pmc/pmc.c
+++ b/src/soc/intel/common/block/pmc/pmc.c
@@ -65,6 +65,23 @@ static void pch_pmc_add_io_resources(struct device *dev,
cfg->abase_addr, cfg->abase_size,
IORESOURCE_IO | IORESOURCE_ASSIGNED |
IORESOURCE_FIXED);
+ if (IS_ENABLED(CONFIG_PMC_INVALID_READ_AFTER_WRITE)) {
+ /*
+ * The ACPI IO BAR (offset 0x20) is not PCI compliant. We've
+ * observed cases where the BAR reads back as 0, but the IO
+ * window is open. This also means that it will not respond
+ * to PCI probing.
+ */
+ pci_write_config16(dev, cfg->abase_offset, cfg->abase_addr);
+ /*
+ * In pci_dev_enable_resources, reading IO SPACE ACCESS bit in
+ * STATUSCOMMAND register does not read back the written
+ * value correctly, hence IO access gets disabled. This is
+ * seen in some PMC devices, hence this code makes sure
+ * IO access is available.
+ */
+ dev->command |= PCI_COMMAND_IO;
+ }
}
static void pch_pmc_read_resources(struct device *dev)