summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCHLin <CHLIN56@nuvoton.com>2019-04-19 17:47:24 +0800
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2019-04-29 22:37:57 +0000
commit0c96a88928610b357e8bbf6c4d9c71a7cc1d869f (patch)
tree905587131e17f686e8208c376a6b9b8d1ee8e9b7
parent5564fac346f83debfbc765c0bc283c4c17c21d06 (diff)
downloadchrome-ec-0c96a88928610b357e8bbf6c4d9c71a7cc1d869f.tar.gz
npcx: disable the selection of JTAG0 signals due to strap
It was observed that pressing recovery key combination + the other keys, some keys on the keyboard become invalid after system reboots. (see b:129908668 for more detail.) It is because the hardware strap pin for JTAG0 signals is unintentionally triggered. This CL reverts the selection of JTAG signals and set them back to keyboard scan function at system initialization. The revert applies to all real platforms except npcx_evbs. BRANCH=none BUG=b:129908668 TEST=pass "make buildall" TEST=Press the specific key combination, after the system reboots, the keyboard function works normally. On npcx EVBs, the JTAG0 is still functional. Change-Id: I7ede1ea4609466fea50a97b1f60308e4cdfd4544 Signed-off-by: CHLin <CHLIN56@nuvoton.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1585467 Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org> Commit-Queue: Daisuke Nojiri <dnojiri@chromium.org> Tested-by: Daisuke Nojiri <dnojiri@chromium.org>
-rw-r--r--board/npcx7_evb/board.h1
-rw-r--r--board/npcx_evb/board.h1
-rw-r--r--board/npcx_evb_arm/board.h1
-rw-r--r--chip/npcx/build.mk2
-rw-r--r--chip/npcx/lpc.c215
-rw-r--r--chip/npcx/registers.h1
-rw-r--r--chip/npcx/sib.c191
-rw-r--r--chip/npcx/sib_chip.h23
-rw-r--r--chip/npcx/system.c23
-rw-r--r--include/config.h9
10 files changed, 271 insertions, 196 deletions
diff --git a/board/npcx7_evb/board.h b/board/npcx7_evb/board.h
index 9080615006..b4d77e7809 100644
--- a/board/npcx7_evb/board.h
+++ b/board/npcx7_evb/board.h
@@ -25,6 +25,7 @@
#define CONFIG_HOSTCMD_ESPI_VW_SIGNALS /* Use VW signals instead of GPIOs */
/* Optional features */
+#define CONFIG_ENABLE_JTAG_SELECTION
#define CONFIG_BOARD_VERSION_GPIO
#define CONFIG_EXTPOWER_GPIO
#define CONFIG_I2C_MASTER
diff --git a/board/npcx_evb/board.h b/board/npcx_evb/board.h
index 59f6add2d4..b74e7cac4f 100644
--- a/board/npcx_evb/board.h
+++ b/board/npcx_evb/board.h
@@ -30,6 +30,7 @@
#define CONFIG_VBOOT_HASH
#define CONFIG_PWM_KBLIGHT
#define CONFIG_BOARD_VERSION_GPIO
+#define CONFIG_ENABLE_JTAG_SELECTION
/* Optional features for test commands */
#define CONFIG_CMD_TASKREADY
diff --git a/board/npcx_evb_arm/board.h b/board/npcx_evb_arm/board.h
index c6c09b1c58..378f44796c 100644
--- a/board/npcx_evb_arm/board.h
+++ b/board/npcx_evb_arm/board.h
@@ -26,6 +26,7 @@
#define CONFIG_VBOOT_HASH
#define CONFIG_PWM_KBLIGHT
#define CONFIG_BOARD_VERSION_GPIO
+#define CONFIG_ENABLE_JTAG_SELECTION
/* Optional features for test commands */
#define CONFIG_CMD_TASKREADY
diff --git a/chip/npcx/build.mk b/chip/npcx/build.mk
index 166519db62..aa1edb29ca 100644
--- a/chip/npcx/build.mk
+++ b/chip/npcx/build.mk
@@ -17,7 +17,7 @@ CHIP_FAMILY:=npcx5
endif
# Required chip modules
-chip-y=header.o clock.o gpio.o hwtimer.o system.o uart.o uartn.o
+chip-y=header.o clock.o gpio.o hwtimer.o system.o uart.o uartn.o sib.o
chip-y+=system-$(CHIP_FAMILY).o
# Optional chip modules
diff --git a/chip/npcx/lpc.c b/chip/npcx/lpc.c
index 2d4391583e..d310a1cc5a 100644
--- a/chip/npcx/lpc.c
+++ b/chip/npcx/lpc.c
@@ -13,16 +13,14 @@
#include "gpio.h"
#include "hooks.h"
#include "host_command.h"
-#include "hwtimer_chip.h"
#include "keyboard_protocol.h"
#include "lpc.h"
#include "lpc_chip.h"
#include "port80.h"
-#include "pwm.h"
#include "registers.h"
#include "system.h"
+#include "sib_chip.h"
#include "task.h"
-#include "timer.h"
#include "uart.h"
#include "util.h"
#include "system_chip.h"
@@ -40,24 +38,6 @@
#define PMC_ACPI PM_CHAN_1
#define PMC_HOST_CMD PM_CHAN_2
-/* Super-IO index and register definitions */
-#define SIO_OFFSET 0x4E
-#define INDEX_SID 0x20
-#define INDEX_CHPREV 0x24
-#define INDEX_SRID 0x27
-
-/*
- * Timeout to wait for host transaction to be completed.
- *
- * For eSPI - it is 200 us.
- * For LPC - it is 5 us.
- */
-#ifdef CONFIG_HOSTCMD_ESPI
-#define LPC_HOST_TRANSACTION_TIMEOUT_US 200
-#else
-#define LPC_HOST_TRANSACTION_TIMEOUT_US 5
-#endif
-
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 */
@@ -333,81 +313,6 @@ void lpc_keyboard_put_char(uint8_t chr, int send_irq)
}
}
-/*
- * Check host read is not in-progress and no timeout
- */
-static void lpc_sib_wait_host_read_done(void)
-{
- timestamp_t deadline, start;
-
- start = get_time();
- deadline.val = start.val + LPC_HOST_TRANSACTION_TIMEOUT_US;
- while (IS_BIT_SET(NPCX_SIBCTRL, NPCX_SIBCTRL_CSRD)) {
- if (timestamp_expired(deadline, NULL)) {
- CPRINTS("Unexpected time of host read transaction");
- break;
- }
- /* Handle ITIM32 overflow condition */
- __hw_clock_handle_overflow(start.le.hi);
- }
-}
-
-/*
- * Check host write is not in-progress and no timeout
- */
-static void lpc_sib_wait_host_write_done(void)
-{
- timestamp_t deadline, start;
-
- start = get_time();
- deadline.val = start.val + LPC_HOST_TRANSACTION_TIMEOUT_US;
- while (IS_BIT_SET(NPCX_SIBCTRL, NPCX_SIBCTRL_CSWR)) {
- if (timestamp_expired(deadline, NULL)) {
- CPRINTS("Unexpected time of host write transaction");
- break;
- }
- /* Handle ITIM32 overflow condition */
- __hw_clock_handle_overflow(start.le.hi);
- }
-}
-
-/* Emulate host to read Keyboard I/O */
-uint8_t lpc_sib_read_kbc_reg(uint8_t io_offset)
-{
- uint8_t data_value;
-
- /* Disable interrupts */
- interrupt_disable();
-
- /* Lock host keyboard module */
- SET_BIT(NPCX_LKSIOHA, NPCX_LKSIOHA_LKHIKBD);
- /* Verify Core read/write to host modules is not in progress */
- lpc_sib_wait_host_read_done();
- lpc_sib_wait_host_write_done();
- /* Enable Core access to keyboard module */
- SET_BIT(NPCX_CRSMAE, NPCX_CRSMAE_HIKBDAE);
-
- /* Specify the io_offset A0 = 0. the index register is accessed */
- NPCX_IHIOA = io_offset;
-
- /* Start a Core read from host module */
- SET_BIT(NPCX_SIBCTRL, NPCX_SIBCTRL_CSRD);
- /* Wait while Core read operation is in progress */
- lpc_sib_wait_host_read_done();
- /* Read the data */
- data_value = NPCX_IHD;
-
- /* Disable Core access to keyboard module */
- CLEAR_BIT(NPCX_CRSMAE, NPCX_CRSMAE_HIKBDAE);
- /* unlock host keyboard module */
- CLEAR_BIT(NPCX_LKSIOHA, NPCX_LKSIOHA_LKHIKBD);
-
- /* Enable interrupts */
- interrupt_enable();
-
- return data_value;
-}
-
void lpc_keyboard_clear_buffer(void)
{
/*
@@ -423,7 +328,7 @@ void lpc_keyboard_clear_buffer(void)
* Emulate a host read to clear these two flags and also
* deassert IRQ1
*/
- lpc_sib_read_kbc_reg(0x0);
+ sib_read_kbc_reg(0x0);
}
#else
/* Make sure the previous TOH and IRQ has been sent out. */
@@ -671,86 +576,6 @@ static void lpc_sysjump(void)
}
DECLARE_HOOK(HOOK_SYSJUMP, lpc_sysjump, HOOK_PRIO_DEFAULT);
-/* Super-IO read/write function */
-void lpc_sib_write_reg(uint8_t io_offset, uint8_t index_value,
- uint8_t io_data)
-{
- /* Disable interrupts */
- interrupt_disable();
-
- /* Lock host CFG module */
- SET_BIT(NPCX_LKSIOHA, NPCX_LKSIOHA_LKCFG);
- /* Enable Core access to CFG module */
- SET_BIT(NPCX_CRSMAE, NPCX_CRSMAE_CFGAE);
- /* Verify Core read/write to host modules is not in progress */
- lpc_sib_wait_host_read_done();
- lpc_sib_wait_host_write_done();
-
- /* Specify the io_offset A0 = 0. the index register is accessed */
- NPCX_IHIOA = io_offset;
- /* Write the data. This starts the write access to the host module */
- NPCX_IHD = index_value;
- /* Wait while Core write operation is in progress */
- lpc_sib_wait_host_write_done();
-
- /* Specify the io_offset A0 = 1. the data register is accessed */
- NPCX_IHIOA = io_offset+1;
- /* Write the data. This starts the write access to the host module */
- NPCX_IHD = io_data;
- /* Wait while Core write operation is in progress */
- lpc_sib_wait_host_write_done();
-
- /* Disable Core access to CFG module */
- CLEAR_BIT(NPCX_CRSMAE, NPCX_CRSMAE_CFGAE);
- /* unlock host CFG module */
- CLEAR_BIT(NPCX_LKSIOHA, NPCX_LKSIOHA_LKCFG);
-
- /* Enable interrupts */
- interrupt_enable();
-}
-
-uint8_t lpc_sib_read_reg(uint8_t io_offset, uint8_t index_value)
-{
- uint8_t data_value;
-
- /* Disable interrupts */
- interrupt_disable();
-
- /* Lock host CFG module */
- SET_BIT(NPCX_LKSIOHA, NPCX_LKSIOHA_LKCFG);
- /* Enable Core access to CFG module */
- SET_BIT(NPCX_CRSMAE, NPCX_CRSMAE_CFGAE);
- /* Verify Core read/write to host modules is not in progress */
- lpc_sib_wait_host_read_done();
- lpc_sib_wait_host_write_done();
-
- /* Specify the io_offset A0 = 0. the index register is accessed */
- NPCX_IHIOA = io_offset;
- /* Write the data. This starts the write access to the host module */
- NPCX_IHD = index_value;
- /* Wait while Core write operation is in progress */
- lpc_sib_wait_host_write_done();
-
- /* Specify the io_offset A0 = 1. the data register is accessed */
- NPCX_IHIOA = io_offset+1;
- /* Start a Core read from host module */
- SET_BIT(NPCX_SIBCTRL, NPCX_SIBCTRL_CSRD);
- /* Wait while Core read operation is in progress */
- lpc_sib_wait_host_read_done();
- /* Read the data */
- data_value = NPCX_IHD;
-
- /* Disable Core access to CFG module */
- CLEAR_BIT(NPCX_CRSMAE, NPCX_CRSMAE_CFGAE);
- /* unlock host CFG module */
- CLEAR_BIT(NPCX_LKSIOHA, NPCX_LKSIOHA_LKCFG);
-
- /* Enable interrupts */
- interrupt_enable();
-
- return data_value;
-}
-
/* For LPC host register initial via SIB module */
void host_register_init(void)
{
@@ -758,41 +583,41 @@ void host_register_init(void)
SET_BIT(NPCX_SIBCTRL, NPCX_SIBCTRL_CSAE);
/* enable ACPI*/
- lpc_sib_write_reg(SIO_OFFSET, 0x07, 0x11);
- lpc_sib_write_reg(SIO_OFFSET, 0x30, 0x01);
+ sib_write_reg(SIO_OFFSET, 0x07, 0x11);
+ sib_write_reg(SIO_OFFSET, 0x30, 0x01);
/* enable KBC*/
#ifdef HAS_TASK_KEYPROTO
- lpc_sib_write_reg(SIO_OFFSET, 0x07, 0x06);
- lpc_sib_write_reg(SIO_OFFSET, 0x30, 0x01);
+ sib_write_reg(SIO_OFFSET, 0x07, 0x06);
+ sib_write_reg(SIO_OFFSET, 0x30, 0x01);
#endif
/* Setting PMC2 */
/* LDN register = 0x12(PMC2) */
- lpc_sib_write_reg(SIO_OFFSET, 0x07, 0x12);
+ sib_write_reg(SIO_OFFSET, 0x07, 0x12);
/* CMD port is 0x200 */
- lpc_sib_write_reg(SIO_OFFSET, 0x60, 0x02);
- lpc_sib_write_reg(SIO_OFFSET, 0x61, 0x00);
+ sib_write_reg(SIO_OFFSET, 0x60, 0x02);
+ sib_write_reg(SIO_OFFSET, 0x61, 0x00);
/* Data port is 0x204 */
- lpc_sib_write_reg(SIO_OFFSET, 0x62, 0x02);
- lpc_sib_write_reg(SIO_OFFSET, 0x63, 0x04);
+ sib_write_reg(SIO_OFFSET, 0x62, 0x02);
+ sib_write_reg(SIO_OFFSET, 0x63, 0x04);
/* enable PMC2 */
- lpc_sib_write_reg(SIO_OFFSET, 0x30, 0x01);
+ sib_write_reg(SIO_OFFSET, 0x30, 0x01);
/* Setting SHM */
/* LDN register = 0x0F(SHM) */
- lpc_sib_write_reg(SIO_OFFSET, 0x07, 0x0F);
+ sib_write_reg(SIO_OFFSET, 0x07, 0x0F);
/* WIN1&2 mapping to IO */
- lpc_sib_write_reg(SIO_OFFSET, 0xF1,
- lpc_sib_read_reg(SIO_OFFSET, 0xF1) | 0x30);
+ sib_write_reg(SIO_OFFSET, 0xF1,
+ sib_read_reg(SIO_OFFSET, 0xF1) | 0x30);
/* WIN1 as Host Command on the IO:0x0800 */
- lpc_sib_write_reg(SIO_OFFSET, 0xF5, 0x08);
- lpc_sib_write_reg(SIO_OFFSET, 0xF4, 0x00);
+ sib_write_reg(SIO_OFFSET, 0xF5, 0x08);
+ sib_write_reg(SIO_OFFSET, 0xF4, 0x00);
/* WIN2 as MEMMAP on the IO:0x900 */
- lpc_sib_write_reg(SIO_OFFSET, 0xF9, 0x09);
- lpc_sib_write_reg(SIO_OFFSET, 0xF8, 0x00);
+ sib_write_reg(SIO_OFFSET, 0xF9, 0x09);
+ sib_write_reg(SIO_OFFSET, 0xF8, 0x00);
/* enable SHM */
- lpc_sib_write_reg(SIO_OFFSET, 0x30, 0x01);
+ sib_write_reg(SIO_OFFSET, 0x30, 0x01);
CPRINTS("Host settings are done!");
diff --git a/chip/npcx/registers.h b/chip/npcx/registers.h
index be5f236a5b..2b54eeb380 100644
--- a/chip/npcx/registers.h
+++ b/chip/npcx/registers.h
@@ -66,6 +66,7 @@
#define DEBUG_ESPI 0
#define DEBUG_WOV 0
#define DEBUG_CEC 0
+#define DEBUG_SIB 0
/* Modules Map */
#define NPCX_ESPI_BASE_ADDR 0x4000A000
diff --git a/chip/npcx/sib.c b/chip/npcx/sib.c
new file mode 100644
index 0000000000..b8e2e17955
--- /dev/null
+++ b/chip/npcx/sib.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2019 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* NPCX-specific SIB module for Chrome EC */
+
+#include "console.h"
+#include "hwtimer_chip.h"
+#include "registers.h"
+#include "task.h"
+#include "timer.h"
+#include "util.h"
+
+/*
+ * Timeout to wait for host transaction to be completed.
+ *
+ * For eSPI - it is 200 us.
+ * For LPC - it is 5 us.
+ */
+#ifdef CONFIG_HOSTCMD_ESPI
+#define HOST_TRANSACTION_TIMEOUT_US 200
+#else
+#define HOST_TRANSACTION_TIMEOUT_US 5
+#endif
+
+/* Console output macros */
+#ifdef DEBUG_SIB
+#define CPUTS(outstr) cputs(CC_SYSTEM, outstr)
+#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args)
+#else
+#define CPUTS(...)
+#define CPRINTS(...)
+#endif
+
+/*
+ * Check host read is not in-progress and no timeout
+ */
+static void sib_wait_host_read_done(void)
+{
+ timestamp_t deadline, start;
+
+ start = get_time();
+ deadline.val = start.val + HOST_TRANSACTION_TIMEOUT_US;
+ while (IS_BIT_SET(NPCX_SIBCTRL, NPCX_SIBCTRL_CSRD)) {
+ if (timestamp_expired(deadline, NULL)) {
+ CPRINTS("Unexpected time of host read transaction");
+ break;
+ }
+ /* Handle ITIM32 overflow condition */
+ __hw_clock_handle_overflow(start.le.hi);
+ }
+}
+
+/*
+ * Check host write is not in-progress and no timeout
+ */
+static void sib_wait_host_write_done(void)
+{
+ timestamp_t deadline, start;
+
+ start = get_time();
+ deadline.val = start.val + HOST_TRANSACTION_TIMEOUT_US;
+ while (IS_BIT_SET(NPCX_SIBCTRL, NPCX_SIBCTRL_CSWR)) {
+ if (timestamp_expired(deadline, NULL)) {
+ CPRINTS("Unexpected time of host write transaction");
+ break;
+ }
+ /* Handle ITIM32 overflow condition */
+ __hw_clock_handle_overflow(start.le.hi);
+ }
+}
+
+/* Emulate host to read Keyboard I/O */
+uint8_t sib_read_kbc_reg(uint8_t io_offset)
+{
+ uint8_t data_value;
+
+ /* Disable interrupts */
+ interrupt_disable();
+
+ /* Lock host keyboard module */
+ SET_BIT(NPCX_LKSIOHA, NPCX_LKSIOHA_LKHIKBD);
+ /* Verify Core read/write to host modules is not in progress */
+ sib_wait_host_read_done();
+ sib_wait_host_write_done();
+ /* Enable Core access to keyboard module */
+ SET_BIT(NPCX_CRSMAE, NPCX_CRSMAE_HIKBDAE);
+
+ /* Specify the io_offset A0 = 0. the index register is accessed */
+ NPCX_IHIOA = io_offset;
+
+ /* Start a Core read from host module */
+ SET_BIT(NPCX_SIBCTRL, NPCX_SIBCTRL_CSRD);
+ /* Wait while Core read operation is in progress */
+ sib_wait_host_read_done();
+ /* Read the data */
+ data_value = NPCX_IHD;
+
+ /* Disable Core access to keyboard module */
+ CLEAR_BIT(NPCX_CRSMAE, NPCX_CRSMAE_HIKBDAE);
+ /* unlock host keyboard module */
+ CLEAR_BIT(NPCX_LKSIOHA, NPCX_LKSIOHA_LKHIKBD);
+
+ /* Enable interrupts */
+ interrupt_enable();
+
+ return data_value;
+}
+
+/* Super-IO read/write function */
+void sib_write_reg(uint8_t io_offset, uint8_t index_value,
+ uint8_t io_data)
+{
+ /* Disable interrupts */
+ interrupt_disable();
+
+ /* Lock host CFG module */
+ SET_BIT(NPCX_LKSIOHA, NPCX_LKSIOHA_LKCFG);
+ /* Enable Core access to CFG module */
+ SET_BIT(NPCX_CRSMAE, NPCX_CRSMAE_CFGAE);
+ /* Verify Core read/write to host modules is not in progress */
+ sib_wait_host_read_done();
+ sib_wait_host_write_done();
+
+ /* Specify the io_offset A0 = 0. the index register is accessed */
+ NPCX_IHIOA = io_offset;
+ /* Write the data. This starts the write access to the host module */
+ NPCX_IHD = index_value;
+ /* Wait while Core write operation is in progress */
+ sib_wait_host_write_done();
+
+ /* Specify the io_offset A0 = 1. the data register is accessed */
+ NPCX_IHIOA = io_offset+1;
+ /* Write the data. This starts the write access to the host module */
+ NPCX_IHD = io_data;
+ /* Wait while Core write operation is in progress */
+ sib_wait_host_write_done();
+
+ /* Disable Core access to CFG module */
+ CLEAR_BIT(NPCX_CRSMAE, NPCX_CRSMAE_CFGAE);
+ /* unlock host CFG module */
+ CLEAR_BIT(NPCX_LKSIOHA, NPCX_LKSIOHA_LKCFG);
+
+ /* Enable interrupts */
+ interrupt_enable();
+}
+
+uint8_t sib_read_reg(uint8_t io_offset, uint8_t index_value)
+{
+ uint8_t data_value;
+
+ /* Disable interrupts */
+ interrupt_disable();
+
+ /* Lock host CFG module */
+ SET_BIT(NPCX_LKSIOHA, NPCX_LKSIOHA_LKCFG);
+ /* Enable Core access to CFG module */
+ SET_BIT(NPCX_CRSMAE, NPCX_CRSMAE_CFGAE);
+ /* Verify Core read/write to host modules is not in progress */
+ sib_wait_host_read_done();
+ sib_wait_host_write_done();
+
+ /* Specify the io_offset A0 = 0. the index register is accessed */
+ NPCX_IHIOA = io_offset;
+ /* Write the data. This starts the write access to the host module */
+ NPCX_IHD = index_value;
+ /* Wait while Core write operation is in progress */
+ sib_wait_host_write_done();
+
+ /* Specify the io_offset A0 = 1. the data register is accessed */
+ NPCX_IHIOA = io_offset+1;
+ /* Start a Core read from host module */
+ SET_BIT(NPCX_SIBCTRL, NPCX_SIBCTRL_CSRD);
+ /* Wait while Core read operation is in progress */
+ sib_wait_host_read_done();
+ /* Read the data */
+ data_value = NPCX_IHD;
+
+ /* Disable Core access to CFG module */
+ CLEAR_BIT(NPCX_CRSMAE, NPCX_CRSMAE_CFGAE);
+ /* unlock host CFG module */
+ CLEAR_BIT(NPCX_LKSIOHA, NPCX_LKSIOHA_LKCFG);
+
+ /* Enable interrupts */
+ interrupt_enable();
+
+ return data_value;
+}
+
diff --git a/chip/npcx/sib_chip.h b/chip/npcx/sib_chip.h
new file mode 100644
index 0000000000..2341f219b4
--- /dev/null
+++ b/chip/npcx/sib_chip.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2019 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/* NPCX-specific SIB module for Chrome EC */
+
+/* Super-IO index and register definitions */
+#define INDEX_SID 0x20
+#define INDEX_CHPREV 0x24
+#define INDEX_SRID 0x27
+
+#define SIO_OFFSET 0x4E
+
+/* Super-IO register write function */
+void sib_write_reg(uint8_t io_offset, uint8_t index_value,
+ uint8_t io_data);
+/* Super-IO register read function */
+uint8_t sib_read_reg(uint8_t io_offset, uint8_t index_value);
+/* Emulate host to read Keyboard I/O */
+uint8_t sib_read_kbc_reg(uint8_t io_offset);
+
diff --git a/chip/npcx/system.c b/chip/npcx/system.c
index c6440134ad..de7fc527bf 100644
--- a/chip/npcx/system.c
+++ b/chip/npcx/system.c
@@ -16,6 +16,7 @@
#include "hwtimer_chip.h"
#include "registers.h"
#include "rom_chip.h"
+#include "sib_chip.h"
#include "system.h"
#include "system_chip.h"
#include "task.h"
@@ -666,6 +667,28 @@ void chip_pre_init(void)
CLEAR_BIT(NPCX_DEVALT(ALT_GROUP_5), NPCX_DEVALT5_NJEN0_EN);
#endif
#endif
+
+#ifndef CONFIG_ENABLE_JTAG_SELECTION
+ /*
+ * (b/129908668)
+ * This is the workaround to disable the JTAG0 which is enabled
+ * accidentally by a special key combination.
+ */
+ if (!IS_BIT_SET(NPCX_DEVALT(5), NPCX_DEVALT5_NJEN0_EN)) {
+ int data;
+ /* Set DEVALT5.nJEN0_EN to disable JTAG0 */
+ SET_BIT(NPCX_DEVALT(5), NPCX_DEVALT5_NJEN0_EN);
+ /* Enable Core-to-Host Modules Access */
+ SET_BIT(NPCX_SIBCTRL, NPCX_SIBCTRL_CSAE);
+ /* Clear SIOCFD.JEN0_HSL to disable JTAG0 */
+ data = sib_read_reg(SIO_OFFSET, 0x2D);
+ data &= ~0x80;
+ sib_write_reg(SIO_OFFSET, 0x2D, data);
+ /* Disable Core-to-Host Modules Access */
+ CLEAR_BIT(NPCX_SIBCTRL, NPCX_SIBCTRL_CSAE);
+ }
+#endif
+
}
void system_pre_init(void)
diff --git a/include/config.h b/include/config.h
index f2dd9496b6..71038e0c25 100644
--- a/include/config.h
+++ b/include/config.h
@@ -1936,6 +1936,15 @@
/* To define it, if I2C channel C and PECI used at the same time. */
#undef CONFIG_IT83XX_SMCLK2_ON_GPC7
+/*
+ * If this is not defined, the firmware will revert the JTAG selection
+ * triggered by the hardware strap pin.
+ * Un-define this flag by default for all real platforms. see (b/129908668)
+ * If some boards (Ex:EVB) require JTAG function, they can define it in
+ * their board.h
+ */
+#undef CONFIG_ENABLE_JTAG_SELECTION
+
/*****************************************************************************/
/* Keyboard config */