summaryrefslogtreecommitdiff
path: root/src/soc/amd/common/block/include/amdblocks/espi.h
blob: 5d758354c5ba6c316ef5afa7a8220108d94d3352 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef AMD_BLOCK_ESPI_H
#define AMD_BLOCK_ESPI_H

#include <stdint.h>
#include <stddef.h>

/* eSPI MMIO base lives at an offset of 0x10000 from the address in SPI BAR. */
#define ESPI_OFFSET_FROM_BAR			0x10000

#define ESPI_DECODE				0x40
#define  ESPI_DECODE_MMIO_RANGE_EN(range)	(1 << (((range) & 3) + 12))
#define  ESPI_DECODE_IO_RANGE_EN(range)		(1 << (((range) & 3) + 8))
#define  ESPI_DECODE_IO_0x80_EN			(1 << 2)
#define  ESPI_DECODE_IO_0X60_0X64_EN		(1 << 1)
#define  ESPI_DECODE_IO_0X2E_0X2F_EN		(1 << 0)

#define ESPI_IO_BASE_OFFSET_REG0		0x44
#define ESPI_IO_BASE_OFFSET_REG1		0x48
#define ESPI_IO_RANGE_SIZE_OFFSET		0x4c
#define ESPI_MMIO_BASE_OFFSET_REG0		0x50
#define ESPI_MMIO_BASE_OFFSET_REG1		0x54
#define ESPI_MMIO_BASE_OFFSET_REG2		0x58
#define ESPI_MMIO_BASE_OFFSET_REG3		0x5C
#define ESPI_MMIO_OFFSET_SIZE_REG0		0x60
#define ESPI_MMIO_OFFSET_SIZE_REG1		0x64

#define ESPI_IO_RANGE_BASE(range)	(ESPI_IO_BASE_OFFSET_REG0 + ((range) & 3) * 2)
#define ESPI_IO_RANGE_SIZE(range)	(ESPI_IO_RANGE_SIZE_OFFSET + ((range) & 3))
#define ESPI_MMIO_RANGE_BASE(range)	(ESPI_MMIO_BASE_OFFSET_REG0 + ((range) & 3) * 4)
#define ESPI_MMIO_RANGE_SIZE(range)	(ESPI_MMIO_OFFSET_SIZE_REG0 + ((range) & 3) * 2)

#define ESPI_GENERIC_IO_WIN_COUNT		4
#define ESPI_GENERIC_IO_MAX_WIN_SIZE		0x100
#define ESPI_GENERIC_MMIO_WIN_COUNT		4
#define ESPI_GENERIC_MMIO_MAX_WIN_SIZE		0x10000

#define ESPI_SLAVE0_CONFIG			0x68
#define  ESPI_CRC_CHECKING_EN			(1 << 31)
#define  ESPI_ALERT_MODE			(1 << 30)

#define  ESPI_IO_MODE_SHIFT			28
#define  ESPI_IO_MODE_MASK			(0x3 << ESPI_IO_MODE_SHIFT)
#define  ESPI_IO_MODE_VALUE(x)			((x) << ESPI_IO_MODE_SHIFT)

#define  ESPI_OP_FREQ_SHIFT			25
#define  ESPI_OP_FREQ_MASK			(0x7 << ESPI_OP_FREQ_SHIFT)
#define  ESPI_OP_FREQ_VALUE(x)			((x) << ESPI_OP_FREQ_SHIFT)

#define  ESPI_PERIPH_CH_EN			(1 << 3)
#define  ESPI_VW_CH_EN				(1 << 2)
#define  ESPI_OOB_CH_EN				(1 << 1)
#define  ESPI_FLASH_CH_EN			(1 << 0)

/* Virtual wire interrupt polarity. eSPI interrupts are active level high signals. The
   polarity register inverts the incoming signal if the associated bit with the irq is
   0. */
#define ESPI_VW_IRQ_LEVEL_HIGH(x)		(1 << (x))
#define ESPI_VW_IRQ_LEVEL_LOW(x)		(0 << (x))
#define ESPI_VW_IRQ_EDGE_HIGH(x)		(1 << (x))
#define ESPI_VW_IRQ_EDGE_LOW(x)			(0 << (x))

enum espi_io_mode {
	ESPI_IO_MODE_SINGLE = ESPI_IO_MODE_VALUE(0),
	ESPI_IO_MODE_DUAL = ESPI_IO_MODE_VALUE(1),
	ESPI_IO_MODE_QUAD = ESPI_IO_MODE_VALUE(2),
};

enum espi_op_freq {
	ESPI_OP_FREQ_16_MHZ = ESPI_OP_FREQ_VALUE(0),
	ESPI_OP_FREQ_33_MHZ = ESPI_OP_FREQ_VALUE(1),
	ESPI_OP_FREQ_66_MHZ = ESPI_OP_FREQ_VALUE(2),
};

enum espi_alert_pin {
	ESPI_ALERT_PIN_IN_BAND,
	ESPI_ALERT_PIN_PUSH_PULL,
	ESPI_ALERT_PIN_OPEN_DRAIN,
};

struct espi_config {
	/* Bitmap for standard IO decodes. Use ESPI_DECODE_IO_* above. */
	uint32_t std_io_decode_bitmap;

	struct {
		uint16_t base;
		size_t size;
	} generic_io_range[ESPI_GENERIC_IO_WIN_COUNT];

	/* Slave configuration parameters */
	enum espi_io_mode io_mode;
	enum espi_op_freq op_freq_mhz;
	enum espi_alert_pin alert_pin;

	uint32_t crc_check_enable:1;
	uint32_t periph_ch_en:1;
	uint32_t vw_ch_en:1;
	uint32_t oob_ch_en:1;
	uint32_t flash_ch_en:1;
	uint32_t subtractive_decode:1;

	/* Use ESPI_VW_IRQ_* above */
	uint32_t vw_irq_polarity;
};

/*
 * Open I/O window using the provided base and size.
 * Return value: 0 = success, -1 = error.
 */
int espi_open_io_window(uint16_t base, size_t size);

/*
 * Open MMIO window using the provided base and size.
 * Return value: 0 = success, -1 = error.
 */
int espi_open_mmio_window(uint32_t base, size_t size);

/*
 * In cases where eSPI BAR is statically provided by SoC, use that BAR instead of reading
 * SPIBASE. This is required for cases where verstage runs on PSP.
 */
void espi_update_static_bar(uintptr_t bar);

/*
 * Perform eSPI connection setup to the slave. Currently, this supports slave0 only.
 * Returns 0 on success and -1 on error.
 */
int espi_setup(void);

#endif /* AMD_BLOCK_ESPI_H */