Wonkyu Kim has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/63198 )
Change subject: soc/intel/common: implement ioc driver ......................................................................
soc/intel/common: implement ioc driver
DMI interface is moved to IOC in MTL Reference: 643504 MTL FAS section 7.5.2 and reference FSP code. https://github.com/otcshare/CCG-MTL-Generic-PSS/blob/master/ ClientOneSiliconPkg/IpBlock/Ioc/IncludePrivate/Register/IocRegs.h
TEST=Build and boot to OS for TGL and MTL
Signed-off-by: Wonkyu Kim wonkyu.kim@intel.com Change-Id: I768027c2ca78310c03845f70f17df19dc8cd0982 --- M src/soc/intel/common/block/gpmr/Kconfig M src/soc/intel/common/block/gpmr/gpmr.c M src/soc/intel/common/block/include/intelblocks/gpmr.h A src/soc/intel/common/block/include/intelblocks/ioc.h A src/soc/intel/common/block/include/intelblocks/ioc_reg.h A src/soc/intel/common/block/ioc/Kconfig A src/soc/intel/common/block/ioc/Makefile.inc A src/soc/intel/common/block/ioc/ioc.c M src/soc/intel/common/block/lpc/lpc_lib.c M src/soc/intel/common/block/smbus/tco.c M src/soc/intel/common/pch/lockdown/lockdown.c 11 files changed, 133 insertions(+), 15 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/98/63198/1
diff --git a/src/soc/intel/common/block/gpmr/Kconfig b/src/soc/intel/common/block/gpmr/Kconfig index b307493..7d21687 100644 --- a/src/soc/intel/common/block/gpmr/Kconfig +++ b/src/soc/intel/common/block/gpmr/Kconfig @@ -1,6 +1,6 @@ config SOC_INTEL_COMMON_BLOCK_GPMR bool - depends on SOC_INTEL_COMMON_BLOCK_DMI + depends on SOC_INTEL_COMMON_BLOCK_DMI || SOC_INTEL_COMMON_BLOCK_IOC help - Mirror GPMR registers for IO/MMIO to their corresponding DMI registers. + Mirror GPMR registers for IO/MMIO to their corresponding DMI/IOC registers. Required for extending BIOS region. diff --git a/src/soc/intel/common/block/gpmr/gpmr.c b/src/soc/intel/common/block/gpmr/gpmr.c index 532d619..306c209 100644 --- a/src/soc/intel/common/block/gpmr/gpmr.c +++ b/src/soc/intel/common/block/gpmr/gpmr.c @@ -8,13 +8,19 @@ /* GPMR Register read given offset */ static uint32_t gpmr_read32(uint16_t offset) { - return pcr_read32(PID_DMI, offset); + if (CONFIG(SOC_INTEL_COMMON_BLOCK_IOC)) + return ioc_reg_read32(offset); + else + return pcr_read32(PID_DMI, offset); }
/* GPMR Register write given offset and val */ static void gpmr_write32(uint16_t offset, uint32_t val) { - return pcr_write32(PID_DMI, offset, val); + if (CONFIG(SOC_INTEL_COMMON_BLOCK_IOC)) + return ioc_reg_write32(offset, val); + else + return pcr_write32(PID_DMI, offset, val); }
/* Check for available free gpmr */ diff --git a/src/soc/intel/common/block/include/intelblocks/gpmr.h b/src/soc/intel/common/block/include/intelblocks/gpmr.h index c9cd3bc..64d37c5 100644 --- a/src/soc/intel/common/block/include/intelblocks/gpmr.h +++ b/src/soc/intel/common/block/include/intelblocks/gpmr.h @@ -5,6 +5,19 @@
#include <types.h> #include <intelblocks/dmi.h> +#include <intelblocks/ioc.h> + +#if CONFIG(SOC_INTEL_COMMON_BLOCK_IOC) + +#define MAX_GPMR_REGS IOC_MAX_GPMR_REGS +#define GPMR_OFFSET IOC_GPMR_OFFSET +#define GPMR_LIMIT_MASK IOC_GPMR_LIMIT_MASK +#define GPMR_BASE_SHIFT IOC_GPMR_BASE_SHIFT +#define GPMR_BASE_MASK IOC_GPMR_BASE_MASK +#define GPMR_DID_OFFSET IOC_GPMR_DID_OFFSET +#define GPMR_EN IOC_GPMR_EN + +#else
#define MAX_GPMR_REGS PCR_MAX_GPMR_REGS #define GPMR_OFFSET PCR_GPMR_OFFSET @@ -14,6 +27,8 @@ #define GPMR_DID_OFFSET PCR_GPMR_DID_OFFSET #define GPMR_EN PCR_GPMR_EN
+#endif + enum cb_err enable_gpmr(uint32_t base, uint32_t size, uint32_t dest_id);
#endif /* SOC_INTEL_COMMON_BLOCK_GPMR_H */ diff --git a/src/soc/intel/common/block/include/intelblocks/ioc.h b/src/soc/intel/common/block/include/intelblocks/ioc.h new file mode 100644 index 0000000..c5d5926 --- /dev/null +++ b/src/soc/intel/common/block/include/intelblocks/ioc.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef SOC_INTEL_COMMON_BLOCK_IOC_H +#define SOC_INTEL_COMMON_BLOCK_IOC_H + +#include <types.h> + +#if CONFIG(SOC_INTEL_COMMON_BLOCK_IOC_REG_HEADER_OVERRIDE) +/* Overridden definitions */ +#include <soc/ioc_reg.h> +#else +/*Default definitions */ +#include <intelblocks/ioc_reg.h> +#endif + +void ioc_reg_write32(uint32_t offset, uint32_t value); +uint32_t ioc_reg_read32(uint32_t offset); + +#endif /* SOC_INTEL_COMMON_BLOCK_IOC_H */ diff --git a/src/soc/intel/common/block/include/intelblocks/ioc_reg.h b/src/soc/intel/common/block/include/intelblocks/ioc_reg.h new file mode 100644 index 0000000..5428949 --- /dev/null +++ b/src/soc/intel/common/block/include/intelblocks/ioc_reg.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _IOC_REG_H_ +#define _IOC_REG_H_ + +#define R_IOC_CFG_LPCLGIR1 0x7a30 +#define R_IOC_CFG_LPCGMR 0x7A40 +#define R_IOC_CFG_GCS 0x7a4C /* Generic Control and Status */ +#define B_IOC_CFG_BILD 0x1 /* BIOS interface Lockdown */ +#define R_IOC_CFG_LPCIOD 0x7a70 /* LPC I/O Decode Ranges */ +#define R_IOC_CFG_LPCIOE 0x7a74 /* LPC I/O Enables */ +#define R_IOC_CFG_TCOBASE 0x7a78 /* TCO Base Address */ +#define B_IOC_CFG_TCOBASE_TCOBA 0xFFE0 +#define R_IOC_CFG_GPMR1 0x7A7C +#define R_IOC_CFG_GPMR1DID 0x7A80 + +#define IOC_MAX_GPMR_REGS 3 + +#define IOC_GPMR_OFFSET(x) (R_IOC_CFG_GPMR1 + (x) * 8) +#define IOC_GPMR_LIMIT_MASK 0xffff0000 +#define IOC_GPMR_BASE_SHIFT 16 +#define IOC_GPMR_BASE_MASK 0xffff + +#define IOC_GPMR_DID_OFFSET(x) (R_IOC_CFG_GPMR1DID + (x) * 8) +#define IOC_GPMR_EN BIT(31) + +#endif diff --git a/src/soc/intel/common/block/ioc/Kconfig b/src/soc/intel/common/block/ioc/Kconfig new file mode 100644 index 0000000..223af43 --- /dev/null +++ b/src/soc/intel/common/block/ioc/Kconfig @@ -0,0 +1,10 @@ +config SOC_INTEL_COMMON_BLOCK_IOC + bool + help + Intel Processor common IO Cache(IOC) + +config SOC_INTEL_COMMON_BLOCK_IOC_REG_HEADER_OVERRIDE + bool + help + ioc register offset override + diff --git a/src/soc/intel/common/block/ioc/Makefile.inc b/src/soc/intel/common/block/ioc/Makefile.inc new file mode 100644 index 0000000..5896534 --- /dev/null +++ b/src/soc/intel/common/block/ioc/Makefile.inc @@ -0,0 +1,3 @@ +bootblock-$(CONFIG_SOC_INTEL_COMMON_BLOCK_IOC) += ioc.c +romstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_IOC) += ioc.c +ramstage-$(CONFIG_SOC_INTEL_COMMON_BLOCK_IOC) += ioc.c diff --git a/src/soc/intel/common/block/ioc/ioc.c b/src/soc/intel/common/block/ioc/ioc.c new file mode 100644 index 0000000..3f2374c --- /dev/null +++ b/src/soc/intel/common/block/ioc/ioc.c @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <intelblocks/ioc.h> +#include <device/mmio.h> +#include <soc/iomap.h> + +void ioc_reg_write32(uint32_t offset, uint32_t value) +{ + write32((void *)MCH_BASE_ADDRESS + offset, value); +} + +uint32_t ioc_reg_read32(uint32_t offset) +{ + uint32_t value; + value = read32((void *)MCH_BASE_ADDRESS + offset); + return value; +} + diff --git a/src/soc/intel/common/block/lpc/lpc_lib.c b/src/soc/intel/common/block/lpc/lpc_lib.c index 1393714..d75a44c 100644 --- a/src/soc/intel/common/block/lpc/lpc_lib.c +++ b/src/soc/intel/common/block/lpc/lpc_lib.c @@ -9,6 +9,7 @@ #include <device/pci_ops.h> #include <intelblocks/itss.h> #include <intelblocks/lpc_lib.h> +#include <intelblocks/ioc.h> #include <intelblocks/pcr.h> #include <lib.h> #include "lpc_def.h" @@ -24,7 +25,9 @@ reg_io_enables = pci_read_config16(PCH_DEV_LPC, LPC_IO_ENABLES); io_enables |= reg_io_enables; pci_write_config16(PCH_DEV_LPC, LPC_IO_ENABLES, io_enables); - if (CONFIG(SOC_INTEL_COMMON_BLOCK_LPC_MIRROR_TO_DMI)) + if (CONFIG(SOC_INTEL_COMMON_BLOCK_IOC)) + ioc_reg_write32(R_IOC_CFG_LPCIOE, io_enables); + else if (CONFIG(SOC_INTEL_COMMON_BLOCK_LPC_MIRROR_TO_DMI)) pcr_write16(PID_DMI, PCR_DMI_LPCIOE, io_enables);
return io_enables; @@ -42,7 +45,9 @@ 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); - if (CONFIG(SOC_INTEL_COMMON_BLOCK_LPC_MIRROR_TO_DMI)) + if (CONFIG(SOC_INTEL_COMMON_BLOCK_IOC)) + ioc_reg_write32(R_IOC_CFG_LPCIOD, io_ranges); + else if (CONFIG(SOC_INTEL_COMMON_BLOCK_LPC_MIRROR_TO_DMI)) pcr_write16(PID_DMI, PCR_DMI_LPCIOD, io_ranges);
return io_ranges; @@ -112,7 +117,10 @@ lgir_reg_offset = LPC_GENERIC_IO_RANGE(lgir_reg_num);
pci_write_config32(PCH_DEV_LPC, lgir_reg_offset, lgir); - if (CONFIG(SOC_INTEL_COMMON_BLOCK_LPC_MIRROR_TO_DMI)) + + if (CONFIG(SOC_INTEL_COMMON_BLOCK_IOC)) + ioc_reg_write32(R_IOC_CFG_LPCLGIR1 + lgir_reg_num * 4, lgir); + else if (CONFIG(SOC_INTEL_COMMON_BLOCK_LPC_MIRROR_TO_DMI)) pcr_write32(PID_DMI, PCR_DMI_LPCLGIR1 + lgir_reg_num * 4, lgir);
printk(BIOS_DEBUG, @@ -147,7 +155,9 @@ lgmr = (base & LPC_LGMR_ADDR_MASK) | LPC_LGMR_EN;
pci_write_config32(PCH_DEV_LPC, LPC_GENERIC_MEM_RANGE, lgmr); - if (CONFIG(SOC_INTEL_COMMON_BLOCK_LPC_MIRROR_TO_DMI)) + if (CONFIG(SOC_INTEL_COMMON_BLOCK_IOC)) + ioc_reg_write32(R_IOC_CFG_LPCGMR, lgmr); + else if (CONFIG(SOC_INTEL_COMMON_BLOCK_LPC_MIRROR_TO_DMI)) pcr_write32(PID_DMI, PCR_DMI_LPCGMR, lgmr); }
@@ -248,7 +258,9 @@ /* 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]); - if (CONFIG(SOC_INTEL_COMMON_BLOCK_LPC_MIRROR_TO_DMI)) + if (CONFIG(SOC_INTEL_COMMON_BLOCK_IOC)) + ioc_reg_write32(R_IOC_CFG_LPCLGIR1 + i * 4, gen_io_dec[i]); + else if (CONFIG(SOC_INTEL_COMMON_BLOCK_LPC_MIRROR_TO_DMI)) pcr_write32(PID_DMI, PCR_DMI_LPCLGIR1 + i * 4, gen_io_dec[i]); } } diff --git a/src/soc/intel/common/block/smbus/tco.c b/src/soc/intel/common/block/smbus/tco.c index 518541b..1d21e2b 100644 --- a/src/soc/intel/common/block/smbus/tco.c +++ b/src/soc/intel/common/block/smbus/tco.c @@ -10,6 +10,7 @@ #include <intelblocks/pcr.h> #include <intelblocks/pmclib.h> #include <intelblocks/tco.h> +#include <intelblocks/ioc.h> #include <soc/iomap.h> #include <soc/pci_devs.h> #include <soc/pcr_ids.h> @@ -122,10 +123,11 @@ /* Enable TCO in SMBUS */ pci_write_config32(dev, TCOCTL, reg32 | TCO_BASE_EN);
- /* - * Program "TCO Base Address" PCR[DMI] + 2778h[15:5, 1] - */ - pcr_write32(PID_DMI, PCR_DMI_TCOBASE, tcobase | TCOEN); + /* Program "TCO Base Address */ + if (CONFIG(SOC_INTEL_COMMON_BLOCK_IOC)) + ioc_reg_write32(R_IOC_CFG_TCOBASE, tcobase | TCOEN); + else + pcr_write32(PID_DMI, PCR_DMI_TCOBASE, tcobase | TCOEN); }
/* diff --git a/src/soc/intel/common/pch/lockdown/lockdown.c b/src/soc/intel/common/pch/lockdown/lockdown.c index 5ab0611..800eee5 100644 --- a/src/soc/intel/common/pch/lockdown/lockdown.c +++ b/src/soc/intel/common/pch/lockdown/lockdown.c @@ -5,6 +5,7 @@ #include <intelblocks/dmi.h> #include <intelblocks/fast_spi.h> #include <intelblocks/pcr.h> +#include <intelblocks/ioc.h> #include <intelpch/lockdown.h> #include <soc/pci_devs.h> #include <soc/pcr_ids.h> @@ -27,6 +28,10 @@
static void dmi_lockdown_cfg(void) { + if (CONFIG(SOC_INTEL_COMMON_BLOCK_IOC)) + ioc_reg_write32(R_IOC_CFG_GCS, + ioc_reg_read32(R_IOC_CFG_GCS)|B_IOC_CFG_BILD); + else { /* * GCS reg of DMI * @@ -37,13 +42,14 @@ * "0b": SPI * "1b": LPC/eSPI */ - pcr_or8(PID_DMI, PCR_DMI_GCS, PCR_DMI_GCS_BILD); + pcr_or8(PID_DMI, PCR_DMI_GCS, PCR_DMI_GCS_BILD);
/* * Set Secure Register Lock (SRL) bit in DMI control register to lock * DMI configuration. */ - pcr_or32(PID_DMI, PCR_DMI_DMICTL, PCR_DMI_DMICTL_SRLOCK); + pcr_or32(PID_DMI, PCR_DMI_DMICTL, PCR_DMI_DMICTL_SRLOCK); + } }
static void fast_spi_lockdown_cfg(int chipset_lockdown)