Skip to content

Commit

Permalink
soc: ambiq: Add power management support for Apollo3 SoCs
Browse files Browse the repository at this point in the history
This commit adds support for the power management for
Apollo3/Apollo3P SoCs

Signed-off-by: Zhengwei Wang <zwang@ambiq.com>
  • Loading branch information
zwang-ambiq authored and henrikbrixandersen committed Aug 20, 2024
1 parent 3b9a16d commit 1eb831e
Show file tree
Hide file tree
Showing 8 changed files with 173 additions and 1 deletion.
26 changes: 26 additions & 0 deletions dts/arm/ambiq/ambiq_apollo3_blue.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,32 @@
cpu0: cpu@0 {
compatible = "arm,cortex-m4f";
reg = <0>;
cpu-power-states = <&idle &suspend_to_ram>;
};

power-states {
idle: idle {
compatible = "zephyr,power-state";
power-state-name = "suspend-to-idle";
/* As Apollo3blue datasheet, run_to_sleep and sleep_to_run
* transition time are both lower than 1us, but considering
* the software overhead we set a bigger value.
*/
min-residency-us = <100>;
exit-latency-us = <5>;
};

suspend_to_ram: suspend_to_ram {
compatible = "zephyr,power-state";
power-state-name = "suspend-to-ram";
/* As Apollo3blue datasheet, run_to_deepsleep transition time is
* the software overhead 1us and deepsleep_to_run transition time
* is about 25us,but considering the software overhead, we set
* a bigger value.
*/
min-residency-us = <2000>;
exit-latency-us = <125>;
};
};
};

Expand Down
26 changes: 26 additions & 0 deletions dts/arm/ambiq/ambiq_apollo3p_blue.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,32 @@
cpu0: cpu@0 {
compatible = "arm,cortex-m4f";
reg = <0>;
cpu-power-states = <&idle &suspend_to_ram>;
};

power-states {
idle: idle {
compatible = "zephyr,power-state";
power-state-name = "suspend-to-idle";
/* As Apollo3blueplus datasheet, run_to_sleep and sleep_to_run
* transition time are both lower than 1us, but considering
* the software overhead we set a bigger value.
*/
min-residency-us = <100>;
exit-latency-us = <5>;
};

suspend_to_ram: suspend_to_ram {
compatible = "zephyr,power-state";
power-state-name = "suspend-to-ram";
/* As Apollo3blueplus datasheet, run_to_deepsleep transition time
* is the software overhead 1us and deepsleep_to_run transition
* time is about 25us,but considering the software overhead,
* we set a bigger value.
*/
min-residency-us = <2000>;
exit-latency-us = <125>;
};
};
};

Expand Down
1 change: 1 addition & 0 deletions soc/ambiq/apollo3x/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

zephyr_sources(soc.c)
zephyr_include_directories(.)
zephyr_sources_ifdef(CONFIG_PM power.c)

zephyr_linker_sources(SECTIONS shared_ram.ld)

Expand Down
1 change: 1 addition & 0 deletions soc/ambiq/apollo3x/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ config SOC_SERIES_APOLLO3X
select CPU_HAS_ARM_MPU
select HAS_SWO
select AMBIQ_HAL
select HAS_PM
5 changes: 5 additions & 0 deletions soc/ambiq/apollo3x/Kconfig.defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,9 @@ if SOC_SERIES_APOLLO3X

rsource "Kconfig.defconfig.apollo3*"

# Need to enlarge the IDLE stack size because the power
# management operations are executed in the idle task
config IDLE_STACK_SIZE
default 2048 if PM

endif # SOC_SERIES_APOLLO3X
107 changes: 107 additions & 0 deletions soc/ambiq/apollo3x/power.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* 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);
6 changes: 6 additions & 0 deletions soc/ambiq/apollo3x/soc.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@

static int arm_apollo3_init(void)
{
/* Set the clock frequency. */
am_hal_clkgen_control(AM_HAL_CLKGEN_CONTROL_SYSCLK_MAX, 0);

/* Enable Flash cache.*/
am_hal_cachectrl_config(&am_hal_cachectrl_defaults);
am_hal_cachectrl_enable();

/* Initialize for low power in the power control block */
am_hal_pwrctrl_low_power_init();
Expand Down
2 changes: 1 addition & 1 deletion soc/ambiq/apollo4x/power.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2024 Ambiq LLC
* Copyright (c) 2024 Ambiq Micro Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down

0 comments on commit 1eb831e

Please sign in to comment.