Merge branch 'feat/esp32p4eco_sleep_feature_update_v5.3' into 'release/v5.3'

feat(esp_hw_support): esp32p4eco1 sleep feature update (v5.3)

See merge request espressif/esp-idf!31682
This commit is contained in:
Jiang Jiang Jian 2024-07-15 19:35:56 +08:00
commit 5c180bf3b6
15 changed files with 129 additions and 36 deletions

View File

@ -83,6 +83,9 @@ typedef enum {
#endif
#if SOC_PM_SUPPORT_TOP_PD
ESP_PD_DOMAIN_TOP, //!< SoC TOP
#endif
#if SOC_PM_SUPPORT_CNNT_PD
ESP_PD_DOMAIN_CNNT, //!< Hight-speed connect peripherals power domain
#endif
ESP_PD_DOMAIN_MAX //!< Number of domains
} esp_sleep_pd_domain_t;

View File

@ -528,8 +528,9 @@ static TCM_IRAM_ATTR void smp_core_do_retention(void)
// Wait another core start to do retention
bool smp_skip_retention = false;
smp_retention_state_t another_core_state;
while (1) {
smp_retention_state_t another_core_state = atomic_load(&s_smp_retention_state[!core_id]);
another_core_state = atomic_load(&s_smp_retention_state[!core_id]);
if (another_core_state == SMP_SKIP_RETENTION) {
// If another core skips the retention, the current core should also have to skip it.
smp_skip_retention = true;
@ -548,9 +549,12 @@ static TCM_IRAM_ATTR void smp_core_do_retention(void)
if ((frame_critical->pmufunc & 0x3) == 0x1) {
atomic_store(&s_smp_retention_state[core_id], SMP_BACKUP_DONE);
// wait another core trigger sleep and wakeup
esp_cpu_wait_for_intr();
while (1) {
;
// If another core's sleep request is rejected by the hardware, jumps out of blocking.
another_core_state = atomic_load(&s_smp_retention_state[!core_id]);
if (another_core_state == SMP_SKIP_RETENTION) {
break;
}
}
} else {
// Start core1

View File

@ -9,6 +9,7 @@
#include "freertos/FreeRTOSConfig.h"
#include "sdkconfig.h"
#include "esp32p4/rom/cache.h"
#include "soc/cache_reg.h"
#define MTVT (0x307)
@ -154,7 +155,7 @@ rv_core_critical_regs_restore:
/* Core 0 is wakeup core, Invalidate L1 Cache here */
/* Invalidate L1 cache is required here!!! */
la t0, CACHE_SYNC_MAP_REG
li t1, 0x7 /* map l1 i/dcache */
li t1, CACHE_MAP_L1_CACHE_MASK /* map l1 i/dcache */
sw t1, 0x0(t0) /* set EXTMEM_CACHE_SYNC_MAP_REG bit 4 */
la t2, CACHE_SYNC_ADDR_REG
sw zero, 0x0(t2) /* clear EXTMEM_CACHE_SYNC_ADDR_REG */

View File

@ -14,6 +14,7 @@
#include "soc/soc.h"
#include "soc/rtc.h"
#include "soc/pmu_struct.h"
#include "hal/efuse_hal.h"
#include "hal/lp_aon_hal.h"
#include "esp_private/esp_pmu.h"
#include "pmu_param.h"
@ -280,6 +281,10 @@ uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp
bool pmu_sleep_finish(bool dslp)
{
(void)dslp;
// Wait eFuse memory update done.
while(efuse_ll_get_controller_state() != EFUSE_CONTROLLER_STATE_IDLE);
return pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev);
}

View File

@ -347,6 +347,10 @@ uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp
bool pmu_sleep_finish(bool dslp)
{
(void)dslp;
// Wait eFuse memory update done.
while(efuse_ll_get_controller_state() != EFUSE_CONTROLLER_STATE_IDLE);
return pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev);
}

View File

@ -11,6 +11,7 @@
#include "sdkconfig.h"
#include "esp_err.h"
#include "esp_attr.h"
#include "esp_private/rtc_clk.h"
#include "esp_private/regi2c_ctrl.h"
#include "esp32p4/rom/cache.h"
#include "soc/chip_revision.h"
@ -22,6 +23,7 @@
#include "soc/pau_reg.h"
#include "soc/pmu_reg.h"
#include "soc/pmu_struct.h"
#include "hal/clk_tree_hal.h"
#include "hal/lp_aon_hal.h"
#include "soc/lp_system_reg.h"
#include "hal/pmu_hal.h"
@ -290,6 +292,8 @@ FORCE_INLINE_ATTR void sleep_writeback_l1_dcache(void) {
while (!REG_GET_BIT(CACHE_SYNC_CTRL_REG, CACHE_SYNC_DONE));
}
static TCM_DRAM_ATTR uint32_t s_mpll_freq_mhz_before_sleep = 0;
TCM_IRAM_ATTR uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp)
{
lp_aon_hal_inform_wakeup_type(dslp);
@ -302,8 +306,15 @@ TCM_IRAM_ATTR uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt,
pmu_ll_hp_clear_reject_intr_status(PMU_instance()->hal->dev);
pmu_ll_hp_clear_reject_cause(PMU_instance()->hal->dev);
// !!! Need to manually check that data in L2 memory will not be modified from now on. !!!
sleep_writeback_l1_dcache();
// !!! Need to manually check that data in PSRAM will not be accessed from now on. !!!
s_mpll_freq_mhz_before_sleep = rtc_clk_mpll_get_freq();
if (s_mpll_freq_mhz_before_sleep) {
rtc_clk_mpll_disable();
}
/* Start entry into sleep mode */
pmu_ll_hp_set_sleep_enable(PMU_instance()->hal->dev);
@ -333,6 +344,14 @@ TCM_IRAM_ATTR bool pmu_sleep_finish(bool dslp)
pmu_sleep_shutdown_ldo();
}
if (s_mpll_freq_mhz_before_sleep) {
rtc_clk_mpll_enable();
rtc_clk_mpll_configure(clk_hal_xtal_get_freq_mhz(), s_mpll_freq_mhz_before_sleep);
}
// Wait eFuse memory update done.
while(efuse_ll_get_controller_state() != EFUSE_CONTROLLER_STATE_IDLE);
unsigned chip_version = efuse_hal_chip_revision();
if (!ESP_CHIP_REV_ABOVE(chip_version, 1)) {
REGI2C_WRITE_MASK(I2C_CPLL, I2C_CPLL_OC_DIV_7_0, 6); // lower default cpu_pll freq to 400M

View File

@ -28,7 +28,7 @@ static const char *TAG = "rtc_clk";
static int s_cur_cpll_freq = 0;
// MPLL frequency option, 400MHz. Zero if MPLL is not enabled.
static DRAM_ATTR uint32_t s_cur_mpll_freq = 0;
static TCM_DRAM_ATTR uint32_t s_cur_mpll_freq = 0;
void rtc_clk_32k_enable(bool enable)
{
@ -484,13 +484,13 @@ bool rtc_dig_8m_enabled(void)
}
//------------------------------------MPLL-------------------------------------//
void rtc_clk_mpll_disable(void)
TCM_IRAM_ATTR void rtc_clk_mpll_disable(void)
{
clk_ll_mpll_disable();
s_cur_mpll_freq = 0;
}
void rtc_clk_mpll_enable(void)
TCM_IRAM_ATTR void rtc_clk_mpll_enable(void)
{
clk_ll_mpll_enable();
}
@ -508,7 +508,7 @@ void rtc_clk_mpll_configure(uint32_t xtal_freq, uint32_t mpll_freq)
s_cur_mpll_freq = mpll_freq;
}
uint32_t rtc_clk_mpll_get_freq(void)
TCM_IRAM_ATTR uint32_t rtc_clk_mpll_get_freq(void)
{
return s_cur_mpll_freq;
}

View File

@ -26,7 +26,9 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "soc/soc_caps.h"
#include "soc/chip_revision.h"
#include "driver/rtc_io.h"
#include "hal/efuse_hal.h"
#include "hal/rtc_io_hal.h"
#include "hal/clk_tree_hal.h"
@ -862,6 +864,12 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
pd_flags &= ~RTC_SLEEP_PD_RTC_PERIPH;
}
}
#elif CONFIG_IDF_TARGET_ESP32P4
/* Due to esp32p4 eco0 hardware bug, if LP peripheral power domain is powerdowned in sleep, there will be a possibility of
triggering the EFUSE_CRC reset, so disable the power-down of this power domain on lightsleep for ECO0 version. */
if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) {
pd_flags &= ~RTC_SLEEP_PD_RTC_PERIPH;
}
#endif
uint32_t reject_triggers = allow_sleep_rejection ? (s_config.wakeup_triggers & RTC_SLEEP_REJECT_MASK) : 0;
@ -981,13 +989,6 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
#endif
#endif
#if SOC_CLK_MPLL_SUPPORTED
uint32_t mpll_freq_mhz = rtc_clk_mpll_get_freq();
if (mpll_freq_mhz) {
rtc_clk_mpll_disable();
}
#endif
#if SOC_DCDC_SUPPORTED
#if CONFIG_ESP_SLEEP_KEEP_DCDC_ALWAYS_ON
if (!deep_sleep) {
@ -1022,13 +1023,6 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m
result = call_rtc_sleep_start(reject_triggers, config.lslp_mem_inf_fpu, deep_sleep);
#endif
#if SOC_CLK_MPLL_SUPPORTED
if (mpll_freq_mhz) {
rtc_clk_mpll_enable();
rtc_clk_mpll_configure(clk_hal_xtal_get_freq_mhz(), mpll_freq_mhz);
}
#endif
/* Unhold the SPI CS pin */
#if (CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && CONFIG_ESP_SLEEP_FLASH_LEAKAGE_WORKAROUND)
#if !CONFIG_IDF_TARGET_ESP32H2 // ESP32H2 TODO IDF-7359: related rtcio ll func not supported yet
@ -2275,6 +2269,12 @@ static uint32_t get_power_down_flags(void)
}
#endif
#if SOC_PM_SUPPORT_CNNT_PD
if (s_config.domain[ESP_PD_DOMAIN_CNNT].pd_option != ESP_PD_OPTION_ON) {
pd_flags |= PMU_SLEEP_PD_CNNT;
}
#endif
#if SOC_PM_SUPPORT_VDDSDIO_PD
if (s_config.domain[ESP_PD_DOMAIN_VDDSDIO].pd_option != ESP_PD_OPTION_ON) {
pd_flags |= RTC_SLEEP_PD_VDDSDIO;

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -7,8 +7,10 @@
#ifndef _ROM_CACHE_H_
#define _ROM_CACHE_H_
#if (!defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__))
#include <stdint.h>
#include "esp_bit_defs.h"
#endif
#ifdef __cplusplus
extern "C" {
@ -86,6 +88,16 @@ extern "C" {
// should NOT =
#define SMMU_GID_TBIT_INDEX_HIGH (SMMU_GID_TBIT_INDEX_LOW + SMMU_GID_TBIT_NUM)
#define CACHE_MAP_L1_ICACHE_0 BIT(0)
#define CACHE_MAP_L1_ICACHE_1 BIT(1)
#define CACHE_MAP_L1_DCACHE BIT(4)
#define CACHE_MAP_L2_CACHE BIT(5)
#define CACHE_MAP_L1_ICACHE_MASK (CACHE_MAP_L1_ICACHE_0 | CACHE_MAP_L1_ICACHE_1)
#define CACHE_MAP_L1_CACHE_MASK (CACHE_MAP_L1_ICACHE_MASK | CACHE_MAP_L1_DCACHE)
#define CACHE_MAP_MASK (CACHE_MAP_L1_ICACHE_MASK | CACHE_MAP_L1_DCACHE | CACHE_MAP_L2_CACHE)
#if (!defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__))
typedef enum {
CACHE_L1_ICACHE0 = 0,
CACHE_L1_ICACHE1 = 1,
@ -225,14 +237,6 @@ typedef enum {
CACHE_SYNC_WRITEBACK_INVALIDATE = BIT(3),
} cache_sync_t;
#define CACHE_MAP_L1_ICACHE_0 BIT(0)
#define CACHE_MAP_L1_ICACHE_1 BIT(1)
#define CACHE_MAP_L1_DCACHE BIT(4)
#define CACHE_MAP_L2_CACHE BIT(5)
#define CACHE_MAP_L1_ICACHE_MASK (CACHE_MAP_L1_ICACHE_0 | CACHE_MAP_L1_ICACHE_1)
#define CACHE_MAP_MASK (CACHE_MAP_L1_ICACHE_MASK | CACHE_MAP_L1_DCACHE | CACHE_MAP_L2_CACHE)
struct cache_internal_stub_table {
uint32_t (*l1_icache_line_size)(void);
uint32_t (*l1_dcache_line_size)(void);
@ -507,7 +511,7 @@ void ROM_Direct_Boot_Cache_Init(void);
*
* @param None
*
* @return 0 if mmu map is sucessfully, others if not.
* @return 0 if mmu map is successfully, others if not.
*/
int ROM_Direct_Boot_MMU_Init(void);
@ -1517,7 +1521,7 @@ void Cache_Freeze_L2_Cache_Disable(void);
void Cache_Travel_Tag_Memory(struct cache_mode *mode, uint32_t filter_addr, void (*process)(struct tag_group_info *, int res[]), int res[]);
/**
* @brief Travel tag memory to run a call back function using 2rd tag api.
* @brief Travel tag memory to run a call back function using 2nd tag api.
* ICache and DCache are suspend when doing this.
* The callback will get the parameter tag_group_info, which will include a group of tag memory addresses and cache memory addresses.
* Please do not call this function in your SDK application.
@ -1539,7 +1543,7 @@ void Cache_Travel_Tag_Memory2(struct cache_mode *mode, uint32_t filter_addr, voi
*
* @param struct cache_mode * mode : the cache to calculate the virtual address and the cache mode.
*
* @param uint32_t tag : the tag part fo a tag item, 12-14 bits.
* @param uint32_t tag : the tag part for a tag item, 12-14 bits.
*
* @param uint32_t addr_offset : the virtual address offset of the cache ways.
*
@ -1602,6 +1606,8 @@ int flash2spiram_rodata_offset(void);
uint32_t flash_instr_rodata_start_page(uint32_t bus);
uint32_t flash_instr_rodata_end_page(uint32_t bus);
#endif // #if (!defined(_ASMLANGUAGE) && !defined(__ASSEMBLER__))
#ifdef __cplusplus
}
#endif

View File

@ -8,6 +8,8 @@
#include "esp_rom_sys.h"
#include "esp_private/system_internal.h"
#include "soc/rtc_periph.h"
#include "soc/chip_revision.h"
#include "hal/efuse_hal.h"
#include "esp32p4/rom/rtc.h"
static void esp_reset_reason_clear_hint(void);
@ -57,7 +59,9 @@ static esp_reset_reason_t get_reset_reason(soc_reset_reason_t rtc_reset_reason,
case RESET_REASON_CORE_EFUSE_CRC:
#if CONFIG_IDF_TARGET_ESP32P4
return ESP_RST_DEEPSLEEP; // TODO: IDF-9564
if (!ESP_CHIP_REV_ABOVE(efuse_hal_chip_revision(), 1)) {
return ESP_RST_DEEPSLEEP;
}
#endif
return ESP_RST_EFUSE;

View File

@ -18,6 +18,15 @@
extern "C" {
#endif
typedef enum {
EFUSE_CONTROLLER_STATE_RESET = 0, ///< efuse_controllerid is on reset state.
EFUSE_CONTROLLER_STATE_IDLE = 1, ///< efuse_controllerid is on idle state.
EFUSE_CONTROLLER_STATE_READ_INIT = 2, ///< efuse_controllerid is on read init state.
EFUSE_CONTROLLER_STATE_READ_BLK0 = 3, ///< efuse_controllerid is on reading block0 state.
EFUSE_CONTROLLER_STATE_BLK0_CRC_CHECK = 4, ///< efuse_controllerid is on checking block0 crc state.
EFUSE_CONTROLLER_STATE_READ_RS_BLK = 5, ///< efuse_controllerid is on reading RS block state.
} efuse_controller_state_t;
// Always inline these functions even no gcc optimization is applied.
/******************* eFuse fields *************************/
@ -134,6 +143,11 @@ __attribute__((always_inline)) static inline void efuse_ll_rs_bypass_update(void
/******************* eFuse control functions *************************/
__attribute__((always_inline)) static inline uint32_t efuse_ll_get_controller_state(void)
{
return EFUSE.status.state;
}
#ifdef __cplusplus
}
#endif

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -16,6 +16,15 @@
extern "C" {
#endif
typedef enum {
EFUSE_CONTROLLER_STATE_RESET = 0, ///< efuse_controllerid is on reset state.
EFUSE_CONTROLLER_STATE_IDLE = 1, ///< efuse_controllerid is on idle state.
EFUSE_CONTROLLER_STATE_READ_INIT = 2, ///< efuse_controllerid is on read init state.
EFUSE_CONTROLLER_STATE_READ_BLK0 = 3, ///< efuse_controllerid is on reading block0 state.
EFUSE_CONTROLLER_STATE_BLK0_CRC_CHECK = 4, ///< efuse_controllerid is on checking block0 crc state.
EFUSE_CONTROLLER_STATE_READ_RS_BLK = 5, ///< efuse_controllerid is on reading RS block state.
} efuse_controller_state_t;
// Always inline these functions even no gcc optimization is applied.
/******************* eFuse fields *************************/
@ -175,6 +184,11 @@ __attribute__((always_inline)) static inline void efuse_ll_set_pwr_off_num(uint1
EFUSE.wr_tim_conf2.pwr_off_num = value;
}
__attribute__((always_inline)) static inline uint32_t efuse_ll_get_controller_state(void)
{
return EFUSE.status.state;
}
/******************* eFuse control functions *************************/
#ifdef __cplusplus

View File

@ -16,6 +16,15 @@
extern "C" {
#endif
typedef enum {
EFUSE_CONTROLLER_STATE_RESET = 0, ///< efuse_controllerid is on reset state.
EFUSE_CONTROLLER_STATE_IDLE = 1, ///< efuse_controllerid is on idle state.
EFUSE_CONTROLLER_STATE_READ_INIT = 2, ///< efuse_controllerid is on read init state.
EFUSE_CONTROLLER_STATE_READ_BLK0 = 3, ///< efuse_controllerid is on reading block0 state.
EFUSE_CONTROLLER_STATE_BLK0_CRC_CHECK = 4, ///< efuse_controllerid is on checking block0 crc state.
EFUSE_CONTROLLER_STATE_READ_RS_BLK = 5, ///< efuse_controllerid is on reading RS block state.
} efuse_controller_state_t;
// Always inline these functions even no gcc optimization is applied.
/******************* eFuse fields *************************/
@ -130,6 +139,11 @@ __attribute__((always_inline)) static inline void efuse_ll_rs_bypass_update(void
EFUSE.wr_tim_conf0_rs_bypass.update = 1;
}
__attribute__((always_inline)) static inline uint32_t efuse_ll_get_controller_state(void)
{
return EFUSE.status.state;
}
/******************* eFuse control functions *************************/
#ifdef __cplusplus

View File

@ -1567,6 +1567,10 @@ config SOC_PM_SUPPORT_CNNT_PD
bool
default y
config SOC_PM_SUPPORT_RTC_PERIPH_PD
bool
default y
config SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY
bool
default y

View File

@ -620,6 +620,7 @@
#define SOC_PM_SUPPORT_VDDSDIO_PD (1)
#define SOC_PM_SUPPORT_TOP_PD (1)
#define SOC_PM_SUPPORT_CNNT_PD (1)
#define SOC_PM_SUPPORT_RTC_PERIPH_PD (1)
#define SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY (1) /*!<Supports CRC only the stub code in RTC memory */