From 62d42c3266a633cd11009148522b4adb2542976e Mon Sep 17 00:00:00 2001 From: Felix Held Date: Wed, 4 May 2022 19:04:33 +0200 Subject: [PATCH] soc/amd/common/include/espi: add more decode ranges Mendocino has more eSPI decode ranges than Picasso or Cezanne. To support these additional ranges, introduce a new Kconfig option SOC_AMD_COMMON_BLOCK_ESPI_EXTENDED_DECODE_RANGES that can be selected by the SoCs that support the additional eSPI IO/MMIO decode ranges. Signed-off-by: Felix Held Change-Id: Ib761cdf201c35805d68cf5e8e462607ffd9fa017 Reviewed-on: https://review.coreboot.org/c/coreboot/+/64054 Tested-by: build bot (Jenkins) Reviewed-by: Raul Rangel --- .../amd/common/block/include/amdblocks/espi.h | 10 +++- src/soc/amd/common/block/lpc/Kconfig | 7 +++ src/soc/amd/common/block/lpc/espi_def.h | 29 +++++++-- src/soc/amd/common/block/lpc/espi_util.c | 60 +++++++++++++++++-- 4 files changed, 95 insertions(+), 11 deletions(-) diff --git a/src/soc/amd/common/block/include/amdblocks/espi.h b/src/soc/amd/common/block/include/amdblocks/espi.h index 296ae4e1e3..b7ab06ee55 100644 --- a/src/soc/amd/common/block/include/amdblocks/espi.h +++ b/src/soc/amd/common/block/include/amdblocks/espi.h @@ -14,9 +14,17 @@ #define ESPI_DECODE_IO_0X60_0X64_EN (1 << 1) #define ESPI_DECODE_IO_0X2E_0X2F_EN (1 << 0) +/* The extended IO/MMIO decode ranges are only available in SoCs that select + SOC_AMD_COMMON_BLOCK_ESPI_EXTENDED_DECODE_RANGES */ +#if CONFIG(SOC_AMD_COMMON_BLOCK_ESPI_EXTENDED_DECODE_RANGES) +#define ESPI_GENERIC_IO_WIN_COUNT 16 +#define ESPI_GENERIC_MMIO_WIN_COUNT 5 +#else #define ESPI_GENERIC_IO_WIN_COUNT 4 -#define ESPI_GENERIC_IO_MAX_WIN_SIZE 0x100 #define ESPI_GENERIC_MMIO_WIN_COUNT 4 +#endif + +#define ESPI_GENERIC_IO_MAX_WIN_SIZE 0x100 #define ESPI_GENERIC_MMIO_MAX_WIN_SIZE 0x10000 #define ESPI_SLAVE0_CONFIG 0x68 diff --git a/src/soc/amd/common/block/lpc/Kconfig b/src/soc/amd/common/block/lpc/Kconfig index b1db1bd254..2de83a554a 100644 --- a/src/soc/amd/common/block/lpc/Kconfig +++ b/src/soc/amd/common/block/lpc/Kconfig @@ -36,6 +36,13 @@ config SOC_AMD_COMMON_BLOCK_HAS_ESPI Select this option if platform supports eSPI using D14F3 configuration registers. +config SOC_AMD_COMMON_BLOCK_ESPI_EXTENDED_DECODE_RANGES + bool + depends on SOC_AMD_COMMON_BLOCK_HAS_ESPI + help + Select this if the platform supports 16 instead of 4 eSPI IO decode + ranges and 5 instead of 4 eSPI MMIO decode ranges. + config SOC_AMD_COMMON_BLOCK_HAS_ESPI_ALERT_ENABLE bool depends on SOC_AMD_COMMON_BLOCK_HAS_ESPI diff --git a/src/soc/amd/common/block/lpc/espi_def.h b/src/soc/amd/common/block/lpc/espi_def.h index 1dacffcf51..7f371c1a1a 100644 --- a/src/soc/amd/common/block/lpc/espi_def.h +++ b/src/soc/amd/common/block/lpc/espi_def.h @@ -41,6 +41,8 @@ #define ESPI_SW_RST (1 << 0) /* bits in ESPI_DECODE 0x40 */ +#define ESPI_DECODE_MMIO_RANGE_EXT_EN(range) (1 << (((range) & 3) + 28)) +#define ESPI_DECODE_IO_RANGE_EXT_EN(range) (1 << ((range) + 16)) #define ESPI_DECODE_MMIO_RANGE_EN(range) (1 << (((range) & 3) + 12)) #define ESPI_DECODE_IO_RANGE_EN(range) (1 << (((range) & 3) + 8)) @@ -64,11 +66,30 @@ #define ESPI_STATUS_WAIT_TIMEOUT (1 << 1) #define ESPI_STATUS_BUS_ERROR (1 << 0) +/* The extended IO/MMIO decode ranges are only available in SoCs that select + SOC_AMD_COMMON_BLOCK_ESPI_EXTENDED_DECODE_RANGES */ +#define ESPI_IO_BASE_REG2 0x80 +#define ESPI_IO_BASE_REG3 0x84 +#define ESPI_IO_SIZE1 0x88 +#define ESPI_IO_BASE_REG4 0x8c +#define ESPI_IO_BASE_REG5 0x90 +#define ESPI_IO_SIZE2 0x94 +#define ESPI_IO_BASE_REG6 0xb0 +#define ESPI_IO_BASE_REG7 0xb4 +#define ESPI_IO_SIZE3 0xb8 +#define ESPI_MMIO_BASE_REG4 0xbc +#define ESPI_MMIO_SIZE_REG2 0xc0 + #define ESPI_RXVW_POLARITY 0xac -#define ESPI_IO_RANGE_BASE_REG(base, range) ((base) + ((range) & 3) * 2) -#define ESPI_IO_RANGE_SIZE_REG(base, range) ((base) + ((range) & 3)) -#define ESPI_MMIO_RANGE_BASE_REG(base, range) ((base) + ((range) & 3) * 4) -#define ESPI_MMIO_RANGE_SIZE_REG(base, range) ((base) + ((range) & 3) * 2) +#define ESPI_DECODE_RANGES_PER_REG_GROUP 4 +#define ESPI_DECODE_RANGE_TO_REG_GROUP(range) ((range) / ESPI_DECODE_RANGES_PER_REG_GROUP) +#define ESPI_DECODE_RANGE_TO_REG_OFFSET(range) ((range) % ESPI_DECODE_RANGES_PER_REG_GROUP) + +/* the range parameter needs to be < ESPI_DECODE_RANGES_PER_REG_GROUP */ +#define ESPI_IO_RANGE_BASE_REG(base, range) ((base) + (range) * 2) +#define ESPI_IO_RANGE_SIZE_REG(base, range) ((base) + (range)) +#define ESPI_MMIO_RANGE_BASE_REG(base, range) ((base) + (range) * 4) +#define ESPI_MMIO_RANGE_SIZE_REG(base, range) ((base) + (range) * 2) #endif /* AMD_BLOCK_ESPI_DEF_H */ diff --git a/src/soc/amd/common/block/lpc/espi_util.c b/src/soc/amd/common/block/lpc/espi_util.c index a5f43f4a42..c80734d6a2 100644 --- a/src/soc/amd/common/block/lpc/espi_util.c +++ b/src/soc/amd/common/block/lpc/espi_util.c @@ -62,32 +62,80 @@ static void espi_write8(unsigned int reg, uint8_t val) static inline uint32_t espi_decode_io_range_en_bit(unsigned int idx) { - return ESPI_DECODE_IO_RANGE_EN(idx); + if (ESPI_DECODE_RANGE_TO_REG_GROUP(idx) == 0) + return ESPI_DECODE_IO_RANGE_EN(idx); + else + return ESPI_DECODE_IO_RANGE_EXT_EN(idx - ESPI_DECODE_RANGES_PER_REG_GROUP); } static inline uint32_t espi_decode_mmio_range_en_bit(unsigned int idx) { - return ESPI_DECODE_MMIO_RANGE_EN(idx); + if (ESPI_DECODE_RANGE_TO_REG_GROUP(idx) == 0) + return ESPI_DECODE_MMIO_RANGE_EN(idx); + else + return ESPI_DECODE_MMIO_RANGE_EXT_EN(idx - ESPI_DECODE_RANGES_PER_REG_GROUP); } static inline unsigned int espi_io_range_base_reg(unsigned int idx) { - return ESPI_IO_RANGE_BASE_REG(ESPI_IO_BASE_REG0, idx); + unsigned int reg_base; + switch (ESPI_DECODE_RANGE_TO_REG_GROUP(idx)) { + case 0: + reg_base = ESPI_IO_BASE_REG0; + break; + case 1: + reg_base = ESPI_IO_BASE_REG2; + break; + case 2: + reg_base = ESPI_IO_BASE_REG4; + break; + default: /* case 3 */ + reg_base = ESPI_IO_BASE_REG6; + break; + } + return ESPI_IO_RANGE_BASE_REG(reg_base, ESPI_DECODE_RANGE_TO_REG_OFFSET(idx)); } static inline unsigned int espi_io_range_size_reg(unsigned int idx) { - return ESPI_IO_RANGE_SIZE_REG(ESPI_IO_SIZE0, idx); + unsigned int reg_base; + switch (ESPI_DECODE_RANGE_TO_REG_GROUP(idx)) { + case 0: + reg_base = ESPI_IO_SIZE0; + break; + case 1: + reg_base = ESPI_IO_SIZE1; + break; + case 2: + reg_base = ESPI_IO_SIZE2; + break; + default: /* case 3 */ + reg_base = ESPI_IO_SIZE3; + break; + } + return ESPI_IO_RANGE_SIZE_REG(reg_base, ESPI_DECODE_RANGE_TO_REG_OFFSET(idx)); } static inline unsigned int espi_mmio_range_base_reg(unsigned int idx) { - return ESPI_MMIO_RANGE_BASE_REG(ESPI_MMIO_BASE_REG0, idx); + unsigned int reg_base; + if (ESPI_DECODE_RANGE_TO_REG_GROUP(idx) == 0) + reg_base = ESPI_MMIO_BASE_REG0; + else + reg_base = ESPI_MMIO_BASE_REG4; + + return ESPI_MMIO_RANGE_BASE_REG(reg_base, ESPI_DECODE_RANGE_TO_REG_OFFSET(idx)); } static inline unsigned int espi_mmio_range_size_reg(unsigned int idx) { - return ESPI_MMIO_RANGE_SIZE_REG(ESPI_MMIO_SIZE_REG0, idx); + unsigned int reg_base; + if (ESPI_DECODE_RANGE_TO_REG_GROUP(idx) == 0) + reg_base = ESPI_MMIO_SIZE_REG0; + else + reg_base = ESPI_MMIO_SIZE_REG2; + + return ESPI_MMIO_RANGE_SIZE_REG(reg_base, ESPI_DECODE_RANGE_TO_REG_OFFSET(idx)); } static void espi_enable_decode(uint32_t decode_en)