summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryangcao <yang.a.cao@intel.com>2019-02-18 15:29:12 +0800
committerJett Rink <jettrink@chromium.org>2019-02-26 14:32:39 +0000
commit456d85195c3ceede52d4c219dfccc51f67b78544 (patch)
tree30bb78da742d08083cb26996a5809b2874daa947
parent8df604fec43740653366a79f53ec6378b97255f9 (diff)
downloadchrome-ec-456d85195c3ceede52d4c219dfccc51f67b78544.tar.gz
ish: add reset prep interrupt handle
Upon reset prep interrupt from PMC, ISH HW will do warm reset. Before full stack of power management in place, this workaround will help fix S5 issue. BRANCH=none BUG=b:123528909 TEST=run "reboot" from host, ISH reboots too. Change-Id: I421ec25a198eb91672ffe770566a4edbe4855fee Signed-off-by: yangcao <yang.a.cao@intel.com> Signed-off-by: li feng <li1.feng@intel.com> Reviewed-on: https://chromium-review.googlesource.com/c/1476299 Reviewed-by: Jett Rink <jettrink@chromium.org> Commit-Queue: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
-rw-r--r--chip/ish/build.mk1
-rw-r--r--chip/ish/registers.h18
-rw-r--r--chip/ish/reset_prep_wr.c51
-rw-r--r--core/minute-ia/interrupts.c1
4 files changed, 71 insertions, 0 deletions
diff --git a/chip/ish/build.mk b/chip/ish/build.mk
index e2fc4872de..dbdbe2eda6 100644
--- a/chip/ish/build.mk
+++ b/chip/ish/build.mk
@@ -18,6 +18,7 @@ endif
# Required chip modules
chip-y+=clock.o gpio.o system.o hwtimer.o uart.o flash.o
+chip-y+=reset_prep_wr.o
chip-$(CONFIG_I2C)+=i2c.o
chip-$(CONFIG_HOSTCMD_LPC)+=ipc.o
chip-$(CONFIG_ISH_IPC)+=ipc_heci.o
diff --git a/chip/ish/registers.h b/chip/ish/registers.h
index 00eb5626b9..f245665ca9 100644
--- a/chip/ish/registers.h
+++ b/chip/ish/registers.h
@@ -37,6 +37,7 @@ enum ish_i2c_port {
#define ISH_UART_BASE 0x00103000
#define ISH_GPIO_BASE 0x001F0000
#define ISH_PMU_BASE 0x00800000
+#define ISH_CCU_BASE 0x00900000
#define ISH_IPC_BASE 0x00B00000
#define ISH_IOAPIC_BASE 0xFEC00000
#define ISH_HPET_BASE 0xFED00000
@@ -54,6 +55,7 @@ enum ish_i2c_port {
#define ISH_IPC_ISH2HOST_CLR_IRQ 24
#define ISH_UART0_IRQ 34
#define ISH_UART1_IRQ 35
+#define ISH_RESET_PREP_IRQ 62
/* Interrupt vectors 0-31 are architecture reserved.
* Vectors 32-255 are user-defined.
@@ -95,6 +97,7 @@ enum ish_i2c_port {
#define ISH_UART0_VEC IRQ_TO_VEC(ISH_UART0_IRQ)
#define ISH_UART1_VEC IRQ_TO_VEC(ISH_UART1_IRQ)
#define ISH_IPC_VEC IRQ_TO_VEC(ISH_IPC_HOST2ISH_IRQ)
+#define ISH_RESET_PREP_VEC IRQ_TO_VEC(ISH_RESET_PREP_IRQ)
#ifdef CONFIG_ISH_UART_0
#define ISH_DEBUG_UART UART_PORT_0
@@ -123,6 +126,21 @@ enum ish_i2c_port {
#define PMU_VNN_REQ_ACK REG32(ISH_PMU_BASE + 0x40)
#define PMU_VNN_REQ_ACK_STATUS (1 << 0) /* VNN req and ack status */
+#define PMU_RST_PREP REG32(ISH_PMU_BASE + 0x5c)
+#define PMU_RST_PREP_GET (1 << 0)
+#define PMU_RST_PREP_AVAIL (1 << 1)
+#define PMU_RST_PREP_INT_MASK (1 << 31)
+
+/* CCU Registers */
+#define CCU_TCG_EN REG32(ISH_CCU_BASE + 0x0)
+#define CCU_BCG_EN REG32(ISH_CCU_BASE + 0x4)
+#define CCU_RST_HST REG32(ISH_CCU_BASE + 0x34)
+#define CCU_TCG_ENABLE REG32(ISH_CCU_BASE + 0x38)
+#define CCU_BCG_ENABLE REG32(ISH_CCU_BASE + 0x3c)
+
+/* CSME Registers */
+#define ISH_RST_REG REG32(ISH_IPC_BASE + 0x44)
+
/* IOAPIC registers */
#define IOAPIC_IDX 0xFEC00000
#define IOAPIC_WDW 0xFEC00010
diff --git a/chip/ish/reset_prep_wr.c b/chip/ish/reset_prep_wr.c
new file mode 100644
index 0000000000..6d8702bee9
--- /dev/null
+++ b/chip/ish/reset_prep_wr.c
@@ -0,0 +1,51 @@
+/* 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.
+ */
+
+/* Power managerment module for ISH */
+#include "common.h"
+#include "console.h"
+#include "registers.h"
+#include "interrupts.h"
+#include "task.h"
+#include "hooks.h"
+
+#ifdef PM_DEBUG
+#define CPUTS(outstr) cputs(CC_SYSTEM, outstr)
+#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args)
+#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args)
+#else
+#define CPUTS(outstr)
+#define CPRINTS(format, args...)
+#define CPRINTF(format, args...)
+#endif
+
+static void reset_prep_wr_isr(void)
+{
+ /*
+ * ISH HW looks at the rising edge of this bit to
+ * trigger a MIA reset. Now in S0, reset MIA.
+ */
+ ISH_RST_REG = 0;
+ ISH_RST_REG = 1;
+}
+DECLARE_IRQ(ISH_RESET_PREP_IRQ, reset_prep_wr_isr);
+
+void reset_prep_init(void)
+{
+ /* Clear reset bit */
+ ISH_RST_REG = 0;
+
+ /* clear reset history register in CCU */
+ CCU_RST_HST = CCU_RST_HST;
+ /* Unmask reset prep avail interrupt mask */
+ PMU_RST_PREP = 0;
+ /* Clear TCG Enable, no trunk level clock gating*/
+ CCU_TCG_ENABLE = 0;
+ /* Clear BCG Enable, no block level clock gating*/
+ CCU_BCG_ENABLE = 0;
+
+ task_enable_irq(ISH_RESET_PREP_IRQ);
+}
+DECLARE_HOOK(HOOK_INIT, reset_prep_init, HOOK_PRIO_DEFAULT);
diff --git a/core/minute-ia/interrupts.c b/core/minute-ia/interrupts.c
index ee9a9c981c..3ede039bcc 100644
--- a/core/minute-ia/interrupts.c
+++ b/core/minute-ia/interrupts.c
@@ -76,6 +76,7 @@ static const irq_desc_t system_irqs[] = {
LEVEL_INTR(ISH_HPET_TIMER0_IRQ, ISH_HPET_TIMER0_VEC),
LEVEL_INTR(ISH_HPET_TIMER1_IRQ, ISH_HPET_TIMER1_VEC),
LEVEL_INTR(ISH_DEBUG_UART_IRQ, ISH_DEBUG_UART_VEC),
+ LEVEL_INTR(ISH_RESET_PREP_IRQ, ISH_RESET_PREP_VEC),
};