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__ 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 #include #include +#include #include #include "lpc_def.h" #include #include +#include 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)