soc/intel/skylake: Control fixed IO decode from devicetree

The current implementation doesn't allow custom values for the LPC IO
decodes and IO enables.

Add the lpc_ioe and lpc_iod values. If they are not zero, they will be
used instead of the current handling for COMA and COMB.

BUG=N/A
TEST=tested on facebook monolith

Change-Id: Iad7bb0e44739e8d656a542c79af7f98a4e9bde69
Signed-off-by: Wim Vervoorn <wvervoorn@eltan.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/38748
Reviewed-by: Frans Hendriks <fhendriks@eltan.com>
Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
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 cf6d8e9..25a7370 100644
--- a/src/soc/intel/common/block/include/intelblocks/lpc_lib.h
+++ b/src/soc/intel/common/block/include/intelblocks/lpc_lib.h
@@ -72,6 +72,8 @@
 uint16_t lpc_enable_fixed_io_ranges(uint16_t io_enables);
 /* Return the current decode settings */
 uint16_t lpc_get_fixed_io_decode(void);
+/* Set the current decode ranges */
+uint16_t lpc_set_fixed_io_ranges(uint16_t io_ranges, uint16_t mask);
 /* Open a generic IO window to the LPC bus. Four windows are available. */
 void lpc_open_pmio_window(uint16_t base, uint16_t size);
 /* Close all generic IO windows to the LPC bus. */
diff --git a/src/soc/intel/common/block/lpc/lpc_lib.c b/src/soc/intel/common/block/lpc/lpc_lib.c
index 5b30a81..8edbd2e 100644
--- a/src/soc/intel/common/block/lpc/lpc_lib.c
+++ b/src/soc/intel/common/block/lpc/lpc_lib.c
@@ -42,6 +42,17 @@
 	return pci_read_config16(PCH_DEV_LPC, LPC_IO_DECODE);
 }
 
+uint16_t lpc_set_fixed_io_ranges(uint16_t io_ranges, uint16_t mask)
+{
+	uint16_t reg_io_ranges;
+
+	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);
+
+	return io_ranges;
+}
+
 /*
  * Find the first unused IO window.
  * Returns -1 if not found, 0 for reg 0x84, 1 for reg 0x88 ...
diff --git a/src/soc/intel/skylake/bootblock/pch.c b/src/soc/intel/skylake/bootblock/pch.c
index d5d3aed..b9a5633 100644
--- a/src/soc/intel/skylake/bootblock/pch.c
+++ b/src/soc/intel/skylake/bootblock/pch.c
@@ -127,9 +127,16 @@
 	uint16_t io_enables = LPC_IOE_SUPERIO_2E_2F | LPC_IOE_KBC_60_64 |
 			LPC_IOE_EC_62_66;
 
-	/* IO Decode Range */
-	if (CONFIG(DRIVERS_UART_8250IO))
-		lpc_io_setup_comm_a_b();
+	const config_t *config = config_of_soc();
+
+	if (config->lpc_ioe) {
+		io_enables = config->lpc_ioe & 0x3f0f;
+		lpc_set_fixed_io_ranges(config->lpc_iod, 0x1377);
+	} else {
+		/* IO Decode Range */
+		if (CONFIG(DRIVERS_UART_8250IO))
+			lpc_io_setup_comm_a_b();
+	}
 
 	/* IO Decode Enable */
 	if (pch_check_decode_enable() == 0) {
diff --git a/src/soc/intel/skylake/chip.h b/src/soc/intel/skylake/chip.h
index 2c3d3a5..69b818b 100644
--- a/src/soc/intel/skylake/chip.h
+++ b/src/soc/intel/skylake/chip.h
@@ -79,6 +79,10 @@
 	uint8_t gpe0_dw1; /* GPE0_63_32 STS/EN */
 	uint8_t gpe0_dw2; /* GPE0_95_64 STS/EN */
 
+	/* LPC fixed enables and ranges */
+	uint16_t lpc_iod;
+	uint16_t lpc_ioe;
+
 	/* Generic IO decode ranges */
 	uint32_t gen1_dec;
 	uint32_t gen2_dec;