diff options
author | li feng <li1.feng@intel.com> | 2019-02-08 19:36:07 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2019-02-20 21:41:46 -0800 |
commit | c8df3ef42411181d99fa71cb8af53498995a1123 (patch) | |
tree | 1a8781c18861cff1686f6ba4a33b128fd9a774a8 /chip | |
parent | 153c90a2026f1ae56705e4880e2461354d1ac9af (diff) | |
download | chrome-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.c | 25 | ||||
-rw-r--r-- | chip/ish/registers.h | 8 | ||||
-rw-r--r-- | chip/ish/system_state_subsys.c | 35 |
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( |