From f7e91d22d46457e2d9f8e9015232d5c7f5119422 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Niew=C3=B6hner?= Date: Sun, 17 Jan 2021 02:51:00 +0100 Subject: [PATCH] soc/intel/lpc_lib: mirror LPC registers to DMI when required MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Starting with SPT, LPC registers IOD, IOE, LGIR* and LGMR need to be mirrored to their corresponding DMI registers. Add the required writes to DMI registers, where the PCI config registers get written. This is already done in soc code for IOD, IOE and LGIR* by mirroring the registers later, during PCH init. Also the code mostly matches accross the platforms. This common implementation will avoid delayed mirroring of the registers and also deduplicate the code. This change also adds a new Kconfig that will be selected by platforms requiring mirroring of LPC IO/MMIO registers to their corresponding DMI registers. For making use of this common code, the redundant soc code needs to be dropped and the newly introduced Kconfig option has to be selected. This is done in the follow-up change. Change-Id: I39f3bf4c486a1bbc112b2b453381de6da4bbac4d Signed-off-by: Michael Niewöhner Reviewed-on: https://review.coreboot.org/c/coreboot/+/49592 Tested-by: build bot (Jenkins) Reviewed-by: Nico Huber --- .../block/include/intelblocks/lpc_lib.h | 2 ++ src/soc/intel/common/block/lpc/Kconfig | 7 ++++++ src/soc/intel/common/block/lpc/lpc_def.h | 6 +++-- src/soc/intel/common/block/lpc/lpc_lib.c | 22 +++++++++++++++---- 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__ 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)