mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-05 05:34:32 +02:00
feat(esp_hw_support): fix some issues and update esp32c61 eco3 sleep features
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -31,11 +31,11 @@ esp_err_t sleep_clock_system_retention_init(void *arg)
|
|||||||
[6] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PCR_LINK(6), PMU_CLK_STATE0_REG, PMU_STABLE_XPD_BBPLL_STATE, PMU_STABLE_XPD_BBPLL_STATE_M, 1, 0), .owner = ENTRY(0) }, /* Wait PMU_WAIT_XTL_STABLE done */
|
[6] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PCR_LINK(6), PMU_CLK_STATE0_REG, PMU_STABLE_XPD_BBPLL_STATE, PMU_STABLE_XPD_BBPLL_STATE_M, 1, 0), .owner = ENTRY(0) }, /* Wait PMU_WAIT_XTL_STABLE done */
|
||||||
[7] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PCR_LINK(7), PCR_AHB_FREQ_CONF_REG, 0, PCR_AHB_DIV_NUM, 1, 0), .owner = ENTRY(0) | ENTRY(1) }, /* Set AHB bus frequency to XTAL frequency */
|
[7] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PCR_LINK(7), PCR_AHB_FREQ_CONF_REG, 0, PCR_AHB_DIV_NUM, 1, 0), .owner = ENTRY(0) | ENTRY(1) }, /* Set AHB bus frequency to XTAL frequency */
|
||||||
[8] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PCR_LINK(8), PCR_BUS_CLK_UPDATE_REG, 1, PCR_BUS_CLOCK_UPDATE, 1, 0), .owner = ENTRY(0) | ENTRY(1) },
|
[8] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_PCR_LINK(8), PCR_BUS_CLK_UPDATE_REG, 1, PCR_BUS_CLOCK_UPDATE, 1, 0), .owner = ENTRY(0) | ENTRY(1) },
|
||||||
|
[9] = {.config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(9), LP_ANA_POWER_GLITCH_CNTL_REG, 0, LP_ANA_POWER_GLITCH_RESET_ENA_M,0, 1), .owner = ENTRY(0) | ENTRY(1)}, /* Disable power glitch detector on sleep backup */
|
||||||
|
[10] = {.config = REGDMA_LINK_WRITE_INIT(REGDMA_PCR_LINK(10), LP_ANA_POWER_GLITCH_CNTL_REG, 0xF, LP_ANA_POWER_GLITCH_RESET_ENA_M,1, 0), .owner = ENTRY(0) | ENTRY(1)}, /* Enable power glitch detector on wakeup restore */
|
||||||
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
|
#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
|
||||||
[9] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_PCR_LINK(9), DR_REG_PCR_BASE, DR_REG_PCR_BASE, 63, 0, 0, 0xfd73ffff, 0xfdffffff, 0xe001, 0x0), .owner = ENTRY(0) | ENTRY(1) },
|
[11] = { .config = REGDMA_LINK_ADDR_MAP_INIT(REGDMA_PCR_LINK(11), DR_REG_PCR_BASE, DR_REG_PCR_BASE, 63, 0, 0, 0xfd73ffff, 0xfdffffff, 0xe001, 0x0), .owner = ENTRY(0) | ENTRY(1) },
|
||||||
#endif
|
#endif
|
||||||
[10] = {.config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(10), LP_ANA_POWER_GLITCH_CNTL_REG, 0, LP_ANA_POWER_GLITCH_RESET_ENA_M, 0, 1), .owner = ENTRY(0) | ENTRY(1)}, /* Disable power glitch detector on sleep backup */
|
|
||||||
[11] = {.config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(11), LP_ANA_POWER_GLITCH_CNTL_REG, 0xF, LP_ANA_POWER_GLITCH_RESET_ENA_M, 1, 0), .owner = ENTRY(0) | ENTRY(1)}, /* Enable power glitch detector on wakeup restore */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
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);
|
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);
|
||||||
|
@@ -1,152 +0,0 @@
|
|||||||
/*
|
|
||||||
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
|
|
||||||
*
|
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
#include "esp_attr.h"
|
|
||||||
#include "esp_check.h"
|
|
||||||
#include "esp_sleep.h"
|
|
||||||
#include "esp_log.h"
|
|
||||||
#include "esp_heap_caps.h"
|
|
||||||
#include "soc/soc_caps.h"
|
|
||||||
#include "sdkconfig.h"
|
|
||||||
#include "soc/spi_mem_reg.h"
|
|
||||||
#include "esp_private/startup_internal.h"
|
|
||||||
|
|
||||||
static const char *TAG = "sleep_mmu";
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint32_t start;
|
|
||||||
uint32_t end;
|
|
||||||
} mmu_domain_dev_regs_region_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
mmu_domain_dev_regs_region_t *region;
|
|
||||||
int region_num;
|
|
||||||
uint32_t *regs_frame;
|
|
||||||
} mmu_domain_dev_sleep_frame_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal structure which holds all requested light sleep mmu retention parameters
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
struct {
|
|
||||||
mmu_domain_dev_sleep_frame_t *mmu_table_frame;
|
|
||||||
} retent;
|
|
||||||
} sleep_mmu_retention_t;
|
|
||||||
|
|
||||||
static DRAM_ATTR __attribute__((unused)) sleep_mmu_retention_t s_mmu_retention;
|
|
||||||
|
|
||||||
static void * mmu_domain_dev_sleep_frame_alloc_and_init(const mmu_domain_dev_regs_region_t *regions, const int region_num)
|
|
||||||
{
|
|
||||||
const int region_sz = sizeof(mmu_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(mmu_domain_dev_sleep_frame_t) + region_sz + regs_frame_sz, MALLOC_CAP_32BIT|MALLOC_CAP_INTERNAL);
|
|
||||||
if (frame) {
|
|
||||||
mmu_domain_dev_regs_region_t *region = (mmu_domain_dev_regs_region_t *)(frame + sizeof(mmu_domain_dev_sleep_frame_t));
|
|
||||||
memcpy(region, regions, region_num * sizeof(mmu_domain_dev_regs_region_t));
|
|
||||||
void *regs_frame = frame + sizeof(mmu_domain_dev_sleep_frame_t) + region_sz;
|
|
||||||
memset(regs_frame, 0, regs_frame_sz);
|
|
||||||
*(mmu_domain_dev_sleep_frame_t *)frame = (mmu_domain_dev_sleep_frame_t) {
|
|
||||||
.region = region,
|
|
||||||
.region_num = region_num,
|
|
||||||
.regs_frame = (uint32_t *)regs_frame
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void * mmu_domain_mmu_table_sleep_frame_alloc_and_init(void)
|
|
||||||
{
|
|
||||||
#define MMU_TABLE_SIZE (512 * 4)
|
|
||||||
const static mmu_domain_dev_regs_region_t regions[] = {
|
|
||||||
{ .start = SPI_MEM_MMU_ITEM_CONTENT_REG(0), .end = SPI_MEM_MMU_ITEM_CONTENT_REG(0) + MMU_TABLE_SIZE}
|
|
||||||
};
|
|
||||||
return mmu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0]));
|
|
||||||
}
|
|
||||||
|
|
||||||
static IRAM_ATTR void mmu_domain_dev_regs_save(mmu_domain_dev_sleep_frame_t *frame)
|
|
||||||
{
|
|
||||||
assert(frame);
|
|
||||||
mmu_domain_dev_regs_region_t *region = frame->region;
|
|
||||||
uint32_t *regs_frame = frame->regs_frame;
|
|
||||||
|
|
||||||
int offset = 0;
|
|
||||||
for (int i = 0; i < frame->region_num; i++) {
|
|
||||||
for (uint32_t addr = region[i].start; addr < region[i].end; addr+=4) {
|
|
||||||
REG_WRITE(SPI_MEM_MMU_ITEM_INDEX_REG(0), offset);
|
|
||||||
regs_frame[offset++] = REG_READ(SPI_MEM_MMU_ITEM_CONTENT_REG(0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static IRAM_ATTR void mmu_domain_dev_regs_restore(mmu_domain_dev_sleep_frame_t *frame)
|
|
||||||
{
|
|
||||||
assert(frame);
|
|
||||||
mmu_domain_dev_regs_region_t *region = frame->region;
|
|
||||||
uint32_t *regs_frame = frame->regs_frame;
|
|
||||||
|
|
||||||
int offset = 0;
|
|
||||||
for (int i = 0; i < frame->region_num; i++) {
|
|
||||||
for (uint32_t addr = region[i].start; addr < region[i].end; addr+=4) {
|
|
||||||
REG_WRITE(SPI_MEM_MMU_ITEM_INDEX_REG(0), offset);
|
|
||||||
REG_WRITE(SPI_MEM_MMU_ITEM_CONTENT_REG(0),regs_frame[offset++]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IRAM_ATTR void esp_sleep_mmu_retention(bool backup_or_restore)
|
|
||||||
{
|
|
||||||
if (backup_or_restore) {
|
|
||||||
mmu_domain_dev_regs_save(s_mmu_retention.retent.mmu_table_frame);
|
|
||||||
} else {
|
|
||||||
mmu_domain_dev_regs_restore(s_mmu_retention.retent.mmu_table_frame);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static esp_err_t esp_sleep_mmu_retention_deinit(void)
|
|
||||||
{
|
|
||||||
if (s_mmu_retention.retent.mmu_table_frame) {
|
|
||||||
heap_caps_free((void *)s_mmu_retention.retent.mmu_table_frame);
|
|
||||||
s_mmu_retention.retent.mmu_table_frame = NULL;
|
|
||||||
}
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static esp_err_t esp_sleep_mmu_retention_init(void)
|
|
||||||
{
|
|
||||||
if (s_mmu_retention.retent.mmu_table_frame == NULL) {
|
|
||||||
void *frame = mmu_domain_mmu_table_sleep_frame_alloc_and_init();
|
|
||||||
if (frame == NULL) {
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
s_mmu_retention.retent.mmu_table_frame = (mmu_domain_dev_sleep_frame_t *)frame;
|
|
||||||
}
|
|
||||||
return ESP_OK;
|
|
||||||
err:
|
|
||||||
esp_sleep_mmu_retention_deinit();
|
|
||||||
return ESP_ERR_NO_MEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool mmu_domain_pd_allowed(void)
|
|
||||||
{
|
|
||||||
return (s_mmu_retention.retent.mmu_table_frame != NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
ESP_SYSTEM_INIT_FN(sleep_mmu_startup_init, SECONDARY, BIT(0), 108)
|
|
||||||
{
|
|
||||||
esp_err_t ret;
|
|
||||||
ret = esp_sleep_mmu_retention_init();
|
|
||||||
if (ret != ESP_OK) {
|
|
||||||
ESP_EARLY_LOGW(TAG, "Failed to enable TOP power down during light sleep.");
|
|
||||||
}
|
|
||||||
return ESP_OK;
|
|
||||||
}
|
|
@@ -182,8 +182,8 @@
|
|||||||
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (318)
|
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (318)
|
||||||
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (56)
|
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (56)
|
||||||
#elif CONFIG_IDF_TARGET_ESP32C61
|
#elif CONFIG_IDF_TARGET_ESP32C61
|
||||||
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (318)
|
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (65)
|
||||||
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (107)
|
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (70)
|
||||||
#elif CONFIG_IDF_TARGET_ESP32H2
|
#elif CONFIG_IDF_TARGET_ESP32H2
|
||||||
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (118)
|
#define DEFAULT_SLEEP_OUT_OVERHEAD_US (118)
|
||||||
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (9)
|
#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (9)
|
||||||
@@ -217,12 +217,8 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD
|
#if SOC_PM_MMU_TABLE_RETENTION_WHEN_TOP_PD
|
||||||
#if CONFIG_IDF_TARGET_ESP32C61
|
|
||||||
#define SLEEP_MMU_TABLE_RETENTION_OVERHEAD_US (1232)
|
|
||||||
#elif CONFIG_IDF_TARGET_ESP32C5
|
|
||||||
#define SLEEP_MMU_TABLE_RETENTION_OVERHEAD_US (1220)
|
#define SLEEP_MMU_TABLE_RETENTION_OVERHEAD_US (1220)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
|
|
||||||
#define RTC_MODULE_SLEEP_PREPARE_CYCLES (6)
|
#define RTC_MODULE_SLEEP_PREPARE_CYCLES (6)
|
||||||
|
|
||||||
|
@@ -88,7 +88,6 @@ SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/p
|
|||||||
SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32p4/sleep_clock.c on BIT(0)
|
SECONDARY: 106: sleep_clock_startup_init in components/esp_hw_support/lowpower/port/esp32p4/sleep_clock.c on BIT(0)
|
||||||
SECONDARY: 107: sleep_sys_periph_startup_init in components/esp_hw_support/sleep_system_peripheral.c on BIT(0)
|
SECONDARY: 107: sleep_sys_periph_startup_init in components/esp_hw_support/sleep_system_peripheral.c on BIT(0)
|
||||||
SECONDARY: 108: sleep_mmu_startup_init in components/esp_hw_support/lowpower/port/esp32c5/sleep_mmu.c on BIT(0)
|
SECONDARY: 108: sleep_mmu_startup_init in components/esp_hw_support/lowpower/port/esp32c5/sleep_mmu.c on BIT(0)
|
||||||
SECONDARY: 108: sleep_mmu_startup_init in components/esp_hw_support/lowpower/port/esp32c61/sleep_mmu.c on BIT(0)
|
|
||||||
|
|
||||||
# app_trace has to be initialized before systemview
|
# app_trace has to be initialized before systemview
|
||||||
SECONDARY: 115: esp_apptrace_init in components/app_trace/app_trace.c on ESP_SYSTEM_INIT_ALL_CORES
|
SECONDARY: 115: esp_apptrace_init in components/app_trace/app_trace.c on ESP_SYSTEM_INIT_ALL_CORES
|
||||||
|
Reference in New Issue
Block a user