Skip to content

Commit 132247e

Browse files
fimohamedkalowsk
authored andcommitted
soc: silabs: siwx91x: Add siwx91x Power Manager driver
This commit enables the Power Manager driver support for the siwx91x device. Signed-off-by: S Mohamed Fiaz <[email protected]>
1 parent c891ace commit 132247e

File tree

8 files changed

+185
-5
lines changed

8 files changed

+185
-5
lines changed

dts/arm/silabs/siwg917.dtsi

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,20 @@
2424
cpu0: cpu@0 {
2525
compatible = "arm,cortex-m4f";
2626
reg = <0>;
27+
cpu-power-states = <&pstate_ps4_standby &pstate_ps4_sleep>;
28+
};
29+
30+
power-states {
31+
pstate_ps4_standby: ps4_standby {
32+
compatible = "zephyr,power-state";
33+
power-state-name = "runtime-idle";
34+
};
35+
pstate_ps4_sleep: ps4_sleep {
36+
compatible = "zephyr,power-state";
37+
power-state-name = "suspend-to-idle";
38+
min-residency-us = <100000>;
39+
exit-latency-us = <3000>;
40+
};
2741
};
2842
};
2943

modules/hal_silabs/wiseconnect/CMakeLists.txt

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
set(SISDK_DIR ${ZEPHYR_HAL_SILABS_MODULE_DIR}/simplicity_sdk)
55
set(WISECONNECT_DIR ${ZEPHYR_HAL_SILABS_MODULE_DIR}/wiseconnect)
6+
set(COMMON_DIR ${ZEPHYR_HAL_SILABS_MODULE_DIR}/simplicity_sdk/platform/common)
67

78
# Keep these values sync with
89
# components/device/silabs/si91x/mcu/core/chip/component/siwg917*.slcc
@@ -23,16 +24,25 @@ zephyr_include_directories(
2324
${SISDK_DIR}/platform/common/inc
2425
${SISDK_DIR}/platform/common/config
2526
${SISDK_DIR}/platform/service/mem_pool/inc
26-
${WISECONNECT_DIR}/components/board/silabs/inc
27+
# Wiseconnect do not provide generic RTE_Device_917.h. However, all the boards
28+
# share more-or-less the same definitions. So we could take any of them.
29+
# In addtion, this file is only required for the compilation, but none the
30+
# symbols are normally used by Zephyr (it is required to compile CMSIS API
31+
# which is not not used).
32+
${WISECONNECT_DIR}/components/board/silabs/config/brd4342a
2733
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/core/config
2834
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/core/chip/inc
2935
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/core/chip/config
36+
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/core/common/inc
3037
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/rom_driver/inc
3138
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/peripheral_drivers/inc
3239
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/service/clock_manager/inc
40+
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/service/power_manager/inc
41+
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/service/power_manager/config
3342
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/systemlevel/inc
3443
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/unified_api/inc
3544
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/unified_api/config
45+
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/unified_api/config/sl_i2s_config
3646
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/unified_peripheral_drivers/inc
3747
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/cmsis_driver/config
3848
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/cmsis_driver
@@ -141,7 +151,7 @@ endif() # CONFIG_BT_SILABS_SIWX91X
141151
if(CONFIG_WISECONNECT_NETWORK_STACK)
142152
zephyr_compile_definitions(
143153
SLI_SI91X_ENABLE_OS
144-
SL_SI91X_SI917_RAM_MEM_CONFIG=1
154+
SL_SI91X_SI917_RAM_MEM_CONFIG=2
145155
SL_WIFI_COMPONENT_INCLUDED # Depite de the name, required for everything
146156
)
147157
zephyr_include_directories(
@@ -198,5 +208,49 @@ if(CONFIG_SOC_SILABS_SLEEPTIMER)
198208
)
199209
endif() # CONFIG_SOC_SILABS_SLEEPTIMER
200210

211+
if(CONFIG_SOC_SIWX91X_PM_BACKEND_PMGR)
212+
zephyr_library_sources(
213+
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/core/common/src/rsi_debug.c
214+
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/core/chip/src/rsi_ps_ram_func.c
215+
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/cmsis_driver/USART.c
216+
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/cmsis_driver/UDMA.c
217+
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/cmsis_driver/SAI.c
218+
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/peripheral_drivers/src/sl_si91x_m4_ps.c
219+
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/peripheral_drivers/src/rsi_usart.c
220+
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/peripheral_drivers/src/rsi_udma_wrapper.c
221+
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/peripheral_drivers/src/rsi_udma.c
222+
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/service/power_manager/src/sl_si91x_power_manager.c
223+
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/service/power_manager/src/sli_si91x_power_manager.c
224+
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/service/clock_manager/src/sli_si91x_clock_manager.c
225+
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/systemlevel/src/rsi_temp_sensor.c
226+
${COMMON_DIR}/src/sl_slist.c
227+
)
228+
zephyr_include_directories(
229+
${COMMON_DIR}/inc
230+
)
231+
zephyr_compile_definitions(
232+
SL_CODE_COMPONENT_POWER_MANAGER=power_manager
233+
SL_SI91X_TICKLESS_MODE
234+
SL_SLEEP_TIMER
235+
SL_SI91X_SI917_RAM_MEM_CONFIG=2
236+
SL_CODE_COMPONENT_CORE=core
237+
DEBUG_ENABLE
238+
DEBUG_UART
239+
SLI_WIRELESS_COMPONENT_PRESENT
240+
)
241+
zephyr_code_relocate(FILES
242+
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/core/chip/src/rsi_deepsleep_soc.c
243+
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/service/power_manager/src/sl_si91x_power_manager.c
244+
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/service/power_manager/src/sli_si91x_power_manager.c
245+
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/service/sleeptimer/src/sl_sleeptimer_hal_si91x_sysrtc.c
246+
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/peripheral_drivers/src/rsi_sysrtc.c
247+
${SISDK_DIR}/platform/service/sleeptimer/src/sl_sleeptimer.c
248+
${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/ahb_interface/src/rsi_hal_mcu_m4_ram.c
249+
${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/ahb_interface/src/rsi_hal_mcu_m4_rom.c
250+
${ZEPHYR_BASE}/drivers/gpio/*.c
251+
LOCATION RAM
252+
)
253+
endif() # CONFIG_SOC_SIWX91X_PM_BACKEND_PMGR
254+
201255
zephyr_linker_sources(ROM_SECTIONS linker/code_classification_text.ld)
202256
zephyr_linker_sources(RAMFUNC_SECTION linker/code_classification_ramfunc.ld)

soc/silabs/silabs_siwx91x/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ config SOC_FAMILY_SILABS_SIWX91X
99
select CPU_HAS_ARM_MPU
1010
select HAS_SILABS_WISECONNECT
1111
select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE
12+
select HAS_PM
1213

1314
if SOC_FAMILY_SILABS_SIWX91X
1415

@@ -19,6 +20,16 @@ config SOC_SILABS_SLEEPTIMER
1920
help
2021
The Sleeptimer HAL module is used for SIWX91X.
2122

23+
config SOC_SIWX91X_PM_BACKEND_PMGR
24+
bool
25+
select WISECONNECT_NETWORK_STACK
26+
select SILABS_SLEEPTIMER_TIMER
27+
select SRAM_VECTOR_TABLE
28+
select CODE_DATA_RELOCATION_SRAM
29+
default y if PM
30+
help
31+
Implement PM using sl_power_manager service from Gecko SDK
32+
2233
config SIWX91X_NWP_INIT_PRIORITY
2334
int "SiWx91x Network Processor init priority"
2435
default 39

soc/silabs/silabs_siwx91x/Kconfig.defconfig

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@
33

44
if SOC_FAMILY_SILABS_SIWX91X
55

6-
configdefault SILABS_SLEEPTIMER_TIMER
7-
default y if PM
8-
96
configdefault CORTEX_M_SYSTICK
107
default n if SILABS_SLEEPTIMER_TIMER
118

soc/silabs/silabs_siwx91x/siwg917/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33

44
zephyr_sources_ifdef(CONFIG_SOC_SERIES_SIWG917 soc.c)
55
zephyr_sources_ifdef(CONFIG_WISECONNECT_NETWORK_STACK nwp.c)
6+
zephyr_sources_ifdef(CONFIG_SOC_SIWX91X_PM_BACKEND_PMGR soc_siwx91x_power_pmgr.c)
67

78
set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "")

soc/silabs/silabs_siwx91x/siwg917/nwp.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#ifdef CONFIG_BT_SILABS_SIWX91X
2020
#include "rsi_ble_common_config.h"
2121
#endif
22+
#include "sl_si91x_power_manager.h"
2223

2324
#define AP_MAX_NUM_STA 4
2425

@@ -243,6 +244,8 @@ static int siwg917_nwp_init(void)
243244
{
244245
sl_wifi_device_configuration_t network_config;
245246
sl_status_t status;
247+
__maybe_unused sl_wifi_performance_profile_t performance_profile = {
248+
.profile = DEEP_SLEEP_WITH_RAM_RETENTION};
246249

247250
siwx91x_get_nwp_config(&network_config, WIFI_STA_MODE, false, 0);
248251
/* TODO: If sl_net_*_profile() functions will be needed for WiFi then call
@@ -253,6 +256,14 @@ static int siwg917_nwp_init(void)
253256
return -EINVAL;
254257
}
255258

259+
if (IS_ENABLED(CONFIG_SOC_SIWX91X_PM_BACKEND_PMGR)) {
260+
status = sl_wifi_set_performance_profile(&performance_profile);
261+
if (status != SL_STATUS_OK) {
262+
return -EINVAL;
263+
}
264+
/* Remove the previously added PS4 power state requirement */
265+
sl_si91x_power_manager_remove_ps_requirement(SL_SI91X_POWER_MANAGER_PS4);
266+
}
256267
return 0;
257268
}
258269
#if defined(CONFIG_MBEDTLS_INIT)

soc/silabs/silabs_siwx91x/siwg917/soc.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,28 @@
1010
#include <zephyr/sw_isr_table.h>
1111

1212
#include "em_device.h"
13+
#ifdef CONFIG_WISECONNECT_NETWORK_STACK
14+
#include "sli_siwx917_soc.h"
15+
#endif
16+
#include "sl_si91x_power_manager.h"
1317

1418
void soc_early_init_hook(void)
1519
{
20+
__maybe_unused sl_power_peripheral_t peripheral_config = {};
21+
__maybe_unused sl_power_ram_retention_config_t ram_configuration = {
22+
.configure_ram_banks = false,
23+
.m4ss_ram_size_kb = (DT_REG_SIZE(DT_NODELABEL(sram0)) / 1024),
24+
.ulpss_ram_size_kb = 4,
25+
};
1626
SystemInit();
27+
#if IS_ENABLED(CONFIG_SOC_SIWX91X_PM_BACKEND_PMGR)
28+
sli_si91x_platform_init();
29+
sl_si91x_power_manager_init();
30+
sl_si91x_power_manager_remove_peripheral_requirement(&peripheral_config);
31+
sl_si91x_power_manager_configure_ram_retention(&ram_configuration);
32+
sl_si91x_power_manager_add_ps_requirement(SL_SI91X_POWER_MANAGER_PS4);
33+
sl_si91x_power_manager_set_clock_scaling(SL_SI91X_POWER_MANAGER_PERFORMANCE);
34+
#endif
1735
}
1836

1937
/* SiWx917's bootloader requires IRQn 32 to hold payload's entry point address. */
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright (c) 2024-2025 Silicon Laboratories Inc.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/kernel.h>
8+
#include <zephyr/logging/log.h>
9+
#include <zephyr/pm/pm.h>
10+
#include "sl_si91x_power_manager.h"
11+
#include "sli_si91x_clock_manager.h"
12+
#include "sl_rsi_utility.h"
13+
#include "sl_si91x_m4_ps.h"
14+
15+
LOG_MODULE_REGISTER(siwx91x_pm);
16+
17+
extern uint32_t frontend_switch_control;
18+
19+
/*
20+
* Power state map:
21+
* PM_STATE_RUNTIME_IDLE: SL_SI91X_POWER_MANAGER_STANDBY (PS4)
22+
* PM_STATE_SUSPEND_TO_IDLE: SL_SI91X_POWER_MANAGER_SLEEP (PS4 Sleep)
23+
*/
24+
void pm_state_set(enum pm_state state, uint8_t substate_id)
25+
{
26+
ARG_UNUSED(substate_id);
27+
28+
/* Set PRIMASK */
29+
__disable_irq();
30+
/* Set BASEPRI to 0. */
31+
irq_unlock(0);
32+
33+
if (!sl_si91x_power_manager_is_ok_to_sleep()) {
34+
/* Device is not ready to sleep; perform necessary actions if required. */
35+
goto out;
36+
}
37+
38+
if (state == PM_STATE_RUNTIME_IDLE) {
39+
sl_si91x_power_manager_standby();
40+
} else {
41+
if (sli_si91x_config_clocks_to_mhz_rc() != 0) {
42+
LOG_ERR("Failed to configure clocks for sleep mode");
43+
goto out;
44+
}
45+
if (IS_ENABLED(CONFIG_WISECONNECT_NETWORK_STACK)) {
46+
if (!(M4_ULP_SLP_STATUS_REG & ULP_MODE_SWITCHED_NPSS)) {
47+
if (!sl_si91x_is_device_initialized()) {
48+
LOG_ERR("Device is not initialized");
49+
goto out;
50+
}
51+
sli_si91x_xtal_turn_off_request_from_m4_to_TA();
52+
}
53+
}
54+
sl_si91x_power_manager_sleep();
55+
}
56+
57+
if (!(M4_ULP_SLP_STATUS_REG & ULP_MODE_SWITCHED_NPSS)) {
58+
if (frontend_switch_control != 0) {
59+
sli_si91x_configure_wireless_frontend_controls(frontend_switch_control);
60+
}
61+
62+
sl_si91x_host_clear_sleep_indicator();
63+
sli_si91x_m4_ta_wakeup_configurations();
64+
}
65+
out:
66+
/* Clear PRIMASK */
67+
__enable_irq();
68+
}
69+
70+
void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id)
71+
{
72+
ARG_UNUSED(state);
73+
ARG_UNUSED(substate_id);
74+
}

0 commit comments

Comments
 (0)