Merge branch 'feat/support_esp32h21_sleep_feature' into 'master'

feat: support esp32h21 lowpower features

Closes PM-425, PM-426, PM-427, PM-428, PM-430, PM-432, IDF-11512, IDF-11515, IDF-11516, IDF-11517, IDF-11519, and IDF-11520

See merge request espressif/esp-idf!40116
This commit is contained in:
Jiang Jiang Jian
2025-09-26 20:17:46 +08:00
44 changed files with 885 additions and 463 deletions
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2017-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2017-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -124,13 +124,15 @@ __attribute__((weak)) void bootloader_clock_configure(void)
#elif CONFIG_IDF_TARGET_ESP32H21
// CLR ENA
CLEAR_PERI_REG_MASK(LP_WDT_INT_ENA_REG, LP_WDT_SUPER_WDT_INT_ENA); /* SWD */
CLEAR_PERI_REG_MASK(LP_ANA_LP_INT_ENA_REG, LP_ANA_BOD_MODE0_LP_INT_ENA); /* BROWN_OUT */
// TODO [ESP32H21] IDF-11530
// CLEAR_PERI_REG_MASK(LP_ANA_LP_INT_ENA_REG, LP_ANA_BOD_MODE0_LP_INT_ENA); /* BROWN_OUT */
CLEAR_PERI_REG_MASK(LP_WDT_INT_ENA_REG, LP_WDT_LP_WDT_INT_ENA); /* WDT */
CLEAR_PERI_REG_MASK(PMU_HP_INT_ENA_REG, PMU_SOC_WAKEUP_INT_ENA); /* SLP_REJECT */
CLEAR_PERI_REG_MASK(PMU_HP_INT_ENA_REG, PMU_SOC_SLEEP_REJECT_INT_ENA); /* SLP_WAKEUP */
// SET CLR
SET_PERI_REG_MASK(LP_WDT_INT_CLR_REG, LP_WDT_SUPER_WDT_INT_CLR); /* SWD */
SET_PERI_REG_MASK(LP_ANA_LP_INT_CLR_REG, LP_ANA_BOD_MODE0_LP_INT_CLR); /* BROWN_OUT */
// TODO [ESP32H21] IDF-11530
// SET_PERI_REG_MASK(LP_ANA_LP_INT_CLR_REG, LP_ANA_BOD_MODE0_LP_INT_CLR); /* BROWN_OUT */
SET_PERI_REG_MASK(LP_WDT_INT_CLR_REG, LP_WDT_LP_WDT_INT_CLR); /* WDT */
SET_PERI_REG_MASK(PMU_HP_INT_CLR_REG, PMU_SOC_WAKEUP_INT_CLR); /* SLP_REJECT */
SET_PERI_REG_MASK(PMU_HP_INT_CLR_REG, PMU_SOC_SLEEP_REJECT_INT_CLR);
@@ -126,6 +126,19 @@ const int s_test_map[TEST_GPIO_PIN_COUNT] = {
};
#define TEST_RTCIO_INTR_PIN_INDEX 5 // IO12
#define TEST_RTCIO_DEEP_SLEEP_PIN_INDEX 5 // IO12
#elif CONFIG_IDF_TARGET_ESP32H21
#define TEST_GPIO_PIN_COUNT 7
const int s_test_map[TEST_GPIO_PIN_COUNT] = {
GPIO_NUM_5, //GPIO5
GPIO_NUM_6, //GPIO6
GPIO_NUM_7, //GPIO7
GPIO_NUM_8, //GPIO8
GPIO_NUM_9, //GPIO9
GPIO_NUM_10, //GPIO10
GPIO_NUM_11, //GPIO11
};
#define TEST_RTCIO_INTR_PIN_INDEX 6 // IO11
#define TEST_RTCIO_DEEP_SLEEP_PIN_INDEX 6 // IO11
#elif CONFIG_IDF_TARGET_ESP32P4
// Has no input-only rtcio pins, all pins support pull-up/down
#define RTCIO_SUPPORT_PU_PD(num) 1
@@ -39,6 +39,9 @@
#elif CONFIG_IDF_TARGET_ESP32C5
#define DEFAULT_UART1_TX_IO_NUM GPIO_NUM_2
#define DEFAULT_UART1_RX_IO_NUM GPIO_NUM_3
#elif CONFIG_IDF_TARGET_ESP32H21
#define DEFAULT_UART1_TX_IO_NUM GPIO_NUM_4
#define DEFAULT_UART1_RX_IO_NUM GPIO_NUM_5
#elif CONFIG_IDF_TARGET_ESP32H4
#define DEFAULT_UART1_TX_IO_NUM GPIO_NUM_15
#define DEFAULT_UART1_RX_IO_NUM GPIO_NUM_16
+1 -2
View File
@@ -70,8 +70,7 @@ menu "Hardware Settings"
# regardless of power management configuration.
config ESP_SLEEP_POWER_DOWN_FLASH
bool "Power down flash in light sleep when there is no SPIRAM or SPIRAM has independent power supply"
# TODO: PM-383
select PM_SLP_IRAM_OPT if (!IDF_TARGET_ESP32H21 && !IDF_TARGET_ESP32H4)
select PM_SLP_IRAM_OPT
select ESP_PERIPH_CTRL_FUNC_IN_IRAM
select ESP_REGI2C_CTRL_FUNC_IN_IRAM
depends on !SPIRAM || ESP_LDO_RESERVE_PSRAM
@@ -30,9 +30,8 @@ esp_err_t sleep_clock_system_retention_init(void *arg)
[5] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(5), I2C_ANA_MST_ANA_CONF0_REG, I2C_MST_BBPLL_STOP_FORCE_HIGH, I2C_MST_BBPLL_STOP_FORCE_HIGH, 1, 0), .owner = ENTRY(0) },
/* Clock configuration retention */
[6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_PCR_LINK(6), DR_REG_PCR_BASE, DR_REG_PCR_BASE, N_REGS_PCR(), 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[7] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_PCR_LINK(7), PCR_RESET_EVENT_BYPASS_REG, PCR_RESET_EVENT_BYPASS_REG, 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[8] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(8), PCR_BUS_CLK_UPDATE_REG, PCR_BUS_CLOCK_UPDATE, PCR_BUS_CLOCK_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[9] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PCR_LINK(9), PCR_BUS_CLK_UPDATE_REG, 0x0, PCR_BUS_CLOCK_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(7), PCR_BUS_CLK_UPDATE_REG, PCR_BUS_CLOCK_UPDATE, PCR_BUS_CLOCK_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[8] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PCR_LINK(8), PCR_BUS_CLK_UPDATE_REG, 0x0, PCR_BUS_CLOCK_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
};
esp_err_t err = sleep_retention_entries_create(pcr_regs_retention, ARRAY_SIZE(pcr_regs_retention), REGDMA_LINK_PRI_SYS_CLK, SLEEP_RETENTION_MODULE_CLOCK_SYSTEM);
@@ -77,7 +76,7 @@ bool clock_domain_pd_allowed(void)
* necessary to check the state of CLOCK_MODEM to determine MODEM domain on
* or off. The clock and reset of digital peripherals are managed through
* PCR, with TOP domain similar to MODEM domain. */
sleep_retention_module_bitmap_t modem_clk_dep_modules = (sleep_retention_module_bitmap_t){ .bitmap = { 0 } };
__attribute__((unused)) sleep_retention_module_bitmap_t modem_clk_dep_modules = (sleep_retention_module_bitmap_t){ .bitmap = { 0 } };
#if SOC_BT_SUPPORTED
modem_clk_dep_modules.bitmap[SLEEP_RETENTION_MODULE_BLE_MAC >> 5] |= BIT(SLEEP_RETENTION_MODULE_BLE_MAC % 32);
modem_clk_dep_modules.bitmap[SLEEP_RETENTION_MODULE_BT_BB >> 5] |= BIT(SLEEP_RETENTION_MODULE_BT_BB % 32);
@@ -18,18 +18,17 @@
#include "esp_rom_crc.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_heap_caps.h"
#include "riscv/csr.h"
#include "soc/soc_caps.h"
#include "soc/cache_reg.h"
#include "soc/intpri_reg.h"
#include "soc/rtc_periph.h"
#include "esp_private/esp_pmu.h"
#include "esp_private/sleep_cpu.h"
#include "esp_private/sleep_event.h"
#include "esp32h21/rom/rtc.h"
#include "esp32h21/rom/cache.h"
#include "rvsleep-frames.h"
#include "sleep_cpu_retention.h"
#if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME
#include "esp_private/system_internal.h"
@@ -38,29 +37,6 @@
ESP_LOG_ATTR_TAG(TAG, "sleep");
typedef struct {
uint32_t start;
uint32_t end;
} cpu_domain_dev_regs_region_t;
typedef struct {
cpu_domain_dev_regs_region_t *region;
int region_num;
uint32_t *regs_frame;
} cpu_domain_dev_sleep_frame_t;
/**
* Internal structure which holds all requested light sleep cpu retention parameters
*/
typedef struct {
struct {
RvCoreCriticalSleepFrame *critical_frame;
RvCoreNonCriticalSleepFrame *non_critical_frame;
cpu_domain_dev_sleep_frame_t *intpri_frame;
cpu_domain_dev_sleep_frame_t *cache_config_frame;
} retent;
} sleep_cpu_retention_t;
static DRAM_ATTR sleep_cpu_retention_t s_cpu_retention;
#define CUSTOM_CSR_PCER_MACHINE 0x7e0
@@ -79,105 +55,6 @@ static DRAM_ATTR sleep_cpu_retention_t s_cpu_retention;
extern RvCoreCriticalSleepFrame *rv_core_critical_regs_frame;
static void * cpu_domain_dev_sleep_frame_alloc_and_init(const cpu_domain_dev_regs_region_t *regions, const int region_num)
{
const int region_sz = sizeof(cpu_domain_dev_regs_region_t) * region_num;
int regs_frame_sz = 0;
for (int num = 0; num < region_num; num++) {
regs_frame_sz += regions[num].end - regions[num].start;
}
void *frame = heap_caps_malloc(sizeof(cpu_domain_dev_sleep_frame_t) + region_sz + regs_frame_sz, MALLOC_CAP_32BIT|MALLOC_CAP_INTERNAL);
if (frame) {
cpu_domain_dev_regs_region_t *region = (cpu_domain_dev_regs_region_t *)(frame + sizeof(cpu_domain_dev_sleep_frame_t));
memcpy(region, regions, region_num * sizeof(cpu_domain_dev_regs_region_t));
void *regs_frame = frame + sizeof(cpu_domain_dev_sleep_frame_t) + region_sz;
memset(regs_frame, 0, regs_frame_sz);
*(cpu_domain_dev_sleep_frame_t *)frame = (cpu_domain_dev_sleep_frame_t) {
.region = region,
.region_num = region_num,
.regs_frame = (uint32_t *)regs_frame
};
}
return frame;
}
static inline void * cpu_domain_intpri_sleep_frame_alloc_and_init(void)
{
const static cpu_domain_dev_regs_region_t regions[] = {
{ .start = INTPRI_CORE0_CPU_INT_ENABLE_REG, .end = INTPRI_CORE0_CPU_INT_TYPE_REG + 4 },
{ .start = INTPRI_CORE0_CPU_INT_PRI_0_REG, .end = INTPRI_CORE0_CPU_INT_THRESH_REG + 4 },
{ .start = INTPRI_CLOCK_GATE_REG, .end = INTPRI_CORE0_CPU_INT_CLEAR_REG + 4 },
};
return cpu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0]));
}
static inline void * cpu_domain_cache_config_sleep_frame_alloc_and_init(void)
{
const static cpu_domain_dev_regs_region_t regions[] = {
{ .start = CACHE_L1_CACHE_WRAP_AROUND_CTRL_REG, .end = CACHE_L1_CACHE_WRAP_AROUND_CTRL_REG + 4 }
};
return cpu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0]));
}
static esp_err_t esp_sleep_cpu_retention_init_impl(void)
{
if (s_cpu_retention.retent.critical_frame == NULL) {
void *frame = heap_caps_calloc(1, RV_SLEEP_CTX_FRMSZ, MALLOC_CAP_32BIT|MALLOC_CAP_INTERNAL);
if (frame == NULL) {
goto err;
}
s_cpu_retention.retent.critical_frame = (RvCoreCriticalSleepFrame *)frame;
rv_core_critical_regs_frame = (RvCoreCriticalSleepFrame *)frame;
}
if (s_cpu_retention.retent.non_critical_frame == NULL) {
void *frame = heap_caps_calloc(1, sizeof(RvCoreNonCriticalSleepFrame), MALLOC_CAP_32BIT|MALLOC_CAP_INTERNAL);
if (frame == NULL) {
goto err;
}
s_cpu_retention.retent.non_critical_frame = (RvCoreNonCriticalSleepFrame *)frame;
}
if (s_cpu_retention.retent.intpri_frame == NULL) {
void *frame = cpu_domain_intpri_sleep_frame_alloc_and_init();
if (frame == NULL) {
goto err;
}
s_cpu_retention.retent.intpri_frame = (cpu_domain_dev_sleep_frame_t *)frame;
}
if (s_cpu_retention.retent.cache_config_frame == NULL) {
void *frame = cpu_domain_cache_config_sleep_frame_alloc_and_init();
if (frame == NULL) {
goto err;
}
s_cpu_retention.retent.cache_config_frame = (cpu_domain_dev_sleep_frame_t *)frame;
}
return ESP_OK;
err:
esp_sleep_cpu_retention_deinit();
return ESP_ERR_NO_MEM;
}
static esp_err_t esp_sleep_cpu_retention_deinit_impl(void)
{
if (s_cpu_retention.retent.critical_frame) {
heap_caps_free((void *)s_cpu_retention.retent.critical_frame);
s_cpu_retention.retent.critical_frame = NULL;
rv_core_critical_regs_frame = NULL;
}
if (s_cpu_retention.retent.non_critical_frame) {
heap_caps_free((void *)s_cpu_retention.retent.non_critical_frame);
s_cpu_retention.retent.non_critical_frame = NULL;
}
if (s_cpu_retention.retent.intpri_frame) {
heap_caps_free((void *)s_cpu_retention.retent.intpri_frame);
s_cpu_retention.retent.intpri_frame = NULL;
}
if (s_cpu_retention.retent.cache_config_frame) {
heap_caps_free((void *)s_cpu_retention.retent.cache_config_frame);
s_cpu_retention.retent.cache_config_frame = NULL;
}
return ESP_OK;
}
FORCE_INLINE_ATTR uint32_t save_mstatus_and_disable_global_int(void)
{
return RV_READ_MSTATUS_AND_DISABLE_INTR();
@@ -437,6 +314,7 @@ esp_err_t IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uin
esp_sleep_execute_event_callbacks(SLEEP_EVENT_SW_CPU_TO_MEM_START, (void *)0);
uint32_t mstatus = save_mstatus_and_disable_global_int();
cpu_domain_dev_regs_save(s_cpu_retention.retent.plic_frame);
cpu_domain_dev_regs_save(s_cpu_retention.retent.intpri_frame);
cpu_domain_dev_regs_save(s_cpu_retention.retent.cache_config_frame);
RvCoreNonCriticalSleepFrame *frame = rv_core_noncritical_regs_save();
@@ -455,26 +333,28 @@ esp_err_t IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uin
rv_core_noncritical_regs_restore(frame);
cpu_domain_dev_regs_restore(s_cpu_retention.retent.cache_config_frame);
cpu_domain_dev_regs_restore(s_cpu_retention.retent.intpri_frame);
cpu_domain_dev_regs_restore(s_cpu_retention.retent.plic_frame);
restore_mstatus(mstatus);
return err;
}
esp_err_t esp_sleep_cpu_retention_init(void)
{
return esp_sleep_cpu_retention_init_impl();
return esp_sleep_cpu_retention_init_impl(& s_cpu_retention);
}
esp_err_t esp_sleep_cpu_retention_deinit(void)
{
return esp_sleep_cpu_retention_deinit_impl();
return esp_sleep_cpu_retention_deinit_impl(& s_cpu_retention);
}
bool cpu_domain_pd_allowed(void)
{
return (s_cpu_retention.retent.critical_frame != NULL) && \
(s_cpu_retention.retent.non_critical_frame != NULL) && \
(s_cpu_retention.retent.intpri_frame != NULL) && \
(s_cpu_retention.retent.cache_config_frame != NULL);
(s_cpu_retention.retent.non_critical_frame != NULL) && \
(s_cpu_retention.retent.intpri_frame != NULL) && \
(s_cpu_retention.retent.cache_config_frame != NULL) && \
(s_cpu_retention.retent.plic_frame != NULL);
}
esp_err_t sleep_cpu_configure(bool light_sleep_enable)
@@ -0,0 +1,141 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include "esp_check.h"
#include "esp_heap_caps.h"
#include "soc/intpri_reg.h"
#include "soc/cache_reg.h"
#include "soc/plic_reg.h"
#include "esp_sleep.h"
#include "rvsleep-frames.h"
#include "sleep_cpu_retention.h"
extern RvCoreCriticalSleepFrame *rv_core_critical_regs_frame;
static void * cpu_domain_dev_sleep_frame_alloc_and_init(const cpu_domain_dev_regs_region_t *regions, const int region_num)
{
const int region_sz = sizeof(cpu_domain_dev_regs_region_t) * region_num;
int regs_frame_sz = 0;
for (int num = 0; num < region_num; num++) {
regs_frame_sz += regions[num].end - regions[num].start;
}
void *frame = heap_caps_malloc(sizeof(cpu_domain_dev_sleep_frame_t) + region_sz + regs_frame_sz, MALLOC_CAP_32BIT|MALLOC_CAP_INTERNAL);
if (frame) {
cpu_domain_dev_regs_region_t *region = (cpu_domain_dev_regs_region_t *)(frame + sizeof(cpu_domain_dev_sleep_frame_t));
memcpy(region, regions, region_num * sizeof(cpu_domain_dev_regs_region_t));
void *regs_frame = frame + sizeof(cpu_domain_dev_sleep_frame_t) + region_sz;
memset(regs_frame, 0, regs_frame_sz);
*(cpu_domain_dev_sleep_frame_t *)frame = (cpu_domain_dev_sleep_frame_t) {
.region = region,
.region_num = region_num,
.regs_frame = (uint32_t *)regs_frame
};
}
return frame;
}
static inline void * cpu_domain_intpri_sleep_frame_alloc_and_init(void)
{
const static cpu_domain_dev_regs_region_t regions[] = {
{ .start = INTPRI_CORE0_CPU_INT_ENABLE_REG, .end = INTPRI_CORE0_CPU_INT_TYPE_REG + 4 },
{ .start = INTPRI_CORE0_CPU_INT_PRI_0_REG, .end = INTPRI_CORE0_CPU_INT_THRESH_REG + 4 },
{ .start = INTPRI_CLOCK_GATE_REG, .end = INTPRI_CORE0_CPU_INT_CLEAR_REG + 4 },
};
return cpu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0]));
}
static inline void * cpu_domain_cache_config_sleep_frame_alloc_and_init(void)
{
const static cpu_domain_dev_regs_region_t regions[] = {
{ .start = CACHE_L1_CACHE_WRAP_AROUND_CTRL_REG, .end = CACHE_L1_CACHE_WRAP_AROUND_CTRL_REG + 4 }
};
return cpu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0]));
}
static inline void * cpu_domain_plic_sleep_frame_alloc_and_init(void)
{
const static cpu_domain_dev_regs_region_t regions[] = {
{ .start = PLIC_MXINT_ENABLE_REG, .end = PLIC_MXINT_CLAIM_REG + 4 },
{ .start = PLIC_MXINT_CONF_REG, .end = PLIC_MXINT_CONF_REG + 4 },
{ .start = PLIC_UXINT_ENABLE_REG, .end = PLIC_UXINT_CLAIM_REG + 4 },
{ .start = PLIC_UXINT_CONF_REG, .end = PLIC_UXINT_CONF_REG + 4 }
};
return cpu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0]));
}
esp_err_t esp_sleep_cpu_retention_init_impl(sleep_cpu_retention_t *sleep_cpu_retention_ptr)
{
if (sleep_cpu_retention_ptr->retent.critical_frame == NULL) {
void *frame = heap_caps_calloc(1, RV_SLEEP_CTX_FRMSZ, MALLOC_CAP_32BIT|MALLOC_CAP_INTERNAL);
if (frame == NULL) {
goto err;
}
sleep_cpu_retention_ptr->retent.critical_frame = (RvCoreCriticalSleepFrame *)frame;
rv_core_critical_regs_frame = (RvCoreCriticalSleepFrame *)frame;
}
if (sleep_cpu_retention_ptr->retent.non_critical_frame == NULL) {
void *frame = heap_caps_calloc(1, sizeof(RvCoreNonCriticalSleepFrame), MALLOC_CAP_32BIT|MALLOC_CAP_INTERNAL);
if (frame == NULL) {
goto err;
}
sleep_cpu_retention_ptr->retent.non_critical_frame = (RvCoreNonCriticalSleepFrame *)frame;
}
if (sleep_cpu_retention_ptr->retent.intpri_frame == NULL) {
void *frame = cpu_domain_intpri_sleep_frame_alloc_and_init();
if (frame == NULL) {
goto err;
}
sleep_cpu_retention_ptr->retent.intpri_frame = (cpu_domain_dev_sleep_frame_t *)frame;
}
if (sleep_cpu_retention_ptr->retent.cache_config_frame == NULL) {
void *frame = cpu_domain_cache_config_sleep_frame_alloc_and_init();
if (frame == NULL) {
goto err;
}
sleep_cpu_retention_ptr->retent.cache_config_frame = (cpu_domain_dev_sleep_frame_t *)frame;
}
if (sleep_cpu_retention_ptr->retent.plic_frame == NULL) {
void *frame = cpu_domain_plic_sleep_frame_alloc_and_init();
if (frame == NULL) {
goto err;
}
sleep_cpu_retention_ptr->retent.plic_frame = (cpu_domain_dev_sleep_frame_t *)frame;
}
return ESP_OK;
err:
esp_sleep_cpu_retention_deinit();
return ESP_ERR_NO_MEM;
}
esp_err_t esp_sleep_cpu_retention_deinit_impl(sleep_cpu_retention_t *sleep_cpu_retention_ptr)
{
if (sleep_cpu_retention_ptr->retent.critical_frame) {
heap_caps_free((void *)sleep_cpu_retention_ptr->retent.critical_frame);
sleep_cpu_retention_ptr->retent.critical_frame = NULL;
rv_core_critical_regs_frame = NULL;
}
if (sleep_cpu_retention_ptr->retent.non_critical_frame) {
heap_caps_free((void *)sleep_cpu_retention_ptr->retent.non_critical_frame);
sleep_cpu_retention_ptr->retent.non_critical_frame = NULL;
}
if (sleep_cpu_retention_ptr->retent.intpri_frame) {
heap_caps_free((void *)sleep_cpu_retention_ptr->retent.intpri_frame);
sleep_cpu_retention_ptr->retent.intpri_frame = NULL;
}
if (sleep_cpu_retention_ptr->retent.cache_config_frame) {
heap_caps_free((void *)sleep_cpu_retention_ptr->retent.cache_config_frame);
sleep_cpu_retention_ptr->retent.cache_config_frame = NULL;
}
if (sleep_cpu_retention_ptr->retent.plic_frame) {
heap_caps_free((void *)sleep_cpu_retention_ptr->retent.plic_frame);
sleep_cpu_retention_ptr->retent.plic_frame = NULL;
}
return ESP_OK;
}
@@ -0,0 +1,41 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __SLEEP_CPU_RETENTION_H__
#define __SLEEP_CPU_RETENTION_H__
#include "rvsleep-frames.h"
#include "esp_err.h"
typedef struct {
uint32_t start;
uint32_t end;
} cpu_domain_dev_regs_region_t;
typedef struct {
cpu_domain_dev_regs_region_t *region;
int region_num;
uint32_t *regs_frame;
} cpu_domain_dev_sleep_frame_t;
/**
* Internal structure which holds all requested light sleep cpu retention parameters
*/
typedef struct {
struct {
RvCoreCriticalSleepFrame *critical_frame;
RvCoreNonCriticalSleepFrame *non_critical_frame;
cpu_domain_dev_sleep_frame_t *intpri_frame;
cpu_domain_dev_sleep_frame_t *plic_frame;
cpu_domain_dev_sleep_frame_t *cache_config_frame;
} retent;
} sleep_cpu_retention_t;
esp_err_t esp_sleep_cpu_retention_init_impl(sleep_cpu_retention_t *sleep_cpu_retention_ptr);
esp_err_t esp_sleep_cpu_retention_deinit_impl(sleep_cpu_retention_t *sleep_cpu_retention_ptr);
#endif /* #ifndef __SLEEP_CPU_RETENTION_H__ */
@@ -0,0 +1,183 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include "esp_check.h"
#include "soc/intpri_reg.h"
#include "soc/cache_reg.h"
#include "soc/plic_reg.h"
#include "rvsleep-frames.h"
#include "sleep_cpu_retention.h"
extern RvCoreCriticalSleepFrame *rv_core_critical_regs_frame;
#define R_CONCAT(s1, s2) _R_CONCAT(s1, s2)
#define _R_CONCAT(s1, s2) s1 ## s2
#define CPU_DOMAIN_DEV_SZ0 (CPU_DOMAIN_DEV_END_ADDR0 - CPU_DOMAIN_DEV_START_ADDR0)
#define CPU_DOMAIN_DEV_SZ1 (CPU_DOMAIN_DEV_END_ADDR1 - CPU_DOMAIN_DEV_START_ADDR1)
#define CPU_DOMAIN_DEV_SZ2 (CPU_DOMAIN_DEV_END_ADDR2 - CPU_DOMAIN_DEV_START_ADDR2)
#define CPU_DOMAIN_DEV_SZ3 (CPU_DOMAIN_DEV_END_ADDR3 - CPU_DOMAIN_DEV_START_ADDR3)
#define CPU_DOMAIN_DEV_SZ4 (CPU_DOMAIN_DEV_END_ADDR4 - CPU_DOMAIN_DEV_START_ADDR4)
#define CPU_DOMAIN_DEV_SZ5 (CPU_DOMAIN_DEV_END_ADDR5 - CPU_DOMAIN_DEV_START_ADDR5)
#define CPU_DOMAIN_DEV_SZ6 (CPU_DOMAIN_DEV_END_ADDR6 - CPU_DOMAIN_DEV_START_ADDR6)
#define CPU_DOMAIN_DEV_SZ7 (CPU_DOMAIN_DEV_END_ADDR7 - CPU_DOMAIN_DEV_START_ADDR7)
#define CPU_DOMAIN_DEV_TOTAL_SZ(n) (R_CONCAT(__TOTAL_SZ, n))
#define __TOTAL_SZ0 (sizeof(cpu_domain_dev_sleep_frame_t))
#define __TOTAL_SZ1 ((__TOTAL_SZ0) + (sizeof(cpu_domain_dev_regs_region_t)) + CPU_DOMAIN_DEV_SZ0)
#define __TOTAL_SZ2 ((__TOTAL_SZ1) + (sizeof(cpu_domain_dev_regs_region_t)) + CPU_DOMAIN_DEV_SZ1)
#define __TOTAL_SZ3 ((__TOTAL_SZ2) + (sizeof(cpu_domain_dev_regs_region_t)) + CPU_DOMAIN_DEV_SZ2)
#define __TOTAL_SZ4 ((__TOTAL_SZ3) + (sizeof(cpu_domain_dev_regs_region_t)) + CPU_DOMAIN_DEV_SZ3)
#define __TOTAL_SZ5 ((__TOTAL_SZ4) + (sizeof(cpu_domain_dev_regs_region_t)) + CPU_DOMAIN_DEV_SZ4)
#define __TOTAL_SZ6 ((__TOTAL_SZ5) + (sizeof(cpu_domain_dev_regs_region_t)) + CPU_DOMAIN_DEV_SZ5)
#define __TOTAL_SZ7 ((__TOTAL_SZ6) + (sizeof(cpu_domain_dev_regs_region_t)) + CPU_DOMAIN_DEV_SZ6)
#define __TOTAL_SZ8 ((__TOTAL_SZ7) + (sizeof(cpu_domain_dev_regs_region_t)) + CPU_DOMAIN_DEV_SZ7)
static void * cpu_domain_dev_sleep_frame_init(const cpu_domain_dev_regs_region_t *regions, const int region_num, void * frame)
{
const int region_sz = sizeof(cpu_domain_dev_regs_region_t) * region_num;
int regs_frame_sz = 0;
for (int num = 0; num < region_num; num++) {
regs_frame_sz += regions[num].end - regions[num].start;
}
if (frame) {
cpu_domain_dev_regs_region_t *region = (cpu_domain_dev_regs_region_t *)(frame + sizeof(cpu_domain_dev_sleep_frame_t));
memcpy(region, regions, region_num * sizeof(cpu_domain_dev_regs_region_t));
void *regs_frame = frame + sizeof(cpu_domain_dev_sleep_frame_t) + region_sz;
memset(regs_frame, 0, regs_frame_sz);
*(cpu_domain_dev_sleep_frame_t *)frame = (cpu_domain_dev_sleep_frame_t) {
.region = region,
.region_num = region_num,
.regs_frame = (uint32_t *)regs_frame
};
}
return frame;
}
#undef CPU_DOMAIN_DEV_START_ADDR0
#undef CPU_DOMAIN_DEV_END_ADDR0
#undef CPU_DOMAIN_DEV_START_ADDR1
#undef CPU_DOMAIN_DEV_END_ADDR1
#undef CPU_DOMAIN_DEV_START_ADDR2
#undef CPU_DOMAIN_DEV_END_ADDR2
#define CPU_DOMAIN_DEV_START_ADDR0 (INTPRI_CORE0_CPU_INT_ENABLE_REG)
#define CPU_DOMAIN_DEV_END_ADDR0 (INTPRI_CORE0_CPU_INT_TYPE_REG + 4)
#define CPU_DOMAIN_DEV_START_ADDR1 (INTPRI_CORE0_CPU_INT_PRI_0_REG)
#define CPU_DOMAIN_DEV_END_ADDR1 (INTPRI_CORE0_CPU_INT_THRESH_REG + 4)
#define CPU_DOMAIN_DEV_START_ADDR2 (INTPRI_CLOCK_GATE_REG)
#define CPU_DOMAIN_DEV_END_ADDR2 (INTPRI_CORE0_CPU_INT_CLEAR_REG + 4)
static void * intpri_sleep_frame_init(void)
{
const static cpu_domain_dev_regs_region_t regions[] = {
{ .start = CPU_DOMAIN_DEV_START_ADDR0, .end = CPU_DOMAIN_DEV_END_ADDR0 },
{ .start = CPU_DOMAIN_DEV_START_ADDR1, .end = CPU_DOMAIN_DEV_END_ADDR1 },
{ .start = CPU_DOMAIN_DEV_START_ADDR2, .end = CPU_DOMAIN_DEV_END_ADDR2 },
};
static DRAM_ATTR uint8_t sleep_frame[CPU_DOMAIN_DEV_TOTAL_SZ(3)] __attribute__((aligned(4)));
return cpu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0]), sleep_frame);
}
#undef CPU_DOMAIN_DEV_START_ADDR0
#undef CPU_DOMAIN_DEV_END_ADDR0
#define CPU_DOMAIN_DEV_START_ADDR0 (CACHE_L1_CACHE_WRAP_AROUND_CTRL_REG)
#define CPU_DOMAIN_DEV_END_ADDR0 (CACHE_L1_CACHE_WRAP_AROUND_CTRL_REG + 4)
static void * cache_sleep_frame_init(void)
{
const static cpu_domain_dev_regs_region_t regions[] = {
{ .start = CPU_DOMAIN_DEV_START_ADDR0, .end = CPU_DOMAIN_DEV_END_ADDR0 }
};
static DRAM_ATTR uint8_t sleep_frame[CPU_DOMAIN_DEV_TOTAL_SZ(1)] __attribute__((aligned(4)));
return cpu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0]), sleep_frame);
}
#undef CPU_DOMAIN_DEV_START_ADDR0
#undef CPU_DOMAIN_DEV_END_ADDR0
#undef CPU_DOMAIN_DEV_START_ADDR1
#undef CPU_DOMAIN_DEV_END_ADDR1
#undef CPU_DOMAIN_DEV_START_ADDR2
#undef CPU_DOMAIN_DEV_END_ADDR2
#undef CPU_DOMAIN_DEV_START_ADDR3
#undef CPU_DOMAIN_DEV_END_ADDR3
#define CPU_DOMAIN_DEV_START_ADDR0 (PLIC_MXINT_ENABLE_REG)
#define CPU_DOMAIN_DEV_END_ADDR0 (PLIC_MXINT_CLAIM_REG + 4)
#define CPU_DOMAIN_DEV_START_ADDR1 (PLIC_MXINT_CONF_REG)
#define CPU_DOMAIN_DEV_END_ADDR1 (PLIC_MXINT_CONF_REG + 4)
#define CPU_DOMAIN_DEV_START_ADDR2 (PLIC_UXINT_ENABLE_REG)
#define CPU_DOMAIN_DEV_END_ADDR2 (PLIC_UXINT_CLAIM_REG + 4)
#define CPU_DOMAIN_DEV_START_ADDR3 (PLIC_UXINT_CONF_REG)
#define CPU_DOMAIN_DEV_END_ADDR3 (PLIC_UXINT_CONF_REG + 4)
static void * plic_sleep_frame_init(void)
{
const static cpu_domain_dev_regs_region_t regions[] = {
{ .start = PLIC_MXINT_ENABLE_REG, .end = PLIC_MXINT_CLAIM_REG + 4 },
{ .start = PLIC_MXINT_CONF_REG, .end = PLIC_MXINT_CONF_REG + 4 },
{ .start = PLIC_UXINT_ENABLE_REG, .end = PLIC_UXINT_CLAIM_REG + 4 },
{ .start = PLIC_UXINT_CONF_REG, .end = PLIC_UXINT_CONF_REG + 4 }
};
static DRAM_ATTR uint8_t sleep_frame[CPU_DOMAIN_DEV_TOTAL_SZ(4)] __attribute__((aligned(4)));
return cpu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0]), sleep_frame);
}
esp_err_t esp_sleep_cpu_retention_init_impl(sleep_cpu_retention_t *sleep_cpu_retention_ptr)
{
if (sleep_cpu_retention_ptr->retent.critical_frame == NULL) {
static DRAM_ATTR uint8_t rv_core_critical_regs[RV_SLEEP_CTX_FRMSZ] __attribute__((aligned(4)));
sleep_cpu_retention_ptr->retent.critical_frame = (RvCoreCriticalSleepFrame *) rv_core_critical_regs;
rv_core_critical_regs_frame = (RvCoreCriticalSleepFrame *) rv_core_critical_regs;
}
if (sleep_cpu_retention_ptr->retent.non_critical_frame == NULL) {
static DRAM_ATTR uint8_t rv_core_non_critical_regs[sizeof(RvCoreNonCriticalSleepFrame)] __attribute__((aligned(4)));
sleep_cpu_retention_ptr->retent.non_critical_frame = (RvCoreNonCriticalSleepFrame *) rv_core_non_critical_regs;
}
if (sleep_cpu_retention_ptr->retent.intpri_frame == NULL) {
void *frame = intpri_sleep_frame_init();
sleep_cpu_retention_ptr->retent.intpri_frame = (cpu_domain_dev_sleep_frame_t *)frame;
}
if (sleep_cpu_retention_ptr->retent.cache_config_frame == NULL) {
void *frame = cache_sleep_frame_init();
sleep_cpu_retention_ptr->retent.cache_config_frame = (cpu_domain_dev_sleep_frame_t *)frame;
}
if (sleep_cpu_retention_ptr->retent.plic_frame == NULL) {
void *frame = plic_sleep_frame_init();
sleep_cpu_retention_ptr->retent.plic_frame = (cpu_domain_dev_sleep_frame_t *)frame;
}
return ESP_OK;
}
esp_err_t esp_sleep_cpu_retention_deinit_impl(sleep_cpu_retention_t *sleep_cpu_retention_ptr)
{
if (sleep_cpu_retention_ptr->retent.critical_frame) {
sleep_cpu_retention_ptr->retent.critical_frame = NULL;
rv_core_critical_regs_frame = NULL;
}
if (sleep_cpu_retention_ptr->retent.non_critical_frame) {
sleep_cpu_retention_ptr->retent.non_critical_frame = NULL;
}
if (sleep_cpu_retention_ptr->retent.intpri_frame) {
sleep_cpu_retention_ptr->retent.intpri_frame = NULL;
}
if (sleep_cpu_retention_ptr->retent.cache_config_frame) {
sleep_cpu_retention_ptr->retent.cache_config_frame = NULL;
}
if (sleep_cpu_retention_ptr->retent.plic_frame) {
sleep_cpu_retention_ptr->retent.plic_frame = NULL;
}
if (sleep_cpu_retention_ptr->retent.clint_frame) {
sleep_cpu_retention_ptr->retent.clint_frame = NULL;
}
return ESP_OK;
}
@@ -10,6 +10,7 @@
#include <sys/lock.h>
#include <sys/param.h>
#include "sdkconfig.h"
#include "esp_attr.h"
#include "esp_check.h"
#include "esp_ipc_isr.h"
@@ -18,19 +19,14 @@
#include "esp_rom_crc.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_heap_caps.h"
#include "riscv/csr.h"
#include "soc/soc_caps.h"
#include "soc/intpri_reg.h"
#include "soc/cache_reg.h"
#include "soc/clint_reg.h"
#include "soc/clic_reg.h"
#include "soc/pcr_reg.h"
#include "soc/intpri_reg.h"
#include "soc/soc_caps.h"
#include "soc/rtc_periph.h"
#include "esp_private/esp_pmu.h"
#include "esp_private/sleep_cpu.h"
#include "esp_private/sleep_event.h"
#include "sdkconfig.h"
#include "esp32h4/rom/rtc.h"
#include "esp32h4/rom/cache.h"
+3 -3
View File
@@ -349,7 +349,7 @@ static IRAM_ATTR uint32_t modem_clock_get_module_deps(periph_module_t module)
#define ICG_NOGATING_SLEEP (BIT(PMU_HP_ICG_MODEM_CODE_SLEEP))
#define ICG_NOGATING_MODEM (BIT(PMU_HP_ICG_MODEM_CODE_MODEM))
#if !CONFIG_IDF_TARGET_ESP32H2
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
static const DRAM_ATTR uint32_t initial_gating_mode[MODEM_CLOCK_DOMAIN_MAX] = {
[MODEM_CLOCK_DOMAIN_MODEM_APB] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM,
[MODEM_CLOCK_DOMAIN_MODEM_PERIPH] = ICG_NOGATING_ACTIVE,
@@ -364,7 +364,7 @@ static const DRAM_ATTR uint32_t initial_gating_mode[MODEM_CLOCK_DOMAIN_MAX] = {
};
#endif
#if !CONFIG_IDF_TARGET_ESP32H2 //TODO: PM-92
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
static IRAM_ATTR void modem_clock_module_icg_map_init_all(void)
{
esp_os_enter_critical_safe(&MODEM_CLOCK_instance()->lock);
@@ -379,7 +379,7 @@ static IRAM_ATTR void modem_clock_module_icg_map_init_all(void)
void IRAM_ATTR modem_clock_module_enable(periph_module_t module)
{
assert(IS_MODEM_MODULE(module));
#if !CONFIG_IDF_TARGET_ESP32H2
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
modem_clock_module_icg_map_init_all();
#endif
uint32_t deps = modem_clock_get_module_deps(module);
@@ -86,6 +86,7 @@ void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, const pmu_hp_sys
pmu_ll_hp_set_dcm_mode (ctx->hal->dev, mode, anlg->bias.dcm_mode);
pmu_ll_hp_set_bias_xpd (ctx->hal->dev, mode, anlg->bias.xpd_bias);
pmu_ll_hp_set_trx_xpd (ctx->hal->dev, mode, anlg->bias.xpd_trx);
pmu_ll_hp_set_discnnt_dig_rtc (ctx->hal->dev, mode, anlg->bias.discnnt_dig_rtc);
pmu_ll_hp_set_current_power_off (ctx->hal->dev, mode, anlg->bias.pd_cur);
pmu_ll_hp_set_bias_sleep_enable (ctx->hal->dev, mode, anlg->bias.bias_sleep);
if (mode == PMU_MODE_HP_ACTIVE) {
@@ -113,6 +114,9 @@ void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, const pmu_hp_sys
pmu_ll_imm_update_dig_icg_switch(ctx->hal->dev, true);
pmu_ll_hp_set_sleep_protect_mode(ctx->hal->dev, PMU_SLEEP_PROTECT_HP_LP_SLEEP);
/* set dcdc ccm mode software enable */
pmu_ll_set_dcdc_ccm_sw_en(&PMU, true);
}
void pmu_lp_system_init(pmu_context_t *ctx, pmu_lp_mode_t mode, const pmu_lp_system_param_t *param)
@@ -135,6 +139,7 @@ void pmu_lp_system_init(pmu_context_t *ctx, pmu_lp_mode_t mode, const pmu_lp_sys
pmu_ll_lp_set_dcm_vset (ctx->hal->dev, mode, anlg->bias.dcm_vset);
pmu_ll_lp_set_dcm_mode (ctx->hal->dev, mode, anlg->bias.dcm_mode);
pmu_ll_lp_set_bias_xpd (ctx->hal->dev, mode, anlg->bias.xpd_bias);
pmu_ll_lp_set_discnnt_dig_rtc (ctx->hal->dev, mode, anlg->bias.discnnt_dig_rtc);
pmu_ll_lp_set_current_power_off (ctx->hal->dev, mode, anlg->bias.pd_cur);
pmu_ll_lp_set_bias_sleep_enable (ctx->hal->dev, mode, anlg->bias.bias_sleep);
}
@@ -166,6 +171,8 @@ static inline void pmu_power_domain_force_default(pmu_context_t *ctx)
/* Isolate all memory banks while sleeping, avoid memory leakage current */
pmu_ll_hp_set_memory_no_isolate (ctx->hal->dev, 0);
/* Disable memory force pu for memory pd during deep sleep */
pmu_ll_hp_set_memory_power_up (ctx->hal->dev, 0);
pmu_ll_lp_set_power_force_power_up (ctx->hal->dev, false);
pmu_ll_lp_set_power_force_no_reset (ctx->hal->dev, false);
@@ -194,6 +201,7 @@ static void pmu_hp_system_init_default(pmu_context_t *ctx)
{
assert(ctx);
for (pmu_hp_mode_t mode = PMU_MODE_HP_ACTIVE; mode < PMU_MODE_HP_MAX; mode++) {
if (mode == PMU_MODE_HP_MODEM) continue;
pmu_hp_system_analog_param_t analog = {};
pmu_hp_system_param_t param = {.analog = &analog};
@@ -228,8 +236,12 @@ static void pmu_lp_system_init_default(pmu_context_t *ctx)
void pmu_init()
{
/* No peripheral reg i2c power up required on the target */
pmu_hp_system_init_default(PMU_instance());
pmu_lp_system_init_default(PMU_instance());
pmu_power_domain_force_default(PMU_instance());
/* No peripheral reg i2c power up required on the target */
#if !CONFIG_IDF_ENV_FPGA
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_EN_I2C_RTC_DREG, 0);
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_EN_I2C_DIG_DREG, 0);
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_EN_I2C_RTC_DREG_SLP, 0);
@@ -237,22 +249,7 @@ void pmu_init()
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OR_XPD_RTC_REG, 0);
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OR_XPD_DIG_REG, 0);
REGI2C_WRITE_MASK(I2C_PMU, I2C_PMU_OR_XPD_TRX, 0);
WRITE_PERI_REG(PMU_POWER_PD_TOP_CNTL_REG, 0);
WRITE_PERI_REG(PMU_POWER_PD_HPAON_CNTL_REG, 0);
WRITE_PERI_REG(PMU_POWER_PD_HPCPU_CNTL_REG, 0);
WRITE_PERI_REG(PMU_POWER_PD_HPPERI_RESERVE_REG, 0);
WRITE_PERI_REG(PMU_POWER_PD_HPWIFI_CNTL_REG, 0);
WRITE_PERI_REG(PMU_POWER_PD_LPPERI_CNTL_REG, 0);
pmu_hp_system_init_default(PMU_instance());
pmu_lp_system_init_default(PMU_instance());
pmu_power_domain_force_default(PMU_instance());
// default ccm mode
REG_SET_FIELD(PMU_DCM_CTRL_REG, PMU_DCDC_CCM_SW_EN, 1);
REG_SET_FIELD(PMU_HP_ACTIVE_BIAS_REG, PMU_HP_ACTIVE_DCDC_CCM_ENB, 0);
#endif
#if !CONFIG_IDF_ENV_FPGA
// TODO: IDF-11548
@@ -39,29 +39,6 @@ ESP_HW_LOG_ATTR_TAG(TAG, "pmu_param");
.xpd_bbpll_i2c = 1, \
.xpd_bbpll = 1 \
}, \
.xtal = { \
.xpd_xtalx2 = 1, \
.xpd_xtal = 1 \
} \
}
#define PMU_HP_MODEM_POWER_CONFIG_DEFAULT() { \
.dig_power = { \
.vdd_flash_mode = 0, \
.mem_dslp = 1, \
.mem_pd_en = 0, \
.wifi_pd_en = 0, \
.cpu_pd_en = 1, \
.aon_pd_en = 0, \
.top_pd_en = 0 \
}, \
.clk_power = { \
.i2c_iso_en = 0, \
.i2c_retention = 0, \
.xpd_bb_i2c = 1, \
.xpd_bbpll_i2c = 1, \
.xpd_bbpll = 1 \
}, \
.xtal = { \
.xpd_xtalx2 = 0, \
.xpd_xtal = 1 \
@@ -70,7 +47,7 @@ ESP_HW_LOG_ATTR_TAG(TAG, "pmu_param");
#define PMU_HP_SLEEP_POWER_CONFIG_DEFAULT() { \
.dig_power = { \
.vdd_flash_mode = 1, \
.vdd_flash_mode = 0, \
.mem_dslp = 0, \
.mem_pd_en = 0, \
.wifi_pd_en = 1, \
@@ -95,7 +72,7 @@ const pmu_hp_system_power_param_t * pmu_hp_system_power_param_default(pmu_hp_mod
{
static const pmu_hp_system_power_param_t hp_power[] = {
PMU_HP_ACTIVE_POWER_CONFIG_DEFAULT(),
PMU_HP_MODEM_POWER_CONFIG_DEFAULT(),
{{}, {}, {}}, // No Modem State
PMU_HP_SLEEP_POWER_CONFIG_DEFAULT()
};
assert(mode < ARRAY_SIZE(hp_power));
@@ -105,9 +82,7 @@ const pmu_hp_system_power_param_t * pmu_hp_system_power_param_default(pmu_hp_mod
#define PMU_HP_ACTIVE_CLOCK_CONFIG_DEFAULT() { \
.icg_func = 0xffffffff, \
.icg_apb = 0xffffffff, \
.icg_modem = { \
.code = PMU_HP_ICG_MODEM_CODE_ACTIVE \
}, \
.icg_modem = {}, \
.sysclk = { \
.dig_sysclk_nodiv = 0, \
.icg_sysclk_en = 1, \
@@ -117,27 +92,10 @@ const pmu_hp_system_power_param_t * pmu_hp_system_power_param_default(pmu_hp_mod
} \
}
#define PMU_HP_MODEM_CLOCK_CONFIG_DEFAULT() { \
.icg_func = 0, \
.icg_apb = 0, \
.icg_modem = { \
.code = PMU_HP_ICG_MODEM_CODE_MODEM \
}, \
.sysclk = { \
.dig_sysclk_nodiv = 0, \
.icg_sysclk_en = 1, \
.sysclk_slp_sel = 1, \
.icg_slp_sel = 1, \
.dig_sysclk_sel = SOC_CPU_CLK_SRC_PLL \
} \
}
#define PMU_HP_SLEEP_CLOCK_CONFIG_DEFAULT() { \
.icg_func = 0, \
.icg_apb = 0, \
.icg_modem = { \
.code = PMU_HP_ICG_MODEM_CODE_SLEEP \
}, \
.icg_modem = {}, \
.sysclk = { \
.dig_sysclk_nodiv = 0, \
.icg_sysclk_en = 0, \
@@ -151,7 +109,7 @@ const pmu_hp_system_clock_param_t * pmu_hp_system_clock_param_default(pmu_hp_mod
{
static const pmu_hp_system_clock_param_t hp_clock[] = {
PMU_HP_ACTIVE_CLOCK_CONFIG_DEFAULT(),
PMU_HP_MODEM_CLOCK_CONFIG_DEFAULT(),
{0, 0, {}, {}}, // No Modem State
PMU_HP_SLEEP_CLOCK_CONFIG_DEFAULT()
};
assert(mode < ARRAY_SIZE(hp_clock));
@@ -169,17 +127,6 @@ const pmu_hp_system_clock_param_t * pmu_hp_system_clock_param_default(pmu_hp_mod
} \
}
#define PMU_HP_MODEM_DIGITAL_CONFIG_DEFAULT() { \
.syscntl = { \
.uart_wakeup_en = 1, \
.lp_pad_hold_all = 0, \
.hp_pad_hold_all = 0, \
.dig_pad_slp_sel = 1, \
.dig_pause_wdt = 1, \
.dig_cpu_stall = 1 \
} \
}
#define PMU_HP_SLEEP_DIGITAL_CONFIG_DEFAULT() { \
.syscntl = { \
.uart_wakeup_en = 1, \
@@ -195,7 +142,7 @@ const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp
{
static const pmu_hp_system_digital_param_t hp_digital[] = {
PMU_HP_ACTIVE_DIGITAL_CONFIG_DEFAULT(),
PMU_HP_MODEM_DIGITAL_CONFIG_DEFAULT(),
{{}}, // No Modem State,
PMU_HP_SLEEP_DIGITAL_CONFIG_DEFAULT()
};
assert(mode < ARRAY_SIZE(hp_digital));
@@ -204,12 +151,12 @@ const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp
#define PMU_HP_ACTIVE_ANALOG_CONFIG_DEFAULT() { \
.bias = { \
.dcdc_ccm_enb = 1, \
.dcdc_ccm_enb = 0, \
.dcdc_clear_rdy = 0, \
.dig_reg_dpcur_bias = 2, \
.dig_reg_dsfmos = 10, \
.dcm_vset = 22, \
.dcm_mode = 2, \
.dcm_vset = 24, \
.dcm_mode = 3, \
.xpd_trx = 1, \
.xpd_bias = 1, \
.discnnt_dig_rtc = 0, \
@@ -234,34 +181,6 @@ const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp
} \
}
#define PMU_HP_MODEM_ANALOG_CONFIG_DEFAULT() { \
.bias = { \
.dcdc_ccm_enb = 1, \
.dcdc_clear_rdy = 0, \
.dig_reg_dpcur_bias = 3, \
.dig_reg_dsfmos = 12, \
.dcm_vset = 20, \
.dcm_mode = 1, \
.xpd_trx = 1, \
.xpd_bias = 1, \
.discnnt_dig_rtc = 0, \
.pd_cur = 0, \
.bias_sleep = 0 \
}, \
.regulator0 = { \
.power_det_bypass = 0, \
.slp_mem_xpd = 0, \
.slp_logic_xpd = 0, \
.xpd = 1, \
.slp_mem_dbias = 0, \
.slp_logic_dbias = 0, \
.dbias = HP_CALI_DBIAS_DEFAULT \
}, \
.regulator1 = { \
.drv_b = 0x1b \
} \
}
#define PMU_HP_SLEEP_ANALOG_CONFIG_DEFAULT() { \
.bias = { \
.dcdc_ccm_enb = 1, \
@@ -269,7 +188,7 @@ const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp
.dig_reg_dpcur_bias = 1, \
.dig_reg_dsfmos = 8, \
.dcm_vset = 0, \
.dcm_mode = 0, \
.dcm_mode = 3, \
.xpd_trx = 0, \
.xpd_bias = 0, \
.discnnt_dig_rtc = 0, \
@@ -286,7 +205,7 @@ const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp
.dbias = 0 \
}, \
.regulator1 = { \
.drv_b = 0x13 \
.drv_b = 26 \
} \
}
@@ -294,7 +213,7 @@ const pmu_hp_system_analog_param_t * pmu_hp_system_analog_param_default(pmu_hp_m
{
static const pmu_hp_system_analog_param_t hp_analog[] = {
PMU_HP_ACTIVE_ANALOG_CONFIG_DEFAULT(),
PMU_HP_MODEM_ANALOG_CONFIG_DEFAULT(),
{{}, {}, {}}, // No modem state
PMU_HP_SLEEP_ANALOG_CONFIG_DEFAULT()
};
assert(mode < ARRAY_SIZE(hp_analog));
@@ -317,16 +236,6 @@ const pmu_hp_system_analog_param_t * pmu_hp_system_analog_param_default(pmu_hp_m
.backup_clk = 0xffffffff, \
}
#define PMU_HP_MODEM_RETENTION_CONFIG_DEFAULT() { \
.retention = { \
.hp_sleep2modem_backup_modem_clk_code = 3, \
.hp_sleep2modem_backup_clk_sel = 0, \
.hp_sleep2modem_backup_mode = PMU_HP_RETENTION_REGDMA_CONFIG(0, 1), \
.hp_sleep2modem_backup_en = 0, \
}, \
.backup_clk = 0xffffffff, \
}
#define PMU_HP_SLEEP_RETENTION_CONFIG_DEFAULT() { \
.retention = { \
.hp_modem2sleep_backup_modem_clk_code = 3, \
@@ -345,7 +254,7 @@ const pmu_hp_system_retention_param_t * pmu_hp_system_retention_param_default(pm
{
static const pmu_hp_system_retention_param_t hp_retention[] = {
PMU_HP_ACTIVE_RETENTION_CONFIG_DEFAULT(),
PMU_HP_MODEM_RETENTION_CONFIG_DEFAULT(),
{{}, 0}, // No Modem
PMU_HP_SLEEP_RETENTION_CONFIG_DEFAULT()
};
assert(mode < ARRAY_SIZE(hp_retention));
@@ -356,7 +265,7 @@ const pmu_hp_system_retention_param_t * pmu_hp_system_retention_param_default(pm
/** LP system default parameter */
#define PMU_LP_ACTIVE_POWER_CONFIG_DEFAULT() { \
.dig_power = { \
.vdd_io_mode = 3, \
.vdd_io_mode = 4, \
.bod_source_sel = 0, \
.vddbat_mode = 2, \
.mem_dslp = 0, \
@@ -365,7 +274,7 @@ const pmu_hp_system_retention_param_t * pmu_hp_system_retention_param_default(pm
.clk_power = { \
.xpd_lppll = 0, \
.xpd_xtal32k = 1, \
.xpd_rc32k = 1, \
.xpd_rc32k = 0, \
.xpd_fosc = 1, \
.pd_osc = 0 \
} \
@@ -373,7 +282,7 @@ const pmu_hp_system_retention_param_t * pmu_hp_system_retention_param_default(pm
#define PMU_LP_SLEEP_POWER_CONFIG_DEFAULT() { \
.dig_power = { \
.vdd_io_mode = 5, \
.vdd_io_mode = 3, \
.bod_source_sel = 0, \
.vddbat_mode = 1, \
.mem_dslp = 1, \
@@ -416,14 +325,14 @@ const pmu_lp_system_power_param_t * pmu_lp_system_power_param_default(pmu_lp_mod
#define PMU_LP_SLEEP_ANALOG_CONFIG_DEFAULT() { \
.bias = { \
.dcdc_ccm_enb = 0, \
.dcdc_ccm_enb = 1, \
.dcdc_clear_rdy = 0, \
.dig_reg_dpcur_bias = 3, \
.dig_reg_dsfmos = 5, \
.dcm_vset = 0, \
.dcm_mode = 0, \
.dcm_mode = 3, \
.xpd_bias = 0, \
.discnnt_dig_rtc = 0, \
.discnnt_dig_rtc = 1, \
.pd_cur = 1, \
.bias_sleep = 1 \
}, \
@@ -434,7 +343,7 @@ const pmu_lp_system_power_param_t * pmu_lp_system_power_param_default(pmu_lp_mod
.dbias = 1 \
}, \
.regulator1 = { \
.drv_b = 9 \
.drv_b = 0 \
} \
}
@@ -25,6 +25,8 @@
ESP_HW_LOG_ATTR_TAG(TAG, "pmu_sleep");
static bool s_pmu_sleep_regdma_backup_enabled;
#define HP(state) (PMU_MODE_HP_ ## state)
#define LP(state) (PMU_MODE_LP_ ## state)
@@ -51,17 +53,23 @@ uint32_t get_slp_lp_dbias(void)
void pmu_sleep_enable_regdma_backup(void)
{
assert(PMU_instance()->hal);
/* entry 0, 1, 2 is used by pmu HP_SLEEP and HP_ACTIVE, HP_SLEEP
* and HP_MODEM or HP_MODEM and HP_ACTIVE states switching,
* respectively. entry 3 is reserved, not used yet! */
pmu_hal_hp_set_sleep_active_backup_enable(PMU_instance()->hal);
if (!s_pmu_sleep_regdma_backup_enabled){
assert(PMU_instance()->hal);
/* entry 0, 1, 2 is used by pmu HP_SLEEP and HP_ACTIVE, HP_SLEEP
* and HP_MODEM or HP_MODEM and HP_ACTIVE states switching,
* respectively. entry 3 is reserved, not used yet! */
pmu_hal_hp_set_sleep_active_backup_enable(PMU_instance()->hal);
s_pmu_sleep_regdma_backup_enabled = true;
}
}
void pmu_sleep_disable_regdma_backup(void)
{
assert(PMU_instance()->hal);
pmu_hal_hp_set_sleep_active_backup_disable(PMU_instance()->hal);
if (s_pmu_sleep_regdma_backup_enabled) {
assert(PMU_instance()->hal);
pmu_hal_hp_set_sleep_active_backup_disable(PMU_instance()->hal);
s_pmu_sleep_regdma_backup_enabled = false;
}
}
uint32_t pmu_sleep_calculate_hw_wait_time(uint32_t sleep_flags, soc_rtc_slow_clk_src_t slowclk_src, uint32_t slowclk_period, uint32_t fastclk_period)
@@ -79,17 +87,14 @@ uint32_t pmu_sleep_calculate_hw_wait_time(uint32_t sleep_flags, soc_rtc_slow_clk
/* HP core hardware wait time, microsecond */
const int hp_digital_power_up_wait_time_us = mc->hp.power_supply_wait_time_us + mc->hp.power_up_wait_time_us;
if (sleep_flags & PMU_SLEEP_PD_TOP) {
mc->hp.regdma_s2a_work_time_us = PMU_REGDMA_S2A_WORK_TIME_PD_TOP_US;
} else {
mc->hp.regdma_s2a_work_time_us = PMU_REGDMA_S2A_WORK_TIME_PU_TOP_US;
}
const int hp_regdma_wait_time_us = mc->hp.regdma_s2a_work_time_us;
const int hp_control_wait_time_us = mc->hp.isolate_wait_time_us + mc->hp.reset_wait_time_us;
const int hp_regdma_wait_time_us = s_pmu_sleep_regdma_backup_enabled ? mc->hp.regdma_s2a_work_time_us : 0;
/* If XTAL is not used as RTC_FAST clock source, it is started in HP_SLEEP -> HP_ACTIVE stage and the clock waiting time is counted into hp_hw_wait_time */
const int hp_clock_wait_time_us = ((sleep_flags & PMU_SLEEP_PD_XTAL) && !(sleep_flags & RTC_SLEEP_XTAL_AS_RTC_FAST)) \
? mc->hp.xtal_wait_stable_time_us + mc->hp.pll_wait_stable_time_us \
: mc->hp.pll_wait_stable_time_us;
const int hp_hw_wait_time_us = mc->hp.analog_wait_time_us + hp_digital_power_up_wait_time_us + hp_regdma_wait_time_us + hp_clock_wait_time_us;
const int hp_hw_wait_time_us = mc->hp.analog_wait_time_us + hp_digital_power_up_wait_time_us + hp_clock_wait_time_us \
+ hp_regdma_wait_time_us + hp_control_wait_time_us;
const int rf_on_protect_time_us = 0;
const int total_hw_wait_time_us = lp_hw_wait_time_us + hp_hw_wait_time_us;
@@ -115,11 +120,15 @@ static inline pmu_sleep_param_config_t * pmu_sleep_param_config_default(
param->hp_sys.digital_power_supply_wait_cycle = rtc_time_us_to_fastclk(mc->hp.power_supply_wait_time_us, fastclk_period);
param->hp_sys.digital_power_up_wait_cycle = rtc_time_us_to_fastclk(mc->hp.power_up_wait_time_us, fastclk_period);
param->hp_sys.pll_stable_wait_cycle = rtc_time_us_to_fastclk(mc->hp.pll_wait_stable_time_us, fastclk_period);
param->hp_sys.isolate_wait_cycle = rtc_time_us_to_fastclk(mc->hp.isolate_wait_time_us, fastclk_period);
param->hp_sys.reset_wait_cycle = rtc_time_us_to_fastclk(mc->hp.reset_wait_time_us, fastclk_period);
param->lp_sys.min_slp_slow_clk_cycle = rtc_time_us_to_slowclk(mc->lp.min_slp_time_us, slowclk_period);
param->lp_sys.analog_wait_target_cycle = rtc_time_us_to_slowclk(mc->lp.analog_wait_time_us, slowclk_period);
param->lp_sys.digital_power_supply_wait_cycle = rtc_time_us_to_fastclk(mc->lp.power_supply_wait_time_us, fastclk_period);
param->lp_sys.digital_power_up_wait_cycle = rtc_time_us_to_fastclk(mc->lp.power_up_wait_time_us, fastclk_period);
param->lp_sys.isolate_wait_cycle = rtc_time_us_to_fastclk(mc->lp.isolate_wait_time_us, fastclk_period);
param->lp_sys.reset_wait_cycle = rtc_time_us_to_fastclk(mc->lp.reset_wait_time_us, fastclk_period);
if (power->hp_sys.xtal.xpd_xtal) {
param->hp_lp.xtal_stable_wait_slow_clk_cycle = rtc_time_us_to_slowclk(mc->lp.xtal_wait_stable_time_us, slowclk_period);
@@ -184,6 +193,12 @@ static void pmu_sleep_power_init(pmu_context_t *ctx, const pmu_sleep_power_confi
pmu_ll_hp_set_clk_power(ctx->hal->dev, HP(SLEEP), power->hp_sys.clk_power.val);
pmu_ll_hp_set_xtal_xpd (ctx->hal->dev, HP(SLEEP), power->hp_sys.xtal.xpd_xtal);
if (dslp) {
pmu_ll_hp_set_memory_power_on_mask(ctx->hal->dev, 0);
} else {
pmu_ll_hp_set_memory_power_on_mask(ctx->hal->dev, 0xf);
}
pmu_ll_lp_set_dig_power(ctx->hal->dev, LP(ACTIVE), power->lp_sys[LP(ACTIVE)].dig_power.val);
pmu_ll_lp_set_clk_power(ctx->hal->dev, LP(ACTIVE), power->lp_sys[LP(ACTIVE)].clk_power.val);
@@ -204,19 +219,21 @@ static void pmu_sleep_digital_init(pmu_context_t *ctx, const pmu_sleep_digital_c
static void pmu_sleep_analog_init(pmu_context_t *ctx, const pmu_sleep_analog_config_t *analog, bool dslp)
{
assert(ctx->hal);
pmu_ll_hp_set_current_power_off (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.pd_cur);
pmu_ll_hp_set_bias_sleep_enable (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.bias_sleep);
pmu_ll_hp_set_regulator_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.xpd);
pmu_ll_hp_set_regulator_dbias (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.dbias);
pmu_ll_hp_set_regulator_driver_bar (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.drv_b);
pmu_ll_hp_set_trx_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.xpd_trx);
pmu_ll_lp_set_current_power_off (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.pd_cur);
pmu_ll_lp_set_bias_sleep_enable (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.bias_sleep);
pmu_ll_lp_set_regulator_slp_xpd (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.slp_xpd);
pmu_ll_lp_set_regulator_xpd (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.xpd);
pmu_ll_lp_set_regulator_sleep_dbias(ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.slp_dbias);
pmu_ll_lp_set_regulator_dbias (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.dbias);
pmu_ll_lp_set_regulator_driver_bar (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.drv_b);
pmu_ll_hp_set_current_power_off (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.pd_cur);
pmu_ll_hp_set_bias_sleep_enable (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.bias_sleep);
pmu_ll_hp_set_regulator_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.xpd);
pmu_ll_hp_set_regulator_dbias (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.dbias);
pmu_ll_hp_set_regulator_driver_bar (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.drv_b);
pmu_ll_hp_set_trx_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.xpd_trx);
pmu_ll_lp_set_current_power_off (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.pd_cur);
pmu_ll_lp_set_bias_sleep_enable (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.bias_sleep);
pmu_ll_lp_set_regulator_slp_xpd (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.slp_xpd);
pmu_ll_lp_set_regulator_xpd (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.xpd);
pmu_ll_lp_set_regulator_sleep_dbias (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.slp_dbias);
pmu_ll_lp_set_regulator_dbias (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.dbias);
pmu_ll_lp_set_regulator_driver_bar (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.drv_b);
pmu_ll_lp_set_dcm_vset (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.dcm_vset);
pmu_ll_lp_set_dcm_mode (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.dcm_mode);
}
static void pmu_sleep_param_init(pmu_context_t *ctx, const pmu_sleep_param_config_t *param, bool dslp)
@@ -41,9 +41,8 @@ extern "C" {
#define PMU_HP_DBIAS_LIGHTSLEEP_0V6_DEFAULT 1
#define PMU_LP_DBIAS_SLEEP_0V7_DEFAULT 6
#define PMU_REGDMA_S2A_WORK_TIME_PD_TOP_US 0
// The current value of this depends on the restoration time overhead of the longest chain in regdma
#define PMU_REGDMA_S2A_WORK_TIME_PU_TOP_US 390
#define PMU_REGDMA_S2A_WORK_TIME_US 520
#define PMU_REGDMA_A2S_WORK_TIME_US 180
// FOR DEEPSLEEP
#define PMU_HP_XPD_DEEPSLEEP 0
@@ -288,7 +287,7 @@ typedef struct {
#define PMU_SLEEP_POWER_CONFIG_DEFAULT(sleep_flags) { \
.hp_sys = { \
.dig_power = { \
.vdd_flash_mode = 3, \
.vdd_flash_mode = ((sleep_flags) & PMU_SLEEP_PD_VDDSDIO) ? 1 : 3, \
.wifi_pd_en = ((sleep_flags) & PMU_SLEEP_PD_MODEM) ? 1 : 0,\
.cpu_pd_en = ((sleep_flags) & PMU_SLEEP_PD_CPU) ? 1 : 0,\
.top_pd_en = ((sleep_flags) & PMU_SLEEP_PD_TOP) ? 1 : 0,\
@@ -309,7 +308,7 @@ typedef struct {
}, \
.lp_sys[PMU_MODE_LP_ACTIVE] = { \
.dig_power = { \
.vdd_io_mode = 5, \
.vdd_io_mode = 4, \
.bod_source_sel = 0, \
.vddbat_mode = 0, \
.peri_pd_en = 0, \
@@ -324,7 +323,7 @@ typedef struct {
}, \
.lp_sys[PMU_MODE_LP_SLEEP] = { \
.dig_power = { \
.vdd_io_mode = 11, \
.vdd_io_mode = 4, \
.bod_source_sel = 0, \
.vddbat_mode = 1, \
.peri_pd_en = ((sleep_flags) & PMU_SLEEP_PD_LP_PERIPH) ? 1 : 0,\
@@ -381,7 +380,7 @@ typedef struct {
.dig_reg_dpcur_bias = 2, \
.dig_reg_dsfmos = 10, \
.dcm_vset = 29, \
.dcm_mode = 2, \
.dcm_mode = 3, \
.xpd_trx = PMU_XPD_TRX_SLEEP_DEFAULT, \
.xpd_bias = 1, \
.discnnt_dig_rtc = 0, \
@@ -408,15 +407,15 @@ typedef struct {
}, \
.lp_sys[PMU_MODE_LP_SLEEP] = { \
.analog = { \
.dcdc_ccm_enb = 0, \
.dcdc_ccm_enb = 1, \
.dcdc_clear_rdy = 0, \
.dig_reg_dpcur_bias = 0, \
.dig_reg_dsfmos = 0, \
.dcm_vset = 0, \
.dcm_mode = 0, \
.dcm_mode = 3, \
.xpd_bias = 1, \
.discnnt_dig_rtc = 1, \
.drv_b = PMU_LP_DRVB_DEEPSLEEP, \
.drv_b = PMU_LP_DRVB_LIGHTSLEEP, \
.pd_cur = PMU_PD_CUR_SLEEP_DEFAULT, \
.bias_sleep = PMU_BIASSLP_SLEEP_DEFAULT, \
.slp_xpd = PMU_LP_SLP_XPD_SLEEP_DEFAULT, \
@@ -430,12 +429,12 @@ typedef struct {
#define PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(sleep_flags) { \
.hp_sys = { \
.analog = { \
.dcdc_ccm_enb = 0, \
.dcdc_ccm_enb = 1, \
.dcdc_clear_rdy = 0, \
.dig_reg_dpcur_bias = 0, \
.dig_reg_dsfmos = 5, \
.dcm_vset = 10, \
.dcm_mode = 0, \
.dcm_mode = 3, \
.xpd_trx = PMU_XPD_TRX_SLEEP_DEFAULT, \
.xpd_bias = 0, \
.discnnt_dig_rtc = 0, \
@@ -462,12 +461,12 @@ typedef struct {
}, \
.lp_sys[PMU_MODE_LP_SLEEP] = { \
.analog = { \
.dcdc_ccm_enb = 0, \
.dcdc_ccm_enb = 1, \
.dcdc_clear_rdy = 0, \
.dig_reg_dpcur_bias = 0, \
.dig_reg_dsfmos = 0, \
.dcm_vset = 0, \
.dcm_mode = 0, \
.dcm_mode = 3, \
.xpd_bias = 1, \
.discnnt_dig_rtc = 1, \
.drv_b = PMU_LP_DRVB_DEEPSLEEP, \
@@ -543,7 +542,7 @@ typedef struct pmu_sleep_machine_constant {
#define PMU_SLEEP_MC_DEFAULT() { \
.lp = { \
.min_slp_time_us = 450, \
.analog_wait_time_us = 154, \
.analog_wait_time_us = 100, \
.xtal_wait_stable_time_us = 250, \
.clk_switch_cycle = 1, \
.clk_power_on_wait_cycle = 1, \
@@ -554,13 +553,13 @@ typedef struct pmu_sleep_machine_constant {
}, \
.hp = { \
.min_slp_time_us = 450, \
.analog_wait_time_us = 154, \
.analog_wait_time_us = 1600, \
.isolate_wait_time_us = 1, \
.reset_wait_time_us = 1, \
.power_supply_wait_time_us = 2, \
.power_up_wait_time_us = 2, \
.regdma_s2a_work_time_us = PMU_REGDMA_S2A_WORK_TIME_PD_TOP_US, \
.regdma_a2s_work_time_us = 0, \
.regdma_s2a_work_time_us = PMU_REGDMA_S2A_WORK_TIME_US, \
.regdma_a2s_work_time_us = PMU_REGDMA_A2S_WORK_TIME_US, \
.xtal_wait_stable_time_us = 250, \
.pll_wait_stable_time_us = 1 \
} \
@@ -205,10 +205,7 @@ uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period)
uint64_t rtc_time_get(void)
{
ESP_EARLY_LOGW(TAG, "rtc_timer has not been implemented yet");
return 0;
// TODO: [ESP32H21] IDF-11512
// return lp_timer_hal_get_cycle_count();
return lp_timer_hal_get_cycle_count();
}
uint32_t rtc_clk_freq_cal(uint32_t cal_val)
@@ -173,6 +173,7 @@ static inline void pmu_power_domain_force_default(pmu_context_t *ctx)
}
/* Isolate all memory banks while sleeping, avoid memory leakage current */
pmu_ll_hp_set_memory_no_isolate (ctx->hal->dev, 0);
/* Disable memory force pu for memory pd during deep sleep */
pmu_ll_hp_set_memory_power_up (ctx->hal->dev, 0);
pmu_ll_lp_set_power_force_power_up (ctx->hal->dev, false);
@@ -42,7 +42,7 @@ static __attribute__((unused)) const char *TAG = "pmu_param";
.xpd_bbpll = 1 \
}, \
.xtal = { \
.xpd_xtalx2 = 1, \
.xpd_xtalx2 = 0, \
.xpd_xtal = 1 \
} \
}
@@ -434,7 +434,7 @@ const pmu_lp_system_power_param_t * pmu_lp_system_power_param_default(pmu_lp_mod
.dcm_mode = 3, \
.dcm_vset = 0, \
.xpd_bias = 0, \
.discnnt_dig_rtc = 0, \
.discnnt_dig_rtc = 1, \
.pd_cur = 1, \
.bias_sleep = 1, \
}, \
@@ -140,9 +140,6 @@ const pmu_sleep_config_t* pmu_sleep_config_default(
config->param = *pmu_sleep_param_config_default(&param_default, &power_default, sleep_flags, adjustment, slowclk_period, fastclk_period);
if (dslp) {
power_default.hp_sys.memory.mem0_mask = 0;
power_default.hp_sys.memory.mem1_mask = 0;
power_default.hp_sys.memory.mem2_mask = 0;
config->param.lp_sys.analog_wait_target_cycle = rtc_time_us_to_slowclk(PMU_LP_ANALOG_WAIT_TARGET_TIME_DSLP_US, slowclk_period);
pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(sleep_flags);
config->analog = analog_default;
@@ -177,14 +174,18 @@ static void pmu_sleep_power_init(pmu_context_t *ctx, const pmu_sleep_power_confi
pmu_ll_hp_set_clk_power(ctx->hal->dev, HP(SLEEP), power->hp_sys.clk_power.val);
pmu_ll_hp_set_xtal_xpd (ctx->hal->dev, HP(SLEEP), power->hp_sys.xtal.xpd_xtal);
if (dslp) {
pmu_ll_hp_set_memory_power_on_mask(ctx->hal->dev, 0);
} else {
pmu_ll_hp_set_memory_power_on_mask(ctx->hal->dev, 0xf);
}
pmu_ll_lp_set_dig_power(ctx->hal->dev, LP(ACTIVE), power->lp_sys[LP(ACTIVE)].dig_power.val);
pmu_ll_lp_set_clk_power(ctx->hal->dev, LP(ACTIVE), power->lp_sys[LP(ACTIVE)].clk_power.val);
pmu_ll_lp_set_dig_power(ctx->hal->dev, LP(SLEEP), power->lp_sys[LP(SLEEP)].dig_power.val);
pmu_ll_lp_set_clk_power(ctx->hal->dev, LP(SLEEP), power->lp_sys[LP(SLEEP)].clk_power.val);
pmu_ll_lp_set_xtal_xpd (ctx->hal->dev, LP(SLEEP), power->lp_sys[LP(SLEEP)].xtal.xpd_xtal);
pmu_ll_hp_set_memory_power_on_mask(ctx->hal->dev, power->hp_sys.memory.mem0_mask, power->hp_sys.memory.mem1_mask, power->hp_sys.memory.mem2_mask);
}
static void pmu_sleep_digital_init(pmu_context_t *ctx, const pmu_sleep_digital_config_t *dig)
@@ -210,14 +211,8 @@ static void pmu_sleep_analog_init(pmu_context_t *ctx, const pmu_sleep_analog_con
pmu_ll_lp_set_regulator_dbias (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.dbias);
pmu_ll_lp_set_regulator_driver_bar (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.drv_b);
pmu_ll_hp_set_discnnt_dig_rtc (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.discnnt_dig_rtc);
pmu_ll_hp_set_regulator_driver_bar (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.drv_b);
pmu_ll_hp_set_dcm_mode (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.dcm_mode);
pmu_ll_hp_set_dcm_vset (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.dcm_vset);
pmu_ll_lp_set_discnnt_dig_rtc (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.discnnt_dig_rtc);
pmu_ll_lp_set_regulator_dbias (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.dbias);
pmu_ll_lp_set_regulator_xpd (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.xpd);
pmu_ll_lp_set_regulator_driver_bar (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.drv_b);
pmu_ll_lp_set_dcm_mode (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.dcm_mode);
pmu_ll_lp_set_dcm_vset (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.dcm_vset);
}
@@ -138,15 +138,6 @@ typedef union {
uint32_t xpd_xtalx2 : 1;
uint32_t xpd_xtal : 1;
};
struct {
uint32_t mem2_pd_mask: 5;
uint32_t mem1_pd_mask: 5;
uint32_t mem0_pd_mask: 5;
uint32_t reserved5 : 2;
uint32_t mem2_mask : 5;
uint32_t mem1_mask : 5;
uint32_t mem0_mask : 5;
};
uint32_t val;
} pmu_hp_power_t;
@@ -290,7 +281,6 @@ typedef struct {
pmu_hp_power_t dig_power;
pmu_hp_power_t clk_power;
pmu_hp_power_t xtal;
pmu_hp_power_t memory;
} hp_sys;
struct {
pmu_lp_power_t dig_power;
@@ -299,76 +289,71 @@ typedef struct {
} lp_sys[PMU_MODE_LP_MAX];
} pmu_sleep_power_config_t;
#define PMU_SLEEP_POWER_CONFIG_DEFAULT(pd_flags) { \
.hp_sys = { \
.dig_power = { \
.vdd_flash_mode = ((pd_flags) & PMU_SLEEP_PD_VDDSDIO) ? 1 : 3, \
.wifi_pd_en = ((pd_flags) & PMU_SLEEP_PD_MODEM) ? 1 : 0, \
.cpu_pd_en = ((pd_flags) & PMU_SLEEP_PD_CPU) ? 1 : 0, \
.aon_pd_en = ((pd_flags) & PMU_SLEEP_PD_HP_AON) ? 1 : 0, \
.top_pd_en = ((pd_flags) & PMU_SLEEP_PD_TOP) ? 1 : 0, \
.mem_pd_en = 0, \
.mem_dslp = 0 \
}, \
.clk_power = { \
.i2c_iso_en = 1, \
.i2c_retention = 1, \
.xpd_bb_i2c = 0, \
.xpd_bbpll_i2c = 0, \
.xpd_bbpll = 0 \
}, \
.xtal = { \
.xpd_xtalx2 = 0, \
.xpd_xtal = ((pd_flags) & PMU_SLEEP_PD_XTAL) ? 0 : 1, \
}, \
.memory = { \
.mem0_mask = ((pd_flags) & PMU_SLEEP_PD_TOP) ? 1 : 0, \
.mem1_mask = ((pd_flags) & PMU_SLEEP_PD_TOP) ? 1 : 0, \
.mem2_mask = ((pd_flags) & PMU_SLEEP_PD_TOP) ? 1 : 0 \
} \
}, \
.lp_sys[PMU_MODE_LP_ACTIVE] = { \
.dig_power = { \
.vdd_io_mode = 0, \
.bod_source_sel = 0, \
.vddbat_mode = 0, \
.peri_pd_en = 0, \
.mem_dslp = 0 \
}, \
.clk_power = { \
.xpd_lppll = 0, \
.xpd_xtal32k = ((pd_flags) & PMU_SLEEP_PD_XTAL32K) ? 0 : 1, \
.xpd_rc32k = ((pd_flags) & PMU_SLEEP_PD_RC32K) ? 0 : 1, \
.xpd_fosc = 1 \
} \
}, \
.lp_sys[PMU_MODE_LP_SLEEP] = { \
.dig_power = { \
.vdd_io_mode = 3, \
.bod_source_sel = 0, \
.vddbat_mode = 0, \
.peri_pd_en = ((pd_flags) & PMU_SLEEP_PD_LP_PERIPH) ? 1 : 0,\
.mem_dslp = 0 \
}, \
.clk_power = { \
.xpd_lppll = 0, \
.xpd_xtal32k = ((pd_flags) & PMU_SLEEP_PD_XTAL32K) ? 0 : 1, \
.xpd_rc32k = ((pd_flags) & PMU_SLEEP_PD_RC32K) ? 0 : 1, \
.xpd_fosc = ((pd_flags) & PMU_SLEEP_PD_RC_FAST) ? 0 : 1 \
}, \
.xtal = { \
.xpd_xtal = ((pd_flags) & PMU_SLEEP_PD_XTAL) ? 0 : 1, \
} \
} \
#define PMU_SLEEP_POWER_CONFIG_DEFAULT(sleep_flags) { \
.hp_sys = { \
.dig_power = { \
.vdd_flash_mode = ((sleep_flags) & PMU_SLEEP_PD_VDDSDIO) ? 1 : 3,\
.wifi_pd_en = ((sleep_flags) & PMU_SLEEP_PD_MODEM) ? 1 : 0,\
.cpu_pd_en = ((sleep_flags) & PMU_SLEEP_PD_CPU) ? 1 : 0,\
.aon_pd_en = ((sleep_flags) & PMU_SLEEP_PD_HP_AON) ? 1 : 0,\
.top_pd_en = ((sleep_flags) & PMU_SLEEP_PD_TOP) ? 1 : 0,\
.mem_pd_en = 0, \
.mem_dslp = 0 \
}, \
.clk_power = { \
.i2c_iso_en = 1, \
.i2c_retention = 1, \
.xpd_bb_i2c = 0, \
.xpd_bbpll_i2c = 0, \
.xpd_bbpll = 0 \
}, \
.xtal = { \
.xpd_xtalx2 = 0, \
.xpd_xtal = ((sleep_flags) & PMU_SLEEP_PD_XTAL) ? 0 : 1, \
}, \
}, \
.lp_sys[PMU_MODE_LP_ACTIVE] = { \
.dig_power = { \
.vdd_io_mode = 0, \
.bod_source_sel = 0, \
.vddbat_mode = 0, \
.peri_pd_en = 0, \
.mem_dslp = 0 \
}, \
.clk_power = { \
.xpd_lppll = 0, \
.xpd_xtal32k = ((sleep_flags) & PMU_SLEEP_PD_XTAL32K) ? 0 : 1,\
.xpd_rc32k = ((sleep_flags) & PMU_SLEEP_PD_RC32K) ? 0 : 1, \
.xpd_fosc = 1 \
} \
}, \
.lp_sys[PMU_MODE_LP_SLEEP] = { \
.dig_power = { \
.vdd_io_mode = 3, \
.bod_source_sel = 0, \
.vddbat_mode = 0, \
.peri_pd_en = ((sleep_flags) & PMU_SLEEP_PD_LP_PERIPH) ? 1 : 0,\
.mem_dslp = 0 \
}, \
.clk_power = { \
.xpd_lppll = 0, \
.xpd_xtal32k = ((sleep_flags) & PMU_SLEEP_PD_XTAL32K) ? 0 : 1,\
.xpd_rc32k = ((sleep_flags) & PMU_SLEEP_PD_RC32K) ? 0 : 1, \
.xpd_fosc = ((sleep_flags) & PMU_SLEEP_PD_RC_FAST) ? 0 : 1 \
}, \
.xtal = { \
.xpd_xtal = ((sleep_flags) & PMU_SLEEP_PD_XTAL) ? 0 : 1, \
} \
} \
}
typedef struct {
pmu_hp_sys_cntl_reg_t syscntl;
} pmu_sleep_digital_config_t;
#define PMU_SLEEP_DIGITAL_LSLP_CONFIG_DEFAULT(pd_flags) { \
#define PMU_SLEEP_DIGITAL_LSLP_CONFIG_DEFAULT(sleep_flags) { \
.syscntl = { \
.dig_pad_slp_sel = ((pd_flags) & PMU_SLEEP_PD_TOP) ? 0 : 1, \
.dig_pad_slp_sel = ((sleep_flags) & PMU_SLEEP_PD_TOP) ? 0 : 1, \
} \
}
@@ -381,10 +366,10 @@ typedef struct {
} lp_sys[PMU_MODE_LP_MAX];
} pmu_sleep_analog_config_t;
#define PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags) { \
#define PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(sleep_flags) { \
.hp_sys = { \
.analog = { \
.dcdc_ccm_enb = 0, \
.dcdc_ccm_enb = 1, \
.dcdc_clear_rdy = 0, \
.dig_reg_dpcur_bias = 1, \
.dig_reg_dsfmos = 4, \
@@ -402,14 +387,14 @@ typedef struct {
}, \
.lp_sys[PMU_MODE_LP_SLEEP] = { \
.analog = { \
.dcdc_ccm_enb = 0, \
.dcdc_ccm_enb = 1, \
.dcdc_clear_rdy = 0, \
.dig_reg_dpcur_bias = 1, \
.dig_reg_dsfmos = 4, \
.dcm_vset = 0, \
.dcm_mode = 3, \
.discnnt_dig_rtc = 0, \
.drv_b = PMU_LP_DRVB_DEEPSLEEP, \
.drv_b = PMU_LP_DRVB_DEEPSLEEP, \
.pd_cur = PMU_PD_CUR_SLEEP_DEFAULT, \
.bias_sleep = PMU_BIASSLP_SLEEP_DEFAULT, \
.slp_xpd = PMU_LP_SLP_XPD_SLEEP_DEFAULT, \
@@ -420,10 +405,10 @@ typedef struct {
} \
}
#define PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(pd_flags) { \
#define PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(sleep_flags) { \
.hp_sys = { \
.analog = { \
.dcdc_ccm_enb = 0, \
.dcdc_ccm_enb = 1, \
.dcdc_clear_rdy = 0, \
.dig_reg_dpcur_bias = 1, \
.dig_reg_dsfmos = 4, \
@@ -439,13 +424,13 @@ typedef struct {
}, \
.lp_sys[PMU_MODE_LP_SLEEP] = { \
.analog = { \
.dcdc_ccm_enb = 0, \
.dcdc_ccm_enb = 1, \
.dcdc_clear_rdy = 0, \
.dig_reg_dpcur_bias = 1, \
.dig_reg_dsfmos = 4, \
.dcm_vset = 0, \
.dcm_mode = 3, \
.discnnt_dig_rtc = 0, \
.discnnt_dig_rtc = 1, \
.drv_b = PMU_LP_DRVB_DEEPSLEEP, \
.pd_cur = PMU_PD_CUR_SLEEP_DEFAULT, \
.bias_sleep = PMU_BIASSLP_SLEEP_DEFAULT, \
@@ -463,7 +448,7 @@ typedef struct {
pmu_hp_lp_param_t hp_lp;
} pmu_sleep_param_config_t;
#define PMU_SLEEP_PARAM_CONFIG_DEFAULT(pd_flags) { \
#define PMU_SLEEP_PARAM_CONFIG_DEFAULT(sleep_flags) { \
.hp_sys = { \
.min_slp_slow_clk_cycle = PMU_HP_SLEEP_MIN_SLOW_CLK_CYCLES, \
.analog_wait_target_cycle = PMU_HP_ANALOG_WAIT_TARGET_CYCLES, \
+1 -1
View File
@@ -195,7 +195,7 @@ inline __attribute__((always_inline)) bool sleep_modem_wifi_modem_link_done(void
bool modem_domain_pd_allowed(void)
{
#if SOC_PM_MODEM_RETENTION_BY_REGDMA
#if SOC_PM_MODEM_RETENTION_BY_REGDMA && SOC_PAU_SUPPORTED
const sleep_retention_module_bitmap_t inited_modules = sleep_retention_get_inited_modules();
const sleep_retention_module_bitmap_t created_modules = sleep_retention_get_created_modules();
@@ -1,2 +1,2 @@
| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-P4 |
| ----------------- | -------- | -------- | --------- | -------- | -------- | -------- |
| Supported Targets | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 |
| ----------------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- |
@@ -1,2 +1,2 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- |
@@ -91,6 +91,10 @@ config ESP_ROM_HAS_VERSION
bool
default y
config ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB
bool
default y
config ESP_ROM_HAS_OUTPUT_PUTC_FUNC
bool
default y
+1 -1
View File
@@ -28,7 +28,7 @@
#define ESP_ROM_HAS_SW_FLOAT (1) // ROM has libgcc software floating point emulation functions
#define ESP_ROM_USB_OTG_NUM (-1) // No USB_OTG CDC in the ROM, set -1 for Kconfig usage.
#define ESP_ROM_HAS_VERSION (1) // ROM has version/eco information
// #define ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB (1) // ROM supports the HP core to jump to the RTC memory to execute stub code after waking up from deepsleep. //TODO: [ESP32H21] IDF-11515
#define ESP_ROM_SUPPORT_DEEP_SLEEP_WAKEUP_STUB (1) // ROM supports the HP core to jump to the RTC memory to execute stub code after waking up from deepsleep.
#define ESP_ROM_HAS_OUTPUT_PUTC_FUNC (1) // ROM has esp_rom_output_putc (or ets_write_char_uart)
#define ESP_ROM_HAS_SUBOPTIMAL_NEWLIB_ON_MISALIGNED_MEMORY (1) // ROM mem/str functions are not optimized well for misaligned memory access.
#define ESP_ROM_NO_USB_SERIAL_OUTPUT_API (1) // ROM does not export the usb-serial-jtag write char function
@@ -185,5 +185,10 @@ void rtc_clk_select_rtc_slow_clk(void)
*/
__attribute__((weak)) void esp_perip_clk_init(void)
{
soc_rtc_slow_clk_src_t rtc_slow_clk_src = rtc_clk_slow_src_get();
esp_sleep_pd_domain_t pu_domain = (esp_sleep_pd_domain_t)(\
(rtc_slow_clk_src == SOC_RTC_SLOW_CLK_SRC_XTAL32K) ? ESP_PD_DOMAIN_XTAL32K \
: ESP_PD_DOMAIN_MAX);
esp_sleep_pd_config(pu_domain, ESP_PD_OPTION_ON);
ESP_EARLY_LOGW(TAG, "esp_perip_clk_init() has not been implemented yet");
}
@@ -79,7 +79,6 @@ static inline void lp_aon_ll_inform_wakeup_type(bool dslp)
{
if (dslp) {
REG_SET_BIT(RTC_SLEEP_MODE_REG, BIT(0)); /* Tell rom to run deep sleep wake stub */
} else {
REG_CLR_BIT(RTC_SLEEP_MODE_REG, BIT(0)); /* Tell rom to run light sleep wake stub */
}
@@ -134,6 +134,12 @@ FORCE_INLINE_ATTR void pmu_ll_hp_set_xtal_xpd(pmu_dev_t *hw, pmu_hp_mode_t mode,
hw->hp_sys[mode].xtal.xpd_xtal = xpd_xtal;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_discnnt_dig_rtc(pmu_dev_t *hw, pmu_hp_mode_t mode, bool discnnt)
{
hw->hp_sys[mode].bias.discnnt_dig_rtc = discnnt;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_current_power_off(pmu_dev_t *hw, pmu_hp_mode_t mode, bool off)
{
hw->hp_sys[mode].bias.pd_cur = off;
@@ -345,6 +351,19 @@ FORCE_INLINE_ATTR void pmu_ll_lp_set_bias_xpd(pmu_dev_t *hw, pmu_lp_mode_t mode,
hw->lp_sys[mode].bias.xpd_bias = xpd_bias;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_memory_power_on_mask(pmu_dev_t *hw, uint32_t mem_mask)
{
hw->power.mem_mask.mem0_mask = mem_mask & BIT(0);
hw->power.mem_mask.mem1_mask = mem_mask & BIT(1);
hw->power.mem_mask.mem2_mask = mem_mask & BIT(2);
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_discnnt_dig_rtc(pmu_dev_t *hw, pmu_lp_mode_t mode, bool discnnt)
{
HAL_ASSERT(mode == PMU_MODE_LP_SLEEP);
hw->lp_sys[mode].bias.discnnt_dig_rtc = discnnt;
}
FORCE_INLINE_ATTR void pmu_ll_lp_set_current_power_off(pmu_dev_t *hw, pmu_lp_mode_t mode, bool off)
{
HAL_ASSERT(mode == PMU_MODE_LP_SLEEP);
@@ -714,6 +733,11 @@ FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_digital_power_up_wait_cycle(pmu_dev_t *
return hw->power.wait_timer0.powerup_timer;
}
FORCE_INLINE_ATTR void pmu_ll_set_dcdc_ccm_sw_en(pmu_dev_t *hw, bool enable)
{
hw->dcm_ctrl.dcdc_ccm_sw_en = enable;
}
#ifdef __cplusplus
}
#endif
+4 -4
View File
@@ -571,11 +571,11 @@ FORCE_INLINE_ATTR void pmu_ll_hp_set_memory_power_up(pmu_dev_t *hw, uint32_t fpu
hw->power.mem_cntl.force_hp_mem_pu = fpu;
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_memory_power_on_mask(pmu_dev_t *hw, uint32_t mem0_mask, uint32_t mem1_mask, uint32_t mem2_mask)
FORCE_INLINE_ATTR void pmu_ll_hp_set_memory_power_on_mask(pmu_dev_t *hw, uint32_t mem_mask)
{
hw->power.mem_mask.mem0_mask = mem0_mask;
hw->power.mem_mask.mem1_mask = mem1_mask;
hw->power.mem_mask.mem2_mask = mem2_mask;
hw->power.mem_mask.mem0_mask = mem_mask & BIT(0);
hw->power.mem_mask.mem1_mask = mem_mask & BIT(1);
hw->power.mem_mask.mem2_mask = mem_mask & BIT(2);
}
FORCE_INLINE_ATTR void pmu_ll_hp_set_memory_power_off_mask(pmu_dev_t *hw, uint32_t mem0_pd_mask, uint32_t mem1_pd_mask, uint32_t mem2_pd_mask)
+1 -1
View File
@@ -24,7 +24,7 @@ typedef struct {
modem_lpcon_dev_t *lpcon_dev;
} modem_clock_hal_context_t;
#if !SOC_IS(ESP32H2) //TODO: PM-92
#if SOC_PM_SUPPORT_PMU_MODEM_STATE
void modem_clock_hal_set_clock_domain_icg_bitmap(modem_clock_hal_context_t *hal, modem_clock_domain_t domain, uint32_t bitmap);
uint32_t modem_clock_hal_get_clock_domain_icg_bitmap(modem_clock_hal_context_t *hal, modem_clock_domain_t domain);
#endif
@@ -99,6 +99,14 @@ config SOC_PMU_SUPPORTED
bool
default y
config SOC_LP_TIMER_SUPPORTED
bool
default y
config SOC_LP_AON_SUPPORTED
bool
default y
config SOC_CLK_TREE_SUPPORTED
bool
default y
@@ -139,6 +147,18 @@ config SOC_PAU_SUPPORTED
bool
default y
config SOC_LIGHT_SLEEP_SUPPORTED
bool
default y
config SOC_DEEP_SLEEP_SUPPORTED
bool
default y
config SOC_PM_SUPPORTED
bool
default y
config SOC_XTAL_SUPPORT_32M
bool
default y
@@ -383,10 +403,6 @@ config SOC_GPIO_SUPPORT_HOLD_SINGLE_IO_IN_DSLP
bool
default y
config SOC_SDM_SUPPORT_SLEEP_RETENTION
bool
default y
config SOC_ETM_SUPPORT_SLEEP_RETENTION
bool
default y
@@ -61,8 +61,8 @@
// #define SOC_BOD_SUPPORTED 1 //TODO: [ESP32H21] IDF-11530
// #define SOC_APM_SUPPORTED 1 //TODO: [ESP32H21] IDF-11494
#define SOC_PMU_SUPPORTED 1
// #define SOC_LP_TIMER_SUPPORTED 1
// #define SOC_LP_AON_SUPPORTED 1
#define SOC_LP_TIMER_SUPPORTED 1
#define SOC_LP_AON_SUPPORTED 1
// #define SOC_LP_PERIPHERALS_SUPPORTED 1
#define SOC_CLK_TREE_SUPPORTED 1
// #define SOC_ASSIST_DEBUG_SUPPORTED 1 //TODO: [ESP32H21] IDF-11544
@@ -81,10 +81,9 @@
#define SOC_AES_SUPPORTED 1
// #define SOC_SDIO_SLAVE_SUPPORTED 1
#define SOC_PAU_SUPPORTED 1
// #define SOC_LIGHT_SLEEP_SUPPORTED 1 //TODO: [ESP32H21] IDF-11517, IDF-11520
// #define SOC_DEEP_SLEEP_SUPPORTED 1 //TODO: [ESP32H21] IDF-11515
// #define SOC_MODEM_CLOCK_SUPPORTED 1
// #define SOC_PM_SUPPORTED 1
#define SOC_LIGHT_SLEEP_SUPPORTED 1
#define SOC_DEEP_SLEEP_SUPPORTED 1
#define SOC_PM_SUPPORTED 1
/*-------------------------- XTAL CAPS ---------------------------------------*/
#define SOC_XTAL_SUPPORT_32M 1
@@ -234,7 +233,7 @@
// #define SOC_GPIO_CLOCKOUT_CHANNEL_NUM (3)
/*-------------------------- Sigma Delta Modulator CAPS -----------------*/
#define SOC_SDM_SUPPORT_SLEEP_RETENTION 1
// #define SOC_SDM_SUPPORT_SLEEP_RETENTION 1 //TODO [ESP32H21] IDF-14159
/*-------------------------- ETM CAPS -----------------------------------*/
#define SOC_ETM_SUPPORT_SLEEP_RETENTION 1
@@ -0,0 +1,82 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <stdint.h>
#include "soc/soc_caps.h"
#include "soc/regdma.h"
#ifdef __cplusplus
extern "C"
{
#endif
/**
* @brief Provide access to interrupt matrix configuration registers retention
* context definition.
*
* This is an internal function of the sleep retention driver, and is not
* useful for external use.
*/
#define INT_MTX_RETENTION_LINK_LEN 1
extern const regdma_entries_config_t intr_matrix_regs_retention[INT_MTX_RETENTION_LINK_LEN];
/**
* @brief Provide access to hp_system configuration registers retention
* context definition.
*
* This is an internal function of the sleep retention driver, and is not
* useful for external use.
*/
#define HP_SYSTEM_RETENTION_LINK_LEN 1
extern const regdma_entries_config_t hp_system_regs_retention[HP_SYSTEM_RETENTION_LINK_LEN];
/**
* @brief Provide access to TEE_APM configuration registers retention
* context definition.
*
* This is an internal function of the sleep retention driver, and is not
* useful for external use.
*/
#define TEE_APM_RETENTION_LINK_LEN 2
extern const regdma_entries_config_t tee_apm_regs_retention[TEE_APM_RETENTION_LINK_LEN];
#define TEE_APM_HIGH_PRI_RETENTION_LINK_LEN 1
extern const regdma_entries_config_t tee_apm_highpri_regs_retention[TEE_APM_HIGH_PRI_RETENTION_LINK_LEN];
/**
* @brief Provide access to IOMUX configuration registers retention
* context definition.
*
* This is an internal function of the sleep retention driver, and is not
* useful for external use.
*/
#define IOMUX_RETENTION_LINK_LEN 4
extern const regdma_entries_config_t iomux_regs_retention[IOMUX_RETENTION_LINK_LEN];
/**
* @brief Provide access to spimem configuration registers retention
* context definition.
*
* This is an internal function of the sleep retention driver, and is not
* useful for external use.
*/
#define SPIMEM_RETENTION_LINK_LEN 8
extern const regdma_entries_config_t flash_spimem_regs_retention[SPIMEM_RETENTION_LINK_LEN];
/**
* @brief Provide access to systimer configuration registers retention
* context definition.
*
* This is an internal function of the sleep retention driver, and is not
* useful for external use.
*/
#define SYSTIMER_RETENTION_LINK_LEN 19
extern const regdma_entries_config_t systimer_regs_retention[SYSTIMER_RETENTION_LINK_LEN];
#ifdef __cplusplus
}
#endif
@@ -1,5 +1,5 @@
/**
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -446,10 +446,10 @@ extern "C" {
/** TEE_DATE_REG : R/W; bitpos: [27:0]; default: 35672706;
* reg_tee_date
*/
#define TEE_DATE_REG 0x0FFFFFFFU
#define TEE_DATE_REG_M (TEE_DATE_REG_V << TEE_DATE_REG_S)
#define TEE_DATE_REG_V 0x0FFFFFFFU
#define TEE_DATE_REG_S 0
#define TEE_DATE 0x0FFFFFFFU
#define TEE_DATE_M (TEE_DATE_V << TEE_DATE_S)
#define TEE_DATE_V 0x0FFFFFFFU
#define TEE_DATE_S 0
#ifdef __cplusplus
}
@@ -0,0 +1,128 @@
/*
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "soc/regdma.h"
#include "soc/system_periph_retention.h"
#include "soc/timer_periph.h"
#include "soc/uart_reg.h"
#include "soc/systimer_reg.h"
#include "soc/timer_group_reg.h"
#include "soc/spi_mem_reg.h"
#include "soc/hp_system_reg.h"
#include "soc/tee_reg.h"
#include "soc/hp_apm_reg.h"
#include "soc/gpio_reg.h"
#include "soc/io_mux_reg.h"
#include "soc/interrupt_matrix_reg.h"
/* Interrupt Matrix Registers Context */
#define N_REGS_INTR_MATRIX() (((INTMTX_CORE0_CLOCK_GATE_REG - DR_REG_INTMTX_BASE) / 4) + 1)
const regdma_entries_config_t intr_matrix_regs_retention[] = {
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_INTMTX_LINK(0), DR_REG_INTMTX_BASE, DR_REG_INTMTX_BASE, N_REGS_INTR_MATRIX(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* intr matrix */
};
_Static_assert(ARRAY_SIZE(intr_matrix_regs_retention) == INT_MTX_RETENTION_LINK_LEN, "Inconsistent INT_MTX retention link length definitions");
/* HP_SYSTEM_EXTERNAL_DEVICE_ENCRYPT_DECRYPT_CONTROL_REG / HP_SYSTEM_SRAM_USAGE_CONF_REG
* HP_SYSTEM_SEC_DPA_CONF_REG / HP_SYSTEM_CPU_PERI_TIMEOUT_CONF_REG
* HP_SYSTEM_HP_PERI_TIMEOUT_CONF_REG /HP_SYSTEM_ROM_TABLE_LOCK_REG /HP_SYSTEM_ROM_TABLE_REG
*/
#define HP_SYSTEM_RETENTION_REGS_CNT 7
#define HP_SYSTEM_RETENTION_REGS_BASE (HP_SYSTEM_EXTERNAL_DEVICE_ENCRYPT_DECRYPT_CONTROL_REG)
static const uint32_t hp_system_regs_map[4] = {0x64f, 0x0, 0x0, 0x0};
const regdma_entries_config_t hp_system_regs_retention[] = {
[0] = {
.config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_HPSYS_LINK(0x00), \
HP_SYSTEM_RETENTION_REGS_BASE, HP_SYSTEM_RETENTION_REGS_BASE, \
HP_SYSTEM_RETENTION_REGS_CNT, 0, 0, \
hp_system_regs_map[0], hp_system_regs_map[1], \
hp_system_regs_map[2], hp_system_regs_map[3]), \
.owner = ENTRY(0) | ENTRY(2)
}, \
};
_Static_assert(ARRAY_SIZE(hp_system_regs_retention) == HP_SYSTEM_RETENTION_LINK_LEN, "Inconsistent HP_SYSTEM retention link length definitions");
/* TEE/APM Registers Context */
#define N_REGS_TEE() (((TEE_CLOCK_GATE_REG - DR_REG_TEE_BASE) / 4) + 1)
#define N_REGS_APM() (((HP_APM_CLOCK_GATE_REG - DR_REG_HP_APM_BASE) / 4) + 1)
const regdma_entries_config_t tee_apm_regs_retention[] = {
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TEEAPM_LINK(0), DR_REG_HP_APM_BASE, DR_REG_HP_APM_BASE, N_REGS_APM(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* apm */
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TEEAPM_LINK(1), DR_REG_TEE_BASE, DR_REG_TEE_BASE, N_REGS_TEE(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* tee */
};
const regdma_entries_config_t tee_apm_highpri_regs_retention[] = {
[0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TEEAPM_LINK(2), TEE_M4_MODE_CTRL_REG, 0x0, 0xffffffff, 1, 0), .owner = ENTRY(2) }
};
_Static_assert((ARRAY_SIZE(tee_apm_regs_retention) == TEE_APM_RETENTION_LINK_LEN) && (ARRAY_SIZE(tee_apm_highpri_regs_retention) == TEE_APM_HIGH_PRI_RETENTION_LINK_LEN), "Inconsistent TEE_APM retention link length definitions");
/* IO MUX Registers Context */
#define N_REGS_IOMUX_0() (SOC_GPIO_PIN_COUNT)
#define N_REGS_IOMUX_1() (SOC_GPIO_PIN_COUNT)
#define N_REGS_IOMUX_2() (((GPIO_FUNC124_IN_SEL_CFG_REG - GPIO_FUNC0_IN_SEL_CFG_REG) / 4) + 1)
#define N_REGS_IOMUX_3() (SOC_GPIO_PIN_COUNT)
const regdma_entries_config_t iomux_regs_retention[] = {
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x00), REG_IO_MUX_BASE, REG_IO_MUX_BASE, N_REGS_IOMUX_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* io_mux */
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x01), DR_REG_GPIO_BASE, DR_REG_GPIO_BASE, N_REGS_IOMUX_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x02), GPIO_FUNC0_IN_SEL_CFG_REG, GPIO_FUNC0_IN_SEL_CFG_REG, N_REGS_IOMUX_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x03), GPIO_FUNC0_OUT_SEL_CFG_REG, GPIO_FUNC0_OUT_SEL_CFG_REG, N_REGS_IOMUX_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) },
};
_Static_assert(ARRAY_SIZE(iomux_regs_retention) == IOMUX_RETENTION_LINK_LEN, "Inconsistent IOMUX retention link length definitions");
/* Memory SPI Registers Context */
#define N_REGS_SPI1_MEM_0() (((SPI_SMEM_DDR_REG(1) - DR_REG_SPI_MEM_BASE(1)) / 4) + 1)
#define N_REGS_SPI1_MEM_1() (1)
#define N_REGS_SPI1_MEM_2() (1)
#define N_REGS_SPI0_MEM_0() (((SPI_SMEM_DDR_REG(0) - DR_REG_SPI_MEM_BASE(0)) / 4) + 1)
#define N_REGS_SPI0_MEM_1() (((SPI_SMEM_AC_REG(0) - SPI_FMEM_PMS0_ATTR_REG(0)) / 4) + 1)
#define N_REGS_SPI0_MEM_2() (1)
#define N_REGS_SPI0_MEM_3() (((SPI_MEM_XTS_PSEUDO_ROUND_CONF_REG(0) - SPI_MEM_MMU_POWER_CTRL_REG(0)) / 4) + 1)
const regdma_entries_config_t flash_spimem_regs_retention[] = {
/* Note: SPI mem should not to write mmu SPI_MEM_MMU_ITEM_CONTENT_REG and SPI_MEM_MMU_ITEM_INDEX_REG */
[0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x00), DR_REG_SPI_MEM_BASE(1), DR_REG_SPI_MEM_BASE(1), N_REGS_SPI1_MEM_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* spi1_mem */
[1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x01), SPI_MEM_TIMING_CALI_REG(1), SPI_MEM_TIMING_CALI_REG(1), N_REGS_SPI1_MEM_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x02), SPI_MEM_CLOCK_GATE_REG(1), SPI_MEM_CLOCK_GATE_REG(1), N_REGS_SPI1_MEM_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) },
/* Note: SPI mem should not to write mmu SPI_MEM_MMU_ITEM_CONTENT_REG and SPI_MEM_MMU_ITEM_INDEX_REG */
[3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x03), DR_REG_SPI_MEM_BASE(0), DR_REG_SPI_MEM_BASE(0), N_REGS_SPI0_MEM_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* spi0_mem */
[4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x04), SPI_FMEM_PMS0_ATTR_REG(0), SPI_FMEM_PMS0_ATTR_REG(0), N_REGS_SPI0_MEM_1(), 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[5] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x05), SPI_MEM_CLOCK_GATE_REG(0), SPI_MEM_CLOCK_GATE_REG(0), N_REGS_SPI0_MEM_2(), 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x06), SPI_MEM_MMU_POWER_CTRL_REG(0), SPI_MEM_MMU_POWER_CTRL_REG(0), N_REGS_SPI0_MEM_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) },
/* Note: spimem register should set update reg to make the configuration take effect */
[7] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SPIMEM_LINK(0x07), SPI_MEM_TIMING_CALI_REG(0), SPI_MEM_TIMING_CALI_UPDATE, SPI_MEM_TIMING_CALI_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
};
_Static_assert(ARRAY_SIZE(flash_spimem_regs_retention) == SPIMEM_RETENTION_LINK_LEN, "Inconsistent SPI Mem retention link length definitions");
/* Systimer Registers Context */
#define N_REGS_SYSTIMER_0() (((SYSTIMER_TARGET2_CONF_REG - SYSTIMER_TARGET0_HI_REG) / 4) + 1)
const regdma_entries_config_t systimer_regs_retention[] = {
[0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SYSTIMER_LINK(0x00), SYSTIMER_UNIT0_OP_REG, SYSTIMER_TIMER_UNIT0_UPDATE_M, SYSTIMER_TIMER_UNIT0_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) }, /* Systimer */
[1] = { .config = REGDMA_LINK_WAIT_INIT(REGDMA_SYSTIMER_LINK(0x01), SYSTIMER_UNIT0_OP_REG, SYSTIMER_TIMER_UNIT0_VALUE_VALID, SYSTIMER_TIMER_UNIT0_VALUE_VALID, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x02), SYSTIMER_UNIT0_VALUE_HI_REG, SYSTIMER_UNIT0_LOAD_HI_REG, 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[3] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SYSTIMER_LINK(0x03), SYSTIMER_UNIT0_LOAD_REG, SYSTIMER_TIMER_UNIT0_LOAD_M, SYSTIMER_TIMER_UNIT0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[4] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SYSTIMER_LINK(0x04), SYSTIMER_UNIT1_OP_REG, SYSTIMER_TIMER_UNIT1_UPDATE_M, SYSTIMER_TIMER_UNIT1_UPDATE_M, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[5] = { .config = REGDMA_LINK_WAIT_INIT(REGDMA_SYSTIMER_LINK(0x05), SYSTIMER_UNIT1_OP_REG, SYSTIMER_TIMER_UNIT1_VALUE_VALID, SYSTIMER_TIMER_UNIT1_VALUE_VALID, 0, 1), .owner = ENTRY(0) | ENTRY(2) },
[6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x06), SYSTIMER_UNIT1_VALUE_HI_REG, SYSTIMER_UNIT1_LOAD_HI_REG, 2, 0, 0), .owner = ENTRY(0) | ENTRY(2) },
[7] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SYSTIMER_LINK(0x07), SYSTIMER_UNIT1_LOAD_REG, SYSTIMER_TIMER_UNIT1_LOAD_M, SYSTIMER_TIMER_UNIT1_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[8] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x08), SYSTIMER_TARGET0_HI_REG, SYSTIMER_TARGET0_HI_REG, N_REGS_SYSTIMER_0(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* Systimer target value & period */
[9] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SYSTIMER_LINK(0x09), SYSTIMER_COMP0_LOAD_REG, SYSTIMER_TIMER_COMP0_LOAD, SYSTIMER_TIMER_COMP0_LOAD, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[10] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SYSTIMER_LINK(0x0a), SYSTIMER_COMP1_LOAD_REG, SYSTIMER_TIMER_COMP1_LOAD, SYSTIMER_TIMER_COMP1_LOAD, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[11] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SYSTIMER_LINK(0x0b), SYSTIMER_COMP2_LOAD_REG, SYSTIMER_TIMER_COMP2_LOAD, SYSTIMER_TIMER_COMP2_LOAD, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[12] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SYSTIMER_LINK(0x0c), SYSTIMER_TARGET0_CONF_REG, 0, SYSTIMER_TARGET0_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[13] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SYSTIMER_LINK(0x0d), SYSTIMER_TARGET0_CONF_REG, SYSTIMER_TARGET0_PERIOD_MODE_M, SYSTIMER_TARGET0_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[14] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SYSTIMER_LINK(0x0e), SYSTIMER_TARGET1_CONF_REG, 0, SYSTIMER_TARGET1_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[15] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SYSTIMER_LINK(0x0f), SYSTIMER_TARGET1_CONF_REG, SYSTIMER_TARGET1_PERIOD_MODE_M, SYSTIMER_TARGET1_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[16] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_SYSTIMER_LINK(0x10), SYSTIMER_TARGET2_CONF_REG, 0, SYSTIMER_TARGET2_PERIOD_MODE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) },
[17] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x11), SYSTIMER_CONF_REG, SYSTIMER_CONF_REG, 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* Systimer work enable */
[18] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x12), SYSTIMER_INT_ENA_REG, SYSTIMER_INT_ENA_REG, 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* Systimer intr enable */
};
_Static_assert(ARRAY_SIZE(systimer_regs_retention) == SYSTIMER_RETENTION_LINK_LEN, "Inconsistent Systimer retention link length definitions");
+2
View File
@@ -106,6 +106,7 @@ const uart_signal_conn_t uart_periph_signal[SOC_UART_NUM] = {
},
};
#if SOC_PAU_SUPPORTED && SOC_UART_SUPPORT_SLEEP_RETENTION
/**
* UART registers to be saved during sleep retention
*
@@ -156,3 +157,4 @@ const uart_reg_retention_info_t uart_reg_retention_info[SOC_UART_HP_NUM] = {
.array_size = ARRAY_SIZE(uart1_regdma_entries),
},
};
#endif
+2
View File
@@ -6,6 +6,7 @@
#include "soc/wdt_periph.h"
#if SOC_PAU_SUPPORTED && SOC_MWDT_SUPPORT_SLEEP_RETENTION
#define N_REGS_TGWDT 6 // TIMG_WDTCONFIG0_REG ... TIMG_WDTCONFIG5_REG & TIMG_INT_ENA_TIMERS_REG
static const regdma_entries_config_t tg0_wdt_regs_retention[] = {
@@ -30,3 +31,4 @@ const tg_reg_ctx_link_t tg_wdt_regs_retention[2] = {
[0] = {tg0_wdt_regs_retention, ARRAY_SIZE(tg0_wdt_regs_retention)},
[1] = {tg1_wdt_regs_retention, ARRAY_SIZE(tg1_wdt_regs_retention)},
};
#endif
+1 -1
View File
@@ -20,7 +20,7 @@ extern "C" {
/* The value that needs to be written to TIMG_WDT_WKEY to write-enable the wdt registers */
#define TIMG_WDT_WKEY_VALUE 0x50D83AA1
#if SOC_MWDT_SUPPORT_SLEEP_RETENTION
#if SOC_MWDT_SUPPORT_SLEEP_RETENTION && SOC_PAU_SUPPORTED
typedef struct {
const regdma_entries_config_t *link_list;
uint32_t link_num;
+2 -2
View File
@@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- |
# Deep Sleep Example
@@ -27,11 +27,12 @@ menu "Example Configuration"
config EXAMPLE_EXT1_WAKEUP_PIN_1
int "Enable wakeup from PIN_1"
depends on !IDF_TARGET_ESP32
default 2 if !IDF_TARGET_ESP32H2
default 10 if IDF_TARGET_ESP32H2
default 2 if !IDF_TARGET_ESP32H2 && !IDF_TARGET_ESP32H21
default 10 if IDF_TARGET_ESP32H2 || IDF_TARGET_ESP32H21
range 0 7 if IDF_TARGET_ESP32C6
range 0 6 if IDF_TARGET_ESP32C61 || IDF_TARGET_ESP32C5
range 7 14 if IDF_TARGET_ESP32H2
range 5 11 if IDF_TARGET_ESP32H21
range 0 21 if IDF_TARGET_ESP32S2
range 0 21 if IDF_TARGET_ESP32S3
range 0 15 if IDF_TARGET_ESP32P4
@@ -103,11 +104,12 @@ menu "Example Configuration"
config EXAMPLE_EXT1_WAKEUP_PIN_2
int "Enable wakeup from PIN_2"
depends on !IDF_TARGET_ESP32
default 4 if !IDF_TARGET_ESP32H2
default 11 if IDF_TARGET_ESP32H2
default 4 if !IDF_TARGET_ESP32H2 && !IDF_TARGET_ESP32H21
default 11 if IDF_TARGET_ESP32H2 || IDF_TARGET_ESP32H2
range 0 7 if IDF_TARGET_ESP32C6
range 0 6 if IDF_TARGET_ESP32C61 || IDF_TARGET_ESP32C5
range 7 14 if IDF_TARGET_ESP32H2
range 5 11 if IDF_TARGET_ESP32H21
range 0 21 if IDF_TARGET_ESP32S2
range 0 21 if IDF_TARGET_ESP32S3
range 0 15 if IDF_TARGET_ESP32P4
+3 -3
View File
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -8,7 +8,7 @@
#include "esp_sleep.h"
#include "sdkconfig.h"
#include "driver/rtc_io.h"
#include "driver/gpio.h"
#if CONFIG_EXAMPLE_EXT0_WAKEUP
#if CONFIG_IDF_TARGET_ESP32
@@ -48,7 +48,7 @@ void example_deep_sleep_register_ext1_wakeup(void)
/* If there are no external pull-up/downs, tie wakeup pins to inactive level with internal pull-up/downs via RTC IO
* during deepsleep. However, RTC IO relies on the RTC_PERIPH power domain. Keeping this power domain on will
* increase some power comsumption. However, if we turn off the RTC_PERIPH domain or if certain chips lack the RTC_PERIPH
* increase some power consumption. However, if we turn off the RTC_PERIPH domain or if certain chips lack the RTC_PERIPH
* domain, we will use the HOLD feature to maintain the pull-up and pull-down on the pins during sleep.*/
#if CONFIG_EXAMPLE_EXT1_USE_INTERNAL_PULLUPS
#if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED
@@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-H21 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- |
# Deep Sleep Wake Stub Example
+2 -2
View File
@@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | --------- | -------- | -------- | -------- | -------- |
# Light Sleep Example
@@ -19,6 +19,8 @@
#define BOOT_BUTTON_NUM 28
#elif CONFIG_IDF_TARGET_ESP32P4
#define BOOT_BUTTON_NUM 35
#elif CONFIG_IDF_TARGET_ESP32H21
#define BOOT_BUTTON_NUM 14
#else
#define BOOT_BUTTON_NUM 0
#endif