drivers: entropy: smartbond: Optimize driver PM

This commit should optimize the way the device is allowed
to enter the suspended state. Instead of returning a PM
error code to abort the PM process, the standby power state
is constrained as long as the device is not allowed to enter
suspension. With that approach, acquiring PD_SYS is not needed
when in PM device runtime mode.

Signed-off-by: Ioannis Karachalios <ioannis.karachalios.px@renesas.com>
This commit is contained in:
Ioannis Karachalios 2024-05-21 19:31:24 +03:00 committed by Anas Nashif
parent 71a5f1b9fd
commit 62f8f160ad

View file

@ -12,6 +12,7 @@
#include <DA1469xAB.h>
#include <zephyr/pm/device.h>
#include <zephyr/pm/device_runtime.h>
#include <zephyr/pm/policy.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(smartbond_entropy, CONFIG_ENTROPY_LOG_LEVEL);
@ -46,6 +47,10 @@ struct entropy_smartbond_dev_data {
RNG_POOL_DEFINE(isr, CONFIG_ENTROPY_SMARTBOND_ISR_POOL_SIZE);
RNG_POOL_DEFINE(thr, CONFIG_ENTROPY_SMARTBOND_THR_POOL_SIZE);
#if defined(CONFIG_PM_DEVICE) || defined(CONFIG_PM_DEVICE_RUNTIME)
ATOMIC_DEFINE(pm_policy_state_flag, 1);
#endif
};
static struct entropy_smartbond_dev_data entropy_smartbond_data;
@ -57,6 +62,33 @@ static struct entropy_smartbond_dev_data entropy_smartbond_data;
#define FIFO_COUNT_MASK \
(TRNG_TRNG_FIFOLVL_REG_TRNG_FIFOFULL_Msk | TRNG_TRNG_FIFOLVL_REG_TRNG_FIFOLVL_Msk)
static inline void entropy_smartbond_pm_policy_state_lock_get(const struct device *dev)
{
#if defined(CONFIG_PM_DEVICE) || defined(CONFIG_PM_DEVICE_RUNTIME)
struct entropy_smartbond_dev_data *data = dev->data;
if (atomic_test_and_set_bit(data->pm_policy_state_flag, 0) == 0) {
/*
* Prevent the SoC from etering the normal sleep state as PDC does not support
* waking up the application core following TRNG events.
*/
pm_policy_state_lock_get(PM_STATE_STANDBY, PM_ALL_SUBSTATES);
}
#endif
}
static inline void entropy_smartbond_pm_policy_state_lock_put(const struct device *dev)
{
#if defined(CONFIG_PM_DEVICE) || defined(CONFIG_PM_DEVICE_RUNTIME)
struct entropy_smartbond_dev_data *data = dev->data;
if (atomic_test_and_clear_bit(data->pm_policy_state_flag, 0) == 1) {
/* Allow the SoC to enter the nornmal sleep state once TRNG is inactive */
pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES);
}
#endif
}
static void trng_enable(bool enable)
{
unsigned int key;
@ -65,9 +97,17 @@ static void trng_enable(bool enable)
if (enable) {
CRG_TOP->CLK_AMBA_REG |= CRG_TOP_CLK_AMBA_REG_TRNG_CLK_ENABLE_Msk;
TRNG->TRNG_CTRL_REG = TRNG_TRNG_CTRL_REG_TRNG_ENABLE_Msk;
/*
* Sleep is not allowed as long as the ISR and thread SW FIFOs
* are being filled with random numbers.
*/
entropy_smartbond_pm_policy_state_lock_get(DEVICE_DT_INST_GET(0));
} else {
CRG_TOP->CLK_AMBA_REG &= ~CRG_TOP_CLK_AMBA_REG_TRNG_CLK_ENABLE_Msk;
TRNG->TRNG_CTRL_REG = 0;
entropy_smartbond_pm_policy_state_lock_put(DEVICE_DT_INST_GET(0));
}
irq_unlock(key);
}
@ -340,25 +380,12 @@ static int entropy_smartbond_get_entropy_isr(const struct device *dev, uint8_t *
}
#if defined(CONFIG_PM_DEVICE) || defined(CONFIG_PM_DEVICE_RUNTIME)
/*
* TRNG is powered by PD_SYS which is the same power domain used to power the SoC.
* Entering the sleep state should not be allowed for as long as the ISR and thread
* SW FIFOs are being filled with random numbers.
*/
static inline bool entropy_is_sleep_allowed(void)
{
return !(TRNG->TRNG_CTRL_REG & TRNG_TRNG_CTRL_REG_TRNG_ENABLE_Msk);
}
static int entropy_smartbond_pm_action(const struct device *dev, enum pm_device_action action)
{
/* Initialize with an error code that should abort sleeping */
int ret = -EBUSY;
int ret = 0;
switch (action) {
case PM_DEVICE_ACTION_RESUME:
__ASSERT_NO_MSG(entropy_is_sleep_allowed());
/*
* No need to turn on TRNG. It should be done when we the space in the FIFOs
* are below the defined ISR and thread FIFO's thresholds.
@ -367,14 +394,9 @@ static int entropy_smartbond_pm_action(const struct device *dev, enum pm_device_
* \sa CONFIG_ENTROPY_SMARTBOND_ISR_THRESHOLD
*
*/
ret = 0;
break;
case PM_DEVICE_ACTION_SUSPEND:
/* Sleep is only allowed when there is no TRNG activity */
if (entropy_is_sleep_allowed()) {
/* At this point TRNG should be disabled; no need to turn it off. */
ret = 0;
}
/* At this point TRNG should be disabled; no need to turn it off. */
break;
default:
ret = -ENOTSUP;