summaryrefslogtreecommitdiff
path: root/chip
diff options
context:
space:
mode:
authorJun Lin <CHLin56@nuvoton.com>2021-04-27 16:12:11 +0800
committerCommit Bot <commit-bot@chromium.org>2021-04-29 03:03:47 +0000
commit24be106a07765b0c5416fa8fdb3e976e40dbaf5e (patch)
tree69c574a7edac3803feb7de911269d6f75e0264cb /chip
parent8bc05328420e50ecf17c41e237eb4210a43eef46 (diff)
downloadchrome-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')
-rw-r--r--chip/npcx/lpc.c55
-rw-r--r--chip/npcx/registers.h1
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