summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMulin Chao <mlchao@nuvoton.com>2015-08-06 18:16:22 +0800
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-08-12 18:12:27 +0000
commit9fdcfe00ca8fd62bced35b970768df2c90b967df (patch)
tree866b45f4208799c9ca833594be62cc31764528c7
parent5b4fd77df38e03b2618b817131101aaeddee03b5 (diff)
downloadchrome-ec-9fdcfe00ca8fd62bced35b970768df2c90b967df.tar.gz
nuc:Using LRESET interrupt to re-initialize LPC settings after warm boot
Fixed bug during polling port 0x204 by BIOS. We should set processing flag before reading command byte in ISR to prevent EC_LPC_STATUS_FROM_HOST and EC_LPC_STATUS_PROCESSING bits are both low. Modified drivers: 1. gpio.c: Add LRESET ISR. 2. lpc.c: Fixed bug during polling port 0x204 by BIOS. 3. flash_ec: Reset ec before flashing ec BUG=chrome-os-partner:34346 TEST=make buildall -j; test nuvoton IC specific drivers BRANCH=none Change-Id: I8e557f2e2be41a7a9d40c03c775313b12668f283 Signed-off-by: Ian Chao <mlchao@nuvoton.com> Reviewed-on: https://chromium-review.googlesource.com/291210 Reviewed-by: Randall Spangler <rspangler@chromium.org> Commit-Queue: Randall Spangler <rspangler@chromium.org> Tested-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r--chip/npcx/gpio.c11
-rw-r--r--chip/npcx/lpc.c46
-rw-r--r--chip/npcx/lpc_chip.h14
-rwxr-xr-xutil/flash_ec3
4 files changed, 61 insertions, 13 deletions
diff --git a/chip/npcx/gpio.c b/chip/npcx/gpio.c
index 51e3d844c8..7192403e82 100644
--- a/chip/npcx/gpio.c
+++ b/chip/npcx/gpio.c
@@ -17,6 +17,7 @@
#include "util.h"
#include "system.h"
#include "system_chip.h"
+#include "lpc_chip.h"
/* Marco functions for GPIO WUI/ALT table */
#define NPCX_GPIO(grp, pin) \
@@ -683,10 +684,18 @@ void _irq_func(void) \
gpio_interrupt(int_no); \
}
+/* If we need to handle the other type interrupts except GPIO, add code here */
+void __gpio_wk0efgh_interrupt(void)
+{
+ if (IS_BIT_SET(NPCX_WKPND(MIWU_TABLE_0 , MIWU_GROUP_5),7))
+ lpc_lreset_pltrst_handler();
+ else
+ gpio_interrupt(NPCX_IRQ_WKINTEFGH_0);
+}
+
GPIO_IRQ_FUNC(__gpio_wk0ad_interrupt , NPCX_IRQ_MTC_WKINTAD_0);
GPIO_IRQ_FUNC(__gpio_wk0b_interrupt , NPCX_IRQ_TWD_WKINTB_0);
GPIO_IRQ_FUNC(__gpio_wk0c_interrupt , NPCX_IRQ_WKINTC_0);
-GPIO_IRQ_FUNC(__gpio_wk0efgh_interrupt, NPCX_IRQ_WKINTEFGH_0);
GPIO_IRQ_FUNC(__gpio_wk1a_interrupt , NPCX_IRQ_WKINTA_1);
GPIO_IRQ_FUNC(__gpio_wk1b_interrupt , NPCX_IRQ_WKINTB_1);
GPIO_IRQ_FUNC(__gpio_wk1d_interrupt , NPCX_IRQ_WKINTD_1);
diff --git a/chip/npcx/lpc.c b/chip/npcx/lpc.c
index 5f01627c68..03aa36f55a 100644
--- a/chip/npcx/lpc.c
+++ b/chip/npcx/lpc.c
@@ -45,7 +45,6 @@
#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;
@@ -418,6 +417,8 @@ static void handle_acpi_write(int is_cmd)
*/
static void handle_host_write(int is_cmd)
{
+ /* Set processing flag before reading command byte */
+ SET_BIT(NPCX_HIPMST(PMC_HOST_CMD), 2);
/*
* Read the command byte. This clears the FRMH bit in
* the status byte.
@@ -443,8 +444,7 @@ static void handle_host_write(int is_cmd)
lpc_packet.response_size = 0;
lpc_packet.driver_result = EC_RES_SUCCESS;
- /* Set processing flag */
- SET_BIT(NPCX_HIPMST(PMC_HOST_CMD), 2);
+
host_packet_receive(&lpc_packet);
return;
@@ -453,6 +453,9 @@ static void handle_host_write(int is_cmd)
int size = lpc_host_args->data_size;
int csum, i;
+ /* Clear processing flag */
+ CLEAR_BIT(NPCX_HIPMST(PMC_HOST_CMD), 2);
+
host_cmd_args.version = lpc_host_args->command_version;
host_cmd_args.params = params_copy;
host_cmd_args.params_size = size;
@@ -489,6 +492,8 @@ static void handle_host_write(int is_cmd)
} else {
/* Old style command, now unsupported */
host_cmd_args.result = EC_RES_INVALID_COMMAND;
+ /* Clear processing flag */
+ CLEAR_BIT(NPCX_HIPMST(PMC_HOST_CMD), 2);
}
/* Hand off to host command handler */
@@ -718,25 +723,33 @@ void lpc_host_register_init(void)
lpc_sib_write_reg(SIO_OFFSET, 0xF8, 0x00);
/* enable SHM */
lpc_sib_write_reg(SIO_OFFSET, 0x30, 0x01);
+
+ /* An active LRESET or PLTRST does not generate host domain reset */
+ SET_BIT(NPCX_RSTCTL, NPCX_RSTCTL_LRESET_PLTRST_MODE);
+
CPRINTS("Host settings are done!");
}
-int lpc_get_pltrst_asserted(void)
+/* Initialize host settings by interrupt */
+void lpc_lreset_pltrst_handler(void)
{
- uint8_t cur_plt_rst_l;
- /* Read current PLTRST status */
- cur_plt_rst_l = (NPCX_MSWCTL1 & 0x04) ? 1 : 0;
+ /* Clear pending bit of WUI */
+ SET_BIT(NPCX_WKPCL(MIWU_TABLE_0 , MIWU_GROUP_5), 7);
/*
- * If plt_rst is deasserted for the first time
- * Initialize all lpc settings
+ * Once LRESET is de-asserted (low -> high),
+ * we need to intialize lpc settings again.
+ * But if RSTCTL_LRESET_PLTRST_MODE is active, we needn't to do it again
*/
- if (cur_plt_rst_l == 0 && plt_rst_l == 1)
+ if(!IS_BIT_SET(NPCX_RSTCTL, NPCX_RSTCTL_LRESET_PLTRST_MODE))
lpc_host_register_init();
+}
- plt_rst_l = cur_plt_rst_l;
- return plt_rst_l;
+int lpc_get_pltrst_asserted(void)
+{
+ /* Read current PLTRST status */
+ return (NPCX_MSWCTL1 & 0x04) ? 1 : 0;
}
static void lpc_init(void)
@@ -848,6 +861,15 @@ static void lpc_init(void)
#ifdef BOARD_NPCX_EVB
/* initial IO port address via SIB-write modules */
lpc_host_register_init();
+#else
+ /* Initialize LRESET# interrupt */
+ /* Set detection mode to edge */
+ CLEAR_BIT(NPCX_WKMOD(MIWU_TABLE_0, MIWU_GROUP_5), 7);
+ /* Handle interrupting on rising edge */
+ CLEAR_BIT(NPCX_WKAEDG(MIWU_TABLE_0, MIWU_GROUP_5), 7);
+ SET_BIT(NPCX_WKEDG(MIWU_TABLE_0, MIWU_GROUP_5), 7);
+ /* Enable wake-up input sources */
+ SET_BIT(NPCX_WKEN(MIWU_TABLE_0, MIWU_GROUP_5), 7);
#endif
}
/*
diff --git a/chip/npcx/lpc_chip.h b/chip/npcx/lpc_chip.h
new file mode 100644
index 0000000000..b87c2779fa
--- /dev/null
+++ b/chip/npcx/lpc_chip.h
@@ -0,0 +1,14 @@
+/* Copyright (c) 2015 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 hwtimer module for Chrome EC */
+
+#ifndef __CROS_EC_LPC_CHIP_H
+#define __CROS_EC_LPC_CHIP_H
+
+/* Initialize host settings by interrupt */
+void lpc_lreset_pltrst_handler(void);
+
+#endif /* __CROS_EC_LPC_CHIP_H */
diff --git a/util/flash_ec b/util/flash_ec
index 0eaca8c85e..96bdb85fbc 100755
--- a/util/flash_ec
+++ b/util/flash_ec
@@ -429,6 +429,9 @@ function flash_npcx() {
OCD_CMDS="init; flash_npcx_all ${IMG_PATH} ${FLAGS_offset}; shutdown;"
fi
+ # Reset the EC
+ ec_reset
+
flash_openocd
}