Skip to content

Commit

Permalink
plat-stm32mp2: add pm support on stm32mp25
Browse files Browse the repository at this point in the history
Add support of low power mode on stm32mp25 and perform the needed OP-TEE
bookkeeping before PSCI executes a power management sequence, with the 3
hooks called by TF-A SPD :
- thread_system_off_handler()
- thread_cpu_resume_handler()
- thread_cpu_suspend_handler()

On PSCI system off request, the STPMIC25 driver need to configure the
regulators properly to handle the always on domain with the board
configuration (PMIC switch OFF, with coin cell, or standby DDR off).

For PSCI suspend requests, the STM32MP25 family supports 5 power levels
in the PSCI topology to handle the regulators configuration done in STPMIC2
for low poser modes, in particular to differentiate the tension for LP and
the LPLV modes:

power level             (System mode for a0= Max power level powered down)
--------------------------------------------------------------------------
0: CPU1 core#0 or core#1   (Stop1 or LP-Stop1)
1: D1 domain               (LPLV-Stop1)
2: LPLV D1                 (Stop2 or LP-Stop2)
3: D2                      (LPLV-Stop2)
4: LPLV D2                 (Standby)
5: MAX                     (PowerOff: Standby or VBat)

The hook calls pm_change_state with generic HINT for inform STM32MP25
drivers to operation to performed on suspend/resume:
- PM_HINT_CLOCK_STATE
  the IP clock will be deactivated, the pending operation should stop,
  cleanup operation can be done on HW to prepare the clock freeze
  (optional support by driver)
- PM_HINT_CONTEXT_STATE
  called for System level standby when the IP configuration is lost.
  The state of each device must be saved in RAM which is preserved
  (DDR in self-refresh, mandatory)

Signed-off-by: Patrick Delaunay <[email protected]>
  • Loading branch information
etienne-lms authored and patrickdelaunay committed Feb 22, 2024
1 parent 5dbb99a commit ec5f720
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 0 deletions.
98 changes: 98 additions & 0 deletions core/arch/arm/plat-stm32mp2/stm32mp_pm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// SPDX-License-Identifier: BSD-2-Clause
/*
* Copyright (c) 2023, STMicroelectronics
*/

#include <kernel/misc.h>
#include <kernel/pm.h>
#include <kernel/thread.h>
#include <sm/psci.h>
#include <stm32mp_pm.h>

/**
* @brief Handler for system off
*
* @param[in] a0 Unused
* @param[in] a1 Unused
*
* @retval 0 if OK, other value else and TF-A will panic
*/
unsigned long thread_system_off_handler(unsigned long a0 __unused,
unsigned long a1 __unused)
{
/*
* configure targeted mode in PMIC for system OFF,
* no need to save context
*/
uint32_t pm_hint = PM_HINT_CLOCK_STATE |
((PM_MAX_LEVEL << PM_HINT_PLATFORM_STATE_SHIFT) &
PM_HINT_PLATFORM_STATE_MASK);

return pm_change_state(PM_OP_SUSPEND, pm_hint);
}

static uint32_t get_pm_hint(unsigned long a0)
{
uint32_t pm_hint = 0U;

/* a0 is the highest power level which was powered down. */
if (a0 < PM_D2_LPLV_LEVEL)
pm_hint = PM_HINT_CLOCK_STATE;
else
pm_hint = PM_HINT_CONTEXT_STATE;

pm_hint |= ((a0 << PM_HINT_PLATFORM_STATE_SHIFT) &
PM_HINT_PLATFORM_STATE_MASK);

return pm_hint;
}

/**
* @brief Handler for cpu resume
*
* @param[in] a0 Max power level powered down
* @param[in] a1 Unused
*
* @retval 0 if OK, other value else and TF-A will panic
*/
unsigned long thread_cpu_resume_handler(unsigned long a0,
unsigned long a1 __unused)
{
TEE_Result retstatus = TEE_SUCCESS;

retstatus = pm_change_state(PM_OP_RESUME, get_pm_hint(a0));

/*
* Returned value to the TF-A.
* If it is not 0, the system will panic
*/
if (retstatus == TEE_SUCCESS)
return 0;
else
return 1;
}

/**
* @brief Handler for cpu suspend
*
* @param[in] a0 Max power level to power down
* @param[in] a1 Unused
*
* @retval 0 if OK, other value else and TF-A will panic
*/
unsigned long thread_cpu_suspend_handler(unsigned long a0,
unsigned long a1 __unused)
{
TEE_Result retstatus = TEE_SUCCESS;

retstatus = pm_change_state(PM_OP_SUSPEND, get_pm_hint(a0));

/*
* Returned value to the TF-A.
* If it is not 0, the system will panic
*/
if (retstatus == TEE_SUCCESS)
return 0;
else
return 1;
}
35 changes: 35 additions & 0 deletions core/arch/arm/plat-stm32mp2/stm32mp_pm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (c) 2023, STMicroelectronics
*/

#ifndef __STM32MP_PM_H__
#define __STM32MP_PM_H__

/*
* The PSCI topology is defined in TF-A, with 5 power levels supported in
* the first parameter a0="Max power level powered down" of TF-A SPD hooks
*
* power level (associated low power mode for a0)
* 0: CPU1 core#0 or core#1 (Stop1 or LP-Stop1)
* 1: D1 domain (LPLV-Stop1)
* 2: LPLV D1 (Stop2 or LP-Stop2)
* 3: D2 (LPLV-Stop1)
* 4: LPLV D2 (Standby)
* 5: MAX (PowerOff)
*
* these power level are only managed in power driver (PMIC), for pm function
* use the 2 associated parameters:
* - PM_HINT_CONTEXT_STATE : advertise driver to save all their context in DDR
* (self refresh) for standby mode
* - PM_HINT_CLOCK_STATE : advertise driver to interrupt operation when clock
* are stalled for the other low power modes
*/
#define PM_CORE_LEVEL 0
#define PM_D1_LEVEL 1
#define PM_D1_LPLV_LEVEL 2
#define PM_D2_LEVEL 3
#define PM_D2_LPLV_LEVEL 4
#define PM_MAX_LEVEL 5

#endif /*__STM32MP_PM_H__*/
1 change: 1 addition & 0 deletions core/arch/arm/plat-stm32mp2/sub.mk
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
global-incdirs-y += .

srcs-y += main.c
srcs-y += stm32mp_pm.c

0 comments on commit ec5f720

Please sign in to comment.