summaryrefslogtreecommitdiff
path: root/chip/npcx
diff options
context:
space:
mode:
authorIan Chao <mlchao@nuvoton.com>2015-07-09 14:53:00 +0800
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-07-25 01:22:32 +0000
commit14bd917343489c09033f0f9c97e7951d5cb2aeec (patch)
tree1722f9d92f5ffb2525eebec68f86b1aab06b3e71 /chip/npcx
parent7de0037538bd0016c9202ad289655cbf4f4d90aa (diff)
downloadchrome-ec-14bd917343489c09033f0f9c97e7951d5cb2aeec.tar.gz
nuc:
Add ECST tool to modify the header used by npcx booter. Modified drivers: 1. i2c.c: Modify for i2c_port design. 2. i2c.c: Fixed bugs when mutil-tasks use the same i2c port and pull-up issue. 3. hwtimer.c: Fixed bug whcih event expired time is behide current timer. 4. lpc.c: Add intializing host settings after pltrst is deasserted. 5. uart.c/clock.c/register.h: Fixed bug which cannot enter deep-idle when gpio is any-edge trigger mode. 6. task.c: Add workaround method for hard fault issue. 7. keyboard_raw.c: Modified for support CONFIG_KEYBOARD_KSO_BASE 8. lpc.c: Modified for support CONFIG_KEYBOARD_IRQ_GPIO 9. lpc.c: fixed obe interrupt bug during 8042 initialization 10.Adjust path of flat files for new Makefile rules 11.Fixed build error on lpc.c without CONFIG_KEYBOARD_IRQ_GPIO BUG=chrome-os-partner:34346 TEST=make buildall -j; test nuvoton IC specific drivers BRANCH=none Change-Id: Icf9494174b245b4026e396be877d578f36b6f6a5 Signed-off-by: Ian Chao <mlchao@nuvoton.com> Reviewed-on: https://chromium-review.googlesource.com/284036 Reviewed-by: Shawn N <shawnn@chromium.org> Tested-by: Shawn N <shawnn@chromium.org> Commit-Queue: Shawn N <shawnn@chromium.org>
Diffstat (limited to 'chip/npcx')
-rw-r--r--chip/npcx/build.mk20
-rw-r--r--chip/npcx/clock.c10
-rw-r--r--chip/npcx/config_chip.h18
-rw-r--r--chip/npcx/gpio.c26
-rw-r--r--chip/npcx/hwtimer.c18
-rw-r--r--chip/npcx/i2c.c107
-rw-r--r--chip/npcx/keyboard_raw.c11
-rw-r--r--chip/npcx/lpc.c238
-rw-r--r--chip/npcx/peci.c2
-rw-r--r--chip/npcx/registers.h44
-rw-r--r--chip/npcx/spiflashfw/ec_npcxflash.c3
-rw-r--r--chip/npcx/uart.c3
12 files changed, 317 insertions, 183 deletions
diff --git a/chip/npcx/build.mk b/chip/npcx/build.mk
index 011396eccc..6a5cd5e213 100644
--- a/chip/npcx/build.mk
+++ b/chip/npcx/build.mk
@@ -32,3 +32,23 @@ chip-$(HAS_TASK_KEYSCAN)+=keyboard_raw.o
npcx-flash-fw=chip/npcx/spiflashfw/ec_npcxflash
npcx-flash-fw-bin=${out}/$(npcx-flash-fw).bin
PROJECT_EXTRA+=${npcx-flash-fw-bin}
+
+# ECST tool is for filling the header used by booter of npcx EC
+show_esct_cmd=$(if $(V),,echo ' ECST ' $(subst $(out)/,,$@) ; )
+
+# ECST options for header
+bld_ecst=${out}/util/ecst -usearmrst -mode bt -ph -i $(1) -o $(2) -nohcrc \
+-nofcrc -flashsize 8 -spimaxclk 50 -spireadmode dual 1> /dev/null
+
+# Replace original one with the flat file including header
+moveflat=mv -f $(1) $(2)
+
+# Commands for ECST
+cmd_ecst=$(show_esct_cmd)$(call moveflat,$@,$@.tmp);$(call bld_ecst,$@.tmp,$@)
+
+# Commands to append npcx header in ec.RO.flat
+cmd_org_ec_elf_to_flat = $(OBJCOPY) --set-section-flags .roshared=share \
+ -O binary $(patsubst %.flat,%.elf,$@) $@
+cmd_npcx_ro_elf_to_flat=$(cmd_org_ec_elf_to_flat);$(cmd_ecst)
+cmd_ec_elf_to_flat = $(if $(filter $(out)/RO/ec.RO.flat, $@), \
+ $(cmd_npcx_ro_elf_to_flat), $(cmd_org_ec_elf_to_flat) )
diff --git a/chip/npcx/clock.c b/chip/npcx/clock.c
index c59516043b..449e4dd8bd 100644
--- a/chip/npcx/clock.c
+++ b/chip/npcx/clock.c
@@ -196,22 +196,18 @@ void clock_uart2gpio(void)
/* Set to GPIO */
npcx_uart2gpio();
/* Enable MIWU for GPIO (UARTRX) */
- npcx_enable_wakeup(1);
- /* Clear Pending bit of GPIO (UARTRX) */
- npcx_clear_wakeup_event();
+ uart_enable_wakeup(1);
}
}
void clock_gpio2uart(void)
{
/* Is Pending bit of GPIO (UARTRX) */
- if (npcx_is_wakeup_from_gpio()) {
- /* Clear Pending bit of GPIO (UARTRX) */
- uart_clear_wakeup_event();
+ if (uart_is_wakeup_from_gpio()) {
/* Refresh console in-use timer */
clock_refresh_console_in_use();
/* Disable MIWU for GPIO (UARTRX) */
- uart_enable_miwu_wakeup(0);
+ uart_enable_wakeup(0);
/* Go back CR_SIN*/
npcx_gpio2uart();
/* Enable uart again */
diff --git a/chip/npcx/config_chip.h b/chip/npcx/config_chip.h
index f7e1541250..f8314f6282 100644
--- a/chip/npcx/config_chip.h
+++ b/chip/npcx/config_chip.h
@@ -19,8 +19,11 @@
#undef CONFIG_UART_TX_BUF_SIZE
#define CONFIG_UART_TX_BUF_SIZE 8192
-/* Interval between HOOK_TICK notifications */
-#define HOOK_TICK_INTERVAL_MS 250
+/*
+ * Interval between HOOK_TICK notifications
+ * Notice instant wake-up from deep-idle cannot exceed 200 ms
+ */
+#define HOOK_TICK_INTERVAL_MS 200
#define HOOK_TICK_INTERVAL (HOOK_TICK_INTERVAL_MS * MSEC)
/* Maximum number of deferrable functions */
@@ -46,12 +49,15 @@
#define CONFIG_STACK_SIZE 4096
/* non-standard task stack sizes */
-#define IDLE_TASK_STACK_SIZE 512
-#define LARGER_TASK_STACK_SIZE 768
-#define SMALLER_TASK_STACK_SIZE 384
+#define IDLE_TASK_STACK_SIZE 512
+#define LARGER_TASK_STACK_SIZE 640
+
+#define CHARGER_TASK_STACK_SIZE 640
+#define HOOKS_TASK_STACK_SIZE 640
+#define CONSOLE_TASK_STACK_SIZE 640
/* Default task stack size */
-#define TASK_STACK_SIZE 512
+#define TASK_STACK_SIZE 512
/* Address of RAM log used by Booter */
#define ADDR_BOOT_RAMLOG 0x100C7FC0
diff --git a/chip/npcx/gpio.c b/chip/npcx/gpio.c
index 34634943b3..51e3d844c8 100644
--- a/chip/npcx/gpio.c
+++ b/chip/npcx/gpio.c
@@ -551,20 +551,34 @@ void gpio_pre_init(void)
int flags;
int i, j;
- uint32_t ksi_mask = (~((1<<KEYBOARD_ROWS)-1)) & KB_ROW_MASK;
- uint32_t ks0_mask = (~((1<<KEYBOARD_COLS)-1)) & KB_COL_MASK;
+ uint32_t ksi_mask = (~((1<<KEYBOARD_ROWS)-1)) & KB_ROW_MASK;
+ uint32_t kso_mask = ((~((1<<KEYBOARD_COLS)-1))
+ << CONFIG_KEYBOARD_KSO_BASE) & KB_COL_MASK;
- /* Set necessary pin mux first */
+#ifdef CONFIG_KEYBOARD_COL2_INVERTED
+ kso_mask |= 1 << (CONFIG_KEYBOARD_KSO_BASE + 2);
+#endif
+
+ /* Set necessary pin mux to GPIO first */
/* Pin_Mux for KSO0-17 & KSI0-7 */
NPCX_DEVALT(ALT_GROUP_7) = (uint8_t)(ksi_mask);
- NPCX_DEVALT(ALT_GROUP_8) = (uint8_t)(ks0_mask);
- NPCX_DEVALT(ALT_GROUP_9) = (uint8_t)(ks0_mask >> 8);
- NPCX_DEVALT(ALT_GROUP_A) |= (uint8_t)(ks0_mask >> 16);
+ NPCX_DEVALT(ALT_GROUP_8) = (uint8_t)(kso_mask);
+ NPCX_DEVALT(ALT_GROUP_9) = (uint8_t)(kso_mask >> 8);
+ NPCX_DEVALT(ALT_GROUP_A) |= (uint8_t)(kso_mask >> 16);
/* Pin_Mux for FIU/SPI (set to GPIO) */
SET_BIT(NPCX_DEVALT(0), NPCX_DEVALT0_GPIO_NO_SPIP);
SET_BIT(NPCX_DEVALT(0), NPCX_DEVALT0_NO_F_SPI);
+ /* Pin_Mux for PWRGD */
+ SET_BIT(NPCX_DEVALT(1), NPCX_DEVALT1_NO_PWRGD);
+
+ /* Pin_Mux for PECI */
+#ifndef CONFIG_PECI
+ SET_BIT(NPCX_DEVALT(0xA), NPCX_DEVALTA_NO_PECI_EN);
+#endif
+
+ /* Pin_Mux for LPC & SHI */
#ifdef CONFIG_SHI
/* Switching to eSPI mode for SHI interface */
NPCX_DEVCNT |= 0x08;
diff --git a/chip/npcx/hwtimer.c b/chip/npcx/hwtimer.c
index 5607222b4d..2104ac942f 100644
--- a/chip/npcx/hwtimer.c
+++ b/chip/npcx/hwtimer.c
@@ -34,6 +34,14 @@ static volatile uint32_t evt_cnt_us_dbg;
static volatile uint32_t cur_cnt_us_dbg;
#endif
+#if !(DEBUG_TMR)
+#define CPUTS(...)
+#define CPRINTS(...)
+#else
+#define CPUTS(outstr) cputs(CC_CLOCK, outstr)
+#define CPRINTS(format, args...) cprints(CC_CLOCK, format, ## args)
+#endif
+
/*****************************************************************************/
/* Internal functions */
void init_hw_timer(int itim_no, enum ITIM_SOURCE_CLOCK_T source)
@@ -57,7 +65,7 @@ void init_hw_timer(int itim_no, enum ITIM_SOURCE_CLOCK_T source)
void __hw_clock_event_set(uint32_t deadline)
{
float inv_evt_tick = INT_32K_CLOCK/(float)SECOND;
- uint32_t evt_cnt_us;
+ int32_t evt_cnt_us;
/* Is deadline min value? */
if (evt_expired_us != 0 && evt_expired_us < deadline)
return;
@@ -68,6 +76,9 @@ void __hw_clock_event_set(uint32_t deadline)
#if DEBUG_TMR
evt_cnt_us_dbg = deadline - __hw_clock_source_read();
#endif
+ /* Deadline is behind current timer */
+ if (evt_cnt_us < 0)
+ evt_cnt_us = 1;
/* Event module disable */
CLEAR_BIT(NPCX_ITCTS(ITIM_EVENT_NO), NPCX_ITCTS_ITEN);
@@ -76,8 +87,11 @@ void __hw_clock_event_set(uint32_t deadline)
* It must exceed evt_expired_us for process_timers function
*/
evt_cnt = ((uint32_t)(evt_cnt_us*inv_evt_tick)+1)-1;
- if (evt_cnt > TICK_EVT_MAX_CNT)
+ if (evt_cnt > TICK_EVT_MAX_CNT) {
+ CPRINTS("Event overflow! 0x%08x, us is %d\r\n",
+ evt_cnt, evt_cnt_us);
evt_cnt = TICK_EVT_MAX_CNT;
+ }
NPCX_ITCNT16(ITIM_EVENT_NO) = evt_cnt;
/* Event module enable */
diff --git a/chip/npcx/i2c.c b/chip/npcx/i2c.c
index fd21aebbf9..d9940b688a 100644
--- a/chip/npcx/i2c.c
+++ b/chip/npcx/i2c.c
@@ -25,9 +25,13 @@
#define CPRINTS(format, args...) cprints(CC_I2C, format, ## args)
#endif
+/* Pull-up bit for I2C */
+#define NPCX_I2C_PUBIT(port, bus) \
+ ((port*2) + bus)
+
/* Data abort timeout unit:ms*/
-#define I2C_ABORT_TIMEOUT 10000
-/* Maximum time we allow for an I2C transfer */
+#define I2C_ABORT_TIMEOUT 35
+/* Maximum time we allow for an I2C transfer (SMB stardard is 25 ms) */
#define I2C_TIMEOUT_US (100*MSEC)
/* Marco functions of I2C */
#define I2C_START(port) SET_BIT(NPCX_SMBCTL1(port), NPCX_SMBCTL1_START)
@@ -94,31 +98,30 @@ int i2c_bus_busy(int port)
return IS_BIT_SET(NPCX_SMBCST(port), NPCX_SMBCST_BB) ? 1 : 0;
}
-void i2c_abort_data(int port)
+int i2c_abort_data(int port)
{
uint16_t timeout = I2C_ABORT_TIMEOUT;
- /* Generate a STOP condition */
- I2C_STOP(port);
-
/* Clear NEGACK, STASTR and BER bits */
SET_BIT(NPCX_SMBST(port), NPCX_SMBST_BER);
SET_BIT(NPCX_SMBST(port), NPCX_SMBST_STASTR);
- /*
- * In Master mode, NEGACK should be cleared only
- * after generating STOP
- */
SET_BIT(NPCX_SMBST(port), NPCX_SMBST_NEGACK);
/* Wait till STOP condition is generated */
while (--timeout) {
- msleep(1);
if (!IS_BIT_SET(NPCX_SMBCTL1(port), NPCX_SMBCTL1_STOP))
break;
+ msleep(1);
}
/* Clear BB (BUS BUSY) bit */
SET_BIT(NPCX_SMBCST(port), NPCX_SMBCST_BB);
+
+ if (timeout == 0) {
+ cprints(CC_I2C, "Abort i2c %02x fail!", port);
+ return 0;
+ } else
+ return 1;
}
void i2c_reset(int port)
@@ -128,21 +131,27 @@ void i2c_reset(int port)
CLEAR_BIT(NPCX_SMBCTL2(port), NPCX_SMBCTL2_ENABLE);
while (--timeout) {
- msleep(1);
/* WAIT FOR SCL & SDA IS HIGH */
if (IS_BIT_SET(NPCX_SMBCTL3(port), NPCX_SMBCTL3_SCL_LVL) &&
IS_BIT_SET(NPCX_SMBCTL3(port), NPCX_SMBCTL3_SDA_LVL))
break;
+ msleep(1);
}
+ if (timeout == 0)
+ cprints(CC_I2C, "Reset i2c %02x fail!", port);
+
/* Enable the SMB module */
SET_BIT(NPCX_SMBCTL2(port), NPCX_SMBCTL2_ENABLE);
}
void i2c_recovery(int port)
{
+ CPUTS("RECOVERY\r\n");
/* Abort data, generating STOP condition */
- i2c_abort_data(port);
+ if (i2c_abort_data(port) == 1 &&
+ i2c_stsobjs[port].err_code == SMB_MASTER_NO_ADDRESS_MATCH)
+ return;
/* Reset i2c port by re-enable i2c port*/
i2c_reset(port);
@@ -204,12 +213,12 @@ inline void i2c_handle_sda_irq(int port)
/* Write the address to the bus R bit*/
I2C_WRITE_BYTE(port, (addr | 0x1));
- CPUTS("-ARR");
+ CPRINTS("-ARR-0x%02x", addr);
} else {/* Transmit mode */
p_status->oper_state = SMB_WRITE_OPER;
/* Write the address to the bus W bit*/
I2C_WRITE_BYTE(port, addr);
- CPUTS("-ARW");
+ CPRINTS("-ARW-0x%02x", addr);
}
/* Completed handling START condition */
return;
@@ -324,6 +333,9 @@ void i2c_master_int_handler (int port)
volatile struct i2c_status *p_status = i2c_stsobjs + port;
/* Condition 1 : A Bus Error has been identified */
if (IS_BIT_SET(NPCX_SMBST(port), NPCX_SMBST_BER)) {
+ /* Generate a STOP condition */
+ I2C_STOP(port);
+ CPUTS("-SP");
/* Clear BER Bit */
SET_BIT(NPCX_SMBST(port), NPCX_SMBST_BER);
/* Set error code */
@@ -336,6 +348,9 @@ void i2c_master_int_handler (int port)
/* Condition 2: A negative acknowledge has occurred */
if (IS_BIT_SET(NPCX_SMBST(port), NPCX_SMBST_NEGACK)) {
+ /* Generate a STOP condition */
+ I2C_STOP(port);
+ CPUTS("-SP");
/* Clear NEGACK Bit */
SET_BIT(NPCX_SMBST(port), NPCX_SMBST_NEGACK);
/* Set error code */
@@ -379,12 +394,20 @@ int chip_i2c_xfer(int port, int slave_addr, const uint8_t *out, int out_size,
{
volatile struct i2c_status *p_status = i2c_stsobjs + port;
- if (port < 0 || port >= i2c_ports_used)
- return EC_ERROR_INVAL;
-
if (out_size == 0 && in_size == 0)
return EC_SUCCESS;
+ interrupt_disable();
+ /* make sure bus is not occupied by the other task */
+ if (p_status->task_waiting != TASK_ID_INVALID) {
+ interrupt_enable();
+ return EC_ERROR_BUSY;
+ }
+
+ /* Assign current task ID */
+ p_status->task_waiting = task_get_current();
+ interrupt_enable();
+
/* Copy data to port struct */
p_status->flags = flags;
p_status->tx_buf = out;
@@ -402,7 +425,6 @@ int chip_i2c_xfer(int port, int slave_addr, const uint8_t *out, int out_size,
p_status->idx_buf = 0;
p_status->err_code = SMB_OK;
-
/* Make sure we're in a good state to start */
if ((flags & I2C_XFER_START) && (i2c_bus_busy(port)
|| (i2c_get_line_levels(port) != I2C_LINE_IDLE))) {
@@ -419,9 +441,6 @@ int chip_i2c_xfer(int port, int slave_addr, const uint8_t *out, int out_size,
CPUTS("\n");
- /* Assign current task ID */
- p_status->task_waiting = task_get_current();
-
/* Start master transaction */
i2c_master_transaction(port);
@@ -485,12 +504,11 @@ int i2c_raw_get_sda(int port)
/* Hooks */
static void i2c_freq_changed(void)
{
- /* I2C is under APB2 */
- int freq;
- int port;
+ int freq, i;
- for (port = 0; port < i2c_ports_used; port++) {
- int bus_freq = i2c_ports[port].kbps;
+ for (i = 0; i < i2c_ports_used; i++) {
+ int bus_freq = i2c_ports[i].kbps;
+ int port = i2c_ports[i].port;
int scl_time;
/* SMB0/1 use core clock & SMB2/3 use apb2 clock */
@@ -520,7 +538,7 @@ DECLARE_HOOK(HOOK_FREQ_CHANGE, i2c_freq_changed, HOOK_PRIO_DEFAULT);
static void i2c_init(void)
{
- int port = 0;
+ int i;
/* Configure pins from GPIOs to I2Cs */
gpio_config_module(MODULE_I2C, 1);
@@ -533,16 +551,37 @@ static void i2c_init(void)
/*
* initialize smb status and register
*/
- for (port = 0; port < i2c_ports_used; port++) {
+ for (i = 0; i < i2c_ports_used; i++) {
+ int port = i2c_ports[i].port;
volatile struct i2c_status *p_status = i2c_stsobjs + port;
/* Configure pull-up for SMB interface pins */
-#ifndef SMB_SUPPORT18V
- /* Enable 3.3V pull-up */
- SET_BIT(NPCX_DEVPU0, port);
+
+ /* Enable 3.3V pull-up or turn to 1.8V support */
+ if (port == NPCX_I2C_PORT0) {
+#if NPCX_I2C0_BUS2
+ SET_BIT(NPCX_DEVPU0, NPCX_I2C_PUBIT(port, 1));
+#else
+ SET_BIT(NPCX_DEVPU0, NPCX_I2C_PUBIT(port, 0));
+#endif
+ } else if (port == NPCX_I2C_PORT2) {
+#ifdef NPCX_I2C2_1P8V
+ SET_BIT(NPCX_LV_GPIO_CTL1, NPCX_LV_GPIO_CTL1_SC2_0_LV);
+ SET_BIT(NPCX_LV_GPIO_CTL1, NPCX_LV_GPIO_CTL1_SD2_0_LV);
#else
- /* Set GPIO Pin voltage judgment to 1.8V */
- SET_BIT(NPCX_LV_GPIO_CTL1, port+1);
+ SET_BIT(NPCX_DEVPU0, NPCX_I2C_PUBIT(port, 0));
#endif
+ } else if (port == NPCX_I2C_PORT3) {
+#ifdef NPCX_I2C3_1P8V
+ SET_BIT(NPCX_LV_GPIO_CTL1, NPCX_LV_GPIO_CTL1_SC3_0_LV);
+ SET_BIT(NPCX_LV_GPIO_CTL1, NPCX_LV_GPIO_CTL1_SD3_0_LV);
+#else
+ SET_BIT(NPCX_DEVPU0, NPCX_I2C_PUBIT(port, 0));
+#endif
+
+ SET_BIT(NPCX_DEVPU0, NPCX_I2C_PUBIT(port, 0));
+ } else {
+ SET_BIT(NPCX_DEVPU0, NPCX_I2C_PUBIT(port, 0));
+ }
/* Enable module - before configuring CTL1 */
SET_BIT(NPCX_SMBCTL2(port), NPCX_SMBCTL2_ENABLE);
diff --git a/chip/npcx/keyboard_raw.c b/chip/npcx/keyboard_raw.c
index f43488a3fa..b52ab61b53 100644
--- a/chip/npcx/keyboard_raw.c
+++ b/chip/npcx/keyboard_raw.c
@@ -84,20 +84,23 @@ test_mockable void keyboard_raw_drive_column(int col)
* Nuvoton Keyboard Scan IP supports 18x8 Matrix
* It also support automatic scan functionality
*/
- uint32_t mask;
+ uint32_t mask, col_out;
+
+ /* Add support for CONFIG_KEYBOARD_KSO_BASE shifting */
+ col_out = col + CONFIG_KEYBOARD_KSO_BASE;
/* Drive all lines to high */
if (col == KEYBOARD_COLUMN_NONE) {
mask = KB_COL_MASK;
#ifdef CONFIG_KEYBOARD_COL2_INVERTED
- gpio_set_level(GPIO_KBD_KSO2, 1);
+ gpio_set_level(GPIO_KBD_KSO2, 0);
#endif
}
/* Set KBSOUT to zero to detect key-press */
else if (col == KEYBOARD_COLUMN_ALL) {
mask = 0;
#ifdef CONFIG_KEYBOARD_COL2_INVERTED
- gpio_set_level(GPIO_KBD_KSO2, 0);
+ gpio_set_level(GPIO_KBD_KSO2, 1);
#endif
}
/* Drive one line for detection */
@@ -108,7 +111,7 @@ test_mockable void keyboard_raw_drive_column(int col)
else
gpio_set_level(GPIO_KBD_KSO2, 0);
#endif
- mask = ((~(1 << col)) & KB_COL_MASK);
+ mask = ((~(1 << col_out)) & KB_COL_MASK);
}
/* Set KBSOUT */
diff --git a/chip/npcx/lpc.c b/chip/npcx/lpc.c
index 6a2a85742f..5f01627c68 100644
--- a/chip/npcx/lpc.c
+++ b/chip/npcx/lpc.c
@@ -25,13 +25,19 @@
#include "system_chip.h"
/* Console output macros */
+#if !(DEBUG_LPC)
+#define CPUTS(...)
+#define CPRINTS(...)
+#else
#define CPUTS(outstr) cputs(CC_LPC, outstr)
#define CPRINTS(format, args...) cprints(CC_LPC, format, ## args)
+#endif
#define LPC_SYSJUMP_TAG 0x4c50 /* "LP" */
-/* Timeout to wait PLTRST is deasserted */
-#define LPC_PLTRST_TIMEOUT_US 800000
+/* PM channel definitions */
+#define PMC_ACPI PM_CHAN_1
+#define PMC_HOST_CMD PM_CHAN_2
/* Super-IO index and register definitions */
#define SIO_OFFSET 0x4E
@@ -39,6 +45,7 @@
#define INDEX_CHPREV 0x24
#define INDEX_SRID 0x27
+static uint8_t plt_rst_l; /* Platform reset assert status */
static uint32_t host_events; /* Currently pending SCI/SMI events */
static uint32_t event_mask[3]; /* Event masks for each type */
static struct host_packet lpc_packet;
@@ -55,9 +62,11 @@ static uint8_t * const cmd_params = (uint8_t *)shm_mem_host_cmd +
static struct ec_lpc_host_args * const lpc_host_args =
(struct ec_lpc_host_args *)shm_mem_host_cmd;
-#ifdef CONFIG_KEYBOARD_IRQ_GPIO
+/*****************************************************************************/
+/* IC specific low-level driver */
static void keyboard_irq_assert(void)
{
+#ifdef CONFIG_KEYBOARD_IRQ_GPIO
/*
* Enforce signal-high for long enough for the signal to be pulled high
* by the external pullup resistor. This ensures the host will see the
@@ -71,27 +80,22 @@ static void keyboard_irq_assert(void)
udelay(4);
/* Set signal high, now that we've generated the edge */
gpio_set_level(CONFIG_KEYBOARD_IRQ_GPIO, 1);
-}
#else
-static inline void keyboard_irq_assert(void)
-{
- /* Use serirq method. */
- /* Using manual IRQ for KBC */
- SET_BIT(NPCX_HIIRQC, 0); /* set IRQ1B to high */
- CLEAR_BIT(NPCX_HICTRL, 0); /* set IRQ1 control by IRQB1 */
-}
+ /*
+ * SERIRQ is automatically sent by KBC
+ */
#endif
+}
-static void lpc_task_enable_irq(void){
-
- task_enable_irq(NPCX_IRQ_SHM);
+static void lpc_task_enable_irq(void)
+{
task_enable_irq(NPCX_IRQ_KBC_IBF);
task_enable_irq(NPCX_IRQ_PM_CHAN_IBF);
task_enable_irq(NPCX_IRQ_PORT80);
}
-static void lpc_task_disable_irq(void){
- task_disable_irq(NPCX_IRQ_SHM);
+static void lpc_task_disable_irq(void)
+{
task_disable_irq(NPCX_IRQ_KBC_IBF);
task_disable_irq(NPCX_IRQ_PM_CHAN_IBF);
task_disable_irq(NPCX_IRQ_PORT80);
@@ -116,7 +120,7 @@ static void lpc_generate_smi(void)
/* Set signal high, now that we've generated the edge */
gpio_set_level(GPIO_PCH_SMI_L, 1);
#else
- NPCX_HIPMIE(PM_CHAN_1) |= NPCX_HIPMIE_SMIE;
+ NPCX_HIPMIE(PMC_ACPI) |= NPCX_HIPMIE_SMIE;
#endif
if (host_events & event_mask[LPC_HOST_EVENT_SMI])
CPRINTS("smi 0x%08x",
@@ -138,7 +142,7 @@ static void lpc_generate_sci(void)
/* Set signal high, now that we've generated the edge */
gpio_set_level(CONFIG_SCI_GPIO, 1);
#else
- SET_BIT(NPCX_HIPMIE(PM_CHAN_1), NPCX_HIPMIE_SCIE);
+ SET_BIT(NPCX_HIPMIE(PMC_ACPI), NPCX_HIPMIE_SCIE);
#endif
if (host_events & event_mask[LPC_HOST_EVENT_SCI])
@@ -206,9 +210,9 @@ static void lpc_send_response(struct host_cmd_handler_args *args)
args->result = EC_RES_INVALID_RESPONSE;
/* Write result to the data byte. This sets the TOH status bit. */
- NPCX_HIPMDO(PM_CHAN_2) = args->result;
+ NPCX_HIPMDO(PMC_HOST_CMD) = args->result;
/* Clear processing flag */
- CLEAR_BIT(NPCX_HIPMST(PM_CHAN_2), 2);
+ CLEAR_BIT(NPCX_HIPMST(PMC_HOST_CMD), 2);
}
static void lpc_send_response_packet(struct host_packet *pkt)
@@ -218,37 +222,43 @@ static void lpc_send_response_packet(struct host_packet *pkt)
return;
/* Write result to the data byte. This sets the TOH status bit. */
- NPCX_HIPMDO(PM_CHAN_2) = pkt->driver_result;
+ NPCX_HIPMDO(PMC_HOST_CMD) = pkt->driver_result;
/* Clear processing flag */
- CLEAR_BIT(NPCX_HIPMST(PM_CHAN_2), 2);
+ CLEAR_BIT(NPCX_HIPMST(PMC_HOST_CMD), 2);
}
int lpc_keyboard_has_char(void)
{
- /* if OBF '1', that mean still have a data in the FIFO */
+ /* if OBF bit is '1', that mean still have a data in DBBOUT */
return (NPCX_HIKMST&0x01) ? 1 : 0;
}
-/* Return true if the FRMH is set */
int lpc_keyboard_input_pending(void)
{
+ /* if IBF bit is '1', that mean still have a data in DBBIN */
return (NPCX_HIKMST&0x02) ? 1 : 0;
}
/* Put a char to host buffer and send IRQ if specified. */
void lpc_keyboard_put_char(uint8_t chr, int send_irq)
{
- UPDATE_BIT(NPCX_HICTRL, NPCX_HICTRL_OBFKIE, send_irq);
NPCX_HIKDO = chr;
- task_enable_irq(NPCX_IRQ_KBC_OBF);
+ CPRINTS("KB put %02x", chr);
+
+ /* Enable OBE interrupt to detect host read data out */
+ SET_BIT(NPCX_HICTRL, NPCX_HICTRL_OBFCIE);
+ task_enable_irq(NPCX_IRQ_KBC_OBE);
+ if (send_irq) {
+ keyboard_irq_assert();
+ }
}
void lpc_keyboard_clear_buffer(void)
{
/* Make sure the previous TOH and IRQ has been sent out. */
udelay(4);
- /*FW_OBF write 1*/
- NPCX_HICTRL |= 0x80;
+ /* Clear OBE flag in host STATUS and HIKMST regs*/
+ SET_BIT(NPCX_HICTRL, NPCX_HICTRL_FW_OBF);
/* Ensure there is no TOH set in this period. */
udelay(4);
}
@@ -278,18 +288,18 @@ static void update_host_event_status(void)
lpc_task_disable_irq();
if (host_events & event_mask[LPC_HOST_EVENT_SMI]) {
/* Only generate SMI for first event */
- if (!(NPCX_HIPMIE(PM_CHAN_1) & NPCX_HIPMIE_SMIE))
+ if (!(NPCX_HIPMIE(PMC_ACPI) & NPCX_HIPMIE_SMIE))
need_smi = 1;
- SET_BIT(NPCX_HIPMIE(PM_CHAN_1), NPCX_HIPMIE_SMIE);
+ SET_BIT(NPCX_HIPMIE(PMC_ACPI), NPCX_HIPMIE_SMIE);
} else
- CLEAR_BIT(NPCX_HIPMIE(PM_CHAN_1), NPCX_HIPMIE_SMIE);
+ CLEAR_BIT(NPCX_HIPMIE(PMC_ACPI), NPCX_HIPMIE_SMIE);
if (host_events & event_mask[LPC_HOST_EVENT_SCI]) {
/* Generate SCI for every event */
need_sci = 1;
- SET_BIT(NPCX_HIPMIE(PM_CHAN_1), NPCX_HIPMIE_SCIE);
+ SET_BIT(NPCX_HIPMIE(PMC_ACPI), NPCX_HIPMIE_SCIE);
} else
- CLEAR_BIT(NPCX_HIPMIE(PM_CHAN_1), NPCX_HIPMIE_SCIE);
+ CLEAR_BIT(NPCX_HIPMIE(PMC_ACPI), NPCX_HIPMIE_SCIE);
/* Copy host events to mapped memory */
*(uint32_t *)host_get_memmap(EC_MEMMAP_HOST_EVENTS) = host_events;
@@ -358,12 +368,24 @@ uint32_t lpc_get_host_event_mask(enum lpc_host_event_type type)
void lpc_set_acpi_status_mask(uint8_t mask)
{
- /* TODO (crbug.com/p/38224): Implement */
+ NPCX_HIPMST(PMC_ACPI) |= mask;
}
void lpc_clear_acpi_status_mask(uint8_t mask)
{
- /* TODO (crbug.com/p/38224): Implement */
+ NPCX_HIPMST(PMC_ACPI) &= ~mask;
+}
+
+/* Enable LPC ACPI-EC interrupts */
+void lpc_enable_acpi_interrupts(void)
+{
+ SET_BIT(NPCX_HIPMCTL(PMC_ACPI), NPCX_HIPMCTL_IBFIE);
+}
+
+/* Disable LPC ACPI-EC interrupts */
+void lpc_disable_acpi_interrupts(void)
+{
+ CLEAR_BIT(NPCX_HIPMCTL(PMC_ACPI), NPCX_HIPMCTL_IBFIE);
}
/**
@@ -376,11 +398,11 @@ static void handle_acpi_write(int is_cmd)
uint8_t value, result;
/* Read command/data; this clears the FRMH status bit. */
- value = NPCX_HIPMDI(PM_CHAN_1);
+ value = NPCX_HIPMDI(PMC_ACPI);
/* Handle whatever this was. */
if (acpi_ap_to_ec(is_cmd, value, &result))
- NPCX_HIPMDO(PM_CHAN_1) = result;
+ NPCX_HIPMDO(PMC_ACPI) = result;
/*
* ACPI 5.0-12.6.1: Generate SCI for Input Buffer Empty / Output Buffer
@@ -400,7 +422,7 @@ static void handle_host_write(int is_cmd)
* Read the command byte. This clears the FRMH bit in
* the status byte.
*/
- host_cmd_args.command = NPCX_HIPMDI(PM_CHAN_2);
+ host_cmd_args.command = NPCX_HIPMDI(PMC_HOST_CMD);
host_cmd_args.result = EC_RES_SUCCESS;
host_cmd_args.send_response = lpc_send_response;
@@ -422,7 +444,7 @@ static void handle_host_write(int is_cmd)
lpc_packet.driver_result = EC_RES_SUCCESS;
/* Set processing flag */
- SET_BIT(NPCX_HIPMST(PM_CHAN_2), 2);
+ SET_BIT(NPCX_HIPMST(PMC_HOST_CMD), 2);
host_packet_receive(&lpc_packet);
return;
@@ -473,46 +495,55 @@ static void handle_host_write(int is_cmd)
host_command_received(&host_cmd_args);
}
-
-void lpc_shm_interrupt(void){
-}
-DECLARE_IRQ(NPCX_IRQ_SHM, lpc_shm_interrupt, 2);
-
+/*****************************************************************************/
+/* Interrupt handlers */
+#ifdef HAS_TASK_KEYPROTO
+/* KB controller input buffer full ISR */
void lpc_kbc_ibf_interrupt(void)
{
-#ifdef CONFIG_KEYBOARD_PROTOCOL_8042
/* If "command" input 0, else 1*/
- keyboard_host_write(NPCX_HIKMDI, (NPCX_HIKMST & 0x08) ? 1 : 0);
-#endif
+ if (lpc_keyboard_input_pending())
+ keyboard_host_write(NPCX_HIKMDI, (NPCX_HIKMST & 0x08) ? 1 : 0);
+ CPRINTS("ibf isr %02x", NPCX_HIKMDI);
+ task_wake(TASK_ID_KEYPROTO);
}
DECLARE_IRQ(NPCX_IRQ_KBC_IBF, lpc_kbc_ibf_interrupt, 2);
-void lpc_kbc_obf_interrupt(void){
- /* reserve for future handle */
- if (!IS_BIT_SET(NPCX_HICTRL, 0)) {
- SET_BIT(NPCX_HICTRL, 0); /* back to H/W control of IRQ1 */
- CLEAR_BIT(NPCX_HIIRQC, 0); /* back to default of IRQB1 */
- }
- task_disable_irq(NPCX_IRQ_KBC_OBF);
+/* KB controller output buffer empty ISR */
+void lpc_kbc_obe_interrupt(void)
+{
+ /* Disable KBC OBE interrupt */
+ CLEAR_BIT(NPCX_HICTRL, NPCX_HICTRL_OBFCIE);
+ task_disable_irq(NPCX_IRQ_KBC_OBE);
+
+ CPRINTS("obe isr %02x", NPCX_HIKMST);
+ task_wake(TASK_ID_KEYPROTO);
}
-DECLARE_IRQ(NPCX_IRQ_KBC_OBF, lpc_kbc_obf_interrupt, 2);
+DECLARE_IRQ(NPCX_IRQ_KBC_OBE, lpc_kbc_obe_interrupt, 2);
+#endif
-void lpc_pmc_ibf_interrupt(void){
+/* PM channel input buffer full ISR */
+void lpc_pmc_ibf_interrupt(void)
+{
/* Channel-1 for ACPI usage*/
/* Channel-2 for Host Command usage , so the argument data had been
* put on the share memory firstly*/
- if (NPCX_HIPMST(PM_CHAN_1) & 0x02)
- handle_acpi_write((NPCX_HIPMST(PM_CHAN_1)&0x08) ? 1 : 0);
- else if (NPCX_HIPMST(PM_CHAN_2)&0x02)
- handle_host_write((NPCX_HIPMST(PM_CHAN_2)&0x08) ? 1 : 0);
+ if (NPCX_HIPMST(PMC_ACPI) & 0x02)
+ handle_acpi_write((NPCX_HIPMST(PMC_ACPI)&0x08) ? 1 : 0);
+ else if (NPCX_HIPMST(PMC_HOST_CMD) & 0x02)
+ handle_host_write((NPCX_HIPMST(PMC_HOST_CMD)&0x08) ? 1 : 0);
}
DECLARE_IRQ(NPCX_IRQ_PM_CHAN_IBF, lpc_pmc_ibf_interrupt, 2);
-void lpc_pmc_obf_interrupt(void){
+/* PM channel output buffer empty ISR */
+void lpc_pmc_obe_interrupt(void)
+{
}
-DECLARE_IRQ(NPCX_IRQ_PM_CHAN_OBF, lpc_pmc_obf_interrupt, 2);
+DECLARE_IRQ(NPCX_IRQ_PM_CHAN_OBE, lpc_pmc_obe_interrupt, 2);
+
-void lpc_port80_interrupt(void){
+void lpc_port80_interrupt(void)
+{
port_80_write((NPCX_GLUE_SDPD0<<0) | (NPCX_GLUE_SDPD1<<8));
/* No matter what , just clear error status bit */
SET_BIT(NPCX_DP80STS, 7);
@@ -546,12 +577,6 @@ static void lpc_post_sysjump(void)
memcpy(event_mask, prev_mask, sizeof(event_mask));
}
-int lpc_get_pltrst_asserted(void)
-{
- /* Read PLTRST status */
- return (NPCX_MSWCTL1 & 0x04) ? 1 : 0;
-}
-
/* Super-IO read/write function */
void lpc_sib_write_reg(uint8_t io_offset, uint8_t index_value,
uint8_t io_data)
@@ -650,20 +675,17 @@ uint8_t lpc_sib_read_reg(uint8_t io_offset, uint8_t index_value)
}
/* For LPC host register initial via SIB module */
-void lpc_host_register_init(void){
-
- timestamp_t deadline;
-
- deadline.val = 0;
- deadline = get_time();
- deadline.val += LPC_PLTRST_TIMEOUT_US;
+void lpc_host_register_init(void)
+{
+ /* enable ACPI*/
+ lpc_sib_write_reg(SIO_OFFSET, 0x07, 0x11);
+ lpc_sib_write_reg(SIO_OFFSET, 0x30, 0x01);
- /* Make sure PLTRST is de-asserted. Or any setting for LPC is useless */
- while (lpc_get_pltrst_asserted())
- if (timestamp_expired(deadline, NULL)) {
- CPRINTS("PLTRST is asserted. LPC settings are ignored");
- return;
- }
+ /* enable KBC*/
+ lpc_sib_write_reg(SIO_OFFSET, 0x07, 0x05);
+ lpc_sib_write_reg(SIO_OFFSET, 0x30, 0x01);
+ lpc_sib_write_reg(SIO_OFFSET, 0x07, 0x06);
+ lpc_sib_write_reg(SIO_OFFSET, 0x30, 0x01);
/* Setting PMC2 */
/* LDN register = 0x12(PMC2) */
@@ -696,6 +718,25 @@ void lpc_host_register_init(void){
lpc_sib_write_reg(SIO_OFFSET, 0xF8, 0x00);
/* enable SHM */
lpc_sib_write_reg(SIO_OFFSET, 0x30, 0x01);
+ CPRINTS("Host settings are done!");
+
+}
+
+int lpc_get_pltrst_asserted(void)
+{
+ uint8_t cur_plt_rst_l;
+ /* Read current PLTRST status */
+ cur_plt_rst_l = (NPCX_MSWCTL1 & 0x04) ? 1 : 0;
+
+ /*
+ * If plt_rst is deasserted for the first time
+ * Initialize all lpc settings
+ */
+ if (cur_plt_rst_l == 0 && plt_rst_l == 1)
+ lpc_host_register_init();
+
+ plt_rst_l = cur_plt_rst_l;
+ return plt_rst_l;
}
static void lpc_init(void)
@@ -741,12 +782,12 @@ static void lpc_init(void)
NPCX_WIN_WR_PROT(1) = 0xFF;
/* Turn on PMC2 for Host Command usage */
- SET_BIT(NPCX_HIPMCTL(PM_CHAN_2), 0);
- SET_BIT(NPCX_HIPMCTL(PM_CHAN_2), 1);
+ SET_BIT(NPCX_HIPMCTL(PMC_HOST_CMD), 0);
+ SET_BIT(NPCX_HIPMCTL(PMC_HOST_CMD), 1);
/* enable PMC2 IRQ */
- SET_BIT(NPCX_HIPMIE(PM_CHAN_2), 0);
+ SET_BIT(NPCX_HIPMIE(PMC_HOST_CMD), 0);
/* IRQ control from HW */
- SET_BIT(NPCX_HIPMIE(PM_CHAN_2), 3);
+ SET_BIT(NPCX_HIPMIE(PMC_HOST_CMD), 3);
/*
* Set required control value (avoid setting HOSTWAIT bit at this stage)
*/
@@ -757,11 +798,12 @@ static void lpc_init(void)
/*
* Init KBC
- * Clear OBF status, PM1 IBF/OBF INT enable, IRQ11 enable,
- * IBF(K&M) INT enable, OBF(K&M) empty INT enable ,
+ * Clear OBF status flag, PM1 IBF/OBE INT enable, IRQ11 enable,
+ * IBF(K&M) INT enable, OBE(K&M) empty INT enable ,
* OBF Mouse Full INT enable and OBF KB Full INT enable
*/
NPCX_HICTRL = 0xFF;
+
/* Normally Polarity IRQ1,12,11 type (level + high) setting */
NPCX_HIIRQC = 0x00; /* Make sure to default */
@@ -771,9 +813,11 @@ static void lpc_init(void)
*/
NPCX_DP80CTL = 0x29;
SET_BIT(NPCX_GLUE_SDP_CTS, 3);
+#if SUPPORT_P80_SEG
SET_BIT(NPCX_GLUE_SDP_CTS, 0);
+#endif
/* Just turn on IRQE */
- NPCX_HIPMIE(PM_CHAN_1) = 0x01;
+ NPCX_HIPMIE(PMC_ACPI) = 0x01;
lpc_task_enable_irq();
/* Initialize host args and memory map to all zero */
@@ -785,8 +829,6 @@ static void lpc_init(void)
EC_HOST_CMD_FLAG_LPC_ARGS_SUPPORTED |
EC_HOST_CMD_FLAG_VERSION_3;
-
-
/* Restore event masks if needed */
lpc_post_sysjump();
@@ -794,7 +836,6 @@ static void lpc_init(void)
init_done = 1;
/* Update host events now that we can copy them to memmap */
-
update_host_event_status();
/*
@@ -809,19 +850,6 @@ static void lpc_init(void)
lpc_host_register_init();
#endif
}
-
-/* Enable LPC ACPI-EC interrupts */
-void lpc_enable_acpi_interrupts(void)
-{
- SET_BIT(NPCX_HIPMCTL(PM_CHAN_1), 0);
-}
-
-/* Disable LPC ACPI-EC interrupts */
-void lpc_disable_acpi_interrupts(void)
-{
- CLEAR_BIT(NPCX_HIPMCTL(PM_CHAN_1), 0);
-}
-
/*
* Set prio to higher than default; this way LPC memory mapped data is ready
* before other inits try to initialize their memmap data.
diff --git a/chip/npcx/peci.c b/chip/npcx/peci.c
index 2850ce793c..64fcf62a0f 100644
--- a/chip/npcx/peci.c
+++ b/chip/npcx/peci.c
@@ -27,7 +27,7 @@
/* PECI Time-out */
-#define PECI_DONE_TIMEOUT_US (100*MSEC)
+#define PECI_DONE_TIMEOUT_US (10*MSEC)
/* Task Event for PECI */
#define TASK_EVENT_PECI_DONE TASK_EVENT_CUSTOM(1<<26)
diff --git a/chip/npcx/registers.h b/chip/npcx/registers.h
index aa741ba805..d981540bb6 100644
--- a/chip/npcx/registers.h
+++ b/chip/npcx/registers.h
@@ -34,9 +34,10 @@
#define SUPPORT_LCT 1
#define SUPPORT_WDG 1
#define SUPPORT_HIB 1
+#define SUPPORT_P80_SEG 0 /* Note: it uses KSO10 & KSO11 */
/* Switcher of debugging */
#define DEBUG_I2C 0
-#define DEBUG_TMR 1
+#define DEBUG_TMR 0
#define DEBUG_WDG 0
#define DEBUG_GPIO 1
#define DEBUG_FAN 0
@@ -45,7 +46,8 @@
#define DEBUG_FLH 0
#define DEBUG_PECI 0
#define DEBUG_SHI 1
-#define DEBUG_CLK 1
+#define DEBUG_CLK 0
+#define DEBUG_LPC 0
/* Modules Map */
#define NPCX_MDC_BASE_ADDR 0x4000C000
@@ -78,7 +80,7 @@
#define NPCX_PM_CH_BASE_ADDR(mdl) (0x400C9000 + ((mdl) * 0x2000L))
#define NPCX_SMB_BASE_ADDR(mdl) ((mdl < 2) ? (0x40009000 + \
((mdl) * 0x2000L)) : \
- (0x400C0000 + ((mdl) * 0x2000L)))
+ (0x400C0000 + ((mdl - 2) * 0x2000L)))
/*
* NPCX-IRQ numbers
@@ -151,7 +153,7 @@
#define NPCX_IRQ0_NOUSED NPCX_IRQ_0
#define NPCX_IRQ1_NOUSED NPCX_IRQ_1
#define NPCX_IRQ_KBSCAN NPCX_IRQ_2
-#define NPCX_IRQ_PM_CHAN_OBF NPCX_IRQ_3
+#define NPCX_IRQ_PM_CHAN_OBE NPCX_IRQ_3
#define NPCX_IRQ_PECI NPCX_IRQ_4
#define NPCX_IRQ5_NOUSED NPCX_IRQ_5
#define NPCX_IRQ_PORT80 NPCX_IRQ_6
@@ -204,7 +206,7 @@
#define NPCX_IRQ_WKINTG_1 NPCX_IRQ_53
#define NPCX_IRQ_WKINTH_1 NPCX_IRQ_54
#define NPCX_IRQ55_NOUSED NPCX_IRQ_55
-#define NPCX_IRQ_KBC_OBF NPCX_IRQ_56
+#define NPCX_IRQ_KBC_OBE NPCX_IRQ_56
#define NPCX_IRQ_SPI NPCX_IRQ_57
#define NPCX_IRQ58_NOUSED NPCX_IRQ_58
#define NPCX_IRQ59_NOUSED NPCX_IRQ_59
@@ -564,8 +566,14 @@ enum {
#define NPCX_DEVALTC_TA2_SL2 6
#define NPCX_DEVALTC_TB2_SL2 7
+/* Others bit definitions */
#define NPCX_LFCGCALCNT_LPREG_CTL_EN 1
+#define NPCX_LV_GPIO_CTL1_SC2_0_LV 0
+#define NPCX_LV_GPIO_CTL1_SD2_0_LV 1
+#define NPCX_LV_GPIO_CTL1_SC3_0_LV 2
+#define NPCX_LV_GPIO_CTL1_SD3_0_LV 3
+
/******************************************************************************/
/* Development and Debug Support (DBG) Registers */
#define NPCX_DBGCTRL REG8(NPCX_SCFG_BASE_ADDR + 0x074)
@@ -758,7 +766,8 @@ enum NPCX_PMC_PWDWN_CTL_T {
(1 << NPCX_PWDWN_CTL2_PWM1_PD))
#define CGC_I2C_MASK ((1 << NPCX_PWDWN_CTL3_SMB0_PD) | \
(1 << NPCX_PWDWN_CTL3_SMB1_PD) | \
- (1 << NPCX_PWDWN_CTL3_SMB2_PD))
+ (1 << NPCX_PWDWN_CTL3_SMB2_PD) | \
+ (1 << NPCX_PWDWN_CTL3_SMB3_PD))
#define CGC_ADC_MASK (1 << NPCX_PWDWN_CTL4_ADC_PD)
#define CGC_PECI_MASK (1 << NPCX_PWDWN_CTL4_PECI_PD)
#define CGC_SPI_MASK (1 << NPCX_PWDWN_CTL4_SPIP_PD)
@@ -886,8 +895,14 @@ enum NPCX_PMC_PWDWN_CTL_T {
#define NPCX_SHIKMDI REG8(NPCX_KBC_BASE_ADDR + 0x00B)
/* KBC register field */
-#define NPCX_HICTRL_OBFKIE 0
-#define NPCX_HICTRL_OBFMIE 1
+#define NPCX_HICTRL_OBFKIE 0 /* Automatic Serial IRQ1 for KBC */
+#define NPCX_HICTRL_OBFMIE 1 /* Automatic Serial IRQ12 for Mouse*/
+#define NPCX_HICTRL_OBFCIE 2 /* KBC OBE interrupt enable */
+#define NPCX_HICTRL_IBFCIE 3 /* KBC IBF interrupt enable */
+#define NPCX_HICTRL_PMIHIE 4 /* Automatic Serial IRQ11 for PMC1 */
+#define NPCX_HICTRL_PMIOCIE 5 /* PMC1 OBE interrupt enable */
+#define NPCX_HICTRL_PMICIE 6 /* PMC1 IBF interrupt enable */
+#define NPCX_HICTRL_FW_OBF 7 /* Firmware control over OBF */
/******************************************************************************/
/* PM Channel Registers */
@@ -906,6 +921,7 @@ enum NPCX_PMC_PWDWN_CTL_T {
/* PM Channel register field */
#define NPCX_HIPMIE_SCIE 1
#define NPCX_HIPMIE_SMIE 2
+#define NPCX_HIPMCTL_IBFIE 0
/*
* PM Channel enumeration
@@ -1296,16 +1312,6 @@ static inline int uart_is_wakeup_from_gpio(void)
#endif
}
-/* This routine clear pending bit of GPIO wake-up functionality */
-static inline void uart_clear_wakeup_event(void)
-{
-#if NPCX_UART_MODULE2
- SET_BIT(NPCX_WKPND(1, 6), 4);
-#else
- SET_BIT(NPCX_WKPND(1, 1), 0);
-#endif
-}
-
/* This routine checks wake-up functionality from GPIO is enabled or not */
static inline int uart_is_enable_wakeup(void)
{
@@ -1340,8 +1346,10 @@ static inline int npcx_is_uart(void)
static inline void npcx_uart2gpio(void)
{
#if NPCX_UART_MODULE2
+ UPDATE_BIT(NPCX_WKEDG(1, 6), 4, 1);
CLEAR_BIT(NPCX_DEVALT(0x0C), NPCX_DEVALTC_UART_SL2);
#else
+ UPDATE_BIT(NPCX_WKEDG(1, 1), 0, 1);
CLEAR_BIT(NPCX_DEVALT(0x0A), NPCX_DEVALTA_UART_SL1);
#endif
}
diff --git a/chip/npcx/spiflashfw/ec_npcxflash.c b/chip/npcx/spiflashfw/ec_npcxflash.c
index 41e833b273..ccaff16872 100644
--- a/chip/npcx/spiflashfw/ec_npcxflash.c
+++ b/chip/npcx/spiflashfw/ec_npcxflash.c
@@ -273,6 +273,9 @@ sspi_flash_upload(int spi_offset, int spi_size)
NPCX_WDSDM = 0x61;
NPCX_WDSDM = 0x63;
+ /* UMA Unlock */
+ CLEAR_BIT(NPCX_UMA_ECTS, NPCX_UMA_ECTS_UMA_LOCK);
+
/* Set pinmux first */
sspi_flash_pinmux(1);
diff --git a/chip/npcx/uart.c b/chip/npcx/uart.c
index 570ded4285..51ef975bc3 100644
--- a/chip/npcx/uart.c
+++ b/chip/npcx/uart.c
@@ -101,6 +101,9 @@ void uart_write_char(char c)
;
NPCX_UTBUF = c;
+#ifdef CONFIG_LOW_POWER_IDLE
+ clock_refresh_console_in_use();
+#endif
}
int uart_read_char(void)