summaryrefslogtreecommitdiff
path: root/chip
diff options
context:
space:
mode:
authorLeifu Zhao <leifu.zhao@intel.com>2020-02-14 10:53:48 +0800
committerCommit Bot <commit-bot@chromium.org>2020-02-27 00:29:05 +0000
commit3f1dc59f201a5e3f52c1f0b6e72c8a166ea8dacf (patch)
treec5a1f3b5ad72d32fb2746c00a67359aac06fcba2 /chip
parente225427d2a04449d65fbae72932caa8270f182c7 (diff)
downloadchrome-ec-3f1dc59f201a5e3f52c1f0b6e72c8a166ea8dacf.tar.gz
ish: chip level enablement for ish5.4 PM
Chip level power management enablement for ish5.4. BUG=b:149238813 BRANCH=none TEST=ISH can successfully enter into D0i1/D0i2/D0i3 on tgl rvp. Signed-off-by: Leifu Zhao <leifu.zhao@intel.com> Change-Id: Icc554a68fe57970bcaa7be457f56db34067858d9 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2055895 Reviewed-by: Leifu Zhao <leifu.zhao@intel.corp-partner.google.com> Reviewed-by: Jack Rosenthal <jrosenth@chromium.org> Tested-by: Leifu Zhao <leifu.zhao@intel.corp-partner.google.com> Commit-Queue: Jack Rosenthal <jrosenth@chromium.org> Auto-Submit: Leifu Zhao <leifu.zhao@intel.corp-partner.google.com>
Diffstat (limited to 'chip')
-rw-r--r--chip/ish/aontaskfw/ish_aontask.c135
-rw-r--r--chip/ish/power_mgt.c68
-rw-r--r--chip/ish/power_mgt.h4
3 files changed, 175 insertions, 32 deletions
diff --git a/chip/ish/aontaskfw/ish_aontask.c b/chip/ish/aontaskfw/ish_aontask.c
index 183c61f97a..c6e5552127 100644
--- a/chip/ish/aontaskfw/ish_aontask.c
+++ b/chip/ish/aontaskfw/ish_aontask.c
@@ -62,7 +62,11 @@
* (256 * 8), so we just defined the only needed IDT entries:
* AON_IDT_ENTRY_VEC_FIRST ~ AON_IDT_ENTRY_VEC_LAST
*/
-#define AON_IDT_ENTRY_VEC_FIRST ISH_PMU_WAKEUP_VEC
+#ifdef CONFIG_ISH_NEW_PM
+#define AON_IDT_ENTRY_VEC_LAST ISH_PMU_WAKEUP_VEC
+#else
+#define AON_IDT_ENTRY_VEC_FIRST ISH_PMU_WAKEUP_VEC
+#endif
#ifdef CONFIG_ISH_PM_RESET_PREP
/**
@@ -70,10 +74,18 @@
* vector, and also need handle reset prep interrupt
* (if CONFIG_ISH_PM_RESET_PREP defined)
*/
-#define AON_IDT_ENTRY_VEC_LAST ISH_RESET_PREP_VEC
+#ifdef CONFIG_ISH_NEW_PM
+#define AON_IDT_ENTRY_VEC_FIRST ISH_RESET_PREP_VEC
+#else
+#define AON_IDT_ENTRY_VEC_LAST ISH_RESET_PREP_VEC
+#endif
#else
/* only need handle single PMU wakeup interrupt */
-#define AON_IDT_ENTRY_VEC_LAST ISH_PMU_WAKEUP_VEC
+#ifdef CONFIG_ISH_NEW_PM
+#define AON_IDT_ENTRY_VEC_FIRST ISH_PMU_WAKEUP_VEC
+#else
+#define AON_IDT_ENTRY_VEC_LAST ISH_PMU_WAKEUP_VEC
+#endif
#endif
static void handle_reset(enum ish_pm_state pm_state);
@@ -291,6 +303,22 @@ static inline void delay(uint32_t count)
count--;
}
+static inline void enable_dma_bcg(void)
+{
+ if (IS_ENABLED(CONFIG_ISH_NEW_PM))
+ CCU_BCG_DMA = 1;
+ else
+ CCU_BCG_EN = CCU_BCG_EN | CCU_BCG_BIT_DMA;
+}
+
+static inline void disable_dma_bcg(void)
+{
+ if (IS_ENABLED(CONFIG_ISH_NEW_PM))
+ CCU_BCG_DMA = 0;
+ else
+ CCU_BCG_EN = CCU_BCG_EN & ~CCU_BCG_BIT_DMA;
+}
+
static int store_main_fw(void)
{
int ret;
@@ -307,7 +335,7 @@ static int store_main_fw(void)
- CONFIG_RAM_BASE);
/* disable BCG (Block Clock Gating) for DMA, DMA can be accessed now */
- CCU_BCG_EN = CCU_BCG_EN & ~CCU_BCG_BIT_DMA;
+ disable_dma_bcg();
/* store main FW's read and write data region to IMR/UMA DDR */
ret = ish_dma_copy(
@@ -318,7 +346,7 @@ static int store_main_fw(void)
SRAM_TO_UMA);
/* enable BCG for DMA, DMA can't be accessed now */
- CCU_BCG_EN = CCU_BCG_EN | CCU_BCG_BIT_DMA;
+ enable_dma_bcg();
if (ret != DMA_RC_OK) {
@@ -352,7 +380,7 @@ static int restore_main_fw(void)
- CONFIG_RAM_BASE);
/* disable BCG (Block Clock Gating) for DMA, DMA can be accessed now */
- CCU_BCG_EN = CCU_BCG_EN & ~CCU_BCG_BIT_DMA;
+ disable_dma_bcg();
/* restore main FW's read only code and data region from IMR/UMA DDR */
ret = ish_dma_copy(
@@ -368,7 +396,7 @@ static int restore_main_fw(void)
aon_share.error_count++;
/* enable BCG for DMA, DMA can't be accessed now */
- CCU_BCG_EN = CCU_BCG_EN | CCU_BCG_BIT_DMA;
+ enable_dma_bcg();
return AON_ERROR_DMA_FAILED;
}
@@ -383,7 +411,7 @@ static int restore_main_fw(void)
);
/* enable BCG for DMA, DMA can't be accessed now */
- CCU_BCG_EN = CCU_BCG_EN | CCU_BCG_BIT_DMA;
+ enable_dma_bcg();
if (ret != DMA_RC_OK) {
@@ -453,18 +481,23 @@ static void sram_power(int on)
* size unit, and using 0 based length, i.e if set 0, will erase one
* DWORD
*/
- erase_cfg = (((bank_size - 4) >> 2) << 2) | 0x1;
+ if (IS_ENABLED(CONFIG_ISH_NEW_PM))
+ erase_cfg = ((bank_size >> 3) << 2) | 0x1;
+ else
+ erase_cfg = (((bank_size - 4) >> 2) << 2) | 0x1;
for (i = 0; i < SRAM_POWER_OFF_BANKS; i++) {
- if (on && (BANK_PG_STATUS(i) || BANK_DISABLE_STATUS(i))) {
+ if (on && (BANK_PG_STATUS(i) || (!IS_ENABLED(CONFIG_ISH_NEW_PM)
+ && BANK_DISABLE_STATUS(i)))) {
/* power on and enable a bank */
BANK_PG_DISABLE(i);
delay(SRAM_WARM_UP_DELAY_CNT);
- BANK_ENABLE(i);
+ if (!IS_ENABLED(CONFIG_ISH_NEW_PM))
+ BANK_ENABLE(i);
/* erase a bank */
ISH_SRAM_CTRL_ERASE_ADDR = sram_addr + (i * bank_size);
@@ -476,7 +509,9 @@ static void sram_power(int on)
} else {
/* disable and power off a bank */
- BANK_DISABLE(i);
+ if (!IS_ENABLED(CONFIG_ISH_NEW_PM))
+ BANK_DISABLE(i);
+
BANK_PG_ENABLE(i);
}
@@ -490,6 +525,22 @@ static void sram_power(int on)
}
}
+static inline void set_vnnred_aoncg(void)
+{
+ if (IS_ENABLED(CONFIG_ISH_NEW_PM)) {
+ PMU_VNNAON_RED = 1;
+ CCU_AONCG_EN = 1;
+ }
+}
+
+static inline void clear_vnnred_aoncg(void)
+{
+ if (IS_ENABLED(CONFIG_ISH_NEW_PM)) {
+ PMU_VNNAON_RED = 0;
+ CCU_AONCG_EN = 0;
+ }
+}
+
static void handle_d0i2(void)
{
/* set main SRAM into retention mode*/
@@ -499,9 +550,13 @@ static void handle_d0i2(void)
/* delay some cycles before halt */
delay(SRAM_RETENTION_CYCLES_DELAY);
+ set_vnnred_aoncg();
+
ish_mia_halt();
/* wakeup from PMU interrupt */
+ clear_vnnred_aoncg();
+
/* set main SRAM intto normal mode */
PMU_LDO_CTRL = PMU_LDO_ENABLE_BIT;
@@ -527,9 +582,13 @@ static void handle_d0i3(void)
/* power off main SRAM */
sram_power(0);
+ set_vnnred_aoncg();
+
ish_mia_halt();
/* wakeup from PMU interrupt */
+ clear_vnnred_aoncg();
+
/* power on main SRAM */
sram_power(1);
@@ -548,6 +607,14 @@ static void handle_d3(void)
handle_reset(ISH_PM_STATE_RESET);
}
+static inline void disable_csme_csrirq(void)
+{
+ if (IS_ENABLED(CONFIG_ISH_NEW_PM))
+ REG32(IPC_PIMR_CIM_SEC) = 1;
+ else
+ REG32(IPC_PIMR) &= ~IPC_PIMR_CSME_CSR_BIT;
+}
+
static void handle_reset(enum ish_pm_state pm_state)
{
/* disable watch dog */
@@ -559,7 +626,7 @@ static void handle_reset(enum ish_pm_state pm_state)
ISH_GPIO_GIMR = 0;
/* disable CSME CSR irq */
- IPC_PIMR &= ~IPC_PIMR_CSME_CSR_BIT;
+ disable_csme_csrirq();
/* power off main SRAM */
sram_power(0);
@@ -633,24 +700,44 @@ void ish_aon_main(void)
{
/* set PMU wakeup interrupt gate using LDT code segment selector(0x4) */
- aon_idt[0].dword_lo = GEN_IDT_DESC_LO(&pmu_wakeup_isr, 0x4,
- IDT_DESC_FLAGS);
-
- aon_idt[0].dword_up = GEN_IDT_DESC_UP(&pmu_wakeup_isr, 0x4,
- IDT_DESC_FLAGS);
+ if (IS_ENABLED(CONFIG_ISH_NEW_PM)) {
+ aon_idt[AON_IDT_ENTRY_VEC_LAST -
+ AON_IDT_ENTRY_VEC_FIRST].dword_lo =
+ GEN_IDT_DESC_LO(&pmu_wakeup_isr, 0x4, IDT_DESC_FLAGS);
+
+ aon_idt[AON_IDT_ENTRY_VEC_LAST -
+ AON_IDT_ENTRY_VEC_FIRST].dword_up =
+ GEN_IDT_DESC_UP(&pmu_wakeup_isr, 0x4, IDT_DESC_FLAGS);
+ } else {
+ aon_idt[0].dword_lo = GEN_IDT_DESC_LO(&pmu_wakeup_isr, 0x4,
+ IDT_DESC_FLAGS);
+
+ aon_idt[0].dword_up = GEN_IDT_DESC_UP(&pmu_wakeup_isr, 0x4,
+ IDT_DESC_FLAGS);
+ }
if (IS_ENABLED(CONFIG_ISH_PM_RESET_PREP)) {
/*
* set reset prep interrupt gate using LDT code segment
* selector(0x4)
*/
- aon_idt[AON_IDT_ENTRY_VEC_LAST - AON_IDT_ENTRY_VEC_FIRST]
- .dword_lo =
- GEN_IDT_DESC_LO(&reset_prep_isr, 0x4, IDT_DESC_FLAGS);
+ if (IS_ENABLED(CONFIG_ISH_NEW_PM)) {
+ aon_idt[0].dword_lo = GEN_IDT_DESC_LO(&reset_prep_isr,
+ 0x4, IDT_DESC_FLAGS);
- aon_idt[AON_IDT_ENTRY_VEC_LAST - AON_IDT_ENTRY_VEC_FIRST]
- .dword_up =
- GEN_IDT_DESC_UP(&reset_prep_isr, 0x4, IDT_DESC_FLAGS);
+ aon_idt[0].dword_up = GEN_IDT_DESC_UP(&reset_prep_isr,
+ 0x4, IDT_DESC_FLAGS);
+ } else {
+ aon_idt[AON_IDT_ENTRY_VEC_LAST -
+ AON_IDT_ENTRY_VEC_FIRST].dword_lo =
+ GEN_IDT_DESC_LO(&reset_prep_isr, 0x4,
+ IDT_DESC_FLAGS);
+
+ aon_idt[AON_IDT_ENTRY_VEC_LAST -
+ AON_IDT_ENTRY_VEC_FIRST].dword_up =
+ GEN_IDT_DESC_UP(&reset_prep_isr, 0x4,
+ IDT_DESC_FLAGS);
+ }
}
while (1) {
diff --git a/chip/ish/power_mgt.c b/chip/ish/power_mgt.c
index f6ef5f8e0b..66c19aa1f2 100644
--- a/chip/ish/power_mgt.c
+++ b/chip/ish/power_mgt.c
@@ -346,6 +346,9 @@ static void enter_d0i1(void)
/* halt ISH cpu, will wakeup from PMU wakeup interrupt */
ish_mia_halt();
+ if (IS_ENABLED(CONFIG_ISH_NEW_PM))
+ clear_fabric_error();
+
/* disable Trunk Clock Gating (TCG) of ISH */
CCU_TCG_EN = 0;
@@ -391,6 +394,9 @@ static void enter_d0i2(void)
/* returned from aontask */
+ if (IS_ENABLED(CONFIG_ISH_NEW_PM))
+ clear_fabric_error();
+
/* disable power gating of RF(Cache) and ROMs */
PMU_RF_ROM_PWR_CTRL = 0;
@@ -439,6 +445,9 @@ static void enter_d0i3(void)
/* returned from aontask */
+ if (IS_ENABLED(CONFIG_ISH_NEW_PM))
+ clear_fabric_error();
+
/* disable power gating of RF(Cache) and ROMs */
PMU_RF_ROM_PWR_CTRL = 0;
@@ -492,6 +501,20 @@ static int d0ix_decide(timestamp_t cur_time, uint32_t idle_us)
return pm_state;
}
+static void pre_setting_d0ix(void)
+{
+ if (IS_ENABLED(CONFIG_ISH_NEW_PM)) {
+ PMU_VNN_REQ = PMU_VNN_REQ;
+ uart_to_idle();
+ }
+}
+
+static void post_setting_d0ix(void)
+{
+ if (IS_ENABLED(CONFIG_ISH_NEW_PM))
+ uart_port_restore();
+}
+
static void pm_process(timestamp_t cur_time, uint32_t idle_us)
{
int decide;
@@ -500,14 +523,20 @@ static void pm_process(timestamp_t cur_time, uint32_t idle_us)
switch (decide) {
case ISH_PM_STATE_D0I1:
+ pre_setting_d0ix();
enter_d0i1();
+ post_setting_d0ix();
break;
case ISH_PM_STATE_D0I2:
+ pre_setting_d0ix();
enter_d0i2();
+ post_setting_d0ix();
check_aon_task_status();
break;
case ISH_PM_STATE_D0I3:
+ pre_setting_d0ix();
enter_d0i3();
+ post_setting_d0ix();
check_aon_task_status();
break;
default:
@@ -516,6 +545,30 @@ static void pm_process(timestamp_t cur_time, uint32_t idle_us)
}
}
+static void reset_bcg(void)
+{
+ if (IS_ENABLED(CONFIG_ISH_NEW_PM)) {
+ CCU_BCG_MIA = 0;
+ CCU_BCG_DMA = 0;
+ CCU_BCG_I2C = 0;
+ CCU_BCG_SPI = 0;
+ CCU_BCG_UART = 0;
+ CCU_BCG_GPIO = 0;
+ } else {
+ CCU_BCG_EN = 0;
+ }
+}
+
+static void enable_d3bme_irqs(void)
+{
+ task_enable_irq(ISH_D3_RISE_IRQ);
+ if (!IS_ENABLED(CONFIG_ISH_NEW_PM)) {
+ task_enable_irq(ISH_D3_FALL_IRQ);
+ task_enable_irq(ISH_BME_RISE_IRQ);
+ task_enable_irq(ISH_BME_FALL_IRQ);
+ }
+}
+
void ish_pm_init(void)
{
/* clear reset bit */
@@ -526,7 +579,7 @@ void ish_pm_init(void)
/* disable TCG and disable BCG */
CCU_TCG_EN = 0;
- CCU_BCG_EN = 0;
+ reset_bcg();
if (IS_ENABLED(CONFIG_ISH_PM_AONTASK))
init_aon_task();
@@ -549,10 +602,7 @@ void ish_pm_init(void)
(PMU_D3_STATUS & PMU_BME_BIT_SET))
PMU_D3_STATUS = PMU_D3_STATUS;
- task_enable_irq(ISH_D3_RISE_IRQ);
- task_enable_irq(ISH_D3_FALL_IRQ);
- task_enable_irq(ISH_BME_RISE_IRQ);
- task_enable_irq(ISH_BME_FALL_IRQ);
+ enable_d3bme_irqs();
}
}
@@ -706,27 +756,29 @@ static void d3_rise_isr(void)
handle_d3(ISH_D3_RISE_VEC);
}
-static void d3_fall_isr(void)
+static __maybe_unused void d3_fall_isr(void)
{
handle_d3(ISH_D3_FALL_VEC);
}
-static void bme_rise_isr(void)
+static __maybe_unused void bme_rise_isr(void)
{
handle_d3(ISH_BME_RISE_VEC);
}
-static void bme_fall_isr(void)
+static __maybe_unused void bme_fall_isr(void)
{
handle_d3(ISH_BME_FALL_VEC);
}
#ifdef CONFIG_ISH_PM_D3
DECLARE_IRQ(ISH_D3_RISE_IRQ, d3_rise_isr);
+#ifndef CONFIG_ISH_NEW_PM
DECLARE_IRQ(ISH_D3_FALL_IRQ, d3_fall_isr);
DECLARE_IRQ(ISH_BME_RISE_IRQ, bme_rise_isr);
DECLARE_IRQ(ISH_BME_FALL_IRQ, bme_fall_isr);
#endif
+#endif
void ish_pm_refresh_console_in_use(void)
{
diff --git a/chip/ish/power_mgt.h b/chip/ish/power_mgt.h
index d66bb96550..bb56191508 100644
--- a/chip/ish/power_mgt.h
+++ b/chip/ish/power_mgt.h
@@ -9,6 +9,10 @@
#include "common.h"
#include "registers.h"
+extern void uart_port_restore(void);
+extern void uart_to_idle(void);
+extern void clear_fabric_error(void);
+
/* power states for ISH */
enum ish_pm_state {
/* D0 state: active mode */