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 596c2b5b26..2b525cab41 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_lock_enable(void); 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 @@ void lpc_set_serirq_mode(enum serirq_mode mode); * 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 da73608a70..c066f68f17 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 c4144cb88b..0fcf383ecb 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 @@ void lpc_io_setup_comm_a_b(void) /* 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); +}