This is an automated email from the ASF dual-hosted git repository.

simbit18 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 56a4a05b347c104c1a4d1e791c4d5e5e939a0cc2
Author: Eren Terzioglu <[email protected]>
AuthorDate: Wed Apr 1 14:27:51 2026 +0200

    arch/risc-v/espressif: Add DFS feature
    
    Add DFS feature for riscv based Espressif devices
    
    Signed-off-by: Eren Terzioglu <[email protected]>
---
 arch/risc-v/src/common/espressif/CMakeLists.txt  |  2 +-
 arch/risc-v/src/common/espressif/Kconfig         | 92 ++++++++++++++++++++++++
 arch/risc-v/src/common/espressif/Make.defs       |  2 +-
 arch/risc-v/src/common/espressif/esp_gptimer.c   | 63 +++++++++++++++-
 arch/risc-v/src/common/espressif/esp_i2c.c       | 75 +++++++++++++++++--
 arch/risc-v/src/common/espressif/esp_i2c_slave.c | 64 +++++++++++++++++
 arch/risc-v/src/common/espressif/esp_i2s.c       | 62 ++++++++++++++--
 arch/risc-v/src/common/espressif/esp_idle.c      |  6 +-
 arch/risc-v/src/common/espressif/esp_mcpwm.c     | 49 +++++++++++++
 arch/risc-v/src/common/espressif/esp_oneshot.c   | 55 ++++++++++++++
 arch/risc-v/src/common/espressif/esp_pcnt.c      | 41 +++++++++++
 arch/risc-v/src/common/espressif/esp_pm.c        | 11 +--
 arch/risc-v/src/common/espressif/esp_pm.h        |  3 +-
 arch/risc-v/src/common/espressif/esp_sdm.c       | 43 +++++++++++
 arch/risc-v/src/common/espressif/esp_spi.c       | 50 ++++++++++++-
 arch/risc-v/src/common/espressif/esp_spi_slave.c | 36 ++++++++++
 arch/risc-v/src/common/espressif/esp_twai.c      | 51 +++++++++++++
 arch/risc-v/src/esp32p4/hal_esp32p4.cmake        |  3 +
 arch/risc-v/src/esp32p4/hal_esp32p4.mk           |  3 +
 19 files changed, 686 insertions(+), 25 deletions(-)

diff --git a/arch/risc-v/src/common/espressif/CMakeLists.txt 
b/arch/risc-v/src/common/espressif/CMakeLists.txt
index 749c7c4deb6..c9e75969c08 100644
--- a/arch/risc-v/src/common/espressif/CMakeLists.txt
+++ b/arch/risc-v/src/common/espressif/CMakeLists.txt
@@ -209,7 +209,7 @@ if(DEFINED ENV{ESP_HAL_3RDPARTY_VERSION})
       CACHE STRING "ESP HAL 3rdparty version")
 else()
   set(ESP_HAL_3RDPARTY_VERSION
-      b7e51db97a3f9dc82d3b3524d2bad298ba1e2647
+      2209449c9864c6d83a0ee2295f5b5299a2c6fb39
       CACHE STRING "ESP HAL 3rdparty version")
 endif()
 
diff --git a/arch/risc-v/src/common/espressif/Kconfig 
b/arch/risc-v/src/common/espressif/Kconfig
index c4798ebf6b4..4b058db0ff0 100644
--- a/arch/risc-v/src/common/espressif/Kconfig
+++ b/arch/risc-v/src/common/espressif/Kconfig
@@ -126,6 +126,11 @@ config ESPRESSIF_CPU_FREQ_MHZ
        default 360 if ESPRESSIF_CPU_FREQ_360
        default 400 if ESPRESSIF_CPU_FREQ_400
 
+config ESPRESSIF_DFS
+       bool "Enable DFS (Dynamic Frequency Scaling)"
+       select PM
+       default n
+
 config ESPRESSIF_REGION_PROTECTION
        bool "Enable region protection"
        default y
@@ -162,6 +167,93 @@ config ESPRESSIF_SOC_RTC_MEM_SUPPORTED
        bool
        default n
 
+menu "Espressif DFS Options"
+       depends on ESPRESSIF_DFS
+
+choice ESPRESSIF_MIN_CPU_FREQ
+       prompt "Minimum CPU frequency"
+       default ESPRESSIF_MIN_CPU_FREQ_40 if ARCH_CHIP_ESP32P4 && 
ESPRESSIF_IDF_ENV_FPGA
+       default ESPRESSIF_MIN_CPU_FREQ_96 if ARCH_CHIP_ESP32H2
+       default ESPRESSIF_MIN_CPU_FREQ_160 if ARCH_CHIP_ESP32C3 || 
ARCH_CHIP_ESP32C6
+       default ESPRESSIF_MIN_CPU_FREQ_360 if ARCH_CHIP_ESP32P4 && 
ESP32P4_SELECTS_REV_LESS_V3
+       default ESPRESSIF_MIN_CPU_FREQ_400 if ARCH_CHIP_ESP32P4 && 
!ESP32P4_SELECTS_REV_LESS_V3
+       ---help---
+               Minimum CPU frequency to be scale.
+
+config ESPRESSIF_MIN_CPU_FREQ_40
+       bool "40 MHz"
+       depends on ARCH_CHIP_ESP32C3 || ARCH_CHIP_ESP32C6 || ARCH_CHIP_ESP32P4
+       ---help---
+               Set the minimum CPU frequency to 40 MHz.
+
+config ESPRESSIF_MIN_CPU_FREQ_48
+       bool "48 MHz"
+       depends on ARCH_CHIP_ESP32H2
+       ---help---
+               Set the minimum CPU frequency to 48 MHz.
+
+config ESPRESSIF_MIN_CPU_FREQ_64
+       bool "64 MHz"
+       depends on ARCH_CHIP_ESP32H2
+       ---help---
+               Set the minimum CPU frequency to 64 MHz.
+
+config ESPRESSIF_MIN_CPU_FREQ_80
+       bool "80 MHz"
+       depends on ARCH_CHIP_ESP32C3 || ARCH_CHIP_ESP32C6
+       ---help---
+               Set the minimum CPU frequency to 80 MHz.
+
+config ESPRESSIF_MIN_CPU_FREQ_96
+       bool "96 MHz"
+       depends on ARCH_CHIP_ESP32H2
+       ---help---
+               Set the minimum CPU frequency to 96 MHz.
+
+config ESPRESSIF_MIN_CPU_FREQ_160
+       bool "160 MHz"
+       depends on ARCH_CHIP_ESP32C3 || ARCH_CHIP_ESP32C6
+       ---help---
+               Set the minimum CPU frequency to 160 MHz.
+
+config ESPRESSIF_MIN_CPU_FREQ_360
+       bool "360 MHz"
+       depends on ARCH_CHIP_ESP32P4 && ESP32P4_SELECTS_REV_LESS_V3
+       ---help---
+               Set the minimum CPU frequency to 360 MHz.
+
+config ESPRESSIF_MIN_CPU_FREQ_400
+       bool "400 MHz"
+       depends on ARCH_CHIP_ESP32P4 && !ESP32P4_SELECTS_REV_LESS_V3
+       ---help---
+               Set the minimum CPU frequency to 400 MHz.
+
+endchoice # ESPRESSIF_MIN_CPU_FREQ
+
+config ESPRESSIF_MAX_CPU_FREQ_MHZ
+       int
+       default 40 if ESPRESSIF_MAX_CPU_FREQ_40
+       default 48 if ESPRESSIF_MAX_CPU_FREQ_48
+       default 64 if ESPRESSIF_MAX_CPU_FREQ_64
+       default 80 if ESPRESSIF_MAX_CPU_FREQ_80
+       default 96 if ESPRESSIF_MAX_CPU_FREQ_96
+       default 160 if ESPRESSIF_MAX_CPU_FREQ_160
+       default 360 if ESPRESSIF_MAX_CPU_FREQ_360
+       default 400 if ESPRESSIF_MAX_CPU_FREQ_400
+
+config ESPRESSIF_MIN_CPU_FREQ_MHZ
+       int
+       default 40 if ESPRESSIF_MIN_CPU_FREQ_40
+       default 48 if ESPRESSIF_MIN_CPU_FREQ_48
+       default 64 if ESPRESSIF_MIN_CPU_FREQ_64
+       default 80 if ESPRESSIF_MIN_CPU_FREQ_80
+       default 96 if ESPRESSIF_MIN_CPU_FREQ_96
+       default 160 if ESPRESSIF_MIN_CPU_FREQ_160
+       default 360 if ESPRESSIF_MIN_CPU_FREQ_360
+       default 400 if ESPRESSIF_MIN_CPU_FREQ_400
+
+endmenu #
+
 menu "Espressif Log Level"
        visible if DEBUG_FEATURES
 
diff --git a/arch/risc-v/src/common/espressif/Make.defs 
b/arch/risc-v/src/common/espressif/Make.defs
index 10c8a2aca1a..e91515f85f2 100644
--- a/arch/risc-v/src/common/espressif/Make.defs
+++ b/arch/risc-v/src/common/espressif/Make.defs
@@ -217,7 +217,7 @@ endif
 
 ESP_HAL_3RDPARTY_REPO   = esp-hal-3rdparty
 ifndef ESP_HAL_3RDPARTY_VERSION
-       ESP_HAL_3RDPARTY_VERSION = b7e51db97a3f9dc82d3b3524d2bad298ba1e2647
+       ESP_HAL_3RDPARTY_VERSION = 2209449c9864c6d83a0ee2295f5b5299a2c6fb39
 endif
 
 ifndef ESP_HAL_3RDPARTY_URL
diff --git a/arch/risc-v/src/common/espressif/esp_gptimer.c 
b/arch/risc-v/src/common/espressif/esp_gptimer.c
index a7d000f3c82..3fb1c4faa8d 100644
--- a/arch/risc-v/src/common/espressif/esp_gptimer.c
+++ b/arch/risc-v/src/common/espressif/esp_gptimer.c
@@ -46,6 +46,9 @@
 #include "periph_ctrl.h"
 #include "soc/clk_tree_defs.h"
 #include "esp_private/esp_clk_tree_common.h"
+#ifdef CONFIG_PM
+#  include "include/esp_pm.h"
+#endif
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -77,6 +80,9 @@ struct esp_timer_lowerhalf_s
   bool                      started;   /* True: Timer has been started */
   void                     *upper;     /* Pointer to timer_upperhalf_s */
   int                       group_id;  /* Timer group number */
+#ifdef CONFIG_PM
+  esp_pm_lock_handle_t      pm_lock;   /* Power management lock */
+#endif
 };
 
 /****************************************************************************
@@ -122,7 +128,10 @@ static const struct timer_ops_s g_timer_ops =
 static struct esp_timer_lowerhalf_s g_timer0_lowerhalf =
 {
   .ops = &g_timer_ops,
-  .group_id = 0
+  .group_id = 0,
+#ifdef CONFIG_PM
+  .pm_lock = NULL,
+#endif
 };
 
 /* TIMER1 lower-half */
@@ -130,7 +139,10 @@ static struct esp_timer_lowerhalf_s g_timer0_lowerhalf =
 static struct esp_timer_lowerhalf_s g_timer1_lowerhalf =
 {
   .ops = &g_timer_ops,
-  .group_id = 1
+  .group_id = 1,
+#ifdef CONFIG_PM
+  .pm_lock = NULL,
+#endif
 };
 
 /****************************************************************************
@@ -171,6 +183,13 @@ static int esp_timer_start(struct timer_lowerhalf_s *lower)
 
   timer_hal_context_t *hal = &(priv->hal);
 
+#ifdef CONFIG_PM
+  if (priv->pm_lock != NULL)
+    {
+      esp_pm_lock_acquire(priv->pm_lock);
+    }
+#endif
+
   /* Make sure the timer is stopped to avoid unpredictable behavior */
 
   timer_ll_enable_intr(hal->dev, TIMER_LL_EVENT_ALARM(hal->timer_id),
@@ -282,6 +301,13 @@ static int esp_timer_stop(struct timer_lowerhalf_s *lower)
                        false);
   timer_ll_enable_counter(hal->dev, hal->timer_id, false);
 
+#ifdef CONFIG_PM
+  if (priv->pm_lock != NULL)
+    {
+      esp_pm_lock_release(priv->pm_lock);
+    }
+#endif
+
   priv->started = false;
   priv->callback = NULL;
 
@@ -542,6 +568,11 @@ int esp_timer_initialize(int group_id)
   char *devpath;
   shared_periph_module_t periph;
   int irq;
+#ifdef CONFIG_PM
+  int ret;
+  bool need_pm_lock = true;
+  esp_pm_lock_type_t pm_lock_type = ESP_PM_NO_LIGHT_SLEEP;
+#endif
 
   switch (group_id)
     {
@@ -590,6 +621,34 @@ int esp_timer_initialize(int group_id)
 
   timer_hal_init(&lower->hal, lower->group_id, lower->hal.timer_id);
 
+#ifdef CONFIG_PM
+#  if TIMER_LL_FUNC_CLOCK_SUPPORT_RC_FAST
+  if (GPTIMER_CLK_SRC_DEFAULT == GPTIMER_CLK_SRC_RC_FAST)
+    {
+      need_pm_lock = false;
+    }
+#  endif
+
+#  if TIMER_LL_FUNC_CLOCK_SUPPORT_APB
+  if (GPTIMER_CLK_SRC_DEFAULT == GPTIMER_CLK_SRC_APB)
+    {
+      pm_lock_type = ESP_PM_APB_FREQ_MAX;
+    }
+#  endif
+
+  if (need_pm_lock && lower->pm_lock == NULL)
+    {
+      ret = esp_pm_lock_create(pm_lock_type, 0,
+                               "TIMER",
+                               &lower->pm_lock);
+      if (ret != OK)
+        {
+          tmrerr("Failed to create GPTIMER PM lock\n");
+          return -ENOMEM;
+        }
+    }
+#endif
+
   /* Register the timer driver as /dev/timerX. If the registration goes
    * right the returned value from timer_register is a pointer to
    * timer_upperhalf_s that can be either used with timer_unregister()
diff --git a/arch/risc-v/src/common/espressif/esp_i2c.c 
b/arch/risc-v/src/common/espressif/esp_i2c.c
index 541a1355dd0..fbc39b3da3f 100644
--- a/arch/risc-v/src/common/espressif/esp_i2c.c
+++ b/arch/risc-v/src/common/espressif/esp_i2c.c
@@ -72,6 +72,9 @@
 #  include "soc/i2c_struct.h"
 #  include "driver/lp_io.h"
 #endif
+#ifdef CONFIG_PM
+#  include "include/esp_pm.h"
+#endif
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -272,6 +275,9 @@ struct esp_i2c_priv_s
 
 #endif
   i2c_hal_context_t *ctx;     /* Common layer struct */
+#ifdef CONFIG_PM
+  esp_pm_lock_handle_t pm_lock; /* Power management lock */
+#endif
 };
 
 /****************************************************************************
@@ -371,7 +377,10 @@ static struct esp_i2c_priv_s esp_i2c0_priv =
   .ready_read = false,
   .clk_src    = I2C_CLK_SRC_DEFAULT,
   .clk_freq   = 0,
-  .ctx = &i2c0_ctx
+  .ctx        = &i2c0_ctx,
+#ifdef CONFIG_PM
+  .pm_lock    = NULL,
+#endif
 };
 #endif
 
@@ -412,7 +421,10 @@ static struct esp_i2c_priv_s esp_i2c1_priv =
   .ready_read = false,
   .clk_src    = I2C_CLK_SRC_DEFAULT,
   .clk_freq   = 0,
-  .ctx        = &i2c1_ctx
+  .ctx        = &i2c1_ctx,
+#ifdef CONFIG_PM
+  .pm_lock    = NULL,
+#endif
 };
 #  else
 #    error "This device contains only a single HP I2C port."
@@ -456,7 +468,10 @@ static struct esp_i2c_priv_s esp_lp_i2c0_priv =
   .ready_read = false,
   .clk_src    = LP_I2C_SCLK_DEFAULT,
   .clk_freq   = 0,
-  .ctx        = &lp_i2c0_ctx
+  .ctx        = &lp_i2c0_ctx,
+#ifdef CONFIG_PM
+  .pm_lock    = NULL,
+#endif
 };
 #  else
 #    error "This device does not contain a LP I2C port."
@@ -1138,6 +1153,10 @@ static int esp_i2c_transfer(struct i2c_master_s *dev,
       return ret;
     }
 
+#ifdef CONFIG_PM
+  esp_pm_lock_acquire(priv->pm_lock);
+#endif
+
   if (priv->i2cstate != I2CSTATE_IDLE)
     {
       esp_i2c_reset_fsmc(priv);
@@ -1239,6 +1258,9 @@ static int esp_i2c_transfer(struct i2c_master_s *dev,
   /* Dump the trace result */
 
   esp_i2c_tracedump(priv);
+#ifdef CONFIG_PM
+  esp_pm_lock_release(priv->pm_lock);
+#endif
   nxmutex_unlock(&priv->lock);
 
   return ret;
@@ -1665,8 +1687,9 @@ static inline void esp_i2c_process(struct esp_i2c_priv_s 
*priv,
 struct i2c_master_s *esp_i2cbus_initialize(int port)
 {
   struct esp_i2c_priv_s *priv;
-#ifndef CONFIG_I2C_POLLED
   int ret;
+#ifdef CONFIG_PM
+  esp_pm_lock_type_t pm_lock_type = ESP_PM_NO_LIGHT_SLEEP;
 #endif
 
   switch (port)
@@ -1702,6 +1725,42 @@ struct i2c_master_s *esp_i2cbus_initialize(int port)
       return (struct i2c_master_s *)priv;
     }
 
+#ifdef CONFIG_PM
+#  if SOC_I2C_SUPPORT_RTC
+  if (I2C_CLK_SRC_DEFAULT == I2C_CLK_SRC_RC_FAST)
+    {
+      pm_lock_type = ESP_PM_NO_LIGHT_SLEEP;
+    }
+#  endif
+
+#  if SOC_I2C_SUPPORT_APB
+  if (I2C_CLK_SRC_DEFAULT == I2C_CLK_SRC_APB)
+    {
+      pm_lock_type = ESP_PM_APB_FREQ_MAX;
+    }
+#  endif
+
+#  ifdef CONFIG_ESPRESSIF_LP_I2C0
+  if (priv->id == ESPRESSIF_LP_I2C0)
+    {
+      pm_lock_type = ESP_PM_NO_LIGHT_SLEEP;
+    }
+#  endif
+
+  ret = esp_pm_lock_create(pm_lock_type,
+                           0,
+                           i2c_periph_signal[priv->id].module_name,
+                           &priv->pm_lock);
+  if (ret != OK)
+    {
+      priv->refs--;
+      nxmutex_unlock(&priv->lock);
+      i2cerr("Failed to create I2C PM lock."
+             "Handler: %p\n", priv);
+      return NULL;
+    }
+#endif
+
 #ifndef CONFIG_I2C_POLLED
   if (priv->cpuint != -ENOMEM)
     {
@@ -1779,6 +1838,14 @@ int esp_i2cbus_uninitialize(struct i2c_master_s *dev)
   priv->cpuint = -ENOMEM;
 #endif
 
+#ifdef CONFIG_PM
+  if (priv->pm_lock != NULL)
+    {
+      esp_pm_lock_delete(priv->pm_lock);
+      priv->pm_lock = NULL;
+    }
+#endif
+
   esp_i2c_deinit(priv);
   nxmutex_unlock(&priv->lock);
 
diff --git a/arch/risc-v/src/common/espressif/esp_i2c_slave.c 
b/arch/risc-v/src/common/espressif/esp_i2c_slave.c
index 8984ade096c..10ca9e06877 100644
--- a/arch/risc-v/src/common/espressif/esp_i2c_slave.c
+++ b/arch/risc-v/src/common/espressif/esp_i2c_slave.c
@@ -65,6 +65,9 @@
 #if defined(CONFIG_ARCH_CHIP_ESP32H2) || defined(CONFIG_ARCH_CHIP_ESP32C6)
 #  include "soc/pcr_reg.h"
 #endif
+#ifdef CONFIG_PM
+#  include "include/esp_pm.h"
+#endif
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -138,6 +141,9 @@ struct esp_i2c_priv_s
   uint8_t tx_buffer[I2C_SLAVE_BUFF_SIZE]; /* I2C Slave TX queue buffer */
   uint32_t rx_length;                     /* Location of next RX value */
   uint8_t rx_buffer[I2C_SLAVE_BUFF_SIZE]; /* I2C Slave RX queue buffer */
+#ifdef CONFIG_PM
+  esp_pm_lock_handle_t pm_lock;           /* Power management lock */
+#endif
 };
 
 /****************************************************************************
@@ -225,6 +231,9 @@ static struct esp_i2c_priv_s esp_i2c0_priv =
   {
     0
   },
+#ifdef CONFIG_PM
+  .pm_lock    = NULL,
+#endif
 };
 #endif
 
@@ -274,6 +283,9 @@ static struct esp_i2c_priv_s esp_i2c1_priv =
   {
     0
   },
+#ifdef CONFIG_PM
+  .pm_lock    = NULL,
+#endif
 };
 #endif /* CONFIG_ESPRESSIF_I2C1 */
 
@@ -627,8 +639,14 @@ static int esp_i2c_slave_irq(int irq, void *context, void 
*arg)
       return OK;
     }
 
+#ifdef CONFIG_PM
+  esp_pm_lock_acquire(priv->pm_lock);
+#endif
   esp_i2c_process(priv , irq_status);
   i2c_ll_clear_intr_mask(priv->ctx->dev, irq_status);
+#ifdef CONFIG_PM
+  esp_pm_lock_release(priv->pm_lock);
+#endif
   return OK;
 }
 #endif
@@ -721,7 +739,13 @@ static int esp_i2c_slave_thread(int argc, char **argv)
   nxsched_usleep(1000);
   while (true)
     {
+#ifdef CONFIG_PM
+      esp_pm_lock_acquire(priv->pm_lock);
+#endif
       esp_i2c_slave_polling_waitdone(priv);
+#ifdef CONFIG_PM
+      esp_pm_lock_release(priv->pm_lock);
+#endif
 
       /* Sleeping thread before checking i2c peripheral */
 
@@ -833,6 +857,9 @@ struct i2c_slave_s *esp_i2cbus_slave_initialize(int port, 
int addr)
 {
   struct esp_i2c_priv_s *priv;
   int ret;
+#ifdef CONFIG_PM
+  esp_pm_lock_type_t pm_lock_type = ESP_PM_NO_LIGHT_SLEEP;
+#endif
 
   switch (port)
     {
@@ -862,6 +889,35 @@ struct i2c_slave_s *esp_i2cbus_slave_initialize(int port, 
int addr)
       return (struct i2c_slave_s *)priv;
     }
 
+#ifdef CONFIG_PM
+#  if SOC_I2C_SUPPORT_RTC
+  if (I2C_CLK_SRC_DEFAULT == I2C_CLK_SRC_RC_FAST)
+    {
+      pm_lock_type = ESP_PM_NO_LIGHT_SLEEP;
+    }
+#  endif
+
+#  if SOC_I2C_SUPPORT_APB
+  if (I2C_CLK_SRC_DEFAULT == I2C_CLK_SRC_APB)
+    {
+      pm_lock_type = ESP_PM_APB_FREQ_MAX;
+    }
+#  endif
+
+  ret = esp_pm_lock_create(pm_lock_type,
+                           0,
+                           i2c_periph_signal[priv->id].module_name,
+                           &priv->pm_lock);
+  if (ret != OK)
+    {
+      priv->refs--;
+      nxmutex_unlock(&priv->lock);
+      i2cerr("Failed to create I2C PM lock."
+             "Handler: %p\n", priv);
+      return NULL;
+    }
+#endif
+
 #ifndef CONFIG_I2C_POLLED
   if (priv->cpuint != -ENOMEM)
     {
@@ -956,6 +1012,14 @@ int esp_i2cbus_slave_uninitialize(struct i2c_slave_s *dev)
       return OK;
     }
 
+#ifdef CONFIG_PM
+  if (priv->pm_lock != NULL)
+    {
+      esp_pm_lock_delete(priv->pm_lock);
+      priv->pm_lock = NULL;
+    }
+#endif
+
 #ifndef CONFIG_I2C_POLLED
   up_disable_irq(ESP_SOURCE2IRQ(i2c_periph_signal[priv->id].irq));
   esp_teardown_irq(i2c_periph_signal[priv->id].irq, priv->cpuint);
diff --git a/arch/risc-v/src/common/espressif/esp_i2s.c 
b/arch/risc-v/src/common/espressif/esp_i2s.c
index 6d3837cde0e..cd60b631e93 100644
--- a/arch/risc-v/src/common/espressif/esp_i2s.c
+++ b/arch/risc-v/src/common/espressif/esp_i2s.c
@@ -64,19 +64,24 @@
 #include "soc/lldesc.h"
 #include "hal/dma_types.h"
 #if SOC_I2S_SUPPORTS_APLL
-#include "hal/clk_tree_ll.h"
-#include "clk_ctrl_os.h"
+#  include "hal/clk_tree_ll.h"
+#  include "clk_ctrl_os.h"
 #endif
 #include "hal/gdma_periph.h"
 #include "hal/gdma_ll.h"
 
 #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
-#include "hal/cache_hal.h"
-#include "hal/cache_ll.h"
+#  include "hal/cache_hal.h"
+#  include "hal/cache_ll.h"
 #endif
 
 #if SOC_GDMA_SUPPORTED
-#include "esp_private/gdma.h"
+#  include "esp_private/gdma.h"
+#endif
+
+#ifdef CONFIG_PM
+#  include "soc/soc_caps.h"
+#  include "include/esp_pm.h"
 #endif
 
 /****************************************************************************
@@ -235,6 +240,9 @@ struct esp_i2s_config_s
 
   i2s_hal_context_t *ctx;           /* Common layer struct */
   i2s_hal_clock_info_t *clk_info;   /* Common layer clock info struct */
+#ifdef CONFIG_PM
+  esp_pm_lock_handle_t pm_lock;     /* Power management lock */
+#endif
 };
 
 struct esp_buffer_s
@@ -470,6 +478,9 @@ static struct esp_i2s_config_s esp_i2s0_config =
   .audio_std_mode   = I2S_TDM_PHILIPS,
   .ctx              = &ctx_i2s0,
   .clk_info         = &clk_info_i2s0,
+#ifdef CONFIG_PM
+  .pm_lock          = NULL,
+#endif
 };
 
 static struct esp_i2s_s esp_i2s0_priv =
@@ -2224,6 +2235,10 @@ static void i2s_tx_channel_start(struct esp_i2s_s *priv)
 {
   if (priv->config->tx_en)
     {
+#ifdef CONFIG_PM
+      esp_pm_lock_acquire(priv->config->pm_lock);
+#endif
+
       /* Reset the TX channel */
 
       i2s_hal_tx_reset(priv->config->ctx);
@@ -2262,6 +2277,10 @@ static void i2s_rx_channel_start(struct esp_i2s_s *priv)
 {
   if (priv->config->rx_en)
     {
+#ifdef CONFIG_PM
+      esp_pm_lock_acquire(priv->config->pm_lock);
+#endif
+
       /* Reset the RX channel */
 
       i2s_hal_rx_reset(priv->config->ctx);
@@ -2317,6 +2336,9 @@ static int i2s_tx_channel_stop(struct esp_i2s_s *priv)
         }
 
       priv->tx_started = false;
+#ifdef CONFIG_PM
+      esp_pm_lock_release(priv->config->pm_lock);
+#endif
 
       i2sinfo("Stopped TX channel of port %ld\n", priv->config->port);
     }
@@ -2363,6 +2385,9 @@ static int i2s_rx_channel_stop(struct esp_i2s_s *priv)
         }
 
       priv->rx_started = false;
+#ifdef CONFIG_PM
+      esp_pm_lock_release(priv->config->pm_lock);
+#endif
 
       i2sinfo("Stopped RX channel of port %ld\n", priv->config->port);
     }
@@ -3412,6 +3437,9 @@ struct i2s_dev_s *esp_i2sbus_initialize(int port)
   int ret;
   struct esp_i2s_s *priv = NULL;
   irqstate_t flags;
+#ifdef CONFIG_PM
+  esp_pm_lock_type_t pm_type = ESP_PM_APB_FREQ_MAX;
+#endif
 
   i2sinfo("port: %d\n", port);
 
@@ -3438,6 +3466,30 @@ struct i2s_dev_s *esp_i2sbus_initialize(int port)
 
   flags = spin_lock_irqsave(&priv->slock);
 
+#ifdef CONFIG_PM
+#  if SOC_I2S_SUPPORTS_APLL && SOC_I2S_HW_VERSION_2
+  if (priv.tx_clk_src == I2S_CLK_SRC_APLL &&
+      priv.tx_clk_src == I2S_CLK_SRC_APLL)
+    {
+      pm_type = ESP_PM_NO_LIGHT_SLEEP;
+    }
+#  endif
+
+  if (priv->config->pm_lock == NULL)
+    {
+      esp_pm_lock_handle_t pm_lock = priv->config->pm_lock;
+      ret =  esp_pm_lock_create(pm_type,
+                                0,
+                                "i2s_driver",
+                                &pm_lock);
+      if (ret != OK)
+        {
+          i2serr("Failed to create I2S PM lock\n");
+          goto err;
+        }
+    }
+#endif
+
   ret = i2s_configure(priv);
   if (ret < 0)
     {
diff --git a/arch/risc-v/src/common/espressif/esp_idle.c 
b/arch/risc-v/src/common/espressif/esp_idle.c
index b09dc5bc51b..1d1384ab7d3 100644
--- a/arch/risc-v/src/common/espressif/esp_idle.c
+++ b/arch/risc-v/src/common/espressif/esp_idle.c
@@ -47,8 +47,8 @@
 #include "esp_tickless.h"
 #endif
 
-#ifdef CONFIG_ESPRESSIF_AUTO_SLEEP
 #include "esp_private/pm_impl.h"
+#if defined(CONFIG_ESPRESSIF_AUTO_SLEEP) || defined(CONFIG_ESPRESSIF_DFS)
 #include "platform/os.h"
 #endif
 
@@ -236,12 +236,8 @@ void up_idle(void)
    * sleep in a reduced power mode until an interrupt occurs to save power
    */
 
-#ifdef CONFIG_ESPRESSIF_AUTO_SLEEP
   esp_pm_impl_idle_hook();
   esp_pm_impl_waiti();
-#else
-  asm("WFI");
-#endif
 
   /* Perform IDLE mode power management */
 
diff --git a/arch/risc-v/src/common/espressif/esp_mcpwm.c 
b/arch/risc-v/src/common/espressif/esp_mcpwm.c
index 10643b6c862..a3a33dc6bbc 100644
--- a/arch/risc-v/src/common/espressif/esp_mcpwm.c
+++ b/arch/risc-v/src/common/espressif/esp_mcpwm.c
@@ -54,6 +54,9 @@
 #include "hal/clk_tree_hal.h"
 #include "esp_clk_tree.h"
 #include "esp_private/esp_clk_tree_common.h"
+#ifdef CONFIG_PM
+#  include "include/esp_pm.h"
+#endif
 
 #ifdef CONFIG_ESP_MCPWM
 
@@ -162,6 +165,9 @@ struct mcpwm_dev_common_s
   bool initialized;          /* MCPWM periph. and HAL has been initialized */
   bool isr_initialized;      /* Shared ISR has been initialized */
   int group_prescale;
+#ifdef CONFIG_PM
+  esp_pm_lock_handle_t pm_lock;   /* Power management lock */
+#endif
 };
 
 #ifdef CONFIG_ESP_MCPWM_MOTOR
@@ -318,6 +324,9 @@ static struct mcpwm_dev_common_s g_mcpwm_common =
   .initialized         = false,
   .isr_initialized     = false,
   .group_prescale      = MCPWM_DEV_CLK_PRESCALE,
+#ifdef CONFIG_PM
+  .pm_lock             = NULL,
+#endif
 };
 
 /* Motor specific data structures */
@@ -537,6 +546,10 @@ static int esp_motor_shutdown(struct motor_lowerhalf_s 
*dev)
   esp_motor_fault_configure(priv, false);
 #endif
 
+#ifdef CONFIG_PM
+  esp_pm_lock_release(g_mcpwm_common.pm_lock);
+#endif
+
   spin_unlock_irqrestore(&g_mcpwm_common.mcpwm_spinlock, flags);
   return OK;
 }
@@ -641,6 +654,11 @@ static int esp_motor_start(struct motor_lowerhalf_s *dev)
   float duty;
 
   flags = spin_lock_irqsave(&g_mcpwm_common.mcpwm_spinlock);
+
+#ifdef CONFIG_PM
+  esp_pm_lock_acquire(g_mcpwm_common.pm_lock);
+#endif
+
   if (priv->state.state == MOTOR_STATE_RUN)
     {
       spin_unlock_irqrestore(&g_mcpwm_common.mcpwm_spinlock, flags);
@@ -1450,6 +1468,10 @@ static int esp_capture_start(struct cap_lowerhalf_s 
*lower)
   mcpwm_hal_context_t *hal = &priv->common->hal;
   flags = spin_lock_irqsave(&priv->common->mcpwm_spinlock);
 
+#ifdef CONFIG_PM
+  esp_pm_lock_acquire(g_mcpwm_common.pm_lock);
+#endif
+
   /* Enable channel and interruption for rising edge */
 
   mcpwm_ll_capture_enable_timer(g_mcpwm_common.hal.dev, true);
@@ -1512,6 +1534,10 @@ static int esp_capture_stop(struct cap_lowerhalf_s 
*lower)
                        false);
   priv->enabled = false;
 
+#ifdef CONFIG_PM
+  esp_pm_lock_release(g_mcpwm_common.pm_lock);
+#endif
+
   spin_unlock_irqrestore(&priv->common->mcpwm_spinlock, flags);
   cpinfo("Channel disabled: %d\n", priv->channel_id);
   return OK;
@@ -1955,6 +1981,16 @@ struct motor_lowerhalf_s *esp_motor_bdc_initialize(int 
channel,
 
   if (!g_mcpwm_common.initialized)
     {
+#ifdef CONFIG_PM
+      ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0,
+                               "mcpwm", &g_mcpwm_common.pm_lock);
+      if (ret != OK)
+        {
+          mtrerr("Failed to create MCPWM PM lock\n");
+          return NULL;
+        }
+#endif
+
       esp_mcpwm_group_start();
     }
 
@@ -2028,6 +2064,9 @@ struct cap_lowerhalf_s *esp_mcpwm_capture_initialize(int 
channel, int pin)
 {
   struct mcpwm_cap_channel_lowerhalf_s *lower = NULL;
   uint32_t group_clock;
+#ifdef CONFIG_PM
+  int ret;
+#endif
 
   /* Single time initialization for the entire MCPWM Peripheral
    * and MCPWM Capture group.
@@ -2035,6 +2074,16 @@ struct cap_lowerhalf_s *esp_mcpwm_capture_initialize(int 
channel, int pin)
 
   if (!g_mcpwm_common.initialized)
     {
+#ifdef CONFIG_PM
+      ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0,
+                               "mcpwm", &g_mcpwm_common.pm_lock);
+      if (ret != OK)
+        {
+          mtrerr("Failed to create MCPWM PM lock\n");
+          return NULL;
+        }
+#endif
+
       esp_mcpwm_group_start();
     }
 
diff --git a/arch/risc-v/src/common/espressif/esp_oneshot.c 
b/arch/risc-v/src/common/espressif/esp_oneshot.c
index 281188baac4..8c3567c5e90 100644
--- a/arch/risc-v/src/common/espressif/esp_oneshot.c
+++ b/arch/risc-v/src/common/espressif/esp_oneshot.c
@@ -47,6 +47,9 @@
 #include "periph_ctrl.h"
 #include "soc/clk_tree_defs.h"
 #include "esp_private/esp_clk_tree_common.h"
+#ifdef CONFIG_PM
+#  include "include/esp_pm.h"
+#endif
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -81,6 +84,9 @@ struct esp_oneshot_lowerhalf_s
   struct oneshot_lowerhalf_s lh;          /* Lower half instance */
   timer_hal_context_t        hal;         /* HAL context */
   bool                       running;     /* True: the timer is running */
+#ifdef CONFIG_PM
+  esp_pm_lock_handle_t      pm_lock;      /* Power management lock */
+#endif
 };
 
 /****************************************************************************
@@ -124,6 +130,9 @@ static struct esp_oneshot_lowerhalf_s g_oneshot_lowerhalf =
     {
       .ops = &g_oneshot_ops,
     },
+#ifdef CONFIG_PM
+  .pm_lock = NULL,
+#endif
 };
 
 /****************************************************************************
@@ -196,6 +205,13 @@ static void esp_oneshot_start(struct oneshot_lowerhalf_s 
*lower,
 
   timer_hal_context_t *hal = &(priv->hal);
 
+#ifdef CONFIG_PM
+  if (priv->pm_lock)
+    {
+      esp_pm_lock_acquire(priv->pm_lock);
+    }
+#endif
+
   /* Make sure the timer is stopped to avoid unpredictable behavior */
 
   timer_ll_enable_intr(hal->dev, TIMER_LL_EVENT_ALARM(hal->timer_id),
@@ -298,6 +314,13 @@ static void esp_oneshot_cancel(struct oneshot_lowerhalf_s 
*lower)
       timer_ll_enable_counter(hal->dev, hal->timer_id, false);
     }
 
+#ifdef CONFIG_PM
+  if (priv->pm_lock)
+    {
+      esp_pm_lock_release(priv->pm_lock);
+    }
+#endif
+
   priv->running = false;
 }
 
@@ -405,6 +428,10 @@ struct oneshot_lowerhalf_s *oneshot_initialize(int chan, 
uint16_t resolution)
   int ret = OK;
   shared_periph_module_t periph;
   int irq;
+#ifdef CONFIG_PM
+  bool need_pm_lock = true;
+  esp_pm_lock_type_t pm_lock_type = ESP_PM_NO_LIGHT_SLEEP;
+#endif
 
   UNUSED(chan);
 
@@ -455,6 +482,34 @@ struct oneshot_lowerhalf_s *oneshot_initialize(int chan, 
uint16_t resolution)
 
   timer_ll_set_clock_prescale(lower->hal.dev, lower->hal.timer_id, prescale);
 
+#ifdef CONFIG_PM
+#  if TIMER_LL_FUNC_CLOCK_SUPPORT_RC_FAST
+  if (GPTIMER_CLK_SRC_DEFAULT == GPTIMER_CLK_SRC_RC_FAST)
+    {
+      need_pm_lock = false;
+    }
+#  endif
+
+#  if TIMER_LL_FUNC_CLOCK_SUPPORT_APB
+  if (GPTIMER_CLK_SRC_DEFAULT == GPTIMER_CLK_SRC_APB)
+    {
+      pm_lock_type = ESP_PM_APB_FREQ_MAX;
+    }
+#  endif
+
+  if (need_pm_lock && lower->pm_lock == NULL)
+    {
+      ret = esp_pm_lock_create(pm_lock_type, 0,
+                              "ONESHOT",
+                              &lower->pm_lock);
+      if (ret != OK)
+        {
+          tmrerr("Failed to create oneshot PM lock\n");
+          return NULL;
+        }
+    }
+#endif
+
   irq = soc_timg_gptimer_signals[GROUP_ID][TIMER_ID].irq_id;
 
   esp_setup_irq(irq,
diff --git a/arch/risc-v/src/common/espressif/esp_pcnt.c 
b/arch/risc-v/src/common/espressif/esp_pcnt.c
index 9141cdfc22d..5ef94528b3b 100644
--- a/arch/risc-v/src/common/espressif/esp_pcnt.c
+++ b/arch/risc-v/src/common/espressif/esp_pcnt.c
@@ -60,6 +60,9 @@
 #include "esp_clk.h"
 #include "esp_irq.h"
 #include "esp_attr.h"
+#ifdef CONFIG_PM
+#  include "include/esp_pm.h"
+#endif
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -117,6 +120,9 @@ struct esp_pcnt_priv_s
   uint32_t accum_value;                                                 /* 
Accumulator value of overflowed PCNT unit */
   bool channels[PCNT_LL_GET(CHANS_PER_UNIT)];                           /* 
Channel information of PCNT unit */
   struct esp_pcnt_watch_point_priv_s watchers[PCNT_LL_WATCH_EVENT_MAX]; /* 
array of PCNT watchers */
+#ifdef CONFIG_PM
+  esp_pm_lock_handle_t pm_lock;                                         /* 
Power management lock */
+#endif
 };
 
 /****************************************************************************
@@ -508,6 +514,10 @@ static int esp_pcnt_unit_enable(struct cap_lowerhalf_s 
*dev)
                           true);
     }
 
+#ifdef CONFIG_PM
+  esp_pm_lock_acquire(priv->pm_lock);
+#endif
+
   priv->state = PCNT_UNIT_ENABLE;
   return OK;
 }
@@ -548,6 +558,10 @@ static int esp_pcnt_unit_disable(struct cap_lowerhalf_s 
*dev)
                           false);
     }
 
+#ifdef CONFIG_PM
+  esp_pm_lock_release(priv->pm_lock);
+#endif
+
   priv->state = PCNT_UNIT_INIT;
   return OK;
 }
@@ -818,6 +832,9 @@ struct cap_lowerhalf_s *esp_pcnt_new_unit(
   int ret;
   int i;
   irqstate_t flags;
+#ifdef CONFIG_PM
+  esp_pm_lock_type_t pm_lock_type = ESP_PM_NO_LIGHT_SLEEP;
+#endif
 
   if (config == NULL)
     {
@@ -874,6 +891,25 @@ struct cap_lowerhalf_s *esp_pcnt_new_unit(
   spin_unlock_irqrestore(&g_pcnt_lock, flags);
   cpinfo("Allocated pcnt unit: %" PRId16 "\n", unit_id);
 
+#ifdef CONFIG_PM
+#  if PCNT_LL_CLOCK_SUPPORT_APB
+  if (PCNT_CLK_SRC_DEFAULT == PCNT_CLK_SRC_APB)
+    {
+      pm_lock_type = ESP_PM_APB_FREQ_MAX;
+    }
+
+#  endif
+  ret = esp_pm_lock_create(pm_lock_type,
+                           0,
+                           soc_pcnt_signals[unit_id].module_name,
+                           &pcnt_units[unit_id].pm_lock);
+  if (ret != OK)
+    {
+      cperr("Failed to create PCNT PM lock\n");
+      return NULL;
+    }
+#endif
+
   if (!g_pcnt_intr)
     {
       nxmutex_lock(&g_pcnt_mutex);
@@ -987,6 +1023,11 @@ int esp_pcnt_del_unit(struct cap_lowerhalf_s *dev)
       esp_teardown_irq(soc_pcnt_signals[0].irq_id, -ENOMEM);
     }
 
+#ifdef CONFIG_PM
+  esp_pm_lock_delete(priv->pm_lock);
+  priv->pm_lock = NULL;
+#endif
+
   spin_unlock_irqrestore(&priv->lock, flags);
 
   return OK;
diff --git a/arch/risc-v/src/common/espressif/esp_pm.c 
b/arch/risc-v/src/common/espressif/esp_pm.c
index f4a9e900826..0bd28b90dfa 100644
--- a/arch/risc-v/src/common/espressif/esp_pm.c
+++ b/arch/risc-v/src/common/espressif/esp_pm.c
@@ -862,8 +862,6 @@ void esp_pmsleep(uint64_t time_in_us)
   esp_pm_deep_sleep_start();
 }
 
-#ifdef CONFIG_ESPRESSIF_AUTO_SLEEP
-
 /****************************************************************************
  * Name: esp_pmconfigure
  *
@@ -891,9 +889,13 @@ int esp_pmconfigure(void)
   esp_pm_config_t pm_config =
     {
       .max_freq_mhz = CONFIG_ESPRESSIF_CPU_FREQ_MHZ,
+#ifdef CONFIG_ESPRESSIF_DFS
+      .min_freq_mhz = CONFIG_ESPRESSIF_MIN_CPU_FREQ_MHZ,
+#else
       .min_freq_mhz = CONFIG_ESPRESSIF_CPU_FREQ_MHZ,
+#endif
 #ifdef CONFIG_ESPRESSIF_AUTO_SLEEP
-      .light_sleep_enable = true
+      .light_sleep_enable = false
 #endif
     };
 
@@ -916,6 +918,7 @@ int esp_pmconfigure(void)
   esp_pm_uart_wakeup_prepare();
 #endif /* CONFIG_PM_UART_WAKEUP */
 
+#ifdef CONFIG_ESPRESSIF_AUTO_SLEEP
   err = esp_pm_register_skip_light_sleep_callback(
           esp_pm_skip_light_sleep);
   if (err != ESP_OK)
@@ -948,7 +951,7 @@ int esp_pmconfigure(void)
       pwrerr("Failed to set console UART handling mode: %d\n", err);
       return -ENOMEM;
     }
+#endif
 
   return ret;
 }
-#endif /* CONFIG_ESPRESSIF_AUTO_SLEEP */
diff --git a/arch/risc-v/src/common/espressif/esp_pm.h 
b/arch/risc-v/src/common/espressif/esp_pm.h
index 596c7083f88..6962fcfc971 100644
--- a/arch/risc-v/src/common/espressif/esp_pm.h
+++ b/arch/risc-v/src/common/espressif/esp_pm.h
@@ -148,9 +148,8 @@ void esp_pmsleep(uint64_t time_in_us);
  *   Returns OK on success; a negated errno value on failure.
  *
  ****************************************************************************/
-#ifdef CONFIG_ESPRESSIF_AUTO_SLEEP
+
 int esp_pmconfigure(void);
-#endif
 
 /****************************************************************************
  * Name: esp_pm_wakeup_set_last_reason
diff --git a/arch/risc-v/src/common/espressif/esp_sdm.c 
b/arch/risc-v/src/common/espressif/esp_sdm.c
index d53db13449d..a5af4132c4e 100644
--- a/arch/risc-v/src/common/espressif/esp_sdm.c
+++ b/arch/risc-v/src/common/espressif/esp_sdm.c
@@ -47,6 +47,9 @@
 #include "hal/sdm_periph.h"
 #include "hal/sdm_caps.h"
 #include "hal/gpio_ll.h"
+#ifdef CONFIG_PM
+#  include "include/esp_pm.h"
+#endif
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -73,6 +76,9 @@ struct esp_sdm_group_priv_s
   sdm_hal_context_t hal;                                                  /* 
Common layer context */
   soc_periph_sdm_clk_src_t clk_src;                                       /* 
Clock source */
   struct esp_sdm_channel_priv_s *channels[SDM_CAPS_GET(CHANS_PER_INST)];  /* 
Array of SDM channels */
+#ifdef CONFIG_PM
+  esp_pm_lock_handle_t pm_lock;                                           /* 
Power management lock */
+#endif
 };
 
 struct esp_sdm_priv_s
@@ -167,6 +173,13 @@ static int dac_setup(struct dac_dev_s *dev)
 {
   struct esp_sdm_group_priv_s *group =
     (struct esp_sdm_group_priv_s *) dev->ad_priv;
+#ifdef CONFIG_PM
+  if (group->pm_lock)
+    {
+      esp_pm_lock_acquire(group->pm_lock);
+    }
+#endif
+
   sdm_ll_enable_clock(group->hal.dev, true);
   return OK;
 }
@@ -189,6 +202,13 @@ static void dac_shutdown(struct dac_dev_s *dev)
 {
   struct esp_sdm_group_priv_s *group =
     (struct esp_sdm_group_priv_s *) dev->ad_priv;
+#ifdef CONFIG_PM
+  if (group->pm_lock)
+    {
+      esp_pm_lock_release(group->pm_lock);
+    }
+#endif
+
   sdm_ll_enable_clock(group->hal.dev, false);
 }
 
@@ -407,6 +427,10 @@ static struct esp_sdm_group_priv_s *esp_sdm_init(
   int group_id = 0;
   int chan_id = -1;
   irqstate_t flags;
+#ifdef CONFIG_PM
+  esp_pm_lock_type_t pm_type = ESP_PM_NO_LIGHT_SLEEP;
+  int res;
+#endif
 
   DEBUGASSERT(GPIO_IS_VALID_GPIO(config.gpio_num));
 
@@ -420,6 +444,7 @@ static struct esp_sdm_group_priv_s *esp_sdm_init(
           if (g_esp_sdm.groups[i] == NULL)
             {
               aerr("Error! No mem for group (%d)\n", i);
+              nxrmutex_unlock(&(g_esp_sdm.lock));
               return NULL;
             }
           else
@@ -435,6 +460,24 @@ static struct esp_sdm_group_priv_s *esp_sdm_init(
               sdm_hal_init(&g_esp_sdm.groups[i]->hal, &hal_config);
               sdm_ll_enable_clock(g_esp_sdm.groups[i]->hal.dev, true);
               ainfo("new group (%d) at %p\n", i, g_esp_sdm.groups[i]);
+#ifdef CONFIG_PM
+#  if SDM_CAPS_GET(FUNC_CLOCK_SUPPORT_APB)
+              if (clk_src == SDM_CLK_SRC_APB)
+                {
+                  pm_type = ESP_PM_APB_FREQ_MAX;
+                }
+#  endif
+
+              res = esp_pm_lock_create(pm_type, 0,
+                                       soc_sdm_signals[group_id].module_name,
+                                       &g_esp_sdm.groups[i]->pm_lock);
+              if (res != OK)
+                {
+                  aerr("Error! No mem to PM lock for group (%d)\n", i);
+                  nxrmutex_unlock(&(g_esp_sdm.lock));
+                  return NULL;
+                }
+#endif
               break;
             }
         }
diff --git a/arch/risc-v/src/common/espressif/esp_spi.c 
b/arch/risc-v/src/common/espressif/esp_spi.c
index 114e67a57d2..ca6760d28e7 100644
--- a/arch/risc-v/src/common/espressif/esp_spi.c
+++ b/arch/risc-v/src/common/espressif/esp_spi.c
@@ -73,6 +73,10 @@
 #  include "esp_private/gdma.h"
 #endif
 
+#ifdef CONFIG_PM
+#  include "include/esp_pm.h"
+#endif
+
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
@@ -224,6 +228,9 @@ struct esp_spi_priv_s
   spi_hal_context_t *ctx;               /* Context struct of common layer */
   spi_hal_dev_config_t *dev_cfg;        /* Device configuration struct of 
common layer */
   spi_hal_timing_param_t *timing_param; /* Timing struct of common layer */
+#ifdef CONFIG_PM
+  esp_pm_lock_handle_t pm_lock;         /* Power management lock */
+#endif
 };
 
 /****************************************************************************
@@ -387,6 +394,9 @@ static struct esp_spi_priv_s esp_spi2_priv =
   .sem_isr      = SEM_INITIALIZER(0),
   .cpuint       = -ENOMEM,
 #endif
+#ifdef CONFIG_PM
+  .pm_lock      = NULL,
+#endif
 };
 #endif /* CONFIG_ESPRESSIF_SPI2 */
 
@@ -1086,8 +1096,17 @@ static uint32_t esp_spi_poll_send(struct esp_spi_priv_s 
*priv, uint32_t wd)
 static uint32_t esp_spi_send(struct spi_dev_s *dev, uint32_t wd)
 {
   struct esp_spi_priv_s *priv = (struct esp_spi_priv_s *)dev;
+  int ret;
+
+#ifdef CONFIG_PM
+  esp_pm_lock_acquire(priv->pm_lock);
+#endif
+  ret = esp_spi_poll_send(priv, wd);
+#ifdef CONFIG_PM
+  esp_pm_lock_release(priv->pm_lock);
+#endif
 
-  return esp_spi_poll_send(priv, wd);
+  return ret;
 }
 
 /****************************************************************************
@@ -1214,6 +1233,9 @@ static void esp_spi_exchange(struct spi_dev_s *dev,
 {
   struct esp_spi_priv_s *priv = (struct esp_spi_priv_s *)dev;
 
+#ifdef CONFIG_PM
+  esp_pm_lock_acquire(priv->pm_lock);
+#endif
 #ifdef CONFIG_ESPRESSIF_SPI2_DMA
   size_t thld = CONFIG_ESPRESSIF_SPI2_DMATHRESHOLD;
 
@@ -1226,6 +1248,10 @@ static void esp_spi_exchange(struct spi_dev_s *dev,
     {
       esp_spi_poll_exchange(priv, txbuffer, rxbuffer, nwords);
     }
+
+#ifdef CONFIG_PM
+  esp_pm_lock_release(priv->pm_lock);
+#endif
 }
 
 #ifndef CONFIG_SPI_EXCHANGE
@@ -1539,6 +1565,9 @@ struct spi_dev_s *esp_spibus_initialize(int port)
 {
   struct spi_dev_s *spi_dev;
   struct esp_spi_priv_s *priv;
+#ifdef CONFIG_PM
+  int ret;
+#endif
 
   switch (port)
     {
@@ -1561,6 +1590,20 @@ struct spi_dev_s *esp_spibus_initialize(int port)
       return spi_dev;
     }
 
+#ifdef CONFIG_PM
+#  if CONFIG_ARCH_CHIP_ESP32P4
+  ret = esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0, "spi", &priv->pm_lock);
+#  else
+  ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "spi", &priv->pm_lock);
+#  endif
+  if (ret != OK)
+    {
+      nxmutex_unlock(&priv->lock);
+      spierr("Failed to create SPI PM lock for SPI:%" PRId8 "\n", priv->id);
+      return NULL;
+    }
+#endif
+
   /* Initialize the blank array */
 
   for (int i = 0; i < SPI_BLANK_ARRAY_SIZE; i++)
@@ -1639,6 +1682,11 @@ int esp_spibus_uninitialize(struct spi_dev_s *dev)
   priv->cpuint = -ENOMEM;
 #endif
 
+#ifdef CONFIG_PM
+  esp_pm_lock_delete(priv->pm_lock);
+  priv->pm_lock = NULL;
+#endif
+
   esp_spi_deinit(dev);
   nxmutex_unlock(&priv->lock);
 
diff --git a/arch/risc-v/src/common/espressif/esp_spi_slave.c 
b/arch/risc-v/src/common/espressif/esp_spi_slave.c
index 71077e34cda..87669a93060 100644
--- a/arch/risc-v/src/common/espressif/esp_spi_slave.c
+++ b/arch/risc-v/src/common/espressif/esp_spi_slave.c
@@ -65,6 +65,10 @@
 
 #include "riscv_internal.h"
 
+#ifdef CONFIG_PM
+#  include "include/esp_pm.h"
+#endif
+
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
@@ -220,6 +224,9 @@ struct spislave_priv_s
   bool is_tx_enabled;
   spi_slave_hal_context_t ctx;  /* Context struct of the common layer */
   spi_slave_hal_config_t cfg;   /* Configuration struct of the common layer */
+#ifdef CONFIG_PM
+  esp_pm_lock_handle_t pm_lock; /* Power management lock */
+#endif
 };
 
 /****************************************************************************
@@ -1045,6 +1052,9 @@ static void spislave_bind(struct spi_slave_ctrlr_s *ctrlr,
   DEBUGASSERT(nbits > 0);
 
   flags = enter_critical_section();
+#ifdef CONFIG_PM
+  esp_pm_lock_acquire(priv->pm_lock);
+#endif
 
   priv->dev = dev;
 
@@ -1172,6 +1182,9 @@ static void spislave_unbind(struct spi_slave_ctrlr_s 
*ctrlr)
 #endif
 
   priv->dev = NULL;
+#ifdef CONFIG_PM
+  esp_pm_lock_release(priv->pm_lock);
+#endif
 
   leave_critical_section(flags);
 }
@@ -1407,6 +1420,22 @@ struct spi_slave_ctrlr_s 
*esp_spislave_ctrlr_initialize(int port)
       return spislave_dev;
     }
 
+#ifdef CONFIG_PM
+#  if CONFIG_ARCH_CHIP_ESP32P4
+  ret = esp_pm_lock_create(ESP_PM_CPU_FREQ_MAX, 0,
+                           "spi_slave", &priv->pm_lock);
+#  else
+  ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0,
+                           "spi_slave", &priv->pm_lock);
+#  endif
+  if (ret != OK)
+    {
+      spierr("Failed to create SPI PM lock for SPI slave driver\n");
+      leave_critical_section(flags);
+      return NULL;
+    }
+#endif
+
   /* Attach IRQ for CS pin interrupt */
 
   ret = esp_gpio_irq(priv->config->cs_pin,
@@ -1509,6 +1538,13 @@ int esp_spislave_ctrlr_uninitialize(struct 
spi_slave_ctrlr_s *ctrlr)
   priv->rx_length = 0;
   priv->is_processing = false;
   priv->is_tx_enabled = false;
+#ifdef CONFIG_PM
+  if (priv->pm_lock != NULL)
+    {
+      esp_pm_lock_delete(priv->pm_lock);
+      priv->pm_lock = NULL;
+    }
+#endif
 
   leave_critical_section(flags);
 
diff --git a/arch/risc-v/src/common/espressif/esp_twai.c 
b/arch/risc-v/src/common/espressif/esp_twai.c
index 96ff99d130a..77920410d3e 100644
--- a/arch/risc-v/src/common/espressif/esp_twai.c
+++ b/arch/risc-v/src/common/espressif/esp_twai.c
@@ -55,6 +55,9 @@
 #include "hal/twai_periph.h"
 #include "soc/gpio_sig_map.h"
 #include "soc/reg_base.h"
+#ifdef CONFIG_PM
+#  include "include/esp_pm.h"
+#endif
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -142,6 +145,9 @@ struct esp_twai_dev_s
   int8_t cpuint;                  /* CPU interrupt assigned to this TWAI */
   twai_hal_context_t ctx;         /* Context struct of common layer */
   twai_timing_config_t t_config;  /* Timing struct of common layer */
+#ifdef CONFIG_PM
+  esp_pm_lock_handle_t pm_lock;   /* Power management lock */
+#endif
 };
 
 /****************************************************************************
@@ -190,6 +196,9 @@ static struct esp_twai_dev_s g_twai0priv =
   .port             = 0,
   .cpuint           = -ENOMEM,
   .t_config         = TWAI0_TIMING_CONFIG,
+#ifdef CONFIG_PM
+  .pm_lock          = NULL,
+#endif
 };
 
 static struct can_dev_s g_twai0dev =
@@ -205,6 +214,9 @@ static struct esp_twai_dev_s g_twai1priv =
   .port             = 1,
   .cpuint           = -ENOMEM,
   .t_config         = TWAI1_TIMING_CONFIG,
+#ifdef CONFIG_PM
+  .pm_lock          = NULL,
+#endif
 };
 
 static struct can_dev_s g_twai1dev =
@@ -273,6 +285,13 @@ static void esp_twai_reset(struct can_dev_s *dev)
   ASSERT(ret);
   twai_hal_configure(&priv->ctx, &priv->t_config, &f_config, 0);
 
+#ifdef CONFIG_PM
+  if (priv->pm_lock)
+    {
+      esp_pm_lock_acquire(priv->pm_lock);
+    }
+#endif
+
   /* Restart the TWAI */
 
   twai_hal_start(&priv->ctx);
@@ -799,6 +818,10 @@ struct can_dev_s *esp_twaiinitialize(int port)
 {
   struct can_dev_s *dev;
   irqstate_t flags;
+#ifdef CONFIG_PM
+  int ret;
+  struct esp_twai_dev_s *priv;
+#endif
 
   caninfo("TWAI%" PRIu8 "\n",  port);
 
@@ -848,6 +871,34 @@ struct can_dev_s *esp_twaiinitialize(int port)
       return NULL;
     }
 
+#ifdef CONFIG_PM
+  priv = (struct esp_twai_dev_s *)dev->cd_priv;
+
+  if (priv->pm_lock == NULL)
+    {
+#  if TWAI_LL_SUPPORT(APB_CLK)
+      if (TWAI_CLK_SRC_DEFAULT == TWAI_CLK_SRC_APB)
+        {
+          ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX,
+                                   0,
+                                   twai_periph_signals[port].module_name,
+                                   &priv->pm_lock);
+        }
+#  else
+      ret = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP,
+                               0,
+                               twai_periph_signals[port].module_name,
+                               &priv->pm_lock);
+#  endif
+      if (ret != OK)
+        {
+          canerr("Failed to create TWAI%" PRIu8 "PM lock\n", port);
+          leave_critical_section(flags);
+          return NULL;
+        }
+    }
+#endif
+
   /* Then just perform a TWAI reset operation */
 
   esp_twai_reset(dev);
diff --git a/arch/risc-v/src/esp32p4/hal_esp32p4.cmake 
b/arch/risc-v/src/esp32p4/hal_esp32p4.cmake
index bdf4c851444..2bafc54031a 100644
--- a/arch/risc-v/src/esp32p4/hal_esp32p4.cmake
+++ b/arch/risc-v/src/esp32p4/hal_esp32p4.cmake
@@ -305,6 +305,7 @@ list(
   ${ESP_HAL_3RDPARTY_REPO}/components/esp_hw_support/periph_ctrl.c
   
${ESP_HAL_3RDPARTY_REPO}/components/esp_hw_support/lowpower/port/${CHIP_SERIES}/sleep_cpu_asm.S
   
${ESP_HAL_3RDPARTY_REPO}/components/esp_hw_support/lowpower/port/${CHIP_SERIES}/sleep_cpu.c
+  
${ESP_HAL_3RDPARTY_REPO}/components/esp_hw_support/lowpower/port/${CHIP_SERIES}/sleep_cpu_static.c
   
${ESP_HAL_3RDPARTY_REPO}/components/esp_hw_support/lowpower/port/${CHIP_SERIES}/sleep_clock.c
   
${ESP_HAL_3RDPARTY_REPO}/components/esp_hw_support/port/${CHIP_SERIES}/cpu_region_protect.c
   
${ESP_HAL_3RDPARTY_REPO}/components/esp_hw_support/port/${CHIP_SERIES}/esp_clk_tree.c
@@ -341,6 +342,8 @@ list(
   ${ESP_HAL_3RDPARTY_REPO}/components/esp_mm/esp_cache_utils.c
   ${ESP_HAL_3RDPARTY_REPO}/components/esp_mm/esp_mmu_map.c
   
${ESP_HAL_3RDPARTY_REPO}/components/esp_mm/port/${CHIP_SERIES}/ext_mem_layout.c
+  ${ESP_HAL_3RDPARTY_REPO}/components/esp_pm/pm_impl.c
+  ${ESP_HAL_3RDPARTY_REPO}/components/esp_pm/pm_locks.c
   ${ESP_HAL_3RDPARTY_REPO}/components/esp_rom/patches/esp_rom_clic.c
   ${ESP_HAL_3RDPARTY_REPO}/components/esp_rom/patches/esp_rom_crc.c
   ${ESP_HAL_3RDPARTY_REPO}/components/esp_rom/patches/esp_rom_efuse.c
diff --git a/arch/risc-v/src/esp32p4/hal_esp32p4.mk 
b/arch/risc-v/src/esp32p4/hal_esp32p4.mk
index 6b4fb09f477..e9d1f703163 100644
--- a/arch/risc-v/src/esp32p4/hal_esp32p4.mk
+++ b/arch/risc-v/src/esp32p4/hal_esp32p4.mk
@@ -265,6 +265,7 @@ CHIP_CSRCS += 
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_
 CHIP_CSRCS += 
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)periph_ctrl.c
 CHIP_ASRCS += 
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)lowpower$(DELIM)port$(DELIM)$(CHIP_SERIES)$(DELIM)sleep_cpu_asm.S
 CHIP_CSRCS += 
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)lowpower$(DELIM)port$(DELIM)$(CHIP_SERIES)$(DELIM)sleep_cpu.c
+CHIP_CSRCS += 
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)lowpower$(DELIM)port$(DELIM)$(CHIP_SERIES)$(DELIM)sleep_cpu_static.c
 CHIP_CSRCS += 
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)lowpower$(DELIM)port$(DELIM)$(CHIP_SERIES)$(DELIM)sleep_clock.c
 CHIP_CSRCS += 
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)port$(DELIM)regdma_link.c
 CHIP_CSRCS += 
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_hw_support$(DELIM)port$(DELIM)$(CHIP_SERIES)$(DELIM)cpu_region_protect.c
@@ -301,6 +302,8 @@ CHIP_CSRCS += 
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_
 CHIP_CSRCS += 
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_mm$(DELIM)esp_cache_utils.c
 CHIP_CSRCS += 
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_mm$(DELIM)esp_mmu_map.c
 CHIP_CSRCS += 
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_mm$(DELIM)port$(DELIM)$(CHIP_SERIES)$(DELIM)ext_mem_layout.c
+CHIP_CSRCS += 
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_pm$(DELIM)pm_impl.c
+CHIP_CSRCS += 
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_pm$(DELIM)pm_locks.c
 CHIP_CSRCS += 
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_rom$(DELIM)patches$(DELIM)esp_rom_clic.c
 CHIP_CSRCS += 
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_rom$(DELIM)patches$(DELIM)esp_rom_crc.c
 CHIP_CSRCS += 
chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)esp_rom$(DELIM)patches$(DELIM)esp_rom_efuse.c

Reply via email to