1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 3 #ifndef AMD_BLOCK_ESPI_H 4 #define AMD_BLOCK_ESPI_H 5 6 #include <types.h> 7 8 /* eSPI MMIO base lives at an offset of 0x10000 from the address in SPI BAR. */ 9 #define ESPI_OFFSET_FROM_BAR 0x10000 10 11 #define ESPI_DECODE 0x40 12 /* more bits defined in soc/common/amd/blocks/lpc/espi_def.h */ 13 #define ESPI_DECODE_IO_0x80_EN (1 << 2) 14 #define ESPI_DECODE_IO_0X60_0X64_EN (1 << 1) 15 #define ESPI_DECODE_IO_0X2E_0X2F_EN (1 << 0) 16 17 /* The extended IO/MMIO decode ranges are only available in SoCs that select 18 SOC_AMD_COMMON_BLOCK_ESPI_EXTENDED_DECODE_RANGES */ 19 #if CONFIG(SOC_AMD_COMMON_BLOCK_ESPI_EXTENDED_DECODE_RANGES) 20 #define ESPI_GENERIC_IO_WIN_COUNT 16 21 #define ESPI_GENERIC_MMIO_WIN_COUNT 5 22 #else 23 #define ESPI_GENERIC_IO_WIN_COUNT 4 24 #define ESPI_GENERIC_MMIO_WIN_COUNT 4 25 #endif 26 27 #define ESPI_GENERIC_IO_MAX_WIN_SIZE 0x100 28 #define ESPI_GENERIC_MMIO_MAX_WIN_SIZE 0x10000 29 30 #define ESPI_SLAVE0_CONFIG 0x68 31 #define ESPI_CRC_CHECKING_EN (1 << 31) 32 #define ESPI_ALERT_MODE (1 << 30) 33 34 #define ESPI_IO_MODE_SHIFT 28 35 #define ESPI_IO_MODE_MASK (0x3 << ESPI_IO_MODE_SHIFT) 36 #define ESPI_IO_MODE_VALUE(x) ((x) << ESPI_IO_MODE_SHIFT) 37 38 #define ESPI_OP_FREQ_SHIFT 25 39 #define ESPI_OP_FREQ_MASK (0x7 << ESPI_OP_FREQ_SHIFT) 40 #define ESPI_OP_FREQ_VALUE(x) ((x) << ESPI_OP_FREQ_SHIFT) 41 42 #define ESPI_PERIPH_CH_EN (1 << 3) 43 #define ESPI_VW_CH_EN (1 << 2) 44 #define ESPI_OOB_CH_EN (1 << 1) 45 #define ESPI_FLASH_CH_EN (1 << 0) 46 47 /* 48 * Internally the SoC uses active low signals for the IRQs. This means what when 49 * the eSPI controller comes out of reset, it's driving its IRQ lines high. 50 * In order to avoid any spurious interrupts the IO-APIC must be configured to 51 * trigger on active low signals. The PIC is only capable of triggering on 52 * active high signals so the hardware has an inverter that converts the signals 53 * before they feed into the PIC. 54 * 55 * +----------+ Active Low 56 * | | | +--------+ 57 * | IO-APIC <------+ | +-----+ LPC | 58 * | | | <---+---> | +--------+ 59 * +----------+ | | 60 * | +-----+ | +--------+ 61 * +---+ AND <---+-----+ eSPI | 62 * | +-----+ | +--------+ 63 * +----------+ | | 64 * | | +--v--+ | +--------+ 65 * | PIC <---+ NOT | +-----+ PIR | 66 * | | ^ +-----+ +--------+ 67 * +----------+ | 68 * | Active High 69 * 70 * The eSPI controller has an inverter that is applied to incoming Virtual Wire 71 * IRQ messages. This allows eSPI peripherals to use active high signaling. 72 * If the peripheral uses active low signaling like the SoC does internally, the 73 * inverter can be disabled. 74 * 75 * The polarity register has the following behavior: 76 * 0: Invert the incoming VW IRQ before outputting to the AND gates. 77 * 1: Do not invert the incoming VW IRQ, but route it directly to the AND 78 * gates. 79 */ 80 #define ESPI_VW_IRQ_LEVEL_HIGH(x) (0 << (x)) 81 #define ESPI_VW_IRQ_LEVEL_LOW(x) (1 << (x)) 82 #define ESPI_VW_IRQ_EDGE_HIGH(x) (0 << (x)) 83 #define ESPI_VW_IRQ_EDGE_LOW(x) (1 << (x)) 84 85 enum espi_io_mode { 86 ESPI_IO_MODE_SINGLE = ESPI_IO_MODE_VALUE(0), 87 ESPI_IO_MODE_DUAL = ESPI_IO_MODE_VALUE(1), 88 ESPI_IO_MODE_QUAD = ESPI_IO_MODE_VALUE(2), 89 }; 90 91 enum espi_op_freq { 92 ESPI_OP_FREQ_16_MHZ = ESPI_OP_FREQ_VALUE(0), 93 ESPI_OP_FREQ_33_MHZ = ESPI_OP_FREQ_VALUE(1), 94 ESPI_OP_FREQ_66_MHZ = ESPI_OP_FREQ_VALUE(2), 95 }; 96 97 enum espi_alert_pin { 98 ESPI_ALERT_PIN_IN_BAND, 99 ESPI_ALERT_PIN_PUSH_PULL, 100 ESPI_ALERT_PIN_OPEN_DRAIN, 101 }; 102 103 struct espi_config { 104 /* Bitmap for standard IO decodes. Use ESPI_DECODE_IO_* above. */ 105 uint32_t std_io_decode_bitmap; 106 107 struct { 108 uint16_t base; 109 size_t size; 110 } generic_io_range[ESPI_GENERIC_IO_WIN_COUNT]; 111 112 /* Slave configuration parameters */ 113 enum espi_io_mode io_mode; 114 enum espi_op_freq op_freq_mhz; 115 enum espi_alert_pin alert_pin; 116 117 uint32_t crc_check_enable:1; 118 uint32_t periph_ch_en:1; 119 uint32_t vw_ch_en:1; 120 uint32_t oob_ch_en:1; 121 uint32_t flash_ch_en:1; 122 uint32_t subtractive_decode:1; 123 124 /* Use ESPI_VW_IRQ_* above */ 125 uint32_t vw_irq_polarity; 126 }; 127 128 /* 129 * Open I/O window using the provided base and size. 130 */ 131 enum cb_err espi_open_io_window(uint16_t base, size_t size); 132 133 /* 134 * Open MMIO window using the provided base and size. 135 */ 136 enum cb_err espi_open_mmio_window(uint32_t base, size_t size); 137 138 /* 139 * In cases where eSPI BAR is statically provided by SoC, use that BAR instead of reading 140 * SPIBASE. This is required for cases where verstage runs on PSP. 141 */ 142 void espi_update_static_bar(uintptr_t bar); 143 144 /* 145 * Perform eSPI connection setup to the slave. Currently, this supports slave0 only. 146 */ 147 enum cb_err espi_setup(void); 148 149 /* Run mainboard configuration needed to set up eSPI */ 150 void mb_set_up_early_espi(void); 151 152 /* Setup eSPI with any mainboard specific initialization. */ 153 void configure_espi_with_mb_hook(void); 154 155 #endif /* AMD_BLOCK_ESPI_H */ 156