diff --git a/src/soc/intel/common/block/lpc/lpc_lib.c b/src/soc/intel/common/block/lpc/lpc_lib.c index 9a7165baaf..337a098848 100644 --- a/src/soc/intel/common/block/lpc/lpc_lib.c +++ b/src/soc/intel/common/block/lpc/lpc_lib.c @@ -169,14 +169,17 @@ void lpc_open_pmio_window(uint16_t base, uint16_t size) alignment = 1UL << (log2_ceil(window_size)); window_size = ALIGN_UP(window_size, alignment); - /* Address[15:2] in LGIR[15:12] and Mask[7:2] in LGIR[23:18]. */ - lgir = (bridge_base & LPC_LGIR_ADDR_MASK) | LPC_LGIR_EN; - lgir |= ((window_size - 1) << 16) & LPC_LGIR_AMASK_MASK; + const struct region win = region_create(bridge_base, window_size); - /* Skip programming if same range already programmed. */ + /* Skip programming if covered by existing window. */ for (i = 0; i < LPC_NUM_GENERIC_IO_RANGES; i++) { - if (lgir == pci_read_config32(PCH_DEV_LPC, - LPC_GENERIC_IO_RANGE(i))) + const u32 reg32 = pci_read_config32(PCH_DEV_LPC, LPC_GENERIC_IO_RANGE(i)); + if (!(reg32 & LPC_LGIR_EN)) + continue; + const struct region exist = region_create(reg32 & LPC_LGIR_ADDR_MASK, + 1 + ((reg32 & LPC_LGIR_AMASK_MASK) >> 16)); + + if (region_is_subregion(&exist, &win)) return; } @@ -190,6 +193,10 @@ void lpc_open_pmio_window(uint16_t base, uint16_t size) } lgir_reg_offset = LPC_GENERIC_IO_RANGE(lgir_reg_num); + /* Address[15:2] in LGIR[15:12] and Mask[7:2] in LGIR[23:18]. */ + lgir = (bridge_base & LPC_LGIR_ADDR_MASK) | LPC_LGIR_EN; + lgir |= ((window_size - 1) << 16) & LPC_LGIR_AMASK_MASK; + pci_write_config32(PCH_DEV_LPC, lgir_reg_offset, lgir); if (CONFIG(SOC_INTEL_COMMON_BLOCK_LPC_MIRROR_TO_GPMR)) gpmr_write32(GPMR_LPCLGIR1 + lgir_reg_num * 4, lgir);