summaryrefslogtreecommitdiff
path: root/chip/ish/power_mgt.c
diff options
context:
space:
mode:
Diffstat (limited to 'chip/ish/power_mgt.c')
-rw-r--r--chip/ish/power_mgt.c83
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();