soc/intel/common/block/lpc: Improve automatic window opening
When an existing LPC window covers an IO range, but is bigger or starts earlier the current code doesn't recognize it. It will open another window overlapping an existing one. Check if an existing LPC IO window covers the current one and allow it to be bigger than the entry. TEST=Thinkpad X280 still boots and error messages are gone. Should fix the following line seen in the coreboot log of the Lenovo T480 and compatible: [ERROR] LPC: Cannot open IO window: 1604 size 1 [ERROR] No more IO windows [ERROR] LPC: Cannot open IO window: 1606 size 1 [ERROR] No more IO windows [ERROR] LPC: Cannot open IO window: 1610 size 10 [ERROR] No more IO windows Change-Id: I586066238b801d2abb1122698fb4092ee0b2f6b9 Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/91171 Reviewed-by: Ladislav Ezr <ladislav@ezr.cz> Reviewed-by: Johann C Rode <jcrode82@gmail.com> Reviewed-by: Paul Menzel <paulepanter@mailbox.org> Reviewed-by: Jérémy Compostella <jeremy.compostella@intel.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
f1e4de7fbf
commit
339ef9b5c9
1 changed files with 13 additions and 6 deletions
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue