blob: 45fcc6f416c0f6a593c2ca5bde690d7d37c73b63 [file] [log] [blame]
Furquan Shaikhf318e032020-05-04 23:38:53 -07001/* SPDX-License-Identifier: GPL-2.0-only */
Furquan Shaikhf318e032020-05-04 23:38:53 -07002
3#include <amdblocks/chip.h>
4#include <amdblocks/espi.h>
5#include <amdblocks/lpc.h>
6#include <arch/mmio.h>
7#include <console/console.h>
Furquan Shaikh70063ff52020-05-11 14:28:13 -07008#include <espi.h>
Furquan Shaikhf318e032020-05-04 23:38:53 -07009#include <soc/pci_devs.h>
Furquan Shaikh70063ff52020-05-11 14:28:13 -070010#include <timer.h>
Furquan Shaikhf318e032020-05-04 23:38:53 -070011#include <types.h>
12
Furquan Shaikh98bc9612020-05-09 19:31:55 -070013static uintptr_t espi_bar;
14
15void espi_update_static_bar(uintptr_t bar)
16{
17 espi_bar = bar;
18}
19
Furquan Shaikhf318e032020-05-04 23:38:53 -070020static uintptr_t espi_get_bar(void)
21{
Martin Rothb39e10d2020-07-14 11:08:55 -060022 if (ENV_X86 && !espi_bar)
23 espi_update_static_bar(lpc_get_spibase() + ESPI_OFFSET_FROM_BAR);
Furquan Shaikh98bc9612020-05-09 19:31:55 -070024 return espi_bar;
Furquan Shaikhf318e032020-05-04 23:38:53 -070025}
26
Felix Held92dd6782020-08-10 20:27:58 +020027static uint32_t espi_read32(unsigned int reg)
Furquan Shaikhf318e032020-05-04 23:38:53 -070028{
29 return read32((void *)(espi_get_bar() + reg));
30}
31
Felix Held92dd6782020-08-10 20:27:58 +020032static void espi_write32(unsigned int reg, uint32_t val)
Furquan Shaikhf318e032020-05-04 23:38:53 -070033{
34 write32((void *)(espi_get_bar() + reg), val);
35}
36
Felix Held92dd6782020-08-10 20:27:58 +020037static uint16_t espi_read16(unsigned int reg)
Furquan Shaikhf318e032020-05-04 23:38:53 -070038{
39 return read16((void *)(espi_get_bar() + reg));
40}
41
Felix Held92dd6782020-08-10 20:27:58 +020042static void espi_write16(unsigned int reg, uint16_t val)
Furquan Shaikhf318e032020-05-04 23:38:53 -070043{
44 write16((void *)(espi_get_bar() + reg), val);
45}
46
Felix Held92dd6782020-08-10 20:27:58 +020047static uint8_t espi_read8(unsigned int reg)
Furquan Shaikhf318e032020-05-04 23:38:53 -070048{
49 return read8((void *)(espi_get_bar() + reg));
50}
51
Felix Held92dd6782020-08-10 20:27:58 +020052static void espi_write8(unsigned int reg, uint8_t val)
Furquan Shaikhf318e032020-05-04 23:38:53 -070053{
54 write8((void *)(espi_get_bar() + reg), val);
55}
56
Felix Heldf08fbf82020-08-10 20:30:36 +020057static void espi_enable_decode(uint32_t decode_en)
Furquan Shaikhf318e032020-05-04 23:38:53 -070058{
59 uint32_t val;
60
61 val = espi_read32(ESPI_DECODE);
62 val |= decode_en;
63 espi_write32(ESPI_DECODE, val);
64}
65
Felix Heldf08fbf82020-08-10 20:30:36 +020066static bool espi_is_decode_enabled(uint32_t decode)
Furquan Shaikhf318e032020-05-04 23:38:53 -070067{
68 uint32_t val;
69
70 val = espi_read32(ESPI_DECODE);
71 return !!(val & decode);
72}
73
74static int espi_find_io_window(uint16_t win_base)
75{
76 int i;
77
78 for (i = 0; i < ESPI_GENERIC_IO_WIN_COUNT; i++) {
79 if (!espi_is_decode_enabled(ESPI_DECODE_IO_RANGE_EN(i)))
80 continue;
81
82 if (espi_read16(ESPI_IO_RANGE_BASE(i)) == win_base)
83 return i;
84 }
85
86 return -1;
87}
88
89static int espi_get_unused_io_window(void)
90{
91 int i;
92
93 for (i = 0; i < ESPI_GENERIC_IO_WIN_COUNT; i++) {
94 if (!espi_is_decode_enabled(ESPI_DECODE_IO_RANGE_EN(i)))
95 return i;
96 }
97
98 return -1;
99}
100
Martin Roth011bf132021-03-23 13:20:42 -0600101void espi_clear_decodes(void)
102{
103 unsigned int idx;
104
105 /* First turn off all enable bits, then zero base, range, and size registers */
106 /*
107 * There is currently a bug where the SMU will lock up at times if the port80h enable
108 * bit is cleared. See b/183974365
109 */
110 espi_write16(ESPI_DECODE, (espi_read16(ESPI_DECODE) & ESPI_DECODE_IO_0x80_EN));
111
112 for (idx = 0; idx < ESPI_GENERIC_IO_WIN_COUNT; idx++) {
113 espi_write16(ESPI_IO_RANGE_BASE(idx), 0);
114 espi_write8(ESPI_IO_RANGE_SIZE(idx), 0);
115 }
116 for (idx = 0; idx < ESPI_GENERIC_MMIO_WIN_COUNT; idx++) {
117 espi_write32(ESPI_MMIO_RANGE_BASE(idx), 0);
118 espi_write16(ESPI_MMIO_RANGE_SIZE(idx), 0);
119 }
120}
121
Furquan Shaikhf318e032020-05-04 23:38:53 -0700122/*
123 * Returns decode enable bits for standard IO port addresses. If port address is not supported
124 * by standard decode or if the size of window is not 1, then it returns -1.
125 */
126static int espi_std_io_decode(uint16_t base, size_t size)
127{
Felix Heldc0d4eeb2020-08-10 20:37:16 +0200128 if (size == 2 && base == 0x2e)
129 return ESPI_DECODE_IO_0X2E_0X2F_EN;
130
Furquan Shaikhf318e032020-05-04 23:38:53 -0700131 if (size != 1)
Felix Held4bf419f2020-08-10 20:33:25 +0200132 return -1;
Furquan Shaikhf318e032020-05-04 23:38:53 -0700133
134 switch (base) {
135 case 0x80:
Felix Held4bf419f2020-08-10 20:33:25 +0200136 return ESPI_DECODE_IO_0x80_EN;
Furquan Shaikhf318e032020-05-04 23:38:53 -0700137 case 0x60:
138 case 0x64:
Felix Held4bf419f2020-08-10 20:33:25 +0200139 return ESPI_DECODE_IO_0X60_0X64_EN;
Furquan Shaikhf318e032020-05-04 23:38:53 -0700140 case 0x2e:
141 case 0x2f:
Felix Held4bf419f2020-08-10 20:33:25 +0200142 return ESPI_DECODE_IO_0X2E_0X2F_EN;
Furquan Shaikhf318e032020-05-04 23:38:53 -0700143 default:
Felix Held4bf419f2020-08-10 20:33:25 +0200144 return -1;
Furquan Shaikhf318e032020-05-04 23:38:53 -0700145 }
Furquan Shaikhf318e032020-05-04 23:38:53 -0700146}
147
148static size_t espi_get_io_window_size(int idx)
149{
150 return espi_read8(ESPI_IO_RANGE_SIZE(idx)) + 1;
151}
152
153static void espi_write_io_window(int idx, uint16_t base, size_t size)
154{
155 espi_write16(ESPI_IO_RANGE_BASE(idx), base);
156 espi_write8(ESPI_IO_RANGE_SIZE(idx), size - 1);
157}
158
159static int espi_open_generic_io_window(uint16_t base, size_t size)
160{
161 size_t win_size;
162 int idx;
163
164 for (; size; size -= win_size, base += win_size) {
165 win_size = MIN(size, ESPI_GENERIC_IO_MAX_WIN_SIZE);
166
167 idx = espi_find_io_window(base);
168 if (idx != -1) {
169 size_t curr_size = espi_get_io_window_size(idx);
170
171 if (curr_size > win_size) {
172 printk(BIOS_INFO, "eSPI window already configured to be larger than requested! ");
173 printk(BIOS_INFO, "Base: 0x%x, Requested size: 0x%zx, Actual size: 0x%zx\n",
174 base, win_size, curr_size);
175 } else if (curr_size < win_size) {
176 espi_write_io_window(idx, base, win_size);
177 printk(BIOS_INFO, "eSPI window at base: 0x%x resized from 0x%zx to 0x%zx\n",
178 base, curr_size, win_size);
179 }
180
181 continue;
182 }
183
184 idx = espi_get_unused_io_window();
185 if (idx == -1) {
186 printk(BIOS_ERR, "Cannot open IO window base %x size %zx\n", base,
187 size);
188 printk(BIOS_ERR, "ERROR: No more available IO windows!\n");
189 return -1;
190 }
191
192 espi_write_io_window(idx, base, win_size);
193 espi_enable_decode(ESPI_DECODE_IO_RANGE_EN(idx));
194 }
195
196 return 0;
197}
198
199int espi_open_io_window(uint16_t base, size_t size)
200{
201 int std_io;
202
203 std_io = espi_std_io_decode(base, size);
204 if (std_io != -1) {
205 espi_enable_decode(std_io);
206 return 0;
Felix Heldb026c7c2020-08-10 20:43:53 +0200207 } else {
208 return espi_open_generic_io_window(base, size);
Furquan Shaikhf318e032020-05-04 23:38:53 -0700209 }
Furquan Shaikhf318e032020-05-04 23:38:53 -0700210}
211
212static int espi_find_mmio_window(uint32_t win_base)
213{
214 int i;
215
216 for (i = 0; i < ESPI_GENERIC_MMIO_WIN_COUNT; i++) {
217 if (!espi_is_decode_enabled(ESPI_DECODE_MMIO_RANGE_EN(i)))
218 continue;
219
220 if (espi_read32(ESPI_MMIO_RANGE_BASE(i)) == win_base)
221 return i;
222 }
223
224 return -1;
225}
226
227static int espi_get_unused_mmio_window(void)
228{
229 int i;
230
231 for (i = 0; i < ESPI_GENERIC_MMIO_WIN_COUNT; i++) {
232 if (!espi_is_decode_enabled(ESPI_DECODE_MMIO_RANGE_EN(i)))
233 return i;
234 }
235
236 return -1;
237
238}
239
240static size_t espi_get_mmio_window_size(int idx)
241{
242 return espi_read16(ESPI_MMIO_RANGE_SIZE(idx)) + 1;
243}
244
245static void espi_write_mmio_window(int idx, uint32_t base, size_t size)
246{
247 espi_write32(ESPI_MMIO_RANGE_BASE(idx), base);
248 espi_write16(ESPI_MMIO_RANGE_SIZE(idx), size - 1);
249}
250
251int espi_open_mmio_window(uint32_t base, size_t size)
252{
253 size_t win_size;
254 int idx;
255
256 for (; size; size -= win_size, base += win_size) {
257 win_size = MIN(size, ESPI_GENERIC_MMIO_MAX_WIN_SIZE);
258
259 idx = espi_find_mmio_window(base);
260 if (idx != -1) {
261 size_t curr_size = espi_get_mmio_window_size(idx);
262
263 if (curr_size > win_size) {
264 printk(BIOS_INFO, "eSPI window already configured to be larger than requested! ");
265 printk(BIOS_INFO, "Base: 0x%x, Requested size: 0x%zx, Actual size: 0x%zx\n",
266 base, win_size, curr_size);
267 } else if (curr_size < win_size) {
268 espi_write_mmio_window(idx, base, win_size);
269 printk(BIOS_INFO, "eSPI window at base: 0x%x resized from 0x%zx to 0x%zx\n",
270 base, curr_size, win_size);
271 }
272
273 continue;
274 }
275
276 idx = espi_get_unused_mmio_window();
277 if (idx == -1) {
278 printk(BIOS_ERR, "Cannot open IO window base %x size %zx\n", base,
279 size);
280 printk(BIOS_ERR, "ERROR: No more available MMIO windows!\n");
281 return -1;
282 }
283
284 espi_write_mmio_window(idx, base, win_size);
285 espi_enable_decode(ESPI_DECODE_MMIO_RANGE_EN(idx));
286 }
287
288 return 0;
289}
290
291static const struct espi_config *espi_get_config(void)
292{
293 const struct soc_amd_common_config *soc_cfg = soc_get_common_config();
294
295 if (!soc_cfg)
296 die("Common config structure is NULL!\n");
297
298 return &soc_cfg->espi_config;
299}
300
301void espi_configure_decodes(void)
302{
303 int i;
304 const struct espi_config *cfg = espi_get_config();
305
306 espi_enable_decode(cfg->std_io_decode_bitmap);
307
308 for (i = 0; i < ESPI_GENERIC_IO_WIN_COUNT; i++) {
309 if (cfg->generic_io_range[i].size == 0)
310 continue;
311 espi_open_generic_io_window(cfg->generic_io_range[i].base,
312 cfg->generic_io_range[i].size);
313 }
314}
Furquan Shaikh70063ff52020-05-11 14:28:13 -0700315
316#define ESPI_DN_TX_HDR0 0x00
317enum espi_cmd_type {
318 CMD_TYPE_SET_CONFIGURATION = 0,
319 CMD_TYPE_GET_CONFIGURATION = 1,
320 CMD_TYPE_IN_BAND_RESET = 2,
321 CMD_TYPE_PERIPHERAL = 4,
322 CMD_TYPE_VW = 5,
323 CMD_TYPE_OOB = 6,
324 CMD_TYPE_FLASH = 7,
325};
326
327#define ESPI_DN_TX_HDR1 0x04
328#define ESPI_DN_TX_HDR2 0x08
329#define ESPI_DN_TX_DATA 0x0c
330
331#define ESPI_MASTER_CAP 0x2c
332#define ESPI_VW_MAX_SIZE_SHIFT 13
333#define ESPI_VW_MAX_SIZE_MASK (0x3f << ESPI_VW_MAX_SIZE_SHIFT)
334
335#define ESPI_GLOBAL_CONTROL_1 0x34
336#define ESPI_SUB_DECODE_SLV_SHIFT 3
337#define ESPI_SUB_DECODE_SLV_MASK (0x3 << ESPI_SUB_DECODE_SLV_SHIFT)
338#define ESPI_SUB_DECODE_EN (1 << 2)
339
Raul E Rangel47740122021-04-02 10:16:54 -0600340#define ESPI_SLAVE0_INT_STS 0x70
Furquan Shaikh70063ff52020-05-11 14:28:13 -0700341#define ESPI_STATUS_DNCMD_COMPLETE (1 << 28)
342#define ESPI_STATUS_NON_FATAL_ERROR (1 << 6)
343#define ESPI_STATUS_FATAL_ERROR (1 << 5)
344#define ESPI_STATUS_NO_RESPONSE (1 << 4)
345#define ESPI_STATUS_CRC_ERR (1 << 2)
346#define ESPI_STATUS_WAIT_TIMEOUT (1 << 1)
347#define ESPI_STATUS_BUS_ERROR (1 << 0)
348
349#define ESPI_RXVW_POLARITY 0xac
350
351#define ESPI_CMD_TIMEOUT_US 100
352#define ESPI_CH_READY_TIMEOUT_US 1000
353
354union espi_txhdr0 {
355 uint32_t val;
356 struct {
357 uint32_t cmd_type:3;
358 uint32_t cmd_sts:1;
359 uint32_t slave_sel:2;
360 uint32_t rsvd:2;
361 uint32_t hdata0:8;
362 uint32_t hdata1:8;
363 uint32_t hdata2:8;
364 };
365} __packed;
366
367union espi_txhdr1 {
368 uint32_t val;
369 struct {
370 uint32_t hdata3:8;
371 uint32_t hdata4:8;
372 uint32_t hdata5:8;
373 uint32_t hdata6:8;
374 };
375} __packed;
376
377union espi_txhdr2 {
378 uint32_t val;
379 struct {
380 uint32_t hdata7:8;
381 uint32_t rsvd:24;
382 };
383} __packed;
384
385union espi_txdata {
386 uint32_t val;
387 struct {
388 uint32_t byte0:8;
389 uint32_t byte1:8;
390 uint32_t byte2:8;
391 uint32_t byte3:8;
392 };
393} __packed;
394
395struct espi_cmd {
396 union espi_txhdr0 hdr0;
397 union espi_txhdr1 hdr1;
398 union espi_txhdr2 hdr2;
399 union espi_txdata data;
400} __packed;
401
402/* Wait up to ESPI_CMD_TIMEOUT_US for hardware to clear DNCMD_STATUS bit. */
403static int espi_wait_ready(void)
404{
405 struct stopwatch sw;
406 union espi_txhdr0 hdr0;
407
408 stopwatch_init_usecs_expire(&sw, ESPI_CMD_TIMEOUT_US);
409 do {
410 hdr0.val = espi_read32(ESPI_DN_TX_HDR0);
411 if (!hdr0.cmd_sts)
412 return 0;
413 } while (!stopwatch_expired(&sw));
414
415 return -1;
416}
417
418/* Clear interrupt status register */
419static void espi_clear_status(void)
420{
Raul E Rangel47740122021-04-02 10:16:54 -0600421 uint32_t status = espi_read32(ESPI_SLAVE0_INT_STS);
Furquan Shaikh70063ff52020-05-11 14:28:13 -0700422 if (status)
Raul E Rangel47740122021-04-02 10:16:54 -0600423 espi_write32(ESPI_SLAVE0_INT_STS, status);
Furquan Shaikh70063ff52020-05-11 14:28:13 -0700424}
425
426/*
427 * Wait up to ESPI_CMD_TIMEOUT_US for interrupt status register to update after sending a
428 * command.
429 */
Felix Held1ba38332020-08-10 20:45:30 +0200430static int espi_poll_status(uint32_t *status)
Furquan Shaikh70063ff52020-05-11 14:28:13 -0700431{
432 struct stopwatch sw;
433
434 stopwatch_init_usecs_expire(&sw, ESPI_CMD_TIMEOUT_US);
435 do {
Raul E Rangel47740122021-04-02 10:16:54 -0600436 *status = espi_read32(ESPI_SLAVE0_INT_STS);
Furquan Shaikh70063ff52020-05-11 14:28:13 -0700437 if (*status)
438 return 0;
439 } while (!stopwatch_expired(&sw));
440
441 printk(BIOS_ERR, "Error: eSPI timed out waiting for status update.\n");
442
443 return -1;
444}
445
446static void espi_show_failure(const struct espi_cmd *cmd, const char *str, uint32_t status)
447{
448 printk(BIOS_ERR, "eSPI cmd0-cmd2: %08x %08x %08x data: %08x.\n",
449 cmd->hdr0.val, cmd->hdr1.val, cmd->hdr2.val, cmd->data.val);
450 printk(BIOS_ERR, "%s (Status = 0x%x)\n", str, status);
451}
452
453static int espi_send_command(const struct espi_cmd *cmd)
454{
455 uint32_t status;
456
457 if (CONFIG(ESPI_DEBUG))
458 printk(BIOS_ERR, "eSPI cmd0-cmd2: %08x %08x %08x data: %08x.\n",
459 cmd->hdr0.val, cmd->hdr1.val, cmd->hdr2.val, cmd->data.val);
460
461 if (espi_wait_ready() == -1) {
462 espi_show_failure(cmd, "Error: eSPI was not ready to accept a command", 0);
463 return -1;
464 }
465
466 espi_clear_status();
467
468 espi_write32(ESPI_DN_TX_HDR1, cmd->hdr1.val);
469 espi_write32(ESPI_DN_TX_HDR2, cmd->hdr2.val);
470 espi_write32(ESPI_DN_TX_DATA, cmd->data.val);
471
472 /* Dword 0 must be last as this write triggers the transaction */
473 espi_write32(ESPI_DN_TX_HDR0, cmd->hdr0.val);
474
475 if (espi_wait_ready() == -1) {
476 espi_show_failure(cmd,
477 "Error: eSPI timed out waiting for command to complete", 0);
478 return -1;
479 }
480
Felix Held1ba38332020-08-10 20:45:30 +0200481 if (espi_poll_status(&status) == -1) {
482 espi_show_failure(cmd, "Error: eSPI poll status failed", 0);
Furquan Shaikh70063ff52020-05-11 14:28:13 -0700483 return -1;
484 }
485
486 /* If command did not complete downstream, return error. */
487 if (!(status & ESPI_STATUS_DNCMD_COMPLETE)) {
488 espi_show_failure(cmd, "Error: eSPI downstream command completion failure",
489 status);
490 return -1;
491 }
492
493 if (status & ~ESPI_STATUS_DNCMD_COMPLETE) {
Felix Held316d59c2020-08-10 20:42:20 +0200494 espi_show_failure(cmd, "Error: unexpected eSPI status register bits set",
495 status);
Furquan Shaikh70063ff52020-05-11 14:28:13 -0700496 return -1;
497 }
498
499 return 0;
500}
501
502static int espi_send_reset(void)
503{
504 struct espi_cmd cmd = {
505 .hdr0 = {
506 .cmd_type = CMD_TYPE_IN_BAND_RESET,
507 .cmd_sts = 1,
508 },
509 };
510
511 return espi_send_command(&cmd);
512}
513
514static int espi_send_pltrst_deassert(const struct espi_config *mb_cfg)
515{
516 struct espi_cmd cmd = {
517 .hdr0 = {
518 .cmd_type = CMD_TYPE_VW,
519 .cmd_sts = 1,
520 .hdata0 = 0, /* 1 VW group */
521 },
522 .data = {
523 .byte0 = ESPI_VW_INDEX_SYSTEM_EVENT_3,
524 .byte1 = ESPI_VW_SIGNAL_HIGH(ESPI_VW_PLTRST),
525 },
526 };
527
528 if (!mb_cfg->vw_ch_en)
529 return 0;
530
531 return espi_send_command(&cmd);
532}
533
534/*
535 * In case of get configuration command, hdata0 contains bits 15:8 of the slave register address
536 * and hdata1 contains bits 7:0 of the slave register address.
537 */
538#define ESPI_CONFIGURATION_HDATA0(a) (((a) >> 8) & 0xff)
539#define ESPI_CONFIGURATION_HDATA1(a) ((a) & 0xff)
540
541static int espi_get_configuration(uint16_t slave_reg_addr, uint32_t *config)
542{
543 struct espi_cmd cmd = {
544 .hdr0 = {
545 .cmd_type = CMD_TYPE_GET_CONFIGURATION,
546 .cmd_sts = 1,
547 .hdata0 = ESPI_CONFIGURATION_HDATA0(slave_reg_addr),
548 .hdata1 = ESPI_CONFIGURATION_HDATA1(slave_reg_addr),
549 },
550 };
551
552 *config = 0;
553
554 if (espi_send_command(&cmd))
555 return -1;
556
557 *config = espi_read32(ESPI_DN_TX_HDR1);
558
559 if (CONFIG(ESPI_DEBUG))
560 printk(BIOS_DEBUG, "Get configuration for slave register(0x%x): 0x%x\n",
561 slave_reg_addr, *config);
562
563 return 0;
564}
565
566static int espi_set_configuration(uint16_t slave_reg_addr, uint32_t config)
567{
568 struct espi_cmd cmd = {
569 .hdr0 = {
570 .cmd_type = CMD_TYPE_SET_CONFIGURATION,
571 .cmd_sts = 1,
572 .hdata0 = ESPI_CONFIGURATION_HDATA0(slave_reg_addr),
573 .hdata1 = ESPI_CONFIGURATION_HDATA1(slave_reg_addr),
574 },
575 .hdr1 = {
576 .val = config,
577 },
578 };
579
580 return espi_send_command(&cmd);
581}
582
583static int espi_get_general_configuration(uint32_t *config)
584{
585 int ret = espi_get_configuration(ESPI_SLAVE_GENERAL_CFG, config);
586 if (ret == -1)
587 return -1;
588
589 espi_show_slave_general_configuration(*config);
590 return 0;
591}
592
593static void espi_set_io_mode_config(enum espi_io_mode mb_io_mode, uint32_t slave_caps,
594 uint32_t *slave_config, uint32_t *ctrlr_config)
595{
596 switch (mb_io_mode) {
597 case ESPI_IO_MODE_QUAD:
598 if (espi_slave_supports_quad_io(slave_caps)) {
599 *slave_config |= ESPI_SLAVE_IO_MODE_SEL_QUAD;
600 *ctrlr_config |= ESPI_IO_MODE_QUAD;
601 break;
602 }
603 printk(BIOS_ERR, "Error: eSPI Quad I/O not supported. Dropping to dual mode.\n");
604 /* Intentional fall-through */
605 case ESPI_IO_MODE_DUAL:
606 if (espi_slave_supports_dual_io(slave_caps)) {
607 *slave_config |= ESPI_SLAVE_IO_MODE_SEL_DUAL;
608 *ctrlr_config |= ESPI_IO_MODE_DUAL;
609 break;
610 }
611 printk(BIOS_ERR,
612 "Error: eSPI Dual I/O not supported. Dropping to single mode.\n");
613 /* Intentional fall-through */
614 case ESPI_IO_MODE_SINGLE:
615 /* Single I/O mode is always supported. */
616 *slave_config |= ESPI_SLAVE_IO_MODE_SEL_SINGLE;
617 *ctrlr_config |= ESPI_IO_MODE_SINGLE;
618 break;
619 default:
620 die("No supported eSPI I/O modes!\n");
621 }
622}
623
624static void espi_set_op_freq_config(enum espi_op_freq mb_op_freq, uint32_t slave_caps,
625 uint32_t *slave_config, uint32_t *ctrlr_config)
626{
627 int slave_max_speed_mhz = espi_slave_max_speed_mhz_supported(slave_caps);
628
629 switch (mb_op_freq) {
630 case ESPI_OP_FREQ_66_MHZ:
631 if (slave_max_speed_mhz >= 66) {
632 *slave_config |= ESPI_SLAVE_OP_FREQ_SEL_66_MHZ;
633 *ctrlr_config |= ESPI_OP_FREQ_66_MHZ;
634 break;
635 }
636 printk(BIOS_ERR, "Error: eSPI 66MHz not supported. Dropping to 33MHz.\n");
637 /* Intentional fall-through */
638 case ESPI_OP_FREQ_33_MHZ:
639 if (slave_max_speed_mhz >= 33) {
640 *slave_config |= ESPI_SLAVE_OP_FREQ_SEL_33_MHZ;
641 *ctrlr_config |= ESPI_OP_FREQ_33_MHZ;
642 break;
643 }
644 printk(BIOS_ERR, "Error: eSPI 33MHz not supported. Dropping to 16MHz.\n");
645 /* Intentional fall-through */
646 case ESPI_OP_FREQ_16_MHZ:
647 /*
648 * eSPI spec says the minimum frequency is 20MHz, but AMD datasheets support
649 * 16.7 Mhz.
650 */
651 if (slave_max_speed_mhz > 0) {
652 *slave_config |= ESPI_SLAVE_OP_FREQ_SEL_20_MHZ;
653 *ctrlr_config |= ESPI_OP_FREQ_16_MHZ;
654 break;
655 }
656 /* Intentional fall-through */
657 default:
658 die("No supported eSPI Operating Frequency!\n");
659 }
660}
661
662static int espi_set_general_configuration(const struct espi_config *mb_cfg, uint32_t slave_caps)
663{
664 uint32_t slave_config = 0;
665 uint32_t ctrlr_config = 0;
666
667 if (mb_cfg->crc_check_enable) {
668 slave_config |= ESPI_SLAVE_CRC_ENABLE;
669 ctrlr_config |= ESPI_CRC_CHECKING_EN;
670 }
671
672 if (mb_cfg->dedicated_alert_pin) {
673 slave_config |= ESPI_SLAVE_ALERT_MODE_PIN;
674 ctrlr_config |= ESPI_ALERT_MODE;
675 }
676
677 espi_set_io_mode_config(mb_cfg->io_mode, slave_caps, &slave_config, &ctrlr_config);
678 espi_set_op_freq_config(mb_cfg->op_freq_mhz, slave_caps, &slave_config, &ctrlr_config);
679
680 if (CONFIG(ESPI_DEBUG))
681 printk(BIOS_INFO, "Setting general configuration: slave: 0x%x controller: 0x%x\n",
682 slave_config, ctrlr_config);
683
684 if (espi_set_configuration(ESPI_SLAVE_GENERAL_CFG, slave_config) == -1)
685 return -1;
686
687 espi_write32(ESPI_SLAVE0_CONFIG, ctrlr_config);
688 return 0;
689}
690
691static int espi_wait_channel_ready(uint16_t slave_reg_addr)
692{
693 struct stopwatch sw;
694 uint32_t config;
695
696 stopwatch_init_usecs_expire(&sw, ESPI_CH_READY_TIMEOUT_US);
697 do {
698 espi_get_configuration(slave_reg_addr, &config);
699 if (espi_slave_is_channel_ready(config))
700 return 0;
701 } while (!stopwatch_expired(&sw));
702
703 printk(BIOS_ERR, "Error: Channel is not ready after %d usec (slave addr: 0x%x)\n",
704 ESPI_CH_READY_TIMEOUT_US, slave_reg_addr);
705 return -1;
706
707}
708
709static void espi_enable_ctrlr_channel(uint32_t channel_en)
710{
711 uint32_t reg = espi_read32(ESPI_SLAVE0_CONFIG);
712
713 reg |= channel_en;
714
715 espi_write32(ESPI_SLAVE0_CONFIG, reg);
716}
717
718static int espi_set_channel_configuration(uint32_t slave_config, uint32_t slave_reg_addr,
719 uint32_t ctrlr_enable)
720{
721 if (espi_set_configuration(slave_reg_addr, slave_config) == -1)
722 return -1;
723
724 if (!(slave_config & ESPI_SLAVE_CHANNEL_ENABLE))
725 return 0;
726
727 if (espi_wait_channel_ready(slave_reg_addr) == -1)
728 return -1;
729
730 espi_enable_ctrlr_channel(ctrlr_enable);
731 return 0;
732}
733
734static int espi_setup_vw_channel(const struct espi_config *mb_cfg, uint32_t slave_caps)
735{
736 uint32_t slave_vw_caps;
737 uint32_t ctrlr_vw_caps;
738 uint32_t slave_vw_count_supp;
739 uint32_t ctrlr_vw_count_supp;
740 uint32_t use_vw_count;
741 uint32_t slave_config;
742
743 if (!mb_cfg->vw_ch_en)
744 return 0;
745
746 if (!espi_slave_supports_vw_channel(slave_caps)) {
747 printk(BIOS_ERR, "Error: eSPI slave doesn't support VW channel!\n");
748 return -1;
749 }
750
751 if (espi_get_configuration(ESPI_SLAVE_VW_CFG, &slave_vw_caps) == -1)
752 return -1;
753
754 ctrlr_vw_caps = espi_read32(ESPI_MASTER_CAP);
755 ctrlr_vw_count_supp = (ctrlr_vw_caps & ESPI_VW_MAX_SIZE_MASK) >> ESPI_VW_MAX_SIZE_SHIFT;
756
757 slave_vw_count_supp = espi_slave_get_vw_count_supp(slave_vw_caps);
758 use_vw_count = MIN(ctrlr_vw_count_supp, slave_vw_count_supp);
759
760 slave_config = ESPI_SLAVE_CHANNEL_ENABLE | ESPI_SLAVE_VW_COUNT_SEL_VAL(use_vw_count);
761 return espi_set_channel_configuration(slave_config, ESPI_SLAVE_VW_CFG, ESPI_VW_CH_EN);
762}
763
764static int espi_setup_periph_channel(const struct espi_config *mb_cfg, uint32_t slave_caps)
765{
766 uint32_t slave_config;
767 /* Peripheral channel requires BME bit to be set when enabling the channel. */
768 const uint32_t slave_en_mask = ESPI_SLAVE_CHANNEL_READY |
769 ESPI_SLAVE_PERIPH_BUS_MASTER_ENABLE;
770
771 if (espi_get_configuration(ESPI_SLAVE_PERIPH_CFG, &slave_config) == -1)
772 return -1;
773
774 /*
775 * Peripheral channel is the only one which is enabled on reset. So, if the mainboard
776 * wants to disable it, set configuration to disable peripheral channel. It also
777 * requires that BME bit be cleared.
778 */
779 if (mb_cfg->periph_ch_en) {
780 if (!espi_slave_supports_periph_channel(slave_caps)) {
781 printk(BIOS_ERR, "Error: eSPI slave doesn't support periph channel!\n");
782 return -1;
783 }
784 slave_config |= slave_en_mask;
785 } else {
786 slave_config &= ~slave_en_mask;
787 }
788
789 return espi_set_channel_configuration(slave_config, ESPI_SLAVE_PERIPH_CFG,
790 ESPI_PERIPH_CH_EN);
791}
792
793static int espi_setup_oob_channel(const struct espi_config *mb_cfg, uint32_t slave_caps)
794{
795 uint32_t slave_config;
796
797 if (!mb_cfg->oob_ch_en)
798 return 0;
799
800 if (!espi_slave_supports_oob_channel(slave_caps)) {
801 printk(BIOS_ERR, "Error: eSPI slave doesn't support OOB channel!\n");
802 return -1;
803 }
804
805 if (espi_get_configuration(ESPI_SLAVE_OOB_CFG, &slave_config) == -1)
806 return -1;
807
808 slave_config |= ESPI_SLAVE_CHANNEL_ENABLE;
809
810 return espi_set_channel_configuration(slave_config, ESPI_SLAVE_OOB_CFG,
811 ESPI_OOB_CH_EN);
812}
813
814static int espi_setup_flash_channel(const struct espi_config *mb_cfg, uint32_t slave_caps)
815{
816 uint32_t slave_config;
817
818 if (!mb_cfg->flash_ch_en)
819 return 0;
820
821 if (!espi_slave_supports_flash_channel(slave_caps)) {
822 printk(BIOS_ERR, "Error: eSPI slave doesn't support flash channel!\n");
823 return -1;
824 }
825
826 if (espi_get_configuration(ESPI_SLAVE_FLASH_CFG, &slave_config) == -1)
827 return -1;
828
829 slave_config |= ESPI_SLAVE_CHANNEL_ENABLE;
830
831 return espi_set_channel_configuration(slave_config, ESPI_SLAVE_FLASH_CFG,
832 ESPI_FLASH_CH_EN);
833}
834
835static void espi_set_initial_config(const struct espi_config *mb_cfg)
836{
837 uint32_t espi_initial_mode = ESPI_OP_FREQ_16_MHZ | ESPI_IO_MODE_SINGLE;
838
839 if (mb_cfg->dedicated_alert_pin)
840 espi_initial_mode |= ESPI_ALERT_MODE;
841
842 espi_write32(ESPI_SLAVE0_CONFIG, espi_initial_mode);
843}
844
845static void espi_setup_subtractive_decode(const struct espi_config *mb_cfg)
846{
847 uint32_t global_ctrl_reg;
848 global_ctrl_reg = espi_read32(ESPI_GLOBAL_CONTROL_1);
849
850 if (mb_cfg->subtractive_decode) {
851 global_ctrl_reg &= ~ESPI_SUB_DECODE_SLV_MASK;
852 global_ctrl_reg |= ESPI_SUB_DECODE_EN;
853
854 } else {
855 global_ctrl_reg &= ~ESPI_SUB_DECODE_EN;
856 }
857 espi_write32(ESPI_GLOBAL_CONTROL_1, global_ctrl_reg);
858}
859
860int espi_setup(void)
861{
862 uint32_t slave_caps;
863 const struct espi_config *cfg = espi_get_config();
864
865 /*
866 * Boot sequence: Step 1
867 * Set correct initial configuration to talk to the slave:
868 * Set clock frequency to 16.7MHz and single IO mode.
869 */
870 espi_set_initial_config(cfg);
871
872 /*
873 * Boot sequence: Step 2
874 * Send in-band reset
875 * The resets affects both host and slave devices, so set initial config again.
876 */
877 if (espi_send_reset() == -1) {
878 printk(BIOS_ERR, "Error: In-band reset failed!\n");
879 return -1;
880 }
881 espi_set_initial_config(cfg);
882
883 /*
884 * Boot sequence: Step 3
885 * Get configuration of slave device.
886 */
887 if (espi_get_general_configuration(&slave_caps) == -1) {
888 printk(BIOS_ERR, "Error: Slave GET_CONFIGURATION failed!\n");
889 return -1;
890 }
891
892 /*
893 * Boot sequence:
894 * Step 4: Write slave device general config
895 * Step 5: Set host slave config
896 */
897 if (espi_set_general_configuration(cfg, slave_caps) == -1) {
898 printk(BIOS_ERR, "Error: Slave SET_CONFIGURATION failed!\n");
899 return -1;
900 }
901
902 /*
903 * Setup polarity before enabling the VW channel so any interrupts
904 * received will have the correct polarity.
905 */
906 espi_write32(ESPI_RXVW_POLARITY, cfg->vw_irq_polarity);
907
908 /*
909 * Boot Sequences: Steps 6 - 9
910 * Channel setup
911 */
912 /* Set up VW first so we can deassert PLTRST#. */
913 if (espi_setup_vw_channel(cfg, slave_caps) == -1) {
914 printk(BIOS_ERR, "Error: Setup VW channel failed!\n");
915 return -1;
916 }
917
918 /* De-assert PLTRST# if VW channel is enabled by mainboard. */
919 if (espi_send_pltrst_deassert(cfg) == -1) {
920 printk(BIOS_ERR, "Error: PLTRST deassertion failed!\n");
921 return -1;
922 }
923
924 if (espi_setup_periph_channel(cfg, slave_caps) == -1) {
925 printk(BIOS_ERR, "Error: Setup Periph channel failed!\n");
926 return -1;
927 }
928
929 if (espi_setup_oob_channel(cfg, slave_caps) == -1) {
930 printk(BIOS_ERR, "Error: Setup OOB channel failed!\n");
931 return -1;
932 }
933
934 if (espi_setup_flash_channel(cfg, slave_caps) == -1) {
935 printk(BIOS_ERR, "Error: Setup Flash channel failed!\n");
936 return -1;
937 }
938
939 /* Enable subtractive decode if configured */
Felix Helda2642d02021-02-17 00:32:46 +0100940 espi_setup_subtractive_decode(cfg);
Furquan Shaikh70063ff52020-05-11 14:28:13 -0700941
942 return 0;
943}