soc: renesas: Add power management support for Renesas RA8
Updated `CMakeLists.txt` and `Kconfig` to integrate power management for RA8D1, RA8M1, and RA8T1. Modified `Kconfig.defconfig` to configure ULPT timer as the system timer when power management is enabled: - Adjusted `SYS_CLOCK_HW_CYCLES_PER_SEC` and `SYS_CLOCK_TICKS_PER_SEC` for ULPT timer. - Disabled `CORTEX_M_SYSTICK` when ULPT timer is used as the system timer. Implemented power management logic in the new `power.c` file for: - RA8D1 (`soc/renesas/ra/ra8d1/power.c`) - RA8M1 (`soc/renesas/ra/ra8m1/power.c`) - RA8T1 (`soc/renesas/ra/ra8t1/power.c`) Signed-off-by: Khanh Nguyen <khanh.nguyen.wz@bp.renesas.com>
This commit is contained in:
parent
528153e245
commit
fb572d59a2
12 changed files with 358 additions and 16 deletions
|
@ -7,6 +7,10 @@ zephyr_sources(
|
|||
soc.c
|
||||
)
|
||||
|
||||
zephyr_sources_ifdef(CONFIG_PM
|
||||
power.c
|
||||
)
|
||||
|
||||
zephyr_linker_sources(SECTIONS sections.ld)
|
||||
|
||||
set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "")
|
||||
|
|
|
@ -15,3 +15,4 @@ config SOC_SERIES_RA8D1
|
|||
select HAS_RENESAS_RA_FSP
|
||||
select SOC_EARLY_INIT_HOOK
|
||||
select GPIO_RA_HAS_VBTICTLR
|
||||
select HAS_PM
|
||||
|
|
|
@ -6,11 +6,6 @@ if SOC_SERIES_RA8D1
|
|||
config NUM_IRQS
|
||||
default 96
|
||||
|
||||
DT_ICLK_PATH := $(dt_nodelabel_path,cpuclk)
|
||||
|
||||
config SYS_CLOCK_HW_CYCLES_PER_SEC
|
||||
default $(dt_node_int_prop_int,$(DT_ICLK_PATH),clock-frequency)
|
||||
|
||||
config BUILD_OUTPUT_HEX
|
||||
default y
|
||||
|
||||
|
@ -27,4 +22,20 @@ config DCACHE
|
|||
config CACHE_MANAGEMENT
|
||||
default n
|
||||
|
||||
config CORTEX_M_SYSTICK
|
||||
default n if RENESAS_RA_ULPT_TIMER
|
||||
|
||||
DT_ICLK_PATH := $(dt_nodelabel_path,cpuclk)
|
||||
DT_LOCO_PATH := $(dt_nodelabel_path,loco)
|
||||
|
||||
config SYS_CLOCK_HW_CYCLES_PER_SEC
|
||||
default $(dt_node_int_prop_int,$(DT_ICLK_PATH),clock-frequency) if CORTEX_M_SYSTICK
|
||||
default $(dt_node_int_prop_int,$(DT_LOCO_PATH),clock-frequency) if RENESAS_RA_ULPT_TIMER
|
||||
|
||||
config SYS_CLOCK_TICKS_PER_SEC
|
||||
default 4096 if RENESAS_RA_ULPT_TIMER
|
||||
|
||||
config PM_DEVICE
|
||||
default y if PM
|
||||
|
||||
endif # SOC_SERIES_RA8D1
|
||||
|
|
98
soc/renesas/ra/ra8d1/power.c
Normal file
98
soc/renesas/ra/ra8d1/power.c
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (c) 2025 Renesas Electronics Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/pm/pm.h>
|
||||
#include <zephyr/init.h>
|
||||
#include <soc.h>
|
||||
#include <r_lpm.h>
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL);
|
||||
|
||||
/* Low Power Mode instance control structure */
|
||||
static lpm_instance_ctrl_t pm_state_ctrl;
|
||||
|
||||
/* Configuration for Runtime Idle Power State */
|
||||
const lpm_cfg_t pm_state_runtime_idle_cfg = {
|
||||
.low_power_mode = LPM_MODE_SLEEP,
|
||||
.standby_wake_sources = LPM_STANDBY_WAKE_SOURCE_ULP0U,
|
||||
.output_port_enable = LPM_OUTPUT_PORT_ENABLE_RETAIN,
|
||||
.io_port_state = LPM_IO_PORT_NO_CHANGE,
|
||||
.power_supply_state = LPM_POWER_SUPPLY_DEEP_STANDBY_MODE1,
|
||||
.deep_standby_cancel_source = (lpm_deep_standby_cancel_source_t)0,
|
||||
.deep_standby_cancel_edge = (lpm_deep_standby_cancel_edge_t)0,
|
||||
.ram_retention_cfg.ram_retention = (uint16_t)(0x7F),
|
||||
.ram_retention_cfg.tcm_retention = true,
|
||||
.ram_retention_cfg.standby_ram_retention = true,
|
||||
.ldo_standby_cfg.pll1_ldo = false,
|
||||
.ldo_standby_cfg.pll2_ldo = false,
|
||||
.ldo_standby_cfg.hoco_ldo = false,
|
||||
.p_extend = NULL,
|
||||
};
|
||||
|
||||
/* Configuration for Standby Power State */
|
||||
const lpm_cfg_t pm_state_standby_cfg = {
|
||||
.low_power_mode = LPM_MODE_STANDBY,
|
||||
.standby_wake_sources = LPM_STANDBY_WAKE_SOURCE_ULP0U,
|
||||
.output_port_enable = LPM_OUTPUT_PORT_ENABLE_RETAIN,
|
||||
.io_port_state = LPM_IO_PORT_NO_CHANGE,
|
||||
.power_supply_state = LPM_POWER_SUPPLY_DEEP_STANDBY_MODE1,
|
||||
.deep_standby_cancel_source = (lpm_deep_standby_cancel_source_t)0,
|
||||
.deep_standby_cancel_edge = (lpm_deep_standby_cancel_edge_t)0,
|
||||
.ram_retention_cfg.ram_retention = (uint16_t)(0x7F),
|
||||
.ram_retention_cfg.tcm_retention = true,
|
||||
.ram_retention_cfg.standby_ram_retention = true,
|
||||
.ldo_standby_cfg.pll1_ldo = false,
|
||||
.ldo_standby_cfg.pll2_ldo = false,
|
||||
.ldo_standby_cfg.hoco_ldo = false,
|
||||
.p_extend = NULL,
|
||||
};
|
||||
|
||||
void pm_state_set(enum pm_state state, uint8_t substate_id)
|
||||
{
|
||||
switch (state) {
|
||||
case PM_STATE_RUNTIME_IDLE:
|
||||
R_LPM_LowPowerReconfigure(&pm_state_ctrl, &pm_state_runtime_idle_cfg);
|
||||
__disable_irq();
|
||||
__set_BASEPRI(0);
|
||||
__ISB();
|
||||
|
||||
R_LPM_LowPowerModeEnter(&pm_state_ctrl);
|
||||
__enable_irq();
|
||||
__ISB();
|
||||
break;
|
||||
|
||||
case PM_STATE_STANDBY:
|
||||
R_LPM_Open(&pm_state_ctrl, &pm_state_standby_cfg);
|
||||
__disable_irq();
|
||||
__set_BASEPRI(0);
|
||||
__ISB();
|
||||
|
||||
R_LPM_LowPowerModeEnter(&pm_state_ctrl);
|
||||
__enable_irq();
|
||||
__ISB();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id)
|
||||
{
|
||||
switch (state) {
|
||||
case PM_STATE_RUNTIME_IDLE:
|
||||
__fallthrough;
|
||||
case PM_STATE_STANDBY:
|
||||
R_LPM_Close(&pm_state_ctrl);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
irq_unlock(0);
|
||||
}
|
|
@ -7,6 +7,10 @@ zephyr_sources(
|
|||
soc.c
|
||||
)
|
||||
|
||||
zephyr_sources_ifdef(CONFIG_PM
|
||||
power.c
|
||||
)
|
||||
|
||||
zephyr_linker_sources(SECTIONS sections.ld)
|
||||
|
||||
set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "")
|
||||
|
|
|
@ -15,5 +15,6 @@ config SOC_SERIES_RA8M1
|
|||
select HAS_RENESAS_RA_FSP
|
||||
select SOC_EARLY_INIT_HOOK
|
||||
select GPIO_RA_HAS_VBTICTLR
|
||||
select HAS_PM
|
||||
help
|
||||
Enable support for Renesas RA8M1 MCU series
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (c) 2024 Renesas Electronics Corporation
|
||||
# Copyright (c) 2024-2025 Renesas Electronics Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
if SOC_SERIES_RA8M1
|
||||
|
@ -6,11 +6,6 @@ if SOC_SERIES_RA8M1
|
|||
config NUM_IRQS
|
||||
default 96
|
||||
|
||||
DT_ICLK_PATH := $(dt_nodelabel_path,cpuclk)
|
||||
|
||||
config SYS_CLOCK_HW_CYCLES_PER_SEC
|
||||
default $(dt_node_int_prop_int,$(DT_ICLK_PATH),clock-frequency)
|
||||
|
||||
config BUILD_OUTPUT_HEX
|
||||
default y
|
||||
|
||||
|
@ -21,4 +16,20 @@ config CLOCK_CONTROL
|
|||
config FLASH_FILL_BUFFER_SIZE
|
||||
default 128
|
||||
|
||||
config CORTEX_M_SYSTICK
|
||||
default n if RENESAS_RA_ULPT_TIMER
|
||||
|
||||
DT_ICLK_PATH := $(dt_nodelabel_path,cpuclk)
|
||||
DT_LOCO_PATH := $(dt_nodelabel_path,loco)
|
||||
|
||||
config SYS_CLOCK_HW_CYCLES_PER_SEC
|
||||
default $(dt_node_int_prop_int,$(DT_ICLK_PATH),clock-frequency) if CORTEX_M_SYSTICK
|
||||
default $(dt_node_int_prop_int,$(DT_LOCO_PATH),clock-frequency) if RENESAS_RA_ULPT_TIMER
|
||||
|
||||
config SYS_CLOCK_TICKS_PER_SEC
|
||||
default 4096 if RENESAS_RA_ULPT_TIMER
|
||||
|
||||
config PM_DEVICE
|
||||
default y if PM
|
||||
|
||||
endif # SOC_SERIES_RA8M1
|
||||
|
|
98
soc/renesas/ra/ra8m1/power.c
Normal file
98
soc/renesas/ra/ra8m1/power.c
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (c) 2025 Renesas Electronics Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/pm/pm.h>
|
||||
#include <zephyr/init.h>
|
||||
#include <soc.h>
|
||||
#include <r_lpm.h>
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL);
|
||||
|
||||
/* Low Power Mode instance control structure */
|
||||
static lpm_instance_ctrl_t pm_state_ctrl;
|
||||
|
||||
/* Configuration for Runtime Idle Power State */
|
||||
const lpm_cfg_t pm_state_runtime_idle_cfg = {
|
||||
.low_power_mode = LPM_MODE_SLEEP,
|
||||
.standby_wake_sources = LPM_STANDBY_WAKE_SOURCE_ULP0U,
|
||||
.output_port_enable = LPM_OUTPUT_PORT_ENABLE_RETAIN,
|
||||
.io_port_state = LPM_IO_PORT_NO_CHANGE,
|
||||
.power_supply_state = LPM_POWER_SUPPLY_DEEP_STANDBY_MODE1,
|
||||
.deep_standby_cancel_source = (lpm_deep_standby_cancel_source_t)0,
|
||||
.deep_standby_cancel_edge = (lpm_deep_standby_cancel_edge_t)0,
|
||||
.ram_retention_cfg.ram_retention = (uint16_t)(0x7F),
|
||||
.ram_retention_cfg.tcm_retention = true,
|
||||
.ram_retention_cfg.standby_ram_retention = true,
|
||||
.ldo_standby_cfg.pll1_ldo = false,
|
||||
.ldo_standby_cfg.pll2_ldo = false,
|
||||
.ldo_standby_cfg.hoco_ldo = false,
|
||||
.p_extend = NULL,
|
||||
};
|
||||
|
||||
/* Configuration for Standby Power State */
|
||||
const lpm_cfg_t pm_state_standby_cfg = {
|
||||
.low_power_mode = LPM_MODE_STANDBY,
|
||||
.standby_wake_sources = LPM_STANDBY_WAKE_SOURCE_ULP0U,
|
||||
.output_port_enable = LPM_OUTPUT_PORT_ENABLE_RETAIN,
|
||||
.io_port_state = LPM_IO_PORT_NO_CHANGE,
|
||||
.power_supply_state = LPM_POWER_SUPPLY_DEEP_STANDBY_MODE1,
|
||||
.deep_standby_cancel_source = (lpm_deep_standby_cancel_source_t)0,
|
||||
.deep_standby_cancel_edge = (lpm_deep_standby_cancel_edge_t)0,
|
||||
.ram_retention_cfg.ram_retention = (uint16_t)(0x7F),
|
||||
.ram_retention_cfg.tcm_retention = true,
|
||||
.ram_retention_cfg.standby_ram_retention = true,
|
||||
.ldo_standby_cfg.pll1_ldo = false,
|
||||
.ldo_standby_cfg.pll2_ldo = false,
|
||||
.ldo_standby_cfg.hoco_ldo = false,
|
||||
.p_extend = NULL,
|
||||
};
|
||||
|
||||
void pm_state_set(enum pm_state state, uint8_t substate_id)
|
||||
{
|
||||
switch (state) {
|
||||
case PM_STATE_RUNTIME_IDLE:
|
||||
R_LPM_LowPowerReconfigure(&pm_state_ctrl, &pm_state_runtime_idle_cfg);
|
||||
__disable_irq();
|
||||
__set_BASEPRI(0);
|
||||
__ISB();
|
||||
|
||||
R_LPM_LowPowerModeEnter(&pm_state_ctrl);
|
||||
__enable_irq();
|
||||
__ISB();
|
||||
break;
|
||||
|
||||
case PM_STATE_STANDBY:
|
||||
R_LPM_Open(&pm_state_ctrl, &pm_state_standby_cfg);
|
||||
__disable_irq();
|
||||
__set_BASEPRI(0);
|
||||
__ISB();
|
||||
|
||||
R_LPM_LowPowerModeEnter(&pm_state_ctrl);
|
||||
__enable_irq();
|
||||
__ISB();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id)
|
||||
{
|
||||
switch (state) {
|
||||
case PM_STATE_RUNTIME_IDLE:
|
||||
__fallthrough;
|
||||
case PM_STATE_STANDBY:
|
||||
R_LPM_Close(&pm_state_ctrl);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
irq_unlock(0);
|
||||
}
|
|
@ -7,6 +7,10 @@ zephyr_sources(
|
|||
soc.c
|
||||
)
|
||||
|
||||
zephyr_sources_ifdef(CONFIG_PM
|
||||
power.c
|
||||
)
|
||||
|
||||
zephyr_linker_sources(SECTIONS sections.ld)
|
||||
|
||||
set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm/cortex_m/scripts/linker.ld CACHE INTERNAL "")
|
||||
|
|
|
@ -15,3 +15,4 @@ config SOC_SERIES_RA8T1
|
|||
select HAS_RENESAS_RA_FSP
|
||||
select SOC_EARLY_INIT_HOOK
|
||||
select GPIO_RA_HAS_VBTICTLR
|
||||
select HAS_PM
|
||||
|
|
|
@ -6,11 +6,6 @@ if SOC_SERIES_RA8T1
|
|||
config NUM_IRQS
|
||||
default 96
|
||||
|
||||
DT_ICLK_PATH := $(dt_nodelabel_path,cpuclk)
|
||||
|
||||
config SYS_CLOCK_HW_CYCLES_PER_SEC
|
||||
default $(dt_node_int_prop_int,$(DT_ICLK_PATH),clock-frequency)
|
||||
|
||||
config BUILD_OUTPUT_HEX
|
||||
default y
|
||||
|
||||
|
@ -21,4 +16,20 @@ config CLOCK_CONTROL
|
|||
config FLASH_FILL_BUFFER_SIZE
|
||||
default 128
|
||||
|
||||
config CORTEX_M_SYSTICK
|
||||
default n if RENESAS_RA_ULPT_TIMER
|
||||
|
||||
DT_ICLK_PATH := $(dt_nodelabel_path,cpuclk)
|
||||
DT_LOCO_PATH := $(dt_nodelabel_path,loco)
|
||||
|
||||
config SYS_CLOCK_HW_CYCLES_PER_SEC
|
||||
default $(dt_node_int_prop_int,$(DT_ICLK_PATH),clock-frequency) if CORTEX_M_SYSTICK
|
||||
default $(dt_node_int_prop_int,$(DT_LOCO_PATH),clock-frequency) if RENESAS_RA_ULPT_TIMER
|
||||
|
||||
config SYS_CLOCK_TICKS_PER_SEC
|
||||
default 4096 if RENESAS_RA_ULPT_TIMER
|
||||
|
||||
config PM_DEVICE
|
||||
default y if PM
|
||||
|
||||
endif # SOC_SERIES_RA8T1
|
||||
|
|
98
soc/renesas/ra/ra8t1/power.c
Normal file
98
soc/renesas/ra/ra8t1/power.c
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (c) 2025 Renesas Electronics Corporation
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/pm/pm.h>
|
||||
#include <zephyr/init.h>
|
||||
#include <soc.h>
|
||||
#include <r_lpm.h>
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL);
|
||||
|
||||
/* Low Power Mode instance control structure */
|
||||
static lpm_instance_ctrl_t pm_state_ctrl;
|
||||
|
||||
/* Configuration for Runtime Idle Power State */
|
||||
const lpm_cfg_t pm_state_runtime_idle_cfg = {
|
||||
.low_power_mode = LPM_MODE_SLEEP,
|
||||
.standby_wake_sources = LPM_STANDBY_WAKE_SOURCE_ULP0U,
|
||||
.output_port_enable = LPM_OUTPUT_PORT_ENABLE_RETAIN,
|
||||
.io_port_state = LPM_IO_PORT_NO_CHANGE,
|
||||
.power_supply_state = LPM_POWER_SUPPLY_DEEP_STANDBY_MODE1,
|
||||
.deep_standby_cancel_source = (lpm_deep_standby_cancel_source_t)0,
|
||||
.deep_standby_cancel_edge = (lpm_deep_standby_cancel_edge_t)0,
|
||||
.ram_retention_cfg.ram_retention = (uint16_t)(0x7F),
|
||||
.ram_retention_cfg.tcm_retention = true,
|
||||
.ram_retention_cfg.standby_ram_retention = true,
|
||||
.ldo_standby_cfg.pll1_ldo = false,
|
||||
.ldo_standby_cfg.pll2_ldo = false,
|
||||
.ldo_standby_cfg.hoco_ldo = false,
|
||||
.p_extend = NULL,
|
||||
};
|
||||
|
||||
/* Configuration for Standby Power State */
|
||||
const lpm_cfg_t pm_state_standby_cfg = {
|
||||
.low_power_mode = LPM_MODE_STANDBY,
|
||||
.standby_wake_sources = LPM_STANDBY_WAKE_SOURCE_ULP0U,
|
||||
.output_port_enable = LPM_OUTPUT_PORT_ENABLE_RETAIN,
|
||||
.io_port_state = LPM_IO_PORT_NO_CHANGE,
|
||||
.power_supply_state = LPM_POWER_SUPPLY_DEEP_STANDBY_MODE1,
|
||||
.deep_standby_cancel_source = (lpm_deep_standby_cancel_source_t)0,
|
||||
.deep_standby_cancel_edge = (lpm_deep_standby_cancel_edge_t)0,
|
||||
.ram_retention_cfg.ram_retention = (uint16_t)(0x7F),
|
||||
.ram_retention_cfg.tcm_retention = true,
|
||||
.ram_retention_cfg.standby_ram_retention = true,
|
||||
.ldo_standby_cfg.pll1_ldo = false,
|
||||
.ldo_standby_cfg.pll2_ldo = false,
|
||||
.ldo_standby_cfg.hoco_ldo = false,
|
||||
.p_extend = NULL,
|
||||
};
|
||||
|
||||
void pm_state_set(enum pm_state state, uint8_t substate_id)
|
||||
{
|
||||
switch (state) {
|
||||
case PM_STATE_RUNTIME_IDLE:
|
||||
R_LPM_LowPowerReconfigure(&pm_state_ctrl, &pm_state_runtime_idle_cfg);
|
||||
__disable_irq();
|
||||
__set_BASEPRI(0);
|
||||
__ISB();
|
||||
|
||||
R_LPM_LowPowerModeEnter(&pm_state_ctrl);
|
||||
__enable_irq();
|
||||
__ISB();
|
||||
break;
|
||||
|
||||
case PM_STATE_STANDBY:
|
||||
R_LPM_Open(&pm_state_ctrl, &pm_state_standby_cfg);
|
||||
__disable_irq();
|
||||
__set_BASEPRI(0);
|
||||
__ISB();
|
||||
|
||||
R_LPM_LowPowerModeEnter(&pm_state_ctrl);
|
||||
__enable_irq();
|
||||
__ISB();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id)
|
||||
{
|
||||
switch (state) {
|
||||
case PM_STATE_RUNTIME_IDLE:
|
||||
__fallthrough;
|
||||
case PM_STATE_STANDBY:
|
||||
R_LPM_Close(&pm_state_ctrl);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
irq_unlock(0);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue