summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/soc/intel/common/block/include/intelblocks/lpc_lib.h2
-rw-r--r--src/soc/intel/common/block/lpc/Kconfig7
-rw-r--r--src/soc/intel/common/block/lpc/lpc_def.h6
-rw-r--r--src/soc/intel/common/block/lpc/lpc_lib.c22
4 files changed, 31 insertions, 6 deletions
diff --git a/src/soc/intel/common/block/include/intelblocks/lpc_lib.h b/src/soc/intel/common/block/include/intelblocks/lpc_lib.h
index bf5c2f68f6..c5842d5f2c 100644
--- a/src/soc/intel/common/block/include/intelblocks/lpc_lib.h
+++ b/src/soc/intel/common/block/include/intelblocks/lpc_lib.h
@@ -30,6 +30,8 @@
#define PCR_DMI_LPCLGIR3 0x2738
#define PCR_DMI_LPCLGIR4 0x273c
+#define PCR_DMI_LPCGMR 0x2740
+
#define PCR_DMI_LPCIOD 0x2770
#define PCR_DMI_LPCIOE 0x2774
diff --git a/src/soc/intel/common/block/lpc/Kconfig b/src/soc/intel/common/block/lpc/Kconfig
index 41e72c474a..d76620af6f 100644
--- a/src/soc/intel/common/block/lpc/Kconfig
+++ b/src/soc/intel/common/block/lpc/Kconfig
@@ -11,3 +11,10 @@ config SOC_INTEL_COMMON_BLOCK_LPC_COMB_ENABLE
help
By default COMA range to LPC is enable. COMB range to LPC is optional
and should select based on platform dedicated selection.
+
+config SOC_INTEL_COMMON_BLOCK_LPC_MIRROR_TO_DMI
+ bool
+ depends on SOC_INTEL_COMMON_BLOCK_DMI
+ help
+ Mirror LPC registers for IO/MMIO to their corresponding DMI registers.
+ Required for platforms starting from SPT.
diff --git a/src/soc/intel/common/block/lpc/lpc_def.h b/src/soc/intel/common/block/lpc/lpc_def.h
index 775316986a..ab9f2018c5 100644
--- a/src/soc/intel/common/block/lpc/lpc_def.h
+++ b/src/soc/intel/common/block/lpc/lpc_def.h
@@ -7,8 +7,10 @@
#define LPC_SCNT_EN (1 << 7)
#define LPC_SCNT_MODE (1 << 6)
#define LPC_IO_DECODE 0x80
-#define LPC_IOD_COMA_RANGE (0 << 0) /* 0x3F8 - 0x3FF COMA*/
-#define LPC_IOD_COMB_RANGE (1 << 4) /* 0x2F8 - 0x2FF COMB*/
+#define LPC_IOD_COMA_RANGE_MASK (7 << 0)
+#define LPC_IOD_COMB_RANGE_MASK (7 << 4)
+#define LPC_IOD_COMA_RANGE (0 << 0) /* 0x3F8 - 0x3FF COMA */
+#define LPC_IOD_COMB_RANGE (1 << 4) /* 0x2F8 - 0x2FF COMB */
/* Use IO_<peripheral>_<IO port> style macros defined in lpc_lib.h
* to enable decoding of I/O locations for a peripheral. */
#define LPC_IO_ENABLES 0x82
diff --git a/src/soc/intel/common/block/lpc/lpc_lib.c b/src/soc/intel/common/block/lpc/lpc_lib.c
index 28c435cce6..242d7d91c9 100644
--- a/src/soc/intel/common/block/lpc/lpc_lib.c
+++ b/src/soc/intel/common/block/lpc/lpc_lib.c
@@ -9,10 +9,12 @@
#include <device/pci_ops.h>
#include <intelblocks/itss.h>
#include <intelblocks/lpc_lib.h>
+#include <intelblocks/pcr.h>
#include <lib.h>
#include "lpc_def.h"
#include <soc/irq.h>
#include <soc/pci_devs.h>
+#include <soc/pcr_ids.h>
uint16_t lpc_enable_fixed_io_ranges(uint16_t io_enables)
{
@@ -21,6 +23,8 @@ uint16_t lpc_enable_fixed_io_ranges(uint16_t io_enables)
reg_io_enables = pci_read_config16(PCH_DEV_LPC, LPC_IO_ENABLES);
io_enables |= reg_io_enables;
pci_write_config16(PCH_DEV_LPC, LPC_IO_ENABLES, io_enables);
+ if (CONFIG(SOC_INTEL_COMMON_BLOCK_LPC_MIRROR_TO_DMI))
+ pcr_write16(PID_DMI, PCR_DMI_LPCIOE, io_enables);
return io_enables;
}
@@ -37,6 +41,8 @@ uint16_t lpc_set_fixed_io_ranges(uint16_t io_ranges, uint16_t mask)
reg_io_ranges = lpc_get_fixed_io_decode() & ~mask;
io_ranges |= reg_io_ranges & mask;
pci_write_config16(PCH_DEV_LPC, LPC_IO_DECODE, io_ranges);
+ if (CONFIG(SOC_INTEL_COMMON_BLOCK_LPC_MIRROR_TO_DMI))
+ pcr_write16(PID_DMI, PCR_DMI_LPCIOD, io_ranges);
return io_ranges;
}
@@ -105,6 +111,8 @@ void lpc_open_pmio_window(uint16_t base, uint16_t size)
lgir_reg_offset = LPC_GENERIC_IO_RANGE(lgir_reg_num);
pci_write_config32(PCH_DEV_LPC, lgir_reg_offset, lgir);
+ if (CONFIG(SOC_INTEL_COMMON_BLOCK_LPC_MIRROR_TO_DMI))
+ pcr_write32(PID_DMI, PCR_DMI_LPCLGIR1 + lgir_reg_num * 4, lgir);
printk(BIOS_DEBUG,
"LPC: Opened IO window LGIR%d: base %llx size %x\n",
@@ -138,6 +146,8 @@ void lpc_open_mmio_window(uintptr_t base, size_t size)
lgmr = (base & LPC_LGMR_ADDR_MASK) | LPC_LGMR_EN;
pci_write_config32(PCH_DEV_LPC, LPC_GENERIC_MEM_RANGE, lgmr);
+ if (CONFIG(SOC_INTEL_COMMON_BLOCK_LPC_MIRROR_TO_DMI))
+ pcr_write32(PID_DMI, PCR_DMI_LPCGMR, lgmr);
}
/*
@@ -214,15 +224,17 @@ void lpc_io_setup_comm_a_b(void)
/* ComA Range 3F8h-3FFh [2:0] */
uint16_t com_ranges = LPC_IOD_COMA_RANGE;
uint16_t com_enable = LPC_IOE_COMA_EN;
+ uint16_t com_mask = LPC_IOD_COMA_RANGE_MASK;
/* ComB Range 2F8h-2FFh [6:4] */
if (CONFIG(SOC_INTEL_COMMON_BLOCK_LPC_COMB_ENABLE)) {
com_ranges |= LPC_IOD_COMB_RANGE;
com_enable |= LPC_IOE_COMB_EN;
+ com_mask |= LPC_IOD_COMB_RANGE_MASK;
}
/* Setup I/O Decode Range Register for LPC */
- pci_write_config16(PCH_DEV_LPC, LPC_IO_DECODE, com_ranges);
+ lpc_set_fixed_io_ranges(com_ranges, com_mask);
/* Enable ComA and ComB Port */
lpc_enable_fixed_io_ranges(com_enable);
}
@@ -233,9 +245,11 @@ static void lpc_set_gen_decode_range(
size_t i;
/* Set in PCI generic decode range registers */
- for (i = 0; i < LPC_NUM_GENERIC_IO_RANGES; i++)
- pci_write_config32(PCH_DEV_LPC, LPC_GENERIC_IO_RANGE(i),
- gen_io_dec[i]);
+ for (i = 0; i < LPC_NUM_GENERIC_IO_RANGES; i++) {
+ pci_write_config32(PCH_DEV_LPC, LPC_GENERIC_IO_RANGE(i), gen_io_dec[i]);
+ if (CONFIG(SOC_INTEL_COMMON_BLOCK_LPC_MIRROR_TO_DMI))
+ pcr_write32(PID_DMI, PCR_DMI_LPCLGIR1 + i * 4, gen_io_dec[i]);
+ }
}
void pch_enable_lpc(void)