zephyr/soc/ambiq/apollo3x/power.c

108 lines
2.8 KiB
C
Raw Normal View History

/*
* Copyright (c) 2024 Ambiq Micro Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <soc.h>
#include <zephyr/drivers/interrupt_controller/gic.h>
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/pm/pm.h>
#include <zephyr/init.h>
/* ambiq-sdk includes */
#include <am_mcu_apollo.h>
LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL);
void pm_state_set(enum pm_state state, uint8_t substate_id)
{
ARG_UNUSED(substate_id);
__disable_irq();
__set_BASEPRI(0);
switch (state) {
case PM_STATE_SUSPEND_TO_IDLE:
/* Put ARM core to normal sleep. */
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_NORMAL);
break;
case PM_STATE_SUSPEND_TO_RAM:
/* Put ARM core to deep sleep. */
/* Cotex-m: power down, register value preserve.*/
/* Cache: power down*/
/* Flash: power down*/
/* Sram: retention*/
am_hal_sysctrl_sleep(AM_HAL_SYSCTRL_SLEEP_DEEP);
break;
default:
LOG_DBG("Unsupported power state %u", state);
break;
}
}
/**
* @brief PM State Exit Post Operations
*
* For PM_STATE_SUSPEND_TO_IDLE:
* Nothing is needed after soc woken up.
*
* For PM_STATE_SUSPEND_TO_RAM:
* Flash, cache, sram automatically switch
* to active state on wake up
*
* @param state PM State
* @param substate_id Unused
*
*/
void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id)
{
ARG_UNUSED(substate_id);
__enable_irq();
irq_unlock(0);
}
static int ambiq_power_init(void)
{
/* Enable flash.
* Currently all flash area is powered on, but we should only enable the used flash area and
* put unused flash in power down mode.
*/
if (am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEM_FLASH_MAX)) {
__ASSERT(0, "Failed to enable FLASH!");
}
/* Enable SRAM.
* Currently all SRAM area is powered on, but we should only enable the used ram area and
* put unused ram in power down mode.
*/
if (am_hal_pwrctrl_memory_enable(AM_HAL_PWRCTRL_MEM_SRAM_MAX)) {
__ASSERT(0, "Failed to enable SRAM!");
}
/* For optimal Deep Sleep current, configure cache to be powered-down in deepsleep. */
am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_CACHE);
/* Power off all flash area, when go to deep sleep.*/
am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_FLASH_MAX);
/* Keep the used SRAM area in retention mode. */
am_hal_pwrctrl_memory_deepsleep_powerdown(AM_HAL_PWRCTRL_MEM_SRAM_MAX);
am_hal_pwrctrl_memory_deepsleep_retain(AM_HAL_PWRCTRL_MEM_SRAM_MAX);
#if defined(CONFIG_SOC_APOLLO3P_BLUE)
/*
* If user has enabled AM_HAL_SYSCTRL_DEEPSLEEP_WA in am_hal_sysctrl.h
* this will allow user to acheive lower current draw in deepsleep
*/
am_hal_sysctrl_control(AM_HAL_SYSCTRL_CONTROL_DEEPSLEEP_MINPWR_EN, 0);
#endif
return 0;
}
SYS_INIT(ambiq_power_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);