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