1 /*
2 * Copyright (c) 2024 Ambiq Micro Inc.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <soc.h>
8
9 #include <zephyr/drivers/interrupt_controller/gic.h>
10 #include <zephyr/kernel.h>
11 #include <zephyr/logging/log.h>
12 #include <zephyr/pm/pm.h>
13 #include <zephyr/init.h>
14
15 /* ambiq-sdk includes */
16 #include <am_mcu_apollo.h>
17
18 LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL);
19
pm_state_set(enum pm_state state,uint8_t substate_id)20 void pm_state_set(enum pm_state state, uint8_t substate_id)
21 {
22 ARG_UNUSED(substate_id);
23
24 __disable_irq();
25 __set_BASEPRI(0);
26
27 switch (state) {
28 case PM_STATE_SUSPEND_TO_IDLE:
29 /* Put ARM core to normal sleep. */
30 am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_NORMAL);
31 break;
32 case PM_STATE_SUSPEND_TO_RAM:
33 /* Put ARM core to deep sleep. */
34 /* Cotex-m: power down, register value preserve.*/
35 /* Cache: power down*/
36 /* Flash: power down*/
37 /* Sram: retention*/
38 am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
39 break;
40 default:
41 LOG_DBG("Unsupported power state %u", state);
42 break;
43 }
44 }
45
46 /**
47 * @brief PM State Exit Post Operations
48 *
49 * For PM_STATE_SUSPEND_TO_IDLE:
50 * Nothing is needed after soc woken up.
51 *
52 * For PM_STATE_SUSPEND_TO_RAM:
53 * Flash, cache, sram automatically switch
54 * to active state on wake up
55 *
56 * @param state PM State
57 * @param substate_id Unused
58 *
59 */
pm_state_exit_post_ops(enum pm_state state,uint8_t substate_id)60 void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id)
61 {
62 ARG_UNUSED(substate_id);
63
64 __enable_irq();
65 irq_unlock(0);
66 }
67
ambiq_power_init(void)68 void ambiq_power_init(void)
69 {
70 /* Enable flash.
71 * Currently all flash area is powered on, but we should only enable the used flash area and
72 * put unused flash in power down mode.
73 */
74 if (am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEM_FLASH_MAX)) {
75 __ASSERT(0, "Failed to enable FLASH!");
76 }
77
78 /* Enable SRAM.
79 * Currently all SRAM area is powered on, but we should only enable the used ram area and
80 * put unused ram in power down mode.
81 */
82 if (am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEM_SRAM_MAX)) {
83 __ASSERT(0, "Failed to enable SRAM!");
84 }
85
86 /* For optimal Deep Sleep current, configure cache to be powered-down in deepsleep. */
87 am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_CACHE);
88
89 /* Power off all flash area, when go to deep sleep.*/
90 am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_FLASH_MAX);
91
92 /* Keep the used SRAM area in retention mode. */
93 am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_SRAM_MAX);
94 am_hal_pwrctrl_memory_deepsleep_retain(AM_HAL_PWRCTRL_MEM_SRAM_MAX);
95
96 #if defined(CONFIG_SOC_APOLLO3P_BLUE)
97 /*
98 * If user has enabled AM_HAL_SYSCTRL_DEEPSLEEP_WA in am_hal_sysctrl.h
99 * this will allow user to acheive lower current draw in deepsleep
100 */
101 am_hal_sysctrl_control(AM_HAL_SYSCTRL_CONTROL_DEEPSLEEP_MINPWR_EN, 0);
102 #endif
103 }
104