diff options
author | Jun Lin <CHLin56@nuvoton.com> | 2021-04-27 16:12:11 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-04-29 03:03:47 +0000 |
commit | 24be106a07765b0c5416fa8fdb3e976e40dbaf5e (patch) | |
tree | 69c574a7edac3803feb7de911269d6f75e0264cb /chip/npcx | |
parent | 8bc05328420e50ecf17c41e237eb4210a43eef46 (diff) | |
download | chrome-ec-24be106a07765b0c5416fa8fdb3e976e40dbaf5e.tar.gz |
npcx9: port80: support 4 bytes mode for eSPI host interface
eSPI PUT_IOWR_SHORT protocol can send a max of 4 bytes of data in a
single transaction. This allows the host to send 4 bytes of the Port80
code at one time. This CL sets the bit OFS0_SEL~OFS3_SEL in the DPAR1
register to let the EC hardware put full 4-bytes of Port80 code to
DP80BUF FIFO. It also groups the 4-byte code into a single 32-bits
variable when necessary by analyzing the offset field in the DP80BUF
register.
BRANCH=none
BUG=b:184872297
TEST=build the image with "#define CONFIG_PORT80_PRINT_IN_INT 1";
connect npcx9_evb to the eSPI host emulator; the host sends a
PUT_IOWR_SHORT transaction to IO address 0x80 with 4 bytes of code
"0xEEE20400"; the EC console shows:
[63.694685 Port 80: 0xeee20400]
Then the host sends a single byte "0xaa" to Port80, the EC console
prints:
[576.531790 Port 80: 0xaa]
Signed-off-by: Jun Lin <CHLin56@nuvoton.com>
Change-Id: I5dfbc0d08172042cb43d72eeb6f0e7da63feccf0
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2847668
Tested-by: CH Lin <chlin56@nuvoton.com>
Reviewed-by: Raul E Rangel <rrangel@chromium.org>
Commit-Queue: CH Lin <chlin56@nuvoton.com>
Diffstat (limited to 'chip/npcx')
-rw-r--r-- | chip/npcx/lpc.c | 55 | ||||
-rw-r--r-- | chip/npcx/registers.h | 1 |
2 files changed, 50 insertions, 6 deletions
diff --git a/chip/npcx/lpc.c b/chip/npcx/lpc.c index d614c1788b..adf78b642d 100644 --- a/chip/npcx/lpc.c +++ b/chip/npcx/lpc.c @@ -39,6 +39,9 @@ #define PMC_ACPI PM_CHAN_1 #define PMC_HOST_CMD PM_CHAN_2 +#define PORT80_MAX_BUF_SIZE 16 +static uint16_t port80_buf[PORT80_MAX_BUF_SIZE]; + static struct host_packet lpc_packet; static struct host_cmd_handler_args host_cmd_args; static uint8_t host_cmd_flags; /* Flags from host command */ @@ -576,18 +579,49 @@ DECLARE_IRQ(NPCX_IRQ_PM_CHAN_OBE, lpc_pmc_obe_interrupt, 4); void lpc_port80_interrupt(void) { - /* Send port 80 data to UART continuously if FIFO is not empty */ - while (IS_BIT_SET(NPCX_DP80STS, 6)) - port_80_write(NPCX_DP80BUF); + uint8_t i; + uint8_t count = 0; + uint32_t code = 0; + + /* buffer Port80 data to the local buffer if FIFO is not empty */ + while (IS_BIT_SET(NPCX_DP80STS, NPCX_DP80STS_FNE)) + port80_buf[count++] = NPCX_DP80BUF; + + for (i = 0; i < count; i++) { + uint8_t offset; + uint32_t buf_data; + + buf_data = port80_buf[i]; + offset = GET_FIELD(buf_data, NPCX_DP80BUF_OFFS_FIELD); + code |= (buf_data & 0xFF) << (8 * offset); + + if (i == count - 1) { + port_80_write(code); + break; + } + + /* peek the offset of the next byte */ + buf_data = port80_buf[i + 1]; + offset = GET_FIELD(buf_data, NPCX_DP80BUF_OFFS_FIELD); + /* + * If the peeked next byte's offset is 0 means it is the start + * of the new code. Pass the current code to Port80 + * common layer. + */ + if (offset == 0) { + port_80_write(code); + code = 0; + } + } /* If FIFO is overflow */ - if (IS_BIT_SET(NPCX_DP80STS, 7)) { - SET_BIT(NPCX_DP80STS, 7); + if (IS_BIT_SET(NPCX_DP80STS, NPCX_DP80STS_FOR)) { + SET_BIT(NPCX_DP80STS, NPCX_DP80STS_FOR); CPRINTS("DP80 FIFO Overflow!"); } /* Clear pending bit of host writing */ - SET_BIT(NPCX_DP80STS, 5); + SET_BIT(NPCX_DP80STS, NPCX_DP80STS_FWR); } DECLARE_IRQ(NPCX_IRQ_PORT80, lpc_port80_interrupt, 4); @@ -657,6 +691,15 @@ void host_register_init(void) /* WIN2 as MEMMAP on the IO:0x900 */ sib_write_reg(SIO_OFFSET, 0xF9, 0x09); sib_write_reg(SIO_OFFSET, 0xF8, 0x00); + + /* + * eSPI allows sending 4 bytes of Port80 code in a single PUT_IOWR_SHORT + * transaction. When setting OFS0_SEL~OFS3_SEL in DPAR1 register to 1, + * EC hardware will put those 4 bytes of Port80 code to DP80BUF FIFO. + * This is only supported when CHIP_FAMILY >= NPCX9. + */ + if (IS_ENABLED(CONFIG_HOSTCMD_ESPI)) + sib_write_reg(SIO_OFFSET, 0xFD, 0x0F); /* enable SHM */ sib_write_reg(SIO_OFFSET, 0x30, 0x01); diff --git a/chip/npcx/registers.h b/chip/npcx/registers.h index 3fc3fbe1e9..aaf7f0477e 100644 --- a/chip/npcx/registers.h +++ b/chip/npcx/registers.h @@ -794,6 +794,7 @@ enum { #define NPCX_PWIN_SIZEI_WPROT 14 #define NPCX_CSEM2 6 #define NPCX_CSEM3 7 +#define NPCX_DP80BUF_OFFS_FIELD FIELD(8, 3) #define NPCX_DP80STS_FWR 5 #define NPCX_DP80STS_FNE 6 #define NPCX_DP80STS_FOR 7 |