diff options
author | Leifu Zhao <leifu.zhao@intel.com> | 2020-02-14 10:53:48 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-02-27 00:29:05 +0000 |
commit | 3f1dc59f201a5e3f52c1f0b6e72c8a166ea8dacf (patch) | |
tree | c5a1f3b5ad72d32fb2746c00a67359aac06fcba2 /chip/ish | |
parent | e225427d2a04449d65fbae72932caa8270f182c7 (diff) | |
download | chrome-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/ish')
-rw-r--r-- | chip/ish/aontaskfw/ish_aontask.c | 135 | ||||
-rw-r--r-- | chip/ish/power_mgt.c | 68 | ||||
-rw-r--r-- | chip/ish/power_mgt.h | 4 |
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 */ |