summaryrefslogtreecommitdiff
path: root/chip
diff options
context:
space:
mode:
authorli feng <li1.feng@intel.com>2019-02-08 19:36:07 -0800
committerchrome-bot <chrome-bot@chromium.org>2019-02-20 21:41:46 -0800
commitc8df3ef42411181d99fa71cb8af53498995a1123 (patch)
tree1a8781c18861cff1686f6ba4a33b128fd9a774a8 /chip
parent153c90a2026f1ae56705e4880e2461354d1ac9af (diff)
downloadchrome-ec-c8df3ef42411181d99fa71cb8af53498995a1123.tar.gz
ish: update power rail request (vnn)
When the AP is trying to go down to S0ix from S0 (suspend), we need to ensure that the ISH is not holding on to any power requests which would prevent the AP from transitioning to S0ix. Re-assert power request when AP enters resume back to S0. Ultimately, the VNN will be controlled at a much finer grain once more power management features are introduces here for the ISH. BRANCH=none BUG=b:123890178 TEST=run "suspend_stress_test -c [loop#]", and pass; this is workaround to fix this issue so not blocking S0ix test. Change-Id: I881f3505300cadf1e0b8dd1750bae4cf2876e514 Signed-off-by: li feng <li1.feng@intel.com> Signed-off-by: Jett Rink <jettrink@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1461665 Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com> Reviewed-by: Edward Hill <ecgh@chromium.org>
Diffstat (limited to 'chip')
-rw-r--r--chip/ish/ipc_heci.c25
-rw-r--r--chip/ish/registers.h8
-rw-r--r--chip/ish/system_state_subsys.c35
3 files changed, 68 insertions, 0 deletions
diff --git a/chip/ish/ipc_heci.c b/chip/ish/ipc_heci.c
index e336994936..9574f38799 100644
--- a/chip/ish/ipc_heci.c
+++ b/chip/ish/ipc_heci.c
@@ -468,6 +468,20 @@ static void ipc_host2ish_isr(void)
uint32_t pisr = REG32(IPC_PISR);
uint32_t pimr = REG32(IPC_PIMR);
+#ifdef CHIP_FAMILY_ISH5
+ /*
+ * TODO(b/122364080): Remove this code once proper power management is
+ * in place for ISH.
+ *
+ * Ensure that the host IPC power is requested after getting an
+ * interrupt otherwise the resume message will never get delivered (via
+ * host ipc communication). Resume is where we would like to restore all
+ * power settings, but that is too late for this power request.
+ */
+
+ PMU_VNN_REQ = VNN_REQ_IPC_HOST_WRITE & ~PMU_VNN_REQ;
+#endif
+
if ((pisr & IPC_PISR_HOST2ISH_BIT) && (pimr & IPC_PIMR_HOST2ISH_BIT))
handle_msg_recv_interrupt(IPC_PEER_ID_HOST);
}
@@ -696,6 +710,17 @@ void ipc_mng_task(void)
struct ipc_msg msg;
ipc_handle_t handle;
+#ifdef CHIP_FAMILY_ISH5
+ /*
+ * TODO(b/122364080): Remove this code once proper power management is
+ * in place for ISH.
+ *
+ * Ensure that power for host IPCs is requested and ack'ed
+ */
+ PMU_VNN_REQ = VNN_REQ_IPC_HOST_WRITE & ~PMU_VNN_REQ;
+ while (!(PMU_VNN_REQ_ACK & PMU_VNN_REQ_ACK_STATUS))
+ continue;
+#endif
handle = ipc_open(IPC_PEER_ID_HOST, IPC_PROTOCOL_MNG,
EVENT_FLAG_BIT_MNG_MSG);
diff --git a/chip/ish/registers.h b/chip/ish/registers.h
index 6137dc6e08..00eb5626b9 100644
--- a/chip/ish/registers.h
+++ b/chip/ish/registers.h
@@ -36,6 +36,7 @@ enum ish_i2c_port {
#define ISH_I2C2_BASE 0x00105000
#define ISH_UART_BASE 0x00103000
#define ISH_GPIO_BASE 0x001F0000
+#define ISH_PMU_BASE 0x00800000
#define ISH_IPC_BASE 0x00B00000
#define ISH_IOAPIC_BASE 0xFEC00000
#define ISH_HPET_BASE 0xFED00000
@@ -115,6 +116,13 @@ enum ish_i2c_port {
#define IPC_ISH2HOST_DOORBELL (ISH_IPC_BASE + 0x54)
#define IPC_BUSY_CLEAR (ISH_IPC_BASE + 0x378)
+/* PMU Registers */
+#define PMU_VNN_REQ REG32(ISH_PMU_BASE + 0x3c)
+#define VNN_REQ_IPC_HOST_WRITE (1 << 3) /* Power for IPC host write */
+
+#define PMU_VNN_REQ_ACK REG32(ISH_PMU_BASE + 0x40)
+#define PMU_VNN_REQ_ACK_STATUS (1 << 0) /* VNN req and ack status */
+
/* IOAPIC registers */
#define IOAPIC_IDX 0xFEC00000
#define IOAPIC_WDW 0xFEC00010
diff --git a/chip/ish/system_state_subsys.c b/chip/ish/system_state_subsys.c
index bb5b62dce3..81a0a6d7b7 100644
--- a/chip/ish/system_state_subsys.c
+++ b/chip/ish/system_state_subsys.c
@@ -4,6 +4,7 @@
*/
#include "heci_client.h"
+#include "registers.h"
#include "system_state.h"
#include "console.h"
@@ -28,6 +29,11 @@
#define SUSPEND_STATE_BIT (1<<1) /* suspend/resume */
+/* Cached state of ISH's requested power rails when AP suspends */
+#ifdef CHIP_FAMILY_ISH5
+static uint32_t cached_vnn_request;
+#endif
+
struct ss_header {
uint32_t cmd;
uint32_t cmd_status;
@@ -102,6 +108,19 @@ static int ss_subsys_suspend(void)
ss_subsys_ctx.clients[i]);
}
+#ifdef CHIP_FAMILY_ISH5
+ /*
+ * TODO(b/122364080): Remove this code once proper power management is
+ * in place for ISH.
+ *
+ * PMU_VNN_REQ is used by ISH FW to assert power requirements of ISH to
+ * PMC. The system won't enter S0ix if ISH is requesting any power
+ * rails. Setting a bit to 1 both sets and clears a requested value.
+ * Cache the value of request power so we can restore it on resume.
+ */
+ cached_vnn_request = PMU_VNN_REQ;
+ PMU_VNN_REQ = cached_vnn_request;
+#endif
return EC_SUCCESS;
}
@@ -109,6 +128,22 @@ static int ss_subsys_resume(void)
{
int i;
+#ifdef CHIP_FAMILY_ISH5
+ /*
+ * TODO(b/122364080): Remove this code once proper power management is
+ * in place for ISH.
+ *
+ * Restore VNN power request from before suspend.
+ */
+ if (cached_vnn_request) {
+ /* Request all cached power rails that are not already on. */
+ PMU_VNN_REQ = cached_vnn_request & ~PMU_VNN_REQ;
+ /* Wait for power request to get acknowledged */
+ while (!(PMU_VNN_REQ_ACK & PMU_VNN_REQ_ACK_STATUS))
+ continue;
+ }
+#endif
+
for (i = 0; i < ss_subsys_ctx.num_of_ss_client; i++) {
if (ss_subsys_ctx.clients[i]->cbs->resume)
ss_subsys_ctx.clients[i]->cbs->resume(