soc/intel/common/block: Update LPC lib

Add support for following functionality:
 1. Set up PCH LPC interrupt routing.
 2. Set up generic IO decoder range settings.
 3. Enable CLKRUN_EN for power gating LPC.

Change-Id: Ib9359765f7293210044b411db49163df0418070a
Signed-off-by: Ravi Sarawadi <ravishankar.sarawadi@intel.com>
Reviewed-on: https://review.coreboot.org/21605
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.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 596c2b5..2b525ca 100644
--- a/src/soc/intel/common/block/include/intelblocks/lpc_lib.h
+++ b/src/soc/intel/common/block/include/intelblocks/lpc_lib.h
@@ -27,16 +27,25 @@
  * use IOE_KBC_60_64 macro. For IOE_ macros that do not specify a port range,
  * the port range is selectable via the IO decodes register.
  */
-#define  LPC_IOE_EC_4E_4F               (1 << 13)
-#define  LPC_IOE_SUPERIO_2E_2F          (1 << 12)
-#define  LPC_IOE_EC_62_66               (1 << 11)
-#define  LPC_IOE_KBC_60_64              (1 << 10)
-#define  LPC_IOE_HGE_208                (1 << 9)
-#define  LPC_IOE_LGE_200                (1 << 8)
-#define  LPC_IOE_FDD_EN                 (1 << 3)
-#define  LPC_IOE_LPT_EN                 (1 << 2)
-#define  LPC_IOE_COMB_EN                (1 << 1)
-#define  LPC_IOE_COMA_EN                (1 << 0)
+#define LPC_IOE_EC_4E_4F               (1 << 13)
+#define LPC_IOE_SUPERIO_2E_2F          (1 << 12)
+#define LPC_IOE_EC_62_66               (1 << 11)
+#define LPC_IOE_KBC_60_64              (1 << 10)
+#define LPC_IOE_HGE_208                (1 << 9)
+#define LPC_IOE_LGE_200                (1 << 8)
+#define LPC_IOE_FDD_EN                 (1 << 3)
+#define LPC_IOE_LPT_EN                 (1 << 2)
+#define LPC_IOE_COMB_EN                (1 << 1)
+#define LPC_IOE_COMA_EN                (1 << 0)
+#define LPC_NUM_GENERIC_IO_RANGES       4
+
+#define PCR_DMI_LPCLGIR1        0x2730
+#define PCR_DMI_LPCLGIR2        0x2734
+#define PCR_DMI_LPCLGIR3        0x2738
+#define PCR_DMI_LPCLGIR4        0x273c
+
+#define PCR_DMI_LPCIOD          0x2770
+#define PCR_DMI_LPCIOE          0x2774
 
 /* Serial IRQ control. SERIRQ_QUIET is the default (0). */
 enum serirq_mode {
@@ -75,6 +84,8 @@
 void lpc_set_eiss(void);
 /* Set LPC Serial IRQ mode. */
 void lpc_set_serirq_mode(enum serirq_mode mode);
+/* Enable CLKRUN_EN for power gating LPC. */
+void lpc_enable_pci_clk_cntl(void);
 /*
 * Setup I/O Decode Range Register for LPC
 * ComA Range 3F8h-3FFh [2:0]
@@ -82,5 +93,14 @@
 * Enable ComA and ComB Port
 */
 void lpc_io_setup_comm_a_b(void);
+/* Enable PCH LPC by setting up generic decode range registers. */
+void pch_enable_lpc(void);
+/* Retrieve and setup SoC speicific PCH LPC interrupt routing. */
+void soc_pch_pirq_init(const struct device *dev);
+/* Get SoC's generic IO decoder range register settings. */
+void soc_get_gen_io_dec_range(const struct device *dev,
+			uint32_t gen_io_dec[LPC_NUM_GENERIC_IO_RANGES]);
+/* Mirror generic IO decoder range register settings into DMI PCR. */
+void soc_setup_dmi_pcr_io_dec(uint32_t gen_io_dec[LPC_NUM_GENERIC_IO_RANGES]);
 
 #endif /* _SOC_COMMON_BLOCK_LPC_LIB_H_ */
diff --git a/src/soc/intel/common/block/lpc/lpc_def.h b/src/soc/intel/common/block/lpc/lpc_def.h
index da73608..c066f68 100644
--- a/src/soc/intel/common/block/lpc/lpc_def.h
+++ b/src/soc/intel/common/block/lpc/lpc_def.h
@@ -31,7 +31,6 @@
 #define  LPC_LGIR_ADDR_MASK		0xfffc
 #define  LPC_LGIR_EN			(1 << 0)
 #define LPC_LGIR_MAX_WINDOW_SIZE	256
-#define LPC_NUM_GENERIC_IO_RANGES	4
 #define LPC_GENERIC_MEM_RANGE		0x98
 #define  LPC_LGMR_ADDR_MASK		0xffff0000
 #define  LPC_LGMR_EN			(1 << 0)
diff --git a/src/soc/intel/common/block/lpc/lpc_lib.c b/src/soc/intel/common/block/lpc/lpc_lib.c
index c4144cb..0fcf383 100644
--- a/src/soc/intel/common/block/lpc/lpc_lib.c
+++ b/src/soc/intel/common/block/lpc/lpc_lib.c
@@ -235,3 +235,47 @@
 	/* Enable ComA and ComB Port */
 	lpc_enable_fixed_io_ranges(LPC_IOE_COMA_EN | LPC_IOE_COMB_EN);
 }
+
+static void lpc_set_gen_decode_range(
+	uint32_t gen_io_dec[LPC_NUM_GENERIC_IO_RANGES])
+{
+	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]);
+}
+
+static void pch_lpc_interrupt_init(void)
+{
+	const struct device *dev;
+
+	dev = dev_find_slot(0, PCI_DEVFN(PCH_DEV_SLOT_LPC, 0));
+	if (!dev || !dev->chip_info)
+		return;
+
+	soc_pch_pirq_init(dev);
+}
+
+void pch_enable_lpc(void)
+{
+	/* Lookup device tree in romstage */
+	const struct device *dev;
+	uint32_t gen_io_dec[LPC_NUM_GENERIC_IO_RANGES];
+
+	dev = dev_find_slot(0, PCI_DEVFN(PCH_DEV_SLOT_LPC, 0));
+	if (!dev || !dev->chip_info)
+		return;
+
+	soc_get_gen_io_dec_range(dev, gen_io_dec);
+	lpc_set_gen_decode_range(gen_io_dec);
+	soc_setup_dmi_pcr_io_dec(gen_io_dec);
+	if (ENV_RAMSTAGE)
+		pch_lpc_interrupt_init();
+}
+
+void lpc_enable_pci_clk_cntl(void)
+{
+	pci_write_config8(PCH_DEV_LPC, LPC_PCCTL, LPC_PCCTL_CLKRUN_EN);
+}