xref: /aosp_15_r20/external/coreboot/src/soc/amd/common/block/include/amdblocks/espi.h (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
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