Attention is currently required from: Jason Glenesk, Raul Rangel, Marshall Dawson, Fred Reitberger. Felix Held has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/64054 )
Change subject: [WIP,UNTESTED] soc/amd/common/include/espi: add more decode ranges ......................................................................
[WIP,UNTESTED] soc/amd/common/include/espi: add more decode ranges
Sabrina 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 felix-coreboot@felixheld.de Change-Id: Ib761cdf201c35805d68cf5e8e462607ffd9fa017 --- M src/soc/amd/common/block/include/amdblocks/espi.h M src/soc/amd/common/block/lpc/Kconfig M src/soc/amd/common/block/lpc/espi_def.h M src/soc/amd/common/block/lpc/espi_util.c 4 files changed, 103 insertions(+), 16 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/54/64054/1
diff --git a/src/soc/amd/common/block/include/amdblocks/espi.h b/src/soc/amd/common/block/include/amdblocks/espi.h index 9717688..6c811e7 100644 --- a/src/soc/amd/common/block/include/amdblocks/espi.h +++ b/src/soc/amd/common/block/include/amdblocks/espi.h @@ -14,11 +14,23 @@ #define ESPI_DECODE_IO_0X60_0X64_EN (1 << 1) #define ESPI_DECODE_IO_0X2E_0X2F_EN (1 << 0)
-#define ESPI_GENERIC_IO_WIN_COUNT 4 +#define ESPI_GENERIC_IO_WIN_LOW_COUNT 4 +#define ESPI_GENERIC_IO_WIN_EXT_COUNT (3 * 4) #define ESPI_GENERIC_IO_MAX_WIN_SIZE 0x100 -#define ESPI_GENERIC_MMIO_WIN_COUNT 4 +#define ESPI_GENERIC_MMIO_WIN_LOW_COUNT 4 +#define ESPI_GENERIC_MMIO_WIN_EXT_COUNT 1 #define ESPI_GENERIC_MMIO_MAX_WIN_SIZE 0x10000
+/* 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_TOTAL_COUNT (ESPI_GENERIC_IO_WIN_LOW_COUNT + ESPI_GENERIC_IO_WIN_EXT_COUNT) +#define ESPI_GENERIC_MMIO_WIN_TOTAL_COUNT (ESPI_GENERIC_MMIO_WIN_LOW_COUNT + ESPI_GENERIC_MMIO_WIN_EXT_COUNT) +#else +#define ESPI_GENERIC_IO_WIN_TOTAL_COUNT ESPI_GENERIC_IO_WIN_LOW_COUNT +#define ESPI_GENERIC_MMIO_WIN_TOTAL_COUNT ESPI_GENERIC_MMIO_WIN_LOW_COUNT +#endif + #define ESPI_SLAVE0_CONFIG 0x68 #define ESPI_CRC_CHECKING_EN (1 << 31) #define ESPI_ALERT_MODE (1 << 30) @@ -69,7 +81,7 @@ struct { uint16_t base; size_t size; - } generic_io_range[ESPI_GENERIC_IO_WIN_COUNT]; + } generic_io_range[ESPI_GENERIC_IO_WIN_TOTAL_COUNT];
/* Slave configuration parameters */ enum espi_io_mode io_mode; diff --git a/src/soc/amd/common/block/lpc/Kconfig b/src/soc/amd/common/block/lpc/Kconfig index b1db1bd..2de83a5 100644 --- a/src/soc/amd/common/block/lpc/Kconfig +++ b/src/soc/amd/common/block/lpc/Kconfig @@ -36,6 +36,13 @@ 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 dc398a9..cec2054 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,6 +66,20 @@ #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) @@ -71,4 +87,8 @@ #define ESPI_MMIO_RANGE_BASE_REG(base, range) ((base) + ((range) & 3) * 4) #define ESPI_MMIO_RANGE_SIZE_REG(base, range) ((base) + ((range) & 3) * 2)
+/* There are up to 4 I/O decode ranges per I/O decoda range register group */ +#define ESPI_DECODE_RANGE_TO_REG_GROUP(range) ((range) / 4) +#define ESPI_DECODE_RANGE_TO_REG_OFFSET(range) ((range) % 4) + #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 a5f43f4..f2a3fe6 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 inline uint32_t espi_decode_io_range_en_bit(unsigned int idx) { - return ESPI_DECODE_IO_RANGE_EN(idx); + if (idx < ESPI_GENERIC_IO_WIN_LOW_COUNT) { + return ESPI_DECODE_IO_RANGE_EN(idx); + } else { + return ESPI_DECODE_IO_RANGE_EXT_EN(idx - ESPI_GENERIC_IO_WIN_LOW_COUNT); + } }
static inline uint32_t espi_decode_mmio_range_en_bit(unsigned int idx) { - return ESPI_DECODE_MMIO_RANGE_EN(idx); + if (idx < ESPI_GENERIC_MMIO_WIN_LOW_COUNT) { + return ESPI_DECODE_MMIO_RANGE_EN(idx); + } else { + return ESPI_DECODE_MMIO_RANGE_EN(idx - ESPI_GENERIC_MMIO_WIN_LOW_COUNT); + } }
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); + if (idx < ESPI_GENERIC_MMIO_WIN_LOW_COUNT) { + return ESPI_MMIO_RANGE_BASE_REG(ESPI_MMIO_BASE_REG0, idx); + } else { + return ESPI_MMIO_RANGE_BASE_REG(ESPI_MMIO_BASE_REG4, + idx - ESPI_GENERIC_MMIO_WIN_LOW_COUNT); + } }
static inline unsigned int espi_mmio_range_size_reg(unsigned int idx) { - return ESPI_MMIO_RANGE_SIZE_REG(ESPI_MMIO_SIZE_REG0, idx); + if (idx < ESPI_GENERIC_MMIO_WIN_LOW_COUNT) { + return ESPI_MMIO_RANGE_SIZE_REG(ESPI_MMIO_BASE_REG0, idx); + } else { + return ESPI_MMIO_RANGE_SIZE_REG(ESPI_MMIO_BASE_REG2, + idx - ESPI_GENERIC_MMIO_WIN_LOW_COUNT); + } }
static void espi_enable_decode(uint32_t decode_en) @@ -111,7 +159,7 @@ { int i;
- for (i = 0; i < ESPI_GENERIC_IO_WIN_COUNT; i++) { + for (i = 0; i < ESPI_GENERIC_IO_WIN_TOTAL_COUNT; i++) { if (!espi_is_decode_enabled(espi_decode_io_range_en_bit(i))) continue;
@@ -126,7 +174,7 @@ { int i;
- for (i = 0; i < ESPI_GENERIC_IO_WIN_COUNT; i++) { + for (i = 0; i < ESPI_GENERIC_IO_WIN_TOTAL_COUNT; i++) { if (!espi_is_decode_enabled(espi_decode_io_range_en_bit(i))) return i; } @@ -144,11 +192,11 @@ else espi_write16(ESPI_DECODE, 0);
- for (idx = 0; idx < ESPI_GENERIC_IO_WIN_COUNT; idx++) { + for (idx = 0; idx < ESPI_GENERIC_IO_WIN_TOTAL_COUNT; idx++) { espi_write16(espi_io_range_base_reg(idx), 0); espi_write8(espi_io_range_size_reg(idx), 0); } - for (idx = 0; idx < ESPI_GENERIC_MMIO_WIN_COUNT; idx++) { + for (idx = 0; idx < ESPI_GENERIC_MMIO_WIN_TOTAL_COUNT; idx++) { espi_write32(espi_mmio_range_base_reg(idx), 0); espi_write16(espi_mmio_range_size_reg(idx), 0); } @@ -248,7 +296,7 @@ { int i;
- for (i = 0; i < ESPI_GENERIC_MMIO_WIN_COUNT; i++) { + for (i = 0; i < ESPI_GENERIC_MMIO_WIN_TOTAL_COUNT; i++) { if (!espi_is_decode_enabled(espi_decode_mmio_range_en_bit(i))) continue;
@@ -263,7 +311,7 @@ { int i;
- for (i = 0; i < ESPI_GENERIC_MMIO_WIN_COUNT; i++) { + for (i = 0; i < ESPI_GENERIC_MMIO_WIN_TOTAL_COUNT; i++) { if (!espi_is_decode_enabled(espi_decode_mmio_range_en_bit(i))) return i; } @@ -339,7 +387,7 @@
espi_enable_decode(cfg->std_io_decode_bitmap);
- for (i = 0; i < ESPI_GENERIC_IO_WIN_COUNT; i++) { + for (i = 0; i < ESPI_GENERIC_IO_WIN_TOTAL_COUNT; i++) { if (cfg->generic_io_range[i].size == 0) continue; if (espi_open_generic_io_window(cfg->generic_io_range[i].base,