diff options
Diffstat (limited to 'chip/ish/power_mgt.c')
-rw-r--r-- | chip/ish/power_mgt.c | 83 |
1 files changed, 71 insertions, 12 deletions
diff --git a/chip/ish/power_mgt.c b/chip/ish/power_mgt.c index da86bb7608..7cf2cdc383 100644 --- a/chip/ish/power_mgt.c +++ b/chip/ish/power_mgt.c @@ -12,6 +12,7 @@ #include "aontaskfw/ish_aon_share.h" #include "power_mgt.h" #include "watchdog.h" +#include "ish_dma.h" #ifdef CONFIG_ISH_PM_DEBUG #define CPUTS(outstr) cputs(CC_SYSTEM, outstr) @@ -28,6 +29,12 @@ extern void watchdog_enable(void); extern void watchdog_disable(void); #endif +/* defined in link script: core/minute-ia/ec.lds.S */ +extern uint32_t __aon_ro_start; +extern uint32_t __aon_ro_end; +extern uint32_t __aon_rw_start; +extern uint32_t __aon_rw_end; + /* power management internal context data structure */ struct pm_context { /* aontask image valid flag */ @@ -168,6 +175,16 @@ static void init_aon_task(void) "movw $0x18, %ax;\n" "ltr %ax;\n" "pop %eax;"); + + aon_share->main_fw_ro_addr = (uint32_t)&__aon_ro_start; + aon_share->main_fw_ro_size = (uint32_t)&__aon_ro_end - + (uint32_t)&__aon_ro_start; + + aon_share->main_fw_rw_addr = (uint32_t)&__aon_rw_start; + aon_share->main_fw_rw_size = (uint32_t)&__aon_rw_end - + (uint32_t)&__aon_rw_start; + + ish_dma_init(); } static inline void check_aon_task_status(void) @@ -236,18 +253,29 @@ static void enter_d0i0(void) static void enter_d0i1(void) { - timestamp_t t0, t1; + uint64_t current_irq_map; + timestamp_t t0, t1; t0 = get_time(); pm_ctx.aon_share->pm_state = ISH_PM_STATE_D0I1; - /* TODO: enable Trunk Clock Gating (TCG) of ISH */ + /* only enable PMU wakeup interrupt */ + current_irq_map = disable_all_interrupts(); + task_enable_irq(ISH_PMU_WAKEUP_IRQ); + + /* enable Trunk Clock Gating (TCG) of ISH */ + CCU_TCG_EN = 1; /* halt ISH cpu, will wakeup from PMU wakeup interrupt */ ish_halt(); - /* TODO disable Trunk Clock Gating (TCG) of ISH */ + /* disable Trunk Clock Gating (TCG) of ISH */ + CCU_TCG_EN = 0; + + /* restore interrupts */ + task_disable_irq(ISH_PMU_WAKEUP_IRQ); + restore_interrupts(current_irq_map); pm_ctx.aon_share->pm_state = ISH_PM_STATE_D0; @@ -262,21 +290,36 @@ static void enter_d0i1(void) static void enter_d0i2(void) { - timestamp_t t0, t1; + uint64_t current_irq_map; + timestamp_t t0, t1; t0 = get_time(); pm_ctx.aon_share->pm_state = ISH_PM_STATE_D0I2; - /* TODO: enable Trunk Clock Gating (TCG) of ISH */ + /* only enable PMU wakeup interrupt */ + current_irq_map = disable_all_interrupts(); + task_enable_irq(ISH_PMU_WAKEUP_IRQ); + + /* enable Trunk Clock Gating (TCG) of ISH */ + CCU_TCG_EN = 1; + + /* enable power gating of RF(Cache) and ROMs */ + PMU_RF_ROM_PWR_CTRL = 1; switch_to_aontask(); + /* returned from aontask */ - /* TODO just for test, will remove later */ - ish_halt(); + /* disable power gating of RF(Cache) and ROMs */ + PMU_RF_ROM_PWR_CTRL = 0; - /* TODO disable Trunk Clock Gating (TCG) of ISH */ + /* disable Trunk Clock Gating (TCG) of ISH */ + CCU_TCG_EN = 0; + + /* restore interrupts */ + task_disable_irq(ISH_PMU_WAKEUP_IRQ); + restore_interrupts(current_irq_map); t1 = get_time(); @@ -292,20 +335,36 @@ static void enter_d0i2(void) static void enter_d0i3(void) { + uint64_t current_irq_map; timestamp_t t0, t1; t0 = get_time(); pm_ctx.aon_share->pm_state = ISH_PM_STATE_D0I3; - /*TODO some preparing work for D0i3 */ + /* only enable PMU wakeup interrupt */ + current_irq_map = disable_all_interrupts(); + task_enable_irq(ISH_PMU_WAKEUP_IRQ); + + /* enable Trunk Clock Gating (TCG) of ISH */ + CCU_TCG_EN = 1; + + /* enable power gating of RF(Cache) and ROMs */ + PMU_RF_ROM_PWR_CTRL = 1; switch_to_aontask(); - /*TODO just for test, will remove later */ - ish_halt(); + /* returned from aontask */ + + /* disable power gating of RF(Cache) and ROMs */ + PMU_RF_ROM_PWR_CTRL = 0; + + /* disable Trunk Clock Gating (TCG) of ISH */ + CCU_TCG_EN = 0; - /*TODO some restore work for D0i3 */ + /* restore interrupts */ + task_disable_irq(ISH_PMU_WAKEUP_IRQ); + restore_interrupts(current_irq_map); t1 = get_time(); |