Browse Source

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 <fiaz.mohamed@silabs.com>
pull/91543/head
S Mohamed Fiaz 2 months ago committed by Dan Kalowsky
parent
commit
132247e2cd
  1. 14
      dts/arm/silabs/siwg917.dtsi
  2. 58
      modules/hal_silabs/wiseconnect/CMakeLists.txt
  3. 11
      soc/silabs/silabs_siwx91x/Kconfig
  4. 3
      soc/silabs/silabs_siwx91x/Kconfig.defconfig
  5. 1
      soc/silabs/silabs_siwx91x/siwg917/CMakeLists.txt
  6. 11
      soc/silabs/silabs_siwx91x/siwg917/nwp.c
  7. 18
      soc/silabs/silabs_siwx91x/siwg917/soc.c
  8. 74
      soc/silabs/silabs_siwx91x/siwg917/soc_siwx91x_power_pmgr.c

14
dts/arm/silabs/siwg917.dtsi

@ -24,6 +24,20 @@ @@ -24,6 +24,20 @@
cpu0: cpu@0 {
compatible = "arm,cortex-m4f";
reg = <0>;
cpu-power-states = <&pstate_ps4_standby &pstate_ps4_sleep>;
};
power-states {
pstate_ps4_standby: ps4_standby {
compatible = "zephyr,power-state";
power-state-name = "runtime-idle";
};
pstate_ps4_sleep: ps4_sleep {
compatible = "zephyr,power-state";
power-state-name = "suspend-to-idle";
min-residency-us = <100000>;
exit-latency-us = <3000>;
};
};
};

58
modules/hal_silabs/wiseconnect/CMakeLists.txt

@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
set(SISDK_DIR ${ZEPHYR_HAL_SILABS_MODULE_DIR}/simplicity_sdk)
set(WISECONNECT_DIR ${ZEPHYR_HAL_SILABS_MODULE_DIR}/wiseconnect)
set(COMMON_DIR ${ZEPHYR_HAL_SILABS_MODULE_DIR}/simplicity_sdk/platform/common)
# Keep these values sync with
# components/device/silabs/si91x/mcu/core/chip/component/siwg917*.slcc
@ -23,16 +24,25 @@ zephyr_include_directories( @@ -23,16 +24,25 @@ zephyr_include_directories(
${SISDK_DIR}/platform/common/inc
${SISDK_DIR}/platform/common/config
${SISDK_DIR}/platform/service/mem_pool/inc
${WISECONNECT_DIR}/components/board/silabs/inc
# Wiseconnect do not provide generic RTE_Device_917.h. However, all the boards
# share more-or-less the same definitions. So we could take any of them.
# In addtion, this file is only required for the compilation, but none the
# symbols are normally used by Zephyr (it is required to compile CMSIS API
# which is not not used).
${WISECONNECT_DIR}/components/board/silabs/config/brd4342a
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/core/config
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/core/chip/inc
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/core/chip/config
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/core/common/inc
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/rom_driver/inc
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/peripheral_drivers/inc
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/service/clock_manager/inc
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/service/power_manager/inc
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/service/power_manager/config
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/systemlevel/inc
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/unified_api/inc
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/unified_api/config
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/unified_api/config/sl_i2s_config
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/unified_peripheral_drivers/inc
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/cmsis_driver/config
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/cmsis_driver
@ -141,7 +151,7 @@ endif() # CONFIG_BT_SILABS_SIWX91X @@ -141,7 +151,7 @@ endif() # CONFIG_BT_SILABS_SIWX91X
if(CONFIG_WISECONNECT_NETWORK_STACK)
zephyr_compile_definitions(
SLI_SI91X_ENABLE_OS
SL_SI91X_SI917_RAM_MEM_CONFIG=1
SL_SI91X_SI917_RAM_MEM_CONFIG=2
SL_WIFI_COMPONENT_INCLUDED # Depite de the name, required for everything
)
zephyr_include_directories(
@ -198,5 +208,49 @@ if(CONFIG_SOC_SILABS_SLEEPTIMER) @@ -198,5 +208,49 @@ if(CONFIG_SOC_SILABS_SLEEPTIMER)
)
endif() # CONFIG_SOC_SILABS_SLEEPTIMER
if(CONFIG_SOC_SIWX91X_PM_BACKEND_PMGR)
zephyr_library_sources(
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/core/common/src/rsi_debug.c
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/core/chip/src/rsi_ps_ram_func.c
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/cmsis_driver/USART.c
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/cmsis_driver/UDMA.c
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/cmsis_driver/SAI.c
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/peripheral_drivers/src/sl_si91x_m4_ps.c
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/peripheral_drivers/src/rsi_usart.c
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/peripheral_drivers/src/rsi_udma_wrapper.c
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/peripheral_drivers/src/rsi_udma.c
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/service/power_manager/src/sl_si91x_power_manager.c
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/service/power_manager/src/sli_si91x_power_manager.c
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/service/clock_manager/src/sli_si91x_clock_manager.c
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/systemlevel/src/rsi_temp_sensor.c
${COMMON_DIR}/src/sl_slist.c
)
zephyr_include_directories(
${COMMON_DIR}/inc
)
zephyr_compile_definitions(
SL_CODE_COMPONENT_POWER_MANAGER=power_manager
SL_SI91X_TICKLESS_MODE
SL_SLEEP_TIMER
SL_SI91X_SI917_RAM_MEM_CONFIG=2
SL_CODE_COMPONENT_CORE=core
DEBUG_ENABLE
DEBUG_UART
SLI_WIRELESS_COMPONENT_PRESENT
)
zephyr_code_relocate(FILES
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/core/chip/src/rsi_deepsleep_soc.c
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/service/power_manager/src/sl_si91x_power_manager.c
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/service/power_manager/src/sli_si91x_power_manager.c
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/service/sleeptimer/src/sl_sleeptimer_hal_si91x_sysrtc.c
${WISECONNECT_DIR}/components/device/silabs/si91x/mcu/drivers/peripheral_drivers/src/rsi_sysrtc.c
${SISDK_DIR}/platform/service/sleeptimer/src/sl_sleeptimer.c
${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/ahb_interface/src/rsi_hal_mcu_m4_ram.c
${WISECONNECT_DIR}/components/device/silabs/si91x/wireless/ahb_interface/src/rsi_hal_mcu_m4_rom.c
${ZEPHYR_BASE}/drivers/gpio/*.c
LOCATION RAM
)
endif() # CONFIG_SOC_SIWX91X_PM_BACKEND_PMGR
zephyr_linker_sources(ROM_SECTIONS linker/code_classification_text.ld)
zephyr_linker_sources(RAMFUNC_SECTION linker/code_classification_ramfunc.ld)

11
soc/silabs/silabs_siwx91x/Kconfig

@ -9,6 +9,7 @@ config SOC_FAMILY_SILABS_SIWX91X @@ -9,6 +9,7 @@ config SOC_FAMILY_SILABS_SIWX91X
select CPU_HAS_ARM_MPU
select HAS_SILABS_WISECONNECT
select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE
select HAS_PM
if SOC_FAMILY_SILABS_SIWX91X
@ -19,6 +20,16 @@ config SOC_SILABS_SLEEPTIMER @@ -19,6 +20,16 @@ config SOC_SILABS_SLEEPTIMER
help
The Sleeptimer HAL module is used for SIWX91X.
config SOC_SIWX91X_PM_BACKEND_PMGR
bool
select WISECONNECT_NETWORK_STACK
select SILABS_SLEEPTIMER_TIMER
select SRAM_VECTOR_TABLE
select CODE_DATA_RELOCATION_SRAM
default y if PM
help
Implement PM using sl_power_manager service from Gecko SDK
config SIWX91X_NWP_INIT_PRIORITY
int "SiWx91x Network Processor init priority"
default 39

3
soc/silabs/silabs_siwx91x/Kconfig.defconfig

@ -3,9 +3,6 @@ @@ -3,9 +3,6 @@
if SOC_FAMILY_SILABS_SIWX91X
configdefault SILABS_SLEEPTIMER_TIMER
default y if PM
configdefault CORTEX_M_SYSTICK
default n if SILABS_SLEEPTIMER_TIMER

1
soc/silabs/silabs_siwx91x/siwg917/CMakeLists.txt

@ -3,5 +3,6 @@ @@ -3,5 +3,6 @@
zephyr_sources_ifdef(CONFIG_SOC_SERIES_SIWG917 soc.c)
zephyr_sources_ifdef(CONFIG_WISECONNECT_NETWORK_STACK nwp.c)
zephyr_sources_ifdef(CONFIG_SOC_SIWX91X_PM_BACKEND_PMGR soc_siwx91x_power_pmgr.c)
set(SOC_LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/linker.ld CACHE INTERNAL "")

11
soc/silabs/silabs_siwx91x/siwg917/nwp.c

@ -19,6 +19,7 @@ @@ -19,6 +19,7 @@
#ifdef CONFIG_BT_SILABS_SIWX91X
#include "rsi_ble_common_config.h"
#endif
#include "sl_si91x_power_manager.h"
#define AP_MAX_NUM_STA 4
@ -243,6 +244,8 @@ static int siwg917_nwp_init(void) @@ -243,6 +244,8 @@ static int siwg917_nwp_init(void)
{
sl_wifi_device_configuration_t network_config;
sl_status_t status;
__maybe_unused sl_wifi_performance_profile_t performance_profile = {
.profile = DEEP_SLEEP_WITH_RAM_RETENTION};
siwx91x_get_nwp_config(&network_config, WIFI_STA_MODE, false, 0);
/* TODO: If sl_net_*_profile() functions will be needed for WiFi then call
@ -253,6 +256,14 @@ static int siwg917_nwp_init(void) @@ -253,6 +256,14 @@ static int siwg917_nwp_init(void)
return -EINVAL;
}
if (IS_ENABLED(CONFIG_SOC_SIWX91X_PM_BACKEND_PMGR)) {
status = sl_wifi_set_performance_profile(&performance_profile);
if (status != SL_STATUS_OK) {
return -EINVAL;
}
/* Remove the previously added PS4 power state requirement */
sl_si91x_power_manager_remove_ps_requirement(SL_SI91X_POWER_MANAGER_PS4);
}
return 0;
}
#if defined(CONFIG_MBEDTLS_INIT)

18
soc/silabs/silabs_siwx91x/siwg917/soc.c

@ -10,10 +10,28 @@ @@ -10,10 +10,28 @@
#include <zephyr/sw_isr_table.h>
#include "em_device.h"
#ifdef CONFIG_WISECONNECT_NETWORK_STACK
#include "sli_siwx917_soc.h"
#endif
#include "sl_si91x_power_manager.h"
void soc_early_init_hook(void)
{
__maybe_unused sl_power_peripheral_t peripheral_config = {};
__maybe_unused sl_power_ram_retention_config_t ram_configuration = {
.configure_ram_banks = false,
.m4ss_ram_size_kb = (DT_REG_SIZE(DT_NODELABEL(sram0)) / 1024),
.ulpss_ram_size_kb = 4,
};
SystemInit();
#if IS_ENABLED(CONFIG_SOC_SIWX91X_PM_BACKEND_PMGR)
sli_si91x_platform_init();
sl_si91x_power_manager_init();
sl_si91x_power_manager_remove_peripheral_requirement(&peripheral_config);
sl_si91x_power_manager_configure_ram_retention(&ram_configuration);
sl_si91x_power_manager_add_ps_requirement(SL_SI91X_POWER_MANAGER_PS4);
sl_si91x_power_manager_set_clock_scaling(SL_SI91X_POWER_MANAGER_PERFORMANCE);
#endif
}
/* SiWx917's bootloader requires IRQn 32 to hold payload's entry point address. */

74
soc/silabs/silabs_siwx91x/siwg917/soc_siwx91x_power_pmgr.c

@ -0,0 +1,74 @@ @@ -0,0 +1,74 @@
/*
* Copyright (c) 2024-2025 Silicon Laboratories Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include <zephyr/pm/pm.h>
#include "sl_si91x_power_manager.h"
#include "sli_si91x_clock_manager.h"
#include "sl_rsi_utility.h"
#include "sl_si91x_m4_ps.h"
LOG_MODULE_REGISTER(siwx91x_pm);
extern uint32_t frontend_switch_control;
/*
* Power state map:
* PM_STATE_RUNTIME_IDLE: SL_SI91X_POWER_MANAGER_STANDBY (PS4)
* PM_STATE_SUSPEND_TO_IDLE: SL_SI91X_POWER_MANAGER_SLEEP (PS4 Sleep)
*/
void pm_state_set(enum pm_state state, uint8_t substate_id)
{
ARG_UNUSED(substate_id);
/* Set PRIMASK */
__disable_irq();
/* Set BASEPRI to 0. */
irq_unlock(0);
if (!sl_si91x_power_manager_is_ok_to_sleep()) {
/* Device is not ready to sleep; perform necessary actions if required. */
goto out;
}
if (state == PM_STATE_RUNTIME_IDLE) {
sl_si91x_power_manager_standby();
} else {
if (sli_si91x_config_clocks_to_mhz_rc() != 0) {
LOG_ERR("Failed to configure clocks for sleep mode");
goto out;
}
if (IS_ENABLED(CONFIG_WISECONNECT_NETWORK_STACK)) {
if (!(M4_ULP_SLP_STATUS_REG & ULP_MODE_SWITCHED_NPSS)) {
if (!sl_si91x_is_device_initialized()) {
LOG_ERR("Device is not initialized");
goto out;
}
sli_si91x_xtal_turn_off_request_from_m4_to_TA();
}
}
sl_si91x_power_manager_sleep();
}
if (!(M4_ULP_SLP_STATUS_REG & ULP_MODE_SWITCHED_NPSS)) {
if (frontend_switch_control != 0) {
sli_si91x_configure_wireless_frontend_controls(frontend_switch_control);
}
sl_si91x_host_clear_sleep_indicator();
sli_si91x_m4_ta_wakeup_configurations();
}
out:
/* Clear PRIMASK */
__enable_irq();
}
void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id)
{
ARG_UNUSED(state);
ARG_UNUSED(substate_id);
}
Loading…
Cancel
Save