Furquan Shaikh | dd52646 | 2020-05-04 22:54:22 -0700 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Furquan Shaikh | dd52646 | 2020-05-04 22:54:22 -0700 | [diff] [blame] | 2 | |
Felix Held | 14e3432 | 2020-11-14 00:30:21 +0100 | [diff] [blame] | 3 | #ifndef AMD_BLOCK_ESPI_H |
| 4 | #define AMD_BLOCK_ESPI_H |
Furquan Shaikh | dd52646 | 2020-05-04 22:54:22 -0700 | [diff] [blame] | 5 | |
Furquan Shaikh | f318e03 | 2020-05-04 23:38:53 -0700 | [diff] [blame] | 6 | #include <stdint.h> |
| 7 | #include <stddef.h> |
| 8 | |
Furquan Shaikh | dd52646 | 2020-05-04 22:54:22 -0700 | [diff] [blame] | 9 | /* eSPI MMIO base lives at an offset of 0x10000 from the address in SPI BAR. */ |
| 10 | #define ESPI_OFFSET_FROM_BAR 0x10000 |
| 11 | |
| 12 | #define ESPI_DECODE 0x40 |
| 13 | #define ESPI_DECODE_MMIO_RANGE_EN(range) (1 << (((range) & 3) + 12)) |
| 14 | #define ESPI_DECODE_IO_RANGE_EN(range) (1 << (((range) & 3) + 8)) |
| 15 | #define ESPI_DECODE_IO_0x80_EN (1 << 2) |
| 16 | #define ESPI_DECODE_IO_0X60_0X64_EN (1 << 1) |
| 17 | #define ESPI_DECODE_IO_0X2E_0X2F_EN (1 << 0) |
| 18 | |
| 19 | #define ESPI_IO_RANGE_BASE(range) (0x44 + ((range) & 3) * 2) |
| 20 | #define ESPI_IO_RANGE_SIZE(range) (0x4c + ((range) & 3)) |
| 21 | #define ESPI_MMIO_RANGE_BASE(range) (0x50 + ((range) & 3) * 4) |
| 22 | #define ESPI_MMIO_RANGE_SIZE(range) (0x60 + ((range) & 3) * 2) |
| 23 | |
| 24 | #define ESPI_GENERIC_IO_WIN_COUNT 4 |
| 25 | #define ESPI_GENERIC_IO_MAX_WIN_SIZE 0x100 |
| 26 | #define ESPI_GENERIC_MMIO_WIN_COUNT 4 |
| 27 | #define ESPI_GENERIC_MMIO_MAX_WIN_SIZE 0x10000 |
| 28 | |
Furquan Shaikh | 70063ff5 | 2020-05-11 14:28:13 -0700 | [diff] [blame] | 29 | #define ESPI_SLAVE0_CONFIG 0x68 |
| 30 | #define ESPI_CRC_CHECKING_EN (1 << 31) |
| 31 | #define ESPI_ALERT_MODE (1 << 30) |
| 32 | |
| 33 | #define ESPI_IO_MODE_SHIFT 28 |
| 34 | #define ESPI_IO_MODE_MASK (0x3 << ESPI_IO_MODE_SHIFT) |
| 35 | #define ESPI_IO_MODE_VALUE(x) ((x) << ESPI_IO_MODE_SHIFT) |
| 36 | |
| 37 | #define ESPI_OP_FREQ_SHIFT 25 |
| 38 | #define ESPI_OP_FREQ_MASK (0x7 << ESPI_OP_FREQ_SHIFT) |
| 39 | #define ESPI_OP_FREQ_VALUE(x) ((x) << ESPI_OP_FREQ_SHIFT) |
| 40 | |
| 41 | #define ESPI_PERIPH_CH_EN (1 << 3) |
| 42 | #define ESPI_VW_CH_EN (1 << 2) |
| 43 | #define ESPI_OOB_CH_EN (1 << 1) |
| 44 | #define ESPI_FLASH_CH_EN (1 << 0) |
| 45 | |
Aaron Durbin | d375854 | 2020-07-02 11:03:44 -0600 | [diff] [blame] | 46 | /* Virtual wire interrupt polarity. eSPI interrupts are active level high signals. The |
| 47 | polarity register inverts the incoming signal if the associated bit with the irq is |
| 48 | 0. */ |
| 49 | #define ESPI_VW_IRQ_LEVEL_HIGH(x) (1 << (x)) |
| 50 | #define ESPI_VW_IRQ_LEVEL_LOW(x) (0 << (x)) |
Furquan Shaikh | 70063ff5 | 2020-05-11 14:28:13 -0700 | [diff] [blame] | 51 | #define ESPI_VW_IRQ_EDGE_HIGH(x) (1 << (x)) |
| 52 | #define ESPI_VW_IRQ_EDGE_LOW(x) (0 << (x)) |
| 53 | |
| 54 | enum espi_io_mode { |
| 55 | ESPI_IO_MODE_SINGLE = ESPI_IO_MODE_VALUE(0), |
| 56 | ESPI_IO_MODE_DUAL = ESPI_IO_MODE_VALUE(1), |
| 57 | ESPI_IO_MODE_QUAD = ESPI_IO_MODE_VALUE(2), |
| 58 | }; |
| 59 | |
| 60 | enum espi_op_freq { |
| 61 | ESPI_OP_FREQ_16_MHZ = ESPI_OP_FREQ_VALUE(0), |
| 62 | ESPI_OP_FREQ_33_MHZ = ESPI_OP_FREQ_VALUE(1), |
| 63 | ESPI_OP_FREQ_66_MHZ = ESPI_OP_FREQ_VALUE(2), |
| 64 | }; |
| 65 | |
Furquan Shaikh | f318e03 | 2020-05-04 23:38:53 -0700 | [diff] [blame] | 66 | struct espi_config { |
| 67 | /* Bitmap for standard IO decodes. Use ESPI_DECODE_IO_* above. */ |
| 68 | uint32_t std_io_decode_bitmap; |
| 69 | |
| 70 | struct { |
| 71 | uint16_t base; |
| 72 | size_t size; |
| 73 | } generic_io_range[ESPI_GENERIC_IO_WIN_COUNT]; |
Furquan Shaikh | 70063ff5 | 2020-05-11 14:28:13 -0700 | [diff] [blame] | 74 | |
| 75 | /* Slave configuration parameters */ |
| 76 | enum espi_io_mode io_mode; |
| 77 | enum espi_op_freq op_freq_mhz; |
| 78 | |
| 79 | uint32_t crc_check_enable:1; |
| 80 | uint32_t dedicated_alert_pin:1; |
| 81 | uint32_t periph_ch_en:1; |
| 82 | uint32_t vw_ch_en:1; |
| 83 | uint32_t oob_ch_en:1; |
| 84 | uint32_t flash_ch_en:1; |
| 85 | uint32_t subtractive_decode:1; |
| 86 | |
| 87 | /* Use ESPI_VW_IRQ_* above */ |
| 88 | uint32_t vw_irq_polarity; |
Furquan Shaikh | f318e03 | 2020-05-04 23:38:53 -0700 | [diff] [blame] | 89 | }; |
| 90 | |
| 91 | /* |
| 92 | * Open I/O window using the provided base and size. |
| 93 | * Return value: 0 = success, -1 = error. |
| 94 | */ |
| 95 | int espi_open_io_window(uint16_t base, size_t size); |
| 96 | |
| 97 | /* |
| 98 | * Open MMIO window using the provided base and size. |
| 99 | * Return value: 0 = success, -1 = error. |
| 100 | */ |
| 101 | int espi_open_mmio_window(uint32_t base, size_t size); |
| 102 | |
| 103 | /* |
Martin Roth | 011bf13 | 2021-03-23 13:20:42 -0600 | [diff] [blame] | 104 | * Clear all configured eSPI memory and I/O decode ranges. This is useful for changing |
| 105 | * the decodes, or if something else has previously setup decode windows that conflict |
| 106 | * with the windows that coreboot needs. |
| 107 | */ |
| 108 | void espi_clear_decodes(void); |
| 109 | |
| 110 | /* |
Furquan Shaikh | 98bc961 | 2020-05-09 19:31:55 -0700 | [diff] [blame] | 111 | * In cases where eSPI BAR is statically provided by SoC, use that BAR instead of reading |
| 112 | * SPIBASE. This is required for cases where verstage runs on PSP. |
| 113 | */ |
| 114 | void espi_update_static_bar(uintptr_t bar); |
| 115 | |
Furquan Shaikh | 70063ff5 | 2020-05-11 14:28:13 -0700 | [diff] [blame] | 116 | /* |
| 117 | * Perform eSPI connection setup to the slave. Currently, this supports slave0 only. |
| 118 | * Returns 0 on success and -1 on error. |
| 119 | */ |
| 120 | int espi_setup(void); |
| 121 | |
Felix Held | 14e3432 | 2020-11-14 00:30:21 +0100 | [diff] [blame] | 122 | #endif /* AMD_BLOCK_ESPI_H */ |