From 4bcb88c4822ab18d3bfc87f86b4cb0df8b409a0e Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Thu, 14 Mar 2024 15:31:13 +0800 Subject: [PATCH 1/8] change(rtc): rename sleep mode related regs defination --- .../cpu_retention/port/esp32c5/sleep_cpu.c | 2 +- .../cpu_retention/port/esp32c6/sleep_cpu.c | 2 +- .../cpu_retention/port/esp32h2/sleep_cpu.c | 2 +- .../cpu_retention/port/esp32p4/sleep_cpu.c | 2 +- .../include/esp32c5/beta3/esp32c5/rom/rtc.h | 4 ++-- components/esp_rom/include/esp32c6/rom/rtc.h | 4 ++-- components/esp_rom/include/esp32h2/rom/rtc.h | 22 +++++++++---------- components/esp_rom/include/esp32p4/rom/rtc.h | 4 ++-- .../hal/esp32c6/include/hal/lp_aon_ll.h | 4 ++-- .../hal/esp32h2/include/hal/lp_aon_ll.h | 4 ++-- .../hal/esp32p4/include/hal/lp_sys_ll.h | 4 ++-- 11 files changed, 27 insertions(+), 27 deletions(-) diff --git a/components/esp_hw_support/lowpower/cpu_retention/port/esp32c5/sleep_cpu.c b/components/esp_hw_support/lowpower/cpu_retention/port/esp32c5/sleep_cpu.c index 5adaad5c83..94d64f61ca 100644 --- a/components/esp_hw_support/lowpower/cpu_retention/port/esp32c5/sleep_cpu.c +++ b/components/esp_hw_support/lowpower/cpu_retention/port/esp32c5/sleep_cpu.c @@ -467,7 +467,7 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep, /* Minus 2 * sizeof(long) is for bypass `pmufunc` and `frame_crc` field */ update_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_FRMSZ - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc)); #endif - REG_WRITE(LIGHT_SLEEP_WAKE_STUB_ADDR_REG, (uint32_t)rv_core_critical_regs_restore); + REG_WRITE(RTC_SLEEP_WAKE_STUB_ADDR_REG, (uint32_t)rv_core_critical_regs_restore); return (*goto_sleep)(wakeup_opt, reject_opt, lslp_mem_inf_fpu, dslp); } #if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME diff --git a/components/esp_hw_support/lowpower/cpu_retention/port/esp32c6/sleep_cpu.c b/components/esp_hw_support/lowpower/cpu_retention/port/esp32c6/sleep_cpu.c index 7378d2b48f..e56d0e12a3 100644 --- a/components/esp_hw_support/lowpower/cpu_retention/port/esp32c6/sleep_cpu.c +++ b/components/esp_hw_support/lowpower/cpu_retention/port/esp32c6/sleep_cpu.c @@ -467,7 +467,7 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep, /* Minus 2 * sizeof(long) is for bypass `pmufunc` and `frame_crc` field */ update_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_FRMSZ - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc)); #endif - REG_WRITE(LIGHT_SLEEP_WAKE_STUB_ADDR_REG, (uint32_t)rv_core_critical_regs_restore); + REG_WRITE(RTC_SLEEP_WAKE_STUB_ADDR_REG, (uint32_t)rv_core_critical_regs_restore); return (*goto_sleep)(wakeup_opt, reject_opt, lslp_mem_inf_fpu, dslp); } #if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME diff --git a/components/esp_hw_support/lowpower/cpu_retention/port/esp32h2/sleep_cpu.c b/components/esp_hw_support/lowpower/cpu_retention/port/esp32h2/sleep_cpu.c index bfcd95b4dd..69e8f05b0f 100644 --- a/components/esp_hw_support/lowpower/cpu_retention/port/esp32h2/sleep_cpu.c +++ b/components/esp_hw_support/lowpower/cpu_retention/port/esp32h2/sleep_cpu.c @@ -467,7 +467,7 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep, /* Minus 2 * sizeof(long) is for bypass `pmufunc` and `frame_crc` field */ update_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_FRMSZ - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc)); #endif - REG_WRITE(LIGHT_SLEEP_WAKE_STUB_ADDR_REG, (uint32_t)rv_core_critical_regs_restore); + REG_WRITE(RTC_SLEEP_WAKE_STUB_ADDR_REG, (uint32_t)rv_core_critical_regs_restore); return (*goto_sleep)(wakeup_opt, reject_opt, lslp_mem_inf_fpu, dslp); } #if CONFIG_PM_CHECK_SLEEP_RETENTION_FRAME diff --git a/components/esp_hw_support/lowpower/cpu_retention/port/esp32p4/sleep_cpu.c b/components/esp_hw_support/lowpower/cpu_retention/port/esp32p4/sleep_cpu.c index 3b18daad91..864dbf24a9 100644 --- a/components/esp_hw_support/lowpower/cpu_retention/port/esp32p4/sleep_cpu.c +++ b/components/esp_hw_support/lowpower/cpu_retention/port/esp32p4/sleep_cpu.c @@ -413,7 +413,7 @@ static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep, /* Minus 2 * sizeof(long) is for bypass `pmufunc` and `frame_crc` field */ update_retention_frame_crc((uint32_t*)frame, RV_SLEEP_CTX_FRMSZ - 2 * sizeof(long), (uint32_t *)(&frame->frame_crc)); #endif - REG_WRITE(LIGHT_SLEEP_WAKE_STUB_ADDR_REG, (uint32_t)rv_core_critical_regs_restore); + REG_WRITE(RTC_SLEEP_WAKE_STUB_ADDR_REG, (uint32_t)rv_core_critical_regs_restore); #if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && !CONFIG_FREERTOS_UNICORE atomic_store(&s_smp_retention_state[core_id], SMP_BACKUP_DONE); diff --git a/components/esp_rom/include/esp32c5/beta3/esp32c5/rom/rtc.h b/components/esp_rom/include/esp32c5/beta3/esp32c5/rom/rtc.h index 9f1e270b6c..65e37dbf7c 100644 --- a/components/esp_rom/include/esp32c5/beta3/esp32c5/rom/rtc.h +++ b/components/esp_rom/include/esp32c5/beta3/esp32c5/rom/rtc.h @@ -63,8 +63,8 @@ extern "C" { #define RTC_ENTRY_ADDR_REG LP_AON_STORE6_REG #define RTC_RESET_CAUSE_REG LP_AON_STORE6_REG #define RTC_MEMORY_CRC_REG LP_AON_STORE7_REG -#define LIGHT_SLEEP_WAKE_STUB_ADDR_REG LP_AON_STORE8_REG -#define SLEEP_MODE_REG LP_AON_STORE9_REG +#define RTC_SLEEP_WAKE_STUB_ADDR_REG LP_AON_STORE8_REG +#define RTC_SLEEP_MODE_REG LP_AON_STORE9_REG #define RTC_DISABLE_ROM_LOG ((1 << 0) | (1 << 16)) //!< Disable logging from the ROM code. diff --git a/components/esp_rom/include/esp32c6/rom/rtc.h b/components/esp_rom/include/esp32c6/rom/rtc.h index ba282307e0..a94fd96c88 100644 --- a/components/esp_rom/include/esp32c6/rom/rtc.h +++ b/components/esp_rom/include/esp32c6/rom/rtc.h @@ -64,8 +64,8 @@ extern "C" { #define RTC_ENTRY_ADDR_REG LP_AON_STORE6_REG #define RTC_RESET_CAUSE_REG LP_AON_STORE6_REG #define RTC_MEMORY_CRC_REG LP_AON_STORE7_REG -#define LIGHT_SLEEP_WAKE_STUB_ADDR_REG LP_AON_STORE8_REG -#define SLEEP_MODE_REG LP_AON_STORE9_REG +#define RTC_SLEEP_WAKE_STUB_ADDR_REG LP_AON_STORE8_REG +#define RTC_SLEEP_MODE_REG LP_AON_STORE9_REG #define RTC_DISABLE_ROM_LOG ((1 << 0) | (1 << 16)) //!< Disable logging from the ROM code. diff --git a/components/esp_rom/include/esp32h2/rom/rtc.h b/components/esp_rom/include/esp32h2/rom/rtc.h index b09e5cc242..1c36cb33b3 100644 --- a/components/esp_rom/include/esp32h2/rom/rtc.h +++ b/components/esp_rom/include/esp32h2/rom/rtc.h @@ -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 */ @@ -55,16 +55,16 @@ extern "C" { ************************************************************************************* */ -#define RTC_SLOW_CLK_CAL_REG LP_AON_STORE1_REG -#define RTC_BOOT_TIME_LOW_REG LP_AON_STORE2_REG -#define RTC_BOOT_TIME_HIGH_REG LP_AON_STORE3_REG -#define RTC_XTAL_FREQ_REG LP_AON_STORE4_REG -#define RTC_APB_FREQ_REG LP_AON_STORE5_REG -#define RTC_ENTRY_ADDR_REG LP_AON_STORE6_REG -#define RTC_RESET_CAUSE_REG LP_AON_STORE6_REG -#define RTC_MEMORY_CRC_REG LP_AON_STORE7_REG -#define LIGHT_SLEEP_WAKE_STUB_ADDR_REG LP_AON_STORE8_REG -#define SLEEP_MODE_REG LP_AON_STORE9_REG +#define RTC_SLOW_CLK_CAL_REG LP_AON_STORE1_REG +#define RTC_BOOT_TIME_LOW_REG LP_AON_STORE2_REG +#define RTC_BOOT_TIME_HIGH_REG LP_AON_STORE3_REG +#define RTC_XTAL_FREQ_REG LP_AON_STORE4_REG +#define RTC_APB_FREQ_REG LP_AON_STORE5_REG +#define RTC_ENTRY_ADDR_REG LP_AON_STORE6_REG +#define RTC_RESET_CAUSE_REG LP_AON_STORE6_REG +#define RTC_MEMORY_CRC_REG LP_AON_STORE7_REG +#define RTC_SLEEP_WAKE_STUB_ADDR_REG LP_AON_STORE8_REG +#define RTC_SLEEP_MODE_REG LP_AON_STORE9_REG #define RTC_DISABLE_ROM_LOG ((1 << 0) | (1 << 16)) //!< Disable logging from the ROM code. diff --git a/components/esp_rom/include/esp32p4/rom/rtc.h b/components/esp_rom/include/esp32p4/rom/rtc.h index d47d202a35..aa45a97d01 100644 --- a/components/esp_rom/include/esp32p4/rom/rtc.h +++ b/components/esp_rom/include/esp32p4/rom/rtc.h @@ -72,8 +72,8 @@ extern "C" { * 0 -- light sleep * 1 -- deep sleep */ -#define LIGHT_SLEEP_WAKE_STUB_ADDR_REG LP_SYSTEM_REG_LP_STORE8_REG -#define SLEEP_MODE_REG LP_SYSTEM_REG_LP_STORE8_REG +#define RTC_SLEEP_WAKE_STUB_ADDR_REG LP_SYSTEM_REG_LP_STORE8_REG +#define RTC_SLEEP_MODE_REG LP_SYSTEM_REG_LP_STORE8_REG typedef enum { AWAKE = 0, // Date: Wed, 27 Mar 2024 10:20:08 +0800 Subject: [PATCH 2/8] fix(esp_hw_support): fix pmu analog parameter configuration missing --- .../port/esp32c6/private_include/pmu_param.h | 6 +++--- components/esp_hw_support/port/esp32p4/pmu_sleep.c | 6 ++++++ .../port/esp32p4/private_include/pmu_param.h | 8 ++++---- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/components/esp_hw_support/port/esp32c6/private_include/pmu_param.h b/components/esp_hw_support/port/esp32c6/private_include/pmu_param.h index 950a3ac91b..751076f752 100644 --- a/components/esp_hw_support/port/esp32c6/private_include/pmu_param.h +++ b/components/esp_hw_support/port/esp32c6/private_include/pmu_param.h @@ -349,7 +349,7 @@ typedef struct { }, \ .lp_sys[PMU_MODE_LP_SLEEP] = { \ .analog = { \ - .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, \ @@ -419,7 +419,7 @@ typedef struct { typedef struct pmu_sleep_machine_constant { struct { - uint16_t min_slp_time_us; /* Mininum sleep protection time (unit: microsecond) */ + uint16_t min_slp_time_us; /* Minimum sleep protection time (unit: microsecond) */ uint8_t wakeup_wait_cycle; /* Modem wakeup signal (WiFi MAC and BEACON wakeup) waits for the slow & fast clock domain synchronization and the wakeup signal triggers the PMU FSM switching wait cycle (unit: slow clock cycle) */ uint8_t reserved0; uint16_t reserved1; @@ -431,7 +431,7 @@ typedef struct pmu_sleep_machine_constant { uint16_t power_up_wait_time_us; /* (unit: microsecond) */ } lp; struct { - uint16_t min_slp_time_us; /* Mininum sleep protection time (unit: microsecond) */ + uint16_t min_slp_time_us; /* Minimum sleep protection time (unit: microsecond) */ uint16_t clock_domain_sync_time_us; /* The Slow OSC clock domain synchronizes time with the Fast OSC domain, at least 4 slow clock cycles (unit: microsecond) */ uint16_t system_dfs_up_work_time_us; /* System DFS up scaling work time (unit: microsecond) */ uint16_t analog_wait_time_us; /* HP LDO power up wait time (unit: microsecond) */ diff --git a/components/esp_hw_support/port/esp32p4/pmu_sleep.c b/components/esp_hw_support/port/esp32p4/pmu_sleep.c index fb4f4017de..fbe5597c38 100644 --- a/components/esp_hw_support/port/esp32p4/pmu_sleep.c +++ b/components/esp_hw_support/port/esp32p4/pmu_sleep.c @@ -191,6 +191,7 @@ static void pmu_sleep_analog_init(pmu_context_t *ctx, const pmu_sleep_analog_con pmu_ll_hp_set_regulator_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.xpd); pmu_ll_hp_set_regulator_sleep_memory_dbias(ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.slp_mem_dbias); pmu_ll_hp_set_regulator_sleep_logic_dbias (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.slp_logic_dbias); + pmu_ll_hp_set_dbg_atten (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.dbg_atten); 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); @@ -201,9 +202,14 @@ static void pmu_sleep_analog_init(pmu_context_t *ctx, const pmu_sleep_analog_con 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_xpd (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.xpd); + 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_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_dbg_atten (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.dbg_atten); pmu_ll_lp_set_regulator_driver_bar (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.drv_b); + + pmu_ll_lp_set_regulator_slp_xpd (ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.slp_xpd); + pmu_ll_lp_set_regulator_xpd (ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.xpd); } static void pmu_sleep_param_init(pmu_context_t *ctx, const pmu_sleep_param_config_t *param, bool dslp) diff --git a/components/esp_hw_support/port/esp32p4/private_include/pmu_param.h b/components/esp_hw_support/port/esp32p4/private_include/pmu_param.h index ccbcc8da90..b1c3aec175 100644 --- a/components/esp_hw_support/port/esp32p4/private_include/pmu_param.h +++ b/components/esp_hw_support/port/esp32p4/private_include/pmu_param.h @@ -349,7 +349,7 @@ typedef struct { }, \ .lp_sys[PMU_MODE_LP_SLEEP] = { \ .analog = { \ - .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, \ @@ -428,7 +428,7 @@ typedef struct { typedef struct pmu_sleep_machine_constant { struct { - uint16_t min_slp_time_us; /* Mininum sleep protection time (unit: microsecond) */ + uint16_t min_slp_time_us; /* Minimum sleep protection time (unit: microsecond) */ uint8_t wakeup_wait_cycle; /* Modem wakeup signal (WiFi MAC and BEACON wakeup) waits for the slow & fast clock domain synchronization and the wakeup signal triggers the PMU FSM switching wait cycle (unit: slow clock cycle) */ uint8_t reserved0; uint16_t reserved1; @@ -440,7 +440,7 @@ typedef struct pmu_sleep_machine_constant { uint16_t power_up_wait_time_us; /* (unit: microsecond) */ } lp; struct { - uint16_t min_slp_time_us; /* Mininum sleep protection time (unit: microsecond) */ + uint16_t min_slp_time_us; /* Minimum sleep protection time (unit: microsecond) */ uint16_t clock_domain_sync_time_us; /* The Slow OSC clock domain synchronizes time with the Fast OSC domain, at least 4 slow clock cycles (unit: microsecond) */ uint16_t system_dfs_up_work_time_us; /* System DFS up scaling work time (unit: microsecond) */ uint16_t analog_wait_time_us; /* HP LDO power up wait time (unit: microsecond) */ @@ -461,7 +461,7 @@ typedef struct pmu_sleep_machine_constant { // If TOP is power down, the time the regdma runs will cover some of the time // spent waiting for the DCDC to startup. #define PMU_HP_ANA_WAIT_TIME_PD_TOP_US 260 -// If TOP doamin is not powered down, we need to stay in HP_SWITCH longer to wait for the +// If TOP domain is not powered down, we need to stay in HP_SWITCH longer to wait for the // DCDC startup, which saves more power compared to waiting in the Active state. #define PMU_HP_ANA_WAIT_TIME_PU_TOP_US (PMU_HP_ANA_WAIT_TIME_PD_TOP_US + PMU_REGDMA_S2A_WORK_TIME_US) // 945 From 5d24a818eb47c16b1b87b764d6b42631abd88c64 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Tue, 6 Feb 2024 10:49:33 +0800 Subject: [PATCH 3/8] feat(esp_hw_support): add esp32p4 pau initial support --- .../esp_hw_support/port/esp32p4/pmu_sleep.c | 15 ++ components/esp_hw_support/port/pau_regdma.c | 7 +- components/esp_hw_support/port/regdma_link.c | 3 + components/hal/esp32c6/include/hal/pau_ll.h | 9 +- components/hal/esp32h2/include/hal/pau_ll.h | 9 +- .../hal/esp32p4/include/hal/clk_gate_ll.h | 8 + .../hal/esp32p4/include/hal/lp_sys_ll.h | 25 +++ components/hal/esp32p4/include/hal/pau_ll.h | 150 ++++++++++++++++++ components/hal/esp32p4/pau_hal.c | 72 +++++++++ components/hal/include/hal/pau_hal.h | 11 +- .../esp32p4/include/soc/Kconfig.soc_caps.in | 8 + .../soc/esp32p4/include/soc/pau_struct.h | 1 + .../soc/esp32p4/include/soc/periph_defs.h | 1 + components/soc/esp32p4/include/soc/reg_base.h | 3 +- components/soc/esp32p4/include/soc/soc_caps.h | 3 +- .../soc/esp32p4/ld/esp32p4.peripherals.ld | 1 + 16 files changed, 306 insertions(+), 20 deletions(-) create mode 100644 components/hal/esp32p4/include/hal/pau_ll.h create mode 100644 components/hal/esp32p4/pau_hal.c diff --git a/components/esp_hw_support/port/esp32p4/pmu_sleep.c b/components/esp_hw_support/port/esp32p4/pmu_sleep.c index fbe5597c38..578c14115e 100644 --- a/components/esp_hw_support/port/esp32p4/pmu_sleep.c +++ b/components/esp_hw_support/port/esp32p4/pmu_sleep.c @@ -20,7 +20,9 @@ #include "soc/pmu_reg.h" #include "soc/pmu_struct.h" #include "hal/lp_aon_hal.h" +#include "soc/lp_system_reg.h" #include "hal/pmu_hal.h" +#include "hal/lp_sys_ll.h" #include "esp_private/esp_pmu.h" #include "pmu_param.h" #include "esp_rom_sys.h" @@ -237,6 +239,19 @@ void pmu_sleep_init(const pmu_sleep_config_t *config, bool dslp) } pmu_sleep_analog_init(PMU_instance(), &config->analog, dslp); pmu_sleep_param_init(PMU_instance(), &config->param, dslp); + + // When light sleep (PD_TOP), the PAU will power down. so need use LP_SYS_BACKUP_DMA_CFG2_REG to store recover link address. + if (!dslp && PMU.hp_sys[PMU_MODE_HP_SLEEP].dig_power.top_pd_en) { + if (PMU.hp_sys[PMU_MODE_HP_SLEEP].backup.hp_active2sleep_backup_en || + PMU.hp_sys[PMU_MODE_HP_ACTIVE].backup.hp_sleep2active_backup_en) { + uint32_t link_sel = PMU.hp_sys[PMU_MODE_HP_SLEEP].backup.hp_active2sleep_backup_mode & 0x3; + uint32_t link_addr = REG_READ(PAU_REGDMA_LINK_0_ADDR_REG + link_sel * 4); + lp_sys_ll_set_pau_link_addr(link_addr); + pmu_sleep_enable_regdma_backup(); + } + } else { + pmu_sleep_disable_regdma_backup(); + } } void pmu_sleep_increase_ldo_volt(void) { diff --git a/components/esp_hw_support/port/pau_regdma.c b/components/esp_hw_support/port/pau_regdma.c index 0ff2a8e6cd..152dbf65be 100644 --- a/components/esp_hw_support/port/pau_regdma.c +++ b/components/esp_hw_support/port/pau_regdma.c @@ -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 */ @@ -11,7 +11,7 @@ #include "esp_attr.h" #include "esp_log.h" #include "soc/soc.h" -#include "soc/pcr_reg.h" +#include "soc/soc_caps.h" #include "esp_private/esp_pau.h" #include "esp_private/periph_ctrl.h" @@ -32,6 +32,9 @@ pau_context_t * __attribute__((weak)) IRAM_ATTR PAU_instance(void) if (pau_hal.dev == NULL) { pau_hal.dev = &PAU; periph_module_enable(PERIPH_REGDMA_MODULE); +#if SOC_PAU_IN_TOP_DOMAIN + pau_hal_lp_sys_initialize(); +#endif } return &pau_context; diff --git a/components/esp_hw_support/port/regdma_link.c b/components/esp_hw_support/port/regdma_link.c index f182318423..76b9ce0a95 100644 --- a/components/esp_hw_support/port/regdma_link.c +++ b/components/esp_hw_support/port/regdma_link.c @@ -531,18 +531,21 @@ static void regdma_link_update_continuous_next_wrapper(void *link, void *next) { regdma_link_continuous_t *continuous = __containerof(link, regdma_link_continuous_t, head); continuous->body.next = next; + continuous->head.eof = !next; } static void regdma_link_update_addr_map_next_wrapper(void *link, void *next) { regdma_link_addr_map_t *addr_map = __containerof(link, regdma_link_addr_map_t, head); addr_map->body.next = next; + addr_map->head.eof = !next; } static void regdma_link_update_write_wait_next_wrapper(void *link, void *next) { regdma_link_write_wait_t *write_wait = __containerof(link, regdma_link_write_wait_t, head); write_wait->body.next = next; + write_wait->head.eof = !next; } static void regdma_link_update_branch_continuous_next_wrapper(void *link, regdma_entry_buf_t *next) diff --git a/components/hal/esp32c6/include/hal/pau_ll.h b/components/hal/esp32c6/include/hal/pau_ll.h index 8fb18d7146..998fa628c8 100644 --- a/components/hal/esp32c6/include/hal/pau_ll.h +++ b/components/hal/esp32c6/include/hal/pau_ll.h @@ -130,14 +130,9 @@ static inline void pau_ll_set_regdma_backup_done_intr_disable(pau_dev_t *dev) dev->int_ena.done_int_ena = 0; } -static inline void pau_ll_set_regdma_backup_error_intr_enable(pau_dev_t *dev) +static inline void pau_ll_set_regdma_backup_error_intr_enable(pau_dev_t *dev, bool enable) { - dev->int_ena.error_int_ena = 1; -} - -static inline void pau_ll_set_regdma_backup_error_intr_disable(pau_dev_t *dev) -{ - dev->int_ena.error_int_ena = 0; + dev->int_ena.error_int_ena = enable; } static inline void pau_ll_clear_regdma_backup_done_intr_state(pau_dev_t *dev) diff --git a/components/hal/esp32h2/include/hal/pau_ll.h b/components/hal/esp32h2/include/hal/pau_ll.h index 98f730ff25..fdc44feec6 100644 --- a/components/hal/esp32h2/include/hal/pau_ll.h +++ b/components/hal/esp32h2/include/hal/pau_ll.h @@ -100,14 +100,9 @@ static inline __attribute__((always_inline)) void pau_ll_set_regdma_backup_done_ dev->int_ena.done_int_ena = 0; } -static inline __attribute__((always_inline)) void pau_ll_set_regdma_backup_error_intr_enable(pau_dev_t *dev) +static inline void pau_ll_set_regdma_backup_error_intr_enable(pau_dev_t *dev, bool enable) { - dev->int_ena.error_int_ena = 1; -} - -static inline __attribute__((always_inline)) void pau_ll_set_regdma_backup_error_intr_disable(pau_dev_t *dev) -{ - dev->int_ena.error_int_ena = 0; + dev->int_ena.error_int_ena = enable; } static inline __attribute__((always_inline)) void pau_ll_clear_regdma_backup_done_intr_state(pau_dev_t *dev) diff --git a/components/hal/esp32p4/include/hal/clk_gate_ll.h b/components/hal/esp32p4/include/hal/clk_gate_ll.h index caf46ad96e..f91e6d1753 100644 --- a/components/hal/esp32p4/include/hal/clk_gate_ll.h +++ b/components/hal/esp32p4/include/hal/clk_gate_ll.h @@ -47,6 +47,8 @@ static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph) return HP_SYS_CLKRST_REG_CRYPTO_ECDSA_CLK_EN; case PERIPH_ISP_MODULE: return HP_SYS_CLKRST_REG_ISP_CLK_EN; + case PERIPH_REGDMA_MODULE: + return HP_SYS_CLKRST_REG_REGDMA_SYS_CLK_EN; default: return 0; } @@ -103,6 +105,8 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en return HP_SYS_CLKRST_REG_RST_EN_ECDSA; case PERIPH_EMAC_MODULE: return LP_CLKRST_RST_EN_EMAC; + case PERIPH_REGDMA_MODULE: + return HP_SYS_CLKRST_REG_RST_EN_REGDMA; default: return 0; } @@ -128,6 +132,8 @@ static inline uint32_t periph_ll_get_clk_en_reg(periph_module_t periph) return HP_SYS_CLKRST_PERI_CLK_CTRL25_REG; case PERIPH_EMAC_MODULE: return LP_CLKRST_HP_CLK_CTRL_REG; + case PERIPH_REGDMA_MODULE: + return HP_SYS_CLKRST_SOC_CLK_CTRL0_REG; default: abort(); return 0; @@ -154,6 +160,8 @@ static inline uint32_t periph_ll_get_rst_en_reg(periph_module_t periph) return HP_SYS_CLKRST_HP_RST_EN2_REG; case PERIPH_EMAC_MODULE: return LP_CLKRST_HP_SDMMC_EMAC_RST_CTRL_REG; + case PERIPH_REGDMA_MODULE: + return HP_SYS_CLKRST_HP_RST_EN0_REG; default: abort(); return 0; diff --git a/components/hal/esp32p4/include/hal/lp_sys_ll.h b/components/hal/esp32p4/include/hal/lp_sys_ll.h index 7c6a2c01cc..d1b8776b51 100644 --- a/components/hal/esp32p4/include/hal/lp_sys_ll.h +++ b/components/hal/esp32p4/include/hal/lp_sys_ll.h @@ -34,6 +34,31 @@ static inline void lp_sys_ll_inform_wakeup_type(bool dslp) } } +static inline void lp_sys_ll_set_pau_aon_bypass(bool bypass) +{ + LP_SYS.backup_dma_cfg1.aon_bypass = bypass ? 1 : 0; +} + +static inline void lp_sys_ll_set_pau_link_tout_thres(uint32_t tout) +{ + LP_SYS.backup_dma_cfg0.link_tout_thres_aon = tout; +} + +static inline void lp_sys_ll_set_pau_link_backup_tout_thres(uint32_t tout) +{ + LP_SYS.backup_dma_cfg0.link_backup_tout_thres_aon = tout; +} + +static inline void lp_sys_ll_set_pau_reg_read_interval(uint32_t val) +{ + LP_SYS.backup_dma_cfg0.read_interval_aon = val; +} + +static inline void lp_sys_ll_set_pau_link_addr(uint32_t addr) +{ + LP_SYS.backup_dma_cfg2.link_addr_aon = addr; +} + #ifdef __cplusplus } #endif diff --git a/components/hal/esp32p4/include/hal/pau_ll.h b/components/hal/esp32p4/include/hal/pau_ll.h new file mode 100644 index 0000000000..ebd48057e2 --- /dev/null +++ b/components/hal/esp32p4/include/hal/pau_ll.h @@ -0,0 +1,150 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The LL layer for ESP32-C6 PAU(Power Assist Unit) register operations + +#pragma once + +#include +#include +#include "soc/soc.h" +#include "soc/pau_reg.h" +#include "soc/pau_struct.h" +#include "hal/pau_types.h" +#include "hal/assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static inline uint32_t pau_ll_get_regdma_backup_flow_error(pau_dev_t *dev) +{ + return dev->regdma_conf.flow_err; +} + +static inline void pau_ll_select_regdma_entry_link(pau_dev_t *dev, int link) +{ + dev->regdma_conf.link_sel = link; +} + +static inline void pau_ll_set_regdma_entry_link_backup_direction(pau_dev_t *dev, bool to_mem) +{ + dev->regdma_conf.to_mem = to_mem ? 1 : 0; +} + +static inline void pau_ll_set_regdma_entry_link_backup_start_enable(pau_dev_t *dev) +{ + dev->regdma_conf.start = 1; +} + +static inline void pau_ll_set_regdma_entry_link_backup_start_disable(pau_dev_t *dev) +{ + dev->regdma_conf.start = 0; +} + +static inline void pau_ll_set_regdma_select_wifimac_link(pau_dev_t *dev) +{ + dev->regdma_conf.sel_mac = 1; +} + +static inline void pau_ll_set_regdma_deselect_wifimac_link(pau_dev_t *dev) +{ + dev->regdma_conf.sel_mac = 0; +} + +static inline void pau_ll_set_regdma_wifimac_link_backup_direction(pau_dev_t *dev, bool to_mem) +{ + dev->regdma_conf.to_mem_mac = to_mem ? 1 : 0; +} + +static inline void pau_ll_set_regdma_wifimac_link_backup_start_enable(pau_dev_t *dev) +{ + dev->regdma_conf.start_mac = 1; +} + +static inline void pau_ll_set_regdma_wifimac_link_backup_start_disable(pau_dev_t *dev) +{ + dev->regdma_conf.start_mac = 0; +} + +static inline void pau_ll_set_regdma_link0_addr(pau_dev_t *dev, void *link_addr) +{ + dev->regdma_link_0_addr.val = (uint32_t)link_addr; +} + +static inline void pau_ll_set_regdma_link1_addr(pau_dev_t *dev, void *link_addr) +{ + dev->regdma_link_1_addr.val = (uint32_t)link_addr; +} + +static inline void pau_ll_set_regdma_link2_addr(pau_dev_t *dev, void *link_addr) +{ + dev->regdma_link_2_addr.val = (uint32_t)link_addr; +} + +static inline void pau_ll_set_regdma_link3_addr(pau_dev_t *dev, void *link_addr) +{ + dev->regdma_link_3_addr.val = (uint32_t)link_addr; +} + +static inline void pau_ll_set_regdma_wifimac_link_addr(pau_dev_t *dev, void *link_addr) +{ + dev->regdma_link_mac_addr.val = (uint32_t)link_addr; +} + +static inline uint32_t pau_ll_get_regdma_current_link_addr(pau_dev_t *dev) +{ + return dev->regdma_current_link_addr.val; +} + +static inline uint32_t pau_ll_get_regdma_backup_addr(pau_dev_t *dev) +{ + return dev->regdma_backup_addr.val; +} + +static inline uint32_t pau_ll_get_regdma_memory_addr(pau_dev_t *dev) +{ + return dev->regdma_mem_addr.val; +} + +static inline uint32_t pau_ll_get_regdma_intr_raw_signal(pau_dev_t *dev) +{ + return dev->int_raw.val; +} + +static inline uint32_t pau_ll_get_regdma_intr_status(pau_dev_t *dev) +{ + return dev->int_st.val; +} + +static inline void pau_ll_set_regdma_backup_done_intr_enable(pau_dev_t *dev) +{ + dev->int_ena.done_int_ena = 1; +} + +static inline void pau_ll_set_regdma_backup_done_intr_disable(pau_dev_t *dev) +{ + dev->int_ena.done_int_ena = 0; +} + +static inline void pau_ll_set_regdma_backup_error_intr_enable(pau_dev_t *dev, bool enable) +{ + dev->int_ena.error_int_ena = enable; +} + +static inline void pau_ll_clear_regdma_backup_done_intr_state(pau_dev_t *dev) +{ + dev->int_clr.done_int_clr = 1; +} + +static inline void pau_ll_clear_regdma_backup_error_intr_state(pau_dev_t *dev) +{ + dev->int_clr.error_int_clr = 1; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32p4/pau_hal.c b/components/hal/esp32p4/pau_hal.c new file mode 100644 index 0000000000..958210f0c1 --- /dev/null +++ b/components/hal/esp32p4/pau_hal.c @@ -0,0 +1,72 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The HAL layer for PAU (ESP32-C6 specific part) + +#include "soc/soc.h" +#include "soc/soc_caps.h" +#include "esp_attr.h" +#include "hal/pau_hal.h" +#include "hal/pau_types.h" +#if SOC_PAU_IN_TOP_DOMAIN +#include "hal/lp_sys_ll.h" +#endif + +void pau_hal_set_regdma_entry_link_addr(pau_hal_context_t *hal, pau_regdma_link_addr_t *link_addr) +{ + pau_ll_set_regdma_link0_addr(hal->dev, (*link_addr)[0]); + pau_ll_set_regdma_link1_addr(hal->dev, (*link_addr)[1]); + pau_ll_set_regdma_link2_addr(hal->dev, (*link_addr)[2]); + /* The link 3 of REGDMA is reserved, PMU state switching will not use + * REGDMA link 3 */ +} + +void IRAM_ATTR pau_hal_start_regdma_modem_link(pau_hal_context_t *hal, bool backup_or_restore) +{ + pau_ll_clear_regdma_backup_done_intr_state(hal->dev); + pau_ll_set_regdma_select_wifimac_link(hal->dev); + pau_ll_set_regdma_wifimac_link_backup_direction(hal->dev, backup_or_restore); + pau_ll_set_regdma_wifimac_link_backup_start_enable(hal->dev); + + while (!(pau_ll_get_regdma_intr_raw_signal(hal->dev) & PAU_DONE_INT_RAW)); +} + +void IRAM_ATTR pau_hal_stop_regdma_modem_link(pau_hal_context_t *hal) +{ + pau_ll_set_regdma_wifimac_link_backup_start_disable(hal->dev); + pau_ll_set_regdma_deselect_wifimac_link(hal->dev); + pau_ll_clear_regdma_backup_done_intr_state(hal->dev); +} + +void IRAM_ATTR pau_hal_start_regdma_extra_link(pau_hal_context_t *hal, bool backup_or_restore) +{ + pau_ll_clear_regdma_backup_done_intr_state(hal->dev); + /* The link 3 of REGDMA is reserved, we use it as an extra linked list to + * provide backup and restore services for BLE, IEEE802.15.4 and possibly + * other modules */ + pau_ll_select_regdma_entry_link(hal->dev, 3); + pau_ll_set_regdma_entry_link_backup_direction(hal->dev, backup_or_restore); + pau_ll_set_regdma_entry_link_backup_start_enable(hal->dev); + + while (!(pau_ll_get_regdma_intr_raw_signal(hal->dev) & PAU_DONE_INT_RAW)); +} + +void IRAM_ATTR pau_hal_stop_regdma_extra_link(pau_hal_context_t *hal) +{ + pau_ll_set_regdma_entry_link_backup_start_disable(hal->dev); + pau_ll_select_regdma_entry_link(hal->dev, 3); /* restore link select to default */ + pau_ll_clear_regdma_backup_done_intr_state(hal->dev); +} + +#if SOC_PAU_IN_TOP_DOMAIN +void IRAM_ATTR pau_hal_lp_sys_initialize(void) +{ + lp_sys_ll_set_pau_aon_bypass(true); + lp_sys_ll_set_pau_link_backup_tout_thres(300); + lp_sys_ll_set_pau_link_tout_thres(200); + lp_sys_ll_set_pau_reg_read_interval(50); +} +#endif diff --git a/components/hal/include/hal/pau_hal.h b/components/hal/include/hal/pau_hal.h index 4853cfa304..9c87e1c393 100644 --- a/components/hal/include/hal/pau_hal.h +++ b/components/hal/include/hal/pau_hal.h @@ -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 */ @@ -111,6 +111,15 @@ void pau_hal_stop_regdma_extra_link(pau_hal_context_t *hal); void pau_hal_regdma_clock_configure(pau_hal_context_t *hal, bool enable); #endif +#if SOC_PAU_IN_TOP_DOMAIN +/** + * If PAU is in TOP power domain, configuration will be lost after sleep, it is necessary + * to use LP_SYS_BACKUP_DMA_CFG2_REG to override restore link address, do related logic + * initialization by this function. + */ +void pau_hal_lp_sys_initialize(void); +#endif + #endif #ifdef __cplusplus diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index bb8858a602..c71dc8331d 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -187,6 +187,10 @@ config SOC_DCDC_SUPPORTED bool default y +config SOC_PAU_SUPPORTED + bool + default y + config SOC_LP_TIMER_SUPPORTED bool default y @@ -1443,6 +1447,10 @@ config SOC_PM_PAU_LINK_NUM int default 4 +config SOC_PAU_IN_TOP_DOMAIN + bool + default y + config SOC_PSRAM_VDD_POWER_MPLL bool default y diff --git a/components/soc/esp32p4/include/soc/pau_struct.h b/components/soc/esp32p4/include/soc/pau_struct.h index eb10b5ba00..63f6b3c750 100644 --- a/components/soc/esp32p4/include/soc/pau_struct.h +++ b/components/soc/esp32p4/include/soc/pau_struct.h @@ -328,6 +328,7 @@ typedef struct { volatile pau_date_reg_t date; } pau_dev_t; +extern pau_dev_t PAU; #ifndef __cplusplus _Static_assert(sizeof(pau_dev_t) == 0x400, "Invalid size of pau_dev_t structure"); diff --git a/components/soc/esp32p4/include/soc/periph_defs.h b/components/soc/esp32p4/include/soc/periph_defs.h index cadf54fdf7..c3536df898 100644 --- a/components/soc/esp32p4/include/soc/periph_defs.h +++ b/components/soc/esp32p4/include/soc/periph_defs.h @@ -69,6 +69,7 @@ typedef enum { PERIPH_UHCI_MODULE, PERIPH_PCNT_MODULE, PERIPH_ASSIST_DEBUG_MODULE, + PERIPH_REGDMA_MODULE, /* LP peripherals */ PERIPH_LP_I2C0_MODULE, PERIPH_LP_UART0_MODULE, diff --git a/components/soc/esp32p4/include/soc/reg_base.h b/components/soc/esp32p4/include/soc/reg_base.h index 97d9c7f280..ca035cf30e 100644 --- a/components/soc/esp32p4/include/soc/reg_base.h +++ b/components/soc/esp32p4/include/soc/reg_base.h @@ -201,8 +201,7 @@ // #define DR_REG_LP_TEE_BASE 0x600B3400 // #define DR_REG_LP_APM_BASE 0x600B3800 -//TODO: IDF-7531 -// #define DR_REG_PAU_BASE 0x60093000 +#define DR_REG_PAU_BASE DR_REG_REGDMA_BASE //TODO: IDF-7688 // #define DR_REG_TRACE_BASE 0x600C0000 diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index b41515c4a8..05124b04f0 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -70,7 +70,7 @@ // #define SOC_APM_SUPPORTED 1 //TODO: IDF-7542 #define SOC_PMU_SUPPORTED 1 #define SOC_DCDC_SUPPORTED 1 -// #define SOC_PAU_SUPPORTED 1 //TODO: IDF-7531 +#define SOC_PAU_SUPPORTED 1 //TODO: IDF-7531 #define SOC_LP_TIMER_SUPPORTED 1 #define SOC_ULP_LP_UART_SUPPORTED 1 #define SOC_LP_GPIO_MATRIX_SUPPORTED 1 @@ -589,6 +589,7 @@ #define SOC_PM_CPU_RETENTION_BY_SW (1) #define SOC_PM_PAU_LINK_NUM (4) +#define SOC_PAU_IN_TOP_DOMAIN (1) /*-------------------------- PSRAM CAPS ----------------------------*/ #define SOC_PSRAM_VDD_POWER_MPLL (1) diff --git a/components/soc/esp32p4/ld/esp32p4.peripherals.ld b/components/soc/esp32p4/ld/esp32p4.peripherals.ld index 62636b9dff..53ddb2f87e 100644 --- a/components/soc/esp32p4/ld/esp32p4.peripherals.ld +++ b/components/soc/esp32p4/ld/esp32p4.peripherals.ld @@ -96,6 +96,7 @@ PROVIDE ( MIPI_CSI_MEM = 0x50104000 ); PROVIDE ( MIPI_DSI_MEM = 0x50105000 ); PROVIDE ( ISP = 0x500A1000 ); PROVIDE ( DW_GDMA = 0x50081000 ); +PROVIDE ( PAU = 0x50082000 ); PROVIDE ( I3C_MST = 0x500DA000 ); PROVIDE ( I3C_MST_MEM = 0x500DA000 ); PROVIDE ( I3C_SLV = 0x500DB000 ); From 194c38479e4f5aae4490b087377323a20fc6656a Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Mon, 29 Jan 2024 21:51:15 +0800 Subject: [PATCH 4/8] refactor(esp_hw_support): split pd_top clock retention initialization by target --- components/esp_hw_support/CMakeLists.txt | 6 +- .../include/esp_private/sleep_clock.h | 12 ++- .../port/esp32c5/clock_retention_init.c | 62 +++++++++++++++ .../port/esp32c6/clock_retention_init.c | 54 +++++++++++++ .../port/esp32h2/clock_retention_init.c | 55 ++++++++++++++ components/esp_hw_support/sleep_clock.c | 76 ------------------- 6 files changed, 187 insertions(+), 78 deletions(-) create mode 100644 components/esp_hw_support/port/esp32c5/clock_retention_init.c create mode 100644 components/esp_hw_support/port/esp32c6/clock_retention_init.c create mode 100644 components/esp_hw_support/port/esp32h2/clock_retention_init.c diff --git a/components/esp_hw_support/CMakeLists.txt b/components/esp_hw_support/CMakeLists.txt index de6c1c373d..8a7ff300a8 100644 --- a/components/esp_hw_support/CMakeLists.txt +++ b/components/esp_hw_support/CMakeLists.txt @@ -49,7 +49,11 @@ if(NOT BOOTLOADER_BUILD) list(APPEND srcs "mipi_csi_share_hw_ctrl.c") endif() if(CONFIG_SOC_PAU_SUPPORTED) - list(APPEND srcs "sleep_retention.c" "sleep_system_peripheral.c" "sleep_clock.c") + list(APPEND srcs "sleep_retention.c" + "sleep_system_peripheral.c" + "sleep_clock.c" + "port/${target}/clock_retention_init.c" + ) endif() # [refactor-todo] diff --git a/components/esp_hw_support/include/esp_private/sleep_clock.h b/components/esp_hw_support/include/esp_private/sleep_clock.h index 5b204c1856..82ad73781e 100644 --- a/components/esp_hw_support/include/esp_private/sleep_clock.h +++ b/components/esp_hw_support/include/esp_private/sleep_clock.h @@ -1,14 +1,24 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once +#include +#include +#include #include #include #include "sdkconfig.h" #include "esp_err.h" +#include "esp_log.h" +#include "esp_attr.h" +#include "esp_check.h" +#include "esp_regdma.h" +#include "esp_private/sleep_retention.h" +#include "esp_private/startup_internal.h" +#include "soc/soc_caps.h" #ifdef __cplusplus extern "C" { diff --git a/components/esp_hw_support/port/esp32c5/clock_retention_init.c b/components/esp_hw_support/port/esp32c5/clock_retention_init.c new file mode 100644 index 0000000000..cb2a38cc5c --- /dev/null +++ b/components/esp_hw_support/port/esp32c5/clock_retention_init.c @@ -0,0 +1,62 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/sleep_clock.h" +#include "soc/pcr_reg.h" +#include "modem/modem_syscon_reg.h" + +static __attribute__((unused)) const char *TAG = "sleep_clock"; + +esp_err_t sleep_clock_system_retention_init(void) +{ +#if CONFIG_IDF_TARGET_ESP32C5_MP_VERSION + #define N_REGS_PCR() (((PCR_SRAM_POWER_CONF_1_REG - DR_REG_PCR_BASE) / 4) + 1) +#elif CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION + #define N_REGS_PCR() (((PCR_PWDET_SAR_CLK_CONF_REG - DR_REG_PCR_BASE) / 4) + 1) +#endif + + const static sleep_retention_entries_config_t pcr_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_PCR_LINK(0), DR_REG_PCR_BASE, DR_REG_PCR_BASE, N_REGS_PCR(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* pcr */ + }; + + 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_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for system (PCR) retention"); + ESP_LOGI(TAG, "System Power, Clock and Reset sleep retention initialization"); + return ESP_OK; +} + +void sleep_clock_system_retention_deinit(void) +{ + sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM); +} + +#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE +esp_err_t sleep_clock_modem_retention_init(void) +{ +#if CONFIG_IDF_TARGET_ESP32C5 + #define N_REGS_SYSCON() (((MODEM_SYSCON_MEM_RF2_CONF_REG - MODEM_SYSCON_TEST_CONF_REG) / 4) + 1) +#else + #define N_REGS_SYSCON() (((MODEM_SYSCON_MEM_CONF_REG - MODEM_SYSCON_TEST_CONF_REG) / 4) + 1) +#endif + + const static sleep_retention_entries_config_t modem_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMSYSCON_LINK(0), MODEM_SYSCON_TEST_CONF_REG, MODEM_SYSCON_TEST_CONF_REG, N_REGS_SYSCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) }, /* MODEM SYSCON */ +#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMLPCON_LINK(0), MODEM_LPCON_TEST_CONF_REG, MODEM_LPCON_TEST_CONF_REG, N_REGS_LPCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) } /* MODEM LPCON */ +#endif + }; + + esp_err_t err = sleep_retention_entries_create(modem_regs_retention, ARRAY_SIZE(modem_regs_retention), REGDMA_LINK_PRI_MODEM_CLK, SLEEP_RETENTION_MODULE_CLOCK_MODEM); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for modem (SYSCON) retention, 1 level priority"); + ESP_LOGI(TAG, "Modem Power, Clock and Reset sleep retention initialization"); + return ESP_OK; +} + +void sleep_clock_modem_retention_deinit(void) +{ + sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_CLOCK_MODEM); +} +#endif diff --git a/components/esp_hw_support/port/esp32c6/clock_retention_init.c b/components/esp_hw_support/port/esp32c6/clock_retention_init.c new file mode 100644 index 0000000000..9082c3c913 --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/clock_retention_init.c @@ -0,0 +1,54 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/sleep_clock.h" +#include "soc/pcr_reg.h" +#include "modem/modem_syscon_reg.h" + +static __attribute__((unused)) const char *TAG = "sleep_clock"; + +esp_err_t sleep_clock_system_retention_init(void) +{ + #define N_REGS_PCR() (((PCR_SRAM_POWER_CONF_REG - DR_REG_PCR_BASE) / 4) + 1) + + const static sleep_retention_entries_config_t pcr_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_PCR_LINK(0), DR_REG_PCR_BASE, DR_REG_PCR_BASE, N_REGS_PCR(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* pcr */ + }; + + 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_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for system (PCR) retention"); + ESP_LOGI(TAG, "System Power, Clock and Reset sleep retention initialization"); + return ESP_OK; +} + +void sleep_clock_system_retention_deinit(void) +{ + sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM); +} + +#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE +esp_err_t sleep_clock_modem_retention_init(void) +{ + #define N_REGS_SYSCON() (((MODEM_SYSCON_MEM_CONF_REG - MODEM_SYSCON_TEST_CONF_REG) / 4) + 1) + + const static sleep_retention_entries_config_t modem_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMSYSCON_LINK(0), MODEM_SYSCON_TEST_CONF_REG, MODEM_SYSCON_TEST_CONF_REG, N_REGS_SYSCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) }, /* MODEM SYSCON */ +#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMLPCON_LINK(0), MODEM_LPCON_TEST_CONF_REG, MODEM_LPCON_TEST_CONF_REG, N_REGS_LPCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) } /* MODEM LPCON */ +#endif + }; + + esp_err_t err = sleep_retention_entries_create(modem_regs_retention, ARRAY_SIZE(modem_regs_retention), REGDMA_LINK_PRI_MODEM_CLK, SLEEP_RETENTION_MODULE_CLOCK_MODEM); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for modem (SYSCON) retention, 1 level priority"); + ESP_LOGI(TAG, "Modem Power, Clock and Reset sleep retention initialization"); + return ESP_OK; +} + +void sleep_clock_modem_retention_deinit(void) +{ + sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_CLOCK_MODEM); +} +#endif diff --git a/components/esp_hw_support/port/esp32h2/clock_retention_init.c b/components/esp_hw_support/port/esp32h2/clock_retention_init.c new file mode 100644 index 0000000000..4e29d0046a --- /dev/null +++ b/components/esp_hw_support/port/esp32h2/clock_retention_init.c @@ -0,0 +1,55 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/sleep_clock.h" +#include "soc/pcr_reg.h" +#include "modem/modem_syscon_reg.h" +#include "modem/modem_lpcon_reg.h" + + +static __attribute__((unused)) const char *TAG = "sleep_clock"; + +esp_err_t sleep_clock_system_retention_init(void) +{ + #define N_REGS_PCR() (((PCR_PWDET_SAR_CLK_CONF_REG - DR_REG_PCR_BASE) / 4) + 1) + + const static sleep_retention_entries_config_t pcr_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_PCR_LINK(0), DR_REG_PCR_BASE, DR_REG_PCR_BASE, N_REGS_PCR(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* pcr */ + }; + + 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_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for system (PCR) retention"); + ESP_LOGI(TAG, "System Power, Clock and Reset sleep retention initialization"); + return ESP_OK; +} + +void sleep_clock_system_retention_deinit(void) +{ + sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM); +} + +#if CONFIG_MAC_BB_PD || CONFIG_BT_LE_SLEEP_ENABLE || CONFIG_IEEE802154_SLEEP_ENABLE +esp_err_t sleep_clock_modem_retention_init(void) +{ + #define N_REGS_SYSCON() (((MODEM_SYSCON_MEM_CONF_REG - MODEM_SYSCON_TEST_CONF_REG) / 4) + 1) + #define N_REGS_LPCON() (((MODEM_LPCON_MEM_CONF_REG - MODEM_LPCON_TEST_CONF_REG) / 4) + 1) + + const static sleep_retention_entries_config_t modem_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMSYSCON_LINK(0), MODEM_SYSCON_TEST_CONF_REG, MODEM_SYSCON_TEST_CONF_REG, N_REGS_SYSCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) }, /* MODEM SYSCON */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMLPCON_LINK(0), MODEM_LPCON_TEST_CONF_REG, MODEM_LPCON_TEST_CONF_REG, N_REGS_LPCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) } /* MODEM LPCON */ + }; + + esp_err_t err = sleep_retention_entries_create(modem_regs_retention, ARRAY_SIZE(modem_regs_retention), REGDMA_LINK_PRI_MODEM_CLK, SLEEP_RETENTION_MODULE_CLOCK_MODEM); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for modem (SYSCON) retention, 1 level priority"); + ESP_LOGI(TAG, "Modem Power, Clock and Reset sleep retention initialization"); + return ESP_OK; +} + +void sleep_clock_modem_retention_deinit(void) +{ + sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_CLOCK_MODEM); +} +#endif diff --git a/components/esp_hw_support/sleep_clock.c b/components/esp_hw_support/sleep_clock.c index c3652b5ff4..433bbc96e2 100644 --- a/components/esp_hw_support/sleep_clock.c +++ b/components/esp_hw_support/sleep_clock.c @@ -4,84 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include -#include -#include - -#include "sdkconfig.h" -#include "soc/soc_caps.h" - -#include "esp_err.h" -#include "esp_log.h" -#include "esp_attr.h" -#include "esp_check.h" -#include "esp_regdma.h" -#include "esp_private/startup_internal.h" -#include "esp_private/sleep_retention.h" #include "esp_private/sleep_clock.h" -#include "soc/pcr_reg.h" -#include "modem/modem_syscon_reg.h" - -#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA -#include "modem/modem_lpcon_reg.h" -#endif - -static __attribute__((unused)) const char *TAG = "sleep_clock"; - -esp_err_t sleep_clock_system_retention_init(void) -{ -#if CONFIG_IDF_TARGET_ESP32C6 - #define N_REGS_PCR() (((PCR_SRAM_POWER_CONF_REG - DR_REG_PCR_BASE) / 4) + 1) -#elif CONFIG_IDF_TARGET_ESP32C5_MP_VERSION - #define N_REGS_PCR() (((PCR_SRAM_POWER_CONF_1_REG - DR_REG_PCR_BASE) / 4) + 1) -#elif CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32C5_BETA3_VERSION - #define N_REGS_PCR() (((PCR_PWDET_SAR_CLK_CONF_REG - DR_REG_PCR_BASE) / 4) + 1) -#endif - const static sleep_retention_entries_config_t pcr_regs_retention[] = { - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_PCR_LINK(0), DR_REG_PCR_BASE, DR_REG_PCR_BASE, N_REGS_PCR(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* pcr */ - }; - - 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_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for system (PCR) retention"); - ESP_LOGI(TAG, "System Power, Clock and Reset sleep retention initialization"); - return ESP_OK; -} - -void sleep_clock_system_retention_deinit(void) -{ - sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM); -} - -esp_err_t sleep_clock_modem_retention_init(void) -{ -#if CONFIG_IDF_TARGET_ESP32C5 - #define N_REGS_SYSCON() (((MODEM_SYSCON_MEM_RF2_CONF_REG - MODEM_SYSCON_TEST_CONF_REG) / 4) + 1) -#else - #define N_REGS_SYSCON() (((MODEM_SYSCON_MEM_CONF_REG - MODEM_SYSCON_TEST_CONF_REG) / 4) + 1) -#endif -#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA - #define N_REGS_LPCON() (((MODEM_LPCON_MEM_CONF_REG - MODEM_LPCON_TEST_CONF_REG) / 4) + 1) -#endif - - const static sleep_retention_entries_config_t modem_regs_retention[] = { - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMSYSCON_LINK(0), MODEM_SYSCON_TEST_CONF_REG, MODEM_SYSCON_TEST_CONF_REG, N_REGS_SYSCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) }, /* MODEM SYSCON */ -#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_MODEMLPCON_LINK(0), MODEM_LPCON_TEST_CONF_REG, MODEM_LPCON_TEST_CONF_REG, N_REGS_LPCON(), 0, 0), .owner = ENTRY(0) | ENTRY(1) } /* MODEM LPCON */ -#endif - }; - - esp_err_t err = sleep_retention_entries_create(modem_regs_retention, ARRAY_SIZE(modem_regs_retention), REGDMA_LINK_PRI_MODEM_CLK, SLEEP_RETENTION_MODULE_CLOCK_MODEM); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for modem (SYSCON) retention, 2 level priority"); - ESP_LOGI(TAG, "Modem Power, Clock and Reset sleep retention initialization"); - return ESP_OK; -} - -void sleep_clock_modem_retention_deinit(void) -{ - sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_CLOCK_MODEM); -} - bool clock_domain_pd_allowed(void) { const uint32_t modules = sleep_retention_get_modules(); From f1beed90ff63d28b73c3e72c580be67153591a16 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Mon, 15 Jan 2024 11:49:10 +0800 Subject: [PATCH 5/8] feat(esp_hw_support): support esp32p4 sleep clock retention --- .../port/esp32p4/clock_retention_init.c | 33 +++ .../system_peripheral_retention_init.c | 214 ++++++++++++++++++ components/esp_hw_support/sleep_modes.c | 29 ++- .../esp_hw_support/sleep_system_peripheral.c | 4 + components/esp_pm/Kconfig | 4 +- .../esp32p4/include/soc/Kconfig.soc_caps.in | 4 + components/soc/esp32p4/include/soc/soc_caps.h | 4 +- 7 files changed, 278 insertions(+), 14 deletions(-) create mode 100644 components/esp_hw_support/port/esp32p4/clock_retention_init.c create mode 100644 components/esp_hw_support/port/esp32p4/system_peripheral_retention_init.c diff --git a/components/esp_hw_support/port/esp32p4/clock_retention_init.c b/components/esp_hw_support/port/esp32p4/clock_retention_init.c new file mode 100644 index 0000000000..b9fc4d7667 --- /dev/null +++ b/components/esp_hw_support/port/esp32p4/clock_retention_init.c @@ -0,0 +1,33 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/sleep_clock.h" +#include "soc/hp_sys_clkrst_reg.h" + +static __attribute__((unused)) const char *TAG = "sleep_clock"; + +esp_err_t sleep_clock_system_retention_init(void) +{ + #define N_REGS_PCR() (((HP_SYS_CLKRST_HPCORE_WDT_RESET_SOURCE0_REG - DR_REG_HP_SYS_CLKRST_BASE) / 4) + 1) + + const static sleep_retention_entries_config_t pcr_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_PCR_LINK(0x0), DR_REG_HP_SYS_CLKRST_BASE, DR_REG_HP_SYS_CLKRST_BASE, N_REGS_PCR(), 0, 0), .owner = ENTRY(0) }, /* pcr */ + [1] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(0x01), HP_SYS_CLKRST_ROOT_CLK_CTRL0_REG, HP_SYS_CLKRST_REG_SOC_CLK_DIV_UPDATE, HP_SYS_CLKRST_REG_SOC_CLK_DIV_UPDATE_M, 1, 0), .owner = ENTRY(0) }, + [2] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PCR_LINK(0x02), HP_SYS_CLKRST_ROOT_CLK_CTRL0_REG, 0x0, HP_SYS_CLKRST_REG_SOC_CLK_DIV_UPDATE_M, 1, 0), .owner = ENTRY(0) }, + [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_PCR_LINK(0x03), HP_SYS_CLKRST_PERI_CLK_CTRL02_REG, HP_SYS_CLKRST_REG_SDIO_LS_CLK_EDGE_CFG_UPDATE, HP_SYS_CLKRST_REG_SDIO_LS_CLK_EDGE_CFG_UPDATE_M, 1, 0), .owner = ENTRY(0) }, + [4] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_PCR_LINK(0x04), HP_SYS_CLKRST_PERI_CLK_CTRL02_REG, 0x0, HP_SYS_CLKRST_REG_SDIO_LS_CLK_EDGE_CFG_UPDATE_M, 1, 0), .owner = ENTRY(0) }, + }; + + 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_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for system (PCR) retention"); + ESP_LOGI(TAG, "System Power, Clock and Reset sleep retention initialization"); + return ESP_OK; +} + +void sleep_clock_system_retention_deinit(void) +{ + sleep_retention_entries_destroy(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM); +} diff --git a/components/esp_hw_support/port/esp32p4/system_peripheral_retention_init.c b/components/esp_hw_support/port/esp32p4/system_peripheral_retention_init.c new file mode 100644 index 0000000000..83ff04175c --- /dev/null +++ b/components/esp_hw_support/port/esp32p4/system_peripheral_retention_init.c @@ -0,0 +1,214 @@ +/* + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_check.h" + +#include "esp_private/startup_internal.h" +#include "esp_private/sleep_retention.h" +#include "esp_private/sleep_clock.h" + +#include "soc/cache_reg.h" +#include "soc/gpio_reg.h" +#include "soc/hp_system_reg.h" +#include "soc/io_mux_reg.h" +#include "soc/interrupt_core0_reg.h" +#include "soc/interrupt_core1_reg.h" +#include "hal/mwdt_ll.h" +#include "soc/pau_reg.h" +#include "soc/spi_mem_reg.h" +#include "soc/systimer_reg.h" +#include "soc/timer_group_reg.h" +#include "soc/uart_reg.h" + +static __attribute__((unused)) const char *TAG = "sleep_sys_periph"; + +#define SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT (REGDMA_LINK_PRI_6) + + +esp_err_t sleep_sys_periph_intr_matrix_retention_init(void) +{ + #define N_REGS_INTR_CORE0() (((INTERRUPT_CORE0_CLOCK_GATE_REG - DR_REG_INTERRUPT_CORE0_BASE) / 4) + 1) + #define N_REGS_INTR_CORE1() (((INTERRUPT_CORE1_CLOCK_GATE_REG - DR_REG_INTERRUPT_CORE1_BASE) / 4) + 1) + + const static sleep_retention_entries_config_t intr_matrix_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_INTMTX_LINK(0x00), DR_REG_INTERRUPT_CORE0_BASE, DR_REG_INTERRUPT_CORE0_BASE, N_REGS_INTR_CORE0(), 0, 0), .owner = ENTRY(0) }, /* intr matrix */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_INTMTX_LINK(0x01), DR_REG_INTERRUPT_CORE1_BASE, DR_REG_INTERRUPT_CORE1_BASE, N_REGS_INTR_CORE1(), 0, 0), .owner = ENTRY(0) } /* intr matrix */ + }; + + esp_err_t err = sleep_retention_entries_create(intr_matrix_regs_retention, ARRAY_SIZE(intr_matrix_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_INTR_MATRIX); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (Interrupt matrix) retention"); + ESP_LOGI(TAG, "Interrupt Matrix sleep retention initialization"); + return ESP_OK; +} + + +esp_err_t sleep_sys_periph_l2_cache_retention_init(void) +{ + #define N_REGS_L2_CACHE() (((CACHE_L2_CACHE_DATA_MEM_POWER_CTRL_REG - CACHE_L2_CACHE_CTRL_REG) / 4) + 1) + + const static sleep_retention_entries_config_t l2_cache_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_HPSYS_LINK(0), CACHE_L2_CACHE_CTRL_REG, CACHE_L2_CACHE_CTRL_REG, N_REGS_L2_CACHE(), 0, 0), .owner = ENTRY(0) } /* hp system */ + }; + + esp_err_t err = sleep_retention_entries_create(l2_cache_regs_retention, ARRAY_SIZE(l2_cache_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_L2_CACHE); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (L2 Cache) retention"); + ESP_LOGI(TAG, "L2 Cache sleep retention initialization"); + return ESP_OK; +} + +esp_err_t sleep_sys_periph_hp_system_retention_init(void) +{ + #define N_REGS_HP_SYSTEM() (((HP_SYSTEM_AHB2AXI_BRESP_ERR_INT_ENA_REG - DR_REG_HP_SYS_BASE) / 4) + 1) + + const static sleep_retention_entries_config_t hp_system_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_HPSYS_LINK(0), DR_REG_HP_SYS_BASE, DR_REG_HP_SYS_BASE, N_REGS_HP_SYSTEM(), 0, 0), .owner = ENTRY(0) } /* hp system */ + }; + + esp_err_t err = sleep_retention_entries_create(hp_system_regs_retention, ARRAY_SIZE(hp_system_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_HP_SYSTEM); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (HP system) retention"); + ESP_LOGI(TAG, "HP System sleep retention initialization"); + return ESP_OK; +} + +esp_err_t sleep_sys_periph_uart0_retention_init(void) +{ + #define N_REGS_UART() (((UART_CLK_CONF_REG(0) - REG_UART_BASE(0)) / 4) + 1) + + const static sleep_retention_entries_config_t uart_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_UART_LINK(0x00), REG_UART_BASE(0), REG_UART_BASE(0), N_REGS_UART(), 0, 0), .owner = ENTRY(0) }, /* uart */ + /* Note: uart register should set update reg to make the configuration take effect */ + [1] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_UART_LINK(0x01), UART_REG_UPDATE_REG(0), UART_REG_UPDATE, UART_REG_UPDATE_M, 1, 0), .owner = ENTRY(0) }, + [2] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_UART_LINK(0x02), UART_REG_UPDATE_REG(0), 0x0, UART_REG_UPDATE_M, 1, 0), .owner = ENTRY(0) } + }; + + esp_err_t err = sleep_retention_entries_create(uart_regs_retention, ARRAY_SIZE(uart_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_UART0); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (UART) retention"); + ESP_LOGI(TAG, "UART sleep retention initialization"); + return ESP_OK; +} + +esp_err_t sleep_sys_periph_tg0_retention_init(void) +{ + #define N_REGS_TG0() (((TIMG_REGCLK_REG(0) - REG_TIMG_BASE(0)) / 4) + 1) + + const static sleep_retention_entries_config_t tg_regs_retention[] = { + /*Timer group0 backup. T0_wdt should get of write project firstly. wdt used by RTOS.*/ + [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) }, /* TG0 */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x01), REG_TIMG_BASE(0), REG_TIMG_BASE(0), N_REGS_TG0(), 0, 0), .owner = ENTRY(0) }, + [2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x02), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) }, + [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x03), TIMG_WDTCONFIG0_REG(0), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) }, + [4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x04), TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) }, + [5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_TIMG_LINK(0x05), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) }, + [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x06), TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), .owner = ENTRY(0) }, + [7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x07), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) }, + }; + + esp_err_t err = sleep_retention_entries_create(tg_regs_retention, ARRAY_SIZE(tg_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_TG0); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (Timer Group0) retention"); + ESP_LOGI(TAG, "Timer Group0 sleep retention initialization"); + return ESP_OK; +} + +esp_err_t sleep_sys_periph_iomux_retention_init(void) +{ + #define N_REGS_IOMUX_0() (((PERIPHS_IO_MUX_U_PAD_GPIO56 - REG_IO_MUX_BASE) / 4) + 1) + #define N_REGS_IOMUX_1() (((GPIO_ZERO_DET1_FILTER_CNT_REG - DR_REG_GPIO_BASE) / 4) + 1) + + const static sleep_retention_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) }, /* 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) }, + }; + + esp_err_t err = sleep_retention_entries_create(iomux_regs_retention, ARRAY_SIZE(iomux_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_IOMUX); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (IO Matrix) retention"); + ESP_LOGI(TAG, "IO Matrix sleep retention initialization"); + return ESP_OK; +} + +esp_err_t sleep_sys_periph_spimem_retention_init(void) +{ + #define N_REGS_SPI1_MEM_0() (((SPI1_MEM_C_SUS_STATUS_REG - DR_REG_FLASH_SPI1_BASE) / 4) + 1) + #define N_REGS_SPI1_MEM_1() (((SPI1_MEM_C_DDR_REG - SPI1_MEM_C_INT_ENA_REG) / 4) + 1) + #define N_REGS_SPI1_MEM_2() (1) + #define N_REGS_SPI1_MEM_3() (1) + + #define N_REGS_SPI0_MEM_0() ((SPI_MEM_C_SMEM_DDR_REG - DR_REG_FLASH_SPI0_BASE) / 4 + 1) + #define N_REGS_SPI0_MEM_1() (((SPI_MEM_C_SMEM_AC_REG - SPI_MEM_C_FMEM__PMS0_ATTR_REG) / 4) + 1) + #define N_REGS_SPI0_MEM_2() (1) + #define N_REGS_SPI0_MEM_3() (((SPI_MEM_C_DATE_REG - SPI_MEM_C_MMU_POWER_CTRL_REG) / 4) + 1) + + const static sleep_retention_entries_config_t 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_FLASH_SPI1_BASE, DR_REG_FLASH_SPI1_BASE, N_REGS_SPI1_MEM_0(), 0, 0), .owner = ENTRY(0) }, /* spi1_mem */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x01), SPI1_MEM_C_INT_ENA_REG, SPI1_MEM_C_INT_ENA_REG, N_REGS_SPI1_MEM_1(), 0, 0), .owner = ENTRY(0) }, + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x02), SPI1_MEM_C_TIMING_CALI_REG, SPI1_MEM_C_TIMING_CALI_REG, N_REGS_SPI1_MEM_2(), 0, 0), .owner = ENTRY(0) }, + [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x03), SPI1_MEM_C_CLOCK_GATE_REG, SPI1_MEM_C_CLOCK_GATE_REG, N_REGS_SPI1_MEM_3(), 0, 0), .owner = ENTRY(0) }, + + /* Note: SPI mem should not to write mmu SPI_MEM_MMU_ITEM_CONTENT_REG and SPI_MEM_MMU_ITEM_INDEX_REG */ + [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x04), DR_REG_FLASH_SPI0_BASE, DR_REG_FLASH_SPI0_BASE, N_REGS_SPI0_MEM_0(), 0, 0), .owner = ENTRY(0) }, /* spi0_mem */ + [5] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x05), SPI_MEM_C_FMEM__PMS0_ATTR_REG, SPI_MEM_C_FMEM__PMS0_ATTR_REG, N_REGS_SPI0_MEM_1(), 0, 0), .owner = ENTRY(0) }, + [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x06), SPI_MEM_C_CLOCK_GATE_REG, SPI_MEM_C_CLOCK_GATE_REG, N_REGS_SPI0_MEM_2(), 0, 0), .owner = ENTRY(0) }, + [7] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x07), SPI_MEM_C_MMU_POWER_CTRL_REG, SPI_MEM_C_MMU_POWER_CTRL_REG, N_REGS_SPI0_MEM_3(), 0, 0), .owner = ENTRY(0) } + }; + + esp_err_t err = sleep_retention_entries_create(spimem_regs_retention, ARRAY_SIZE(spimem_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SPIMEM); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (SPI mem) retention"); + ESP_LOGI(TAG, "SPI Mem sleep retention initialization"); + return ESP_OK; +} + +esp_err_t sleep_sys_periph_systimer_retention_init(void) +{ + #define N_REGS_SYSTIMER_0() (((SYSTIMER_TARGET2_CONF_REG - SYSTIMER_TARGET0_HI_REG) / 4) + 1) + + const static sleep_retention_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) }, /* 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) }, + [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) }, + [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) }, + + [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) }, + [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) }, + [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) }, + [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) }, + + [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) }, /* 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) }, + [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) }, + [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) }, + + [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) }, + [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) }, + + [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) }, + [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) }, + + [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) }, + + [17] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x11), SYSTIMER_CONF_REG, SYSTIMER_CONF_REG, 1, 0, 0), .owner = ENTRY(0) }, /* 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) } /* Systimer intr enable */ + }; + + esp_err_t err = sleep_retention_entries_create(systimer_regs_retention, ARRAY_SIZE(systimer_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SYSTIMER); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (SysTimer) retention"); + ESP_LOGI(TAG, "SysTimer sleep retention initialization"); + return ESP_OK; +} + +esp_err_t sleep_pau_retention_init(void) +{ + #define N_REGS_PAU() (((PAU_INT_ENA_REG - DR_REG_PAU_BASE) / 4) + 1) + + const static sleep_retention_entries_config_t pau_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_PAU_LINK(0x0), DR_REG_PAU_BASE, DR_REG_PAU_BASE, N_REGS_PAU(), 0, 0), .owner = ENTRY(0) }, /* pau */ + }; + + esp_err_t err = sleep_retention_entries_create(pau_regs_retention, ARRAY_SIZE(pau_regs_retention), REGDMA_LINK_PRI_7, SLEEP_RETENTION_MODULE_REGDMA_SYSTEM); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for system (PAU) retention"); + ESP_LOGI(TAG, "PAU sleep retention initialization"); + return ESP_OK; +} diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index e20f2f7d3e..b4dc4592b8 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -301,8 +301,8 @@ static void RTC_IRAM_ATTR __attribute__((used, noinline)) esp_wake_stub_start(vo /* We must have a default deep sleep wake stub entry function, which must be * located at the start address of the RTC fast memory, and its implementation - * must be simple enough to ensure that there is no litteral data before the - * wake stub entry, otherwise, the litteral data before the wake stub entry + * must be simple enough to ensure that there is no literal data before the + * wake stub entry, otherwise, the literal data before the wake stub entry * will not be CRC checked. */ static void __attribute__((section(".rtc.entry.text"))) esp_wake_stub_entry(void) { @@ -769,7 +769,7 @@ static esp_err_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags, esp_sleep_mode_t m if (!deep_sleep) { /* Enable sleep reject for faster return from this function, - * in case the wakeup is already triggerred. + * in case the wakeup is already triggered. */ reject_triggers |= sleep_modem_reject_triggers(); } @@ -1216,8 +1216,8 @@ esp_err_t esp_light_sleep_start(void) /* * Adjustment time consists of parts below: - * 1. Hardware time waiting for internal 8M oscilate clock and XTAL; - * 2. Hardware state swithing time of the rtc main state machine; + * 1. Hardware time waiting for internal 8M oscillate clock and XTAL; + * 2. Hardware state switching time of the rtc main state machine; * 3. Code execution time when clock is not stable; * 4. Code execution time which can be measured; */ @@ -1990,11 +1990,20 @@ esp_err_t esp_sleep_pd_config(esp_sleep_pd_domain_t domain, esp_sleep_pd_option_ */ #if SOC_PM_SUPPORT_TOP_PD FORCE_INLINE_ATTR bool top_domain_pd_allowed(void) { - return (cpu_domain_pd_allowed() && \ - clock_domain_pd_allowed() && \ - peripheral_domain_pd_allowed() && \ - modem_domain_pd_allowed() && \ - s_config.domain[ESP_PD_DOMAIN_XTAL].pd_option != ESP_PD_OPTION_ON); + bool top_pd_allowed = true; +#if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP + top_pd_allowed &= cpu_domain_pd_allowed(); +#else + top_pd_allowed = false; +#endif + top_pd_allowed &= clock_domain_pd_allowed(); + top_pd_allowed &= peripheral_domain_pd_allowed(); +#if SOC_PM_SUPPORT_MODEM_PD + top_pd_allowed &= modem_domain_pd_allowed(); +#endif + top_pd_allowed &= (s_config.domain[ESP_PD_DOMAIN_XTAL].pd_option != ESP_PD_OPTION_ON); + + return top_pd_allowed; } #endif diff --git a/components/esp_hw_support/sleep_system_peripheral.c b/components/esp_hw_support/sleep_system_peripheral.c index 6feddc3fd8..71344a4383 100644 --- a/components/esp_hw_support/sleep_system_peripheral.c +++ b/components/esp_hw_support/sleep_system_peripheral.c @@ -105,6 +105,10 @@ esp_err_t sleep_sys_periph_retention_init(void) err = sleep_sys_periph_spimem_retention_init(); if(err) goto error; err = sleep_sys_periph_systimer_retention_init(); +#if SOC_PAU_IN_TOP_DOMAIN + if(err) goto error; + err = sleep_pau_retention_init(); +#endif error: return err; diff --git a/components/esp_pm/Kconfig b/components/esp_pm/Kconfig index 5134b7d988..3058381fbd 100644 --- a/components/esp_pm/Kconfig +++ b/components/esp_pm/Kconfig @@ -2,7 +2,7 @@ menu "Power Management" config PM_ENABLE bool "Support for power management" # SMP FreeRTOS currently does not support power management IDF-4997 - depends on (!FREERTOS_SMP && !IDF_TARGET_ESP32P4) || __DOXYGEN__ # TODO: IDF-7527 + depends on !FREERTOS_SMP || __DOXYGEN__ default n help If enabled, application is compiled with support for power management. @@ -75,7 +75,7 @@ menu "Power Management" you can call 'gpio_sleep_sel_dis' to disable this feature on those pins. You can also keep this feature on and call 'gpio_sleep_set_direction' and 'gpio_sleep_set_pull_mode' to have a different GPIO configuration at sleep. - Waring: If you want to enable this option on ESP32, you should enable `GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL` + Warning: If you want to enable this option on ESP32, you should enable `GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL` at first, otherwise you will not be able to switch pullup/pulldown mode. config PM_SLP_DEFAULT_PARAMS_OPT diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index c71dc8331d..0318025f10 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -1431,6 +1431,10 @@ config SOC_PM_SUPPORT_VDDSDIO_PD bool default y +config SOC_PM_SUPPORT_TOP_PD + bool + default y + config SOC_PM_SUPPORT_CNNT_PD bool default y diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index 05124b04f0..2698fd2910 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -574,14 +574,14 @@ // TODO: IDF-5351 (Copy from esp32c3, need check) /*-------------------------- Power Management CAPS ----------------------------*/ #define SOC_PM_SUPPORT_EXT1_WAKEUP (1) -#define SOC_PM_SUPPORT_EXT1_WAKEUP_MODE_PER_PIN (1) /*! Date: Mon, 29 Jan 2024 21:47:56 +0800 Subject: [PATCH 6/8] feat(esp_hw_support): support esp32p4 sleep peripheral retention --- components/driver/i2c/i2c.c | 4 +- components/esp_driver_i2c/i2c_common.c | 4 +- components/esp_hw_support/dma/gdma.c | 4 +- .../include/esp_private/sleep_cpu.h | 4 +- .../system_peripheral_retention_init.c | 214 ------------------ .../esp_hw_support/sleep_system_peripheral.c | 57 ++++- components/hal/include/hal/pmu_types.h | 5 +- .../include/soc/retention_periph_defs.h | 38 ++++ .../include/soc/system_periph_retention.h | 110 +++++++++ .../soc/esp32p4/system_retention_periph.c | 133 +++++++++++ components/soc/include/soc/regdma.h | 1 + 11 files changed, 342 insertions(+), 232 deletions(-) delete mode 100644 components/esp_hw_support/port/esp32p4/system_peripheral_retention_init.c create mode 100644 components/soc/esp32p4/include/soc/retention_periph_defs.h create mode 100644 components/soc/esp32p4/include/soc/system_periph_retention.h create mode 100644 components/soc/esp32p4/system_retention_periph.c diff --git a/components/driver/i2c/i2c.c b/components/driver/i2c/i2c.c index beffa611d8..5ebdddcd5d 100644 --- a/components/driver/i2c/i2c.c +++ b/components/driver/i2c/i2c.c @@ -414,7 +414,7 @@ esp_err_t i2c_driver_install(i2c_port_t i2c_num, i2c_mode_t mode, size_t slv_rx_ } #endif // SOC_I2C_SUPPORT_SLAVE -#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-9353 ret = sleep_retention_entries_create(i2c_regs_retention[i2c_num].link_list, i2c_regs_retention[i2c_num].link_num, REGDMA_LINK_PRI_7, I2C_SLEEP_RETENTION_MODULE(i2c_num)); ESP_GOTO_ON_ERROR(ret, err, I2C_TAG, "failed to allocate mem for sleep retention"); #endif @@ -470,7 +470,7 @@ esp_err_t i2c_driver_delete(i2c_port_t i2c_num) esp_intr_free(p_i2c->intr_handle); p_i2c->intr_handle = NULL; -#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-9353 sleep_retention_entries_destroy(I2C_SLEEP_RETENTION_MODULE(i2c_num)); #endif diff --git a/components/esp_driver_i2c/i2c_common.c b/components/esp_driver_i2c/i2c_common.c index 671b40573e..34025ecba6 100644 --- a/components/esp_driver_i2c/i2c_common.c +++ b/components/esp_driver_i2c/i2c_common.c @@ -59,7 +59,7 @@ static esp_err_t s_i2c_bus_handle_acquire(i2c_port_num_t port_num, i2c_bus_handl bus->spinlock = (portMUX_TYPE)portMUX_INITIALIZER_UNLOCKED; bus->bus_mode = mode; -#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-9353 ret = sleep_retention_entries_create(i2c_regs_retention[port_num].link_list, i2c_regs_retention[port_num].link_num, REGDMA_LINK_PRI_7, I2C_SLEEP_RETENTION_MODULE(port_num)); ESP_RETURN_ON_ERROR(ret, TAG, "failed to allocate mem for sleep retention"); #endif @@ -137,7 +137,7 @@ esp_err_t i2c_release_bus_handle(i2c_bus_handle_t i2c_bus) if (s_i2c_platform.count[port_num] == 0) { do_deinitialize = true; s_i2c_platform.buses[port_num] = NULL; -#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP +#if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP && !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-9353 sleep_retention_entries_destroy(I2C_SLEEP_RETENTION_MODULE(port_num)); #endif if (i2c_bus->intr_handle) { diff --git a/components/esp_hw_support/dma/gdma.c b/components/esp_hw_support/dma/gdma.c index beba4955d8..a619205cb6 100644 --- a/components/esp_hw_support/dma/gdma.c +++ b/components/esp_hw_support/dma/gdma.c @@ -698,7 +698,7 @@ static void gdma_release_pair_handle(gdma_pair_t *pair) if (do_deinitialize) { free(pair); -#if CONFIG_PM_ENABLE && SOC_PM_SUPPORT_TOP_PD +#if CONFIG_PM_ENABLE && SOC_PM_SUPPORT_TOP_PD && !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-8461 gdma_sleep_retention_deinit(group->group_id, pair_id); #endif ESP_LOGD(TAG, "del pair (%d,%d)", group->group_id, pair_id); @@ -738,7 +738,7 @@ static gdma_pair_t *gdma_acquire_pair_handle(gdma_group_t *group, int pair_id) s_platform.group_ref_counts[group->group_id]++; portEXIT_CRITICAL(&s_platform.spinlock); -#if CONFIG_PM_ENABLE && SOC_PM_SUPPORT_TOP_PD +#if CONFIG_PM_ENABLE && SOC_PM_SUPPORT_TOP_PD && !CONFIG_IDF_TARGET_ESP32P4 // TODO: IDF-8461 gdma_sleep_retention_init(group->group_id, pair_id); #endif ESP_LOGD(TAG, "new pair (%d,%d) at %p", group->group_id, pair_id, pair); diff --git a/components/esp_hw_support/include/esp_private/sleep_cpu.h b/components/esp_hw_support/include/esp_private/sleep_cpu.h index 5ace9e067f..136c034103 100644 --- a/components/esp_hw_support/include/esp_private/sleep_cpu.h +++ b/components/esp_hw_support/include/esp_private/sleep_cpu.h @@ -6,8 +6,8 @@ #pragma once #include +#include #include "sdkconfig.h" -#include "stdbool.h" #include "esp_err.h" #include "soc/soc_caps.h" @@ -55,7 +55,7 @@ void sleep_enable_cpu_retention(void); * @brief Disable cpu retention of some modules. * * In light sleep mode, after the system exits sleep, disable the cpu - * retention of moudles such as CPU and I/D-cache tag memory. + * retention of modules such as CPU and I/D-cache tag memory. */ void sleep_disable_cpu_retention(void); #endif // SOC_PM_CPU_RETENTION_BY_RTCCNTL diff --git a/components/esp_hw_support/port/esp32p4/system_peripheral_retention_init.c b/components/esp_hw_support/port/esp32p4/system_peripheral_retention_init.c deleted file mode 100644 index 83ff04175c..0000000000 --- a/components/esp_hw_support/port/esp32p4/system_peripheral_retention_init.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "esp_check.h" - -#include "esp_private/startup_internal.h" -#include "esp_private/sleep_retention.h" -#include "esp_private/sleep_clock.h" - -#include "soc/cache_reg.h" -#include "soc/gpio_reg.h" -#include "soc/hp_system_reg.h" -#include "soc/io_mux_reg.h" -#include "soc/interrupt_core0_reg.h" -#include "soc/interrupt_core1_reg.h" -#include "hal/mwdt_ll.h" -#include "soc/pau_reg.h" -#include "soc/spi_mem_reg.h" -#include "soc/systimer_reg.h" -#include "soc/timer_group_reg.h" -#include "soc/uart_reg.h" - -static __attribute__((unused)) const char *TAG = "sleep_sys_periph"; - -#define SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT (REGDMA_LINK_PRI_6) - - -esp_err_t sleep_sys_periph_intr_matrix_retention_init(void) -{ - #define N_REGS_INTR_CORE0() (((INTERRUPT_CORE0_CLOCK_GATE_REG - DR_REG_INTERRUPT_CORE0_BASE) / 4) + 1) - #define N_REGS_INTR_CORE1() (((INTERRUPT_CORE1_CLOCK_GATE_REG - DR_REG_INTERRUPT_CORE1_BASE) / 4) + 1) - - const static sleep_retention_entries_config_t intr_matrix_regs_retention[] = { - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_INTMTX_LINK(0x00), DR_REG_INTERRUPT_CORE0_BASE, DR_REG_INTERRUPT_CORE0_BASE, N_REGS_INTR_CORE0(), 0, 0), .owner = ENTRY(0) }, /* intr matrix */ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_INTMTX_LINK(0x01), DR_REG_INTERRUPT_CORE1_BASE, DR_REG_INTERRUPT_CORE1_BASE, N_REGS_INTR_CORE1(), 0, 0), .owner = ENTRY(0) } /* intr matrix */ - }; - - esp_err_t err = sleep_retention_entries_create(intr_matrix_regs_retention, ARRAY_SIZE(intr_matrix_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_INTR_MATRIX); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (Interrupt matrix) retention"); - ESP_LOGI(TAG, "Interrupt Matrix sleep retention initialization"); - return ESP_OK; -} - - -esp_err_t sleep_sys_periph_l2_cache_retention_init(void) -{ - #define N_REGS_L2_CACHE() (((CACHE_L2_CACHE_DATA_MEM_POWER_CTRL_REG - CACHE_L2_CACHE_CTRL_REG) / 4) + 1) - - const static sleep_retention_entries_config_t l2_cache_regs_retention[] = { - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_HPSYS_LINK(0), CACHE_L2_CACHE_CTRL_REG, CACHE_L2_CACHE_CTRL_REG, N_REGS_L2_CACHE(), 0, 0), .owner = ENTRY(0) } /* hp system */ - }; - - esp_err_t err = sleep_retention_entries_create(l2_cache_regs_retention, ARRAY_SIZE(l2_cache_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_L2_CACHE); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (L2 Cache) retention"); - ESP_LOGI(TAG, "L2 Cache sleep retention initialization"); - return ESP_OK; -} - -esp_err_t sleep_sys_periph_hp_system_retention_init(void) -{ - #define N_REGS_HP_SYSTEM() (((HP_SYSTEM_AHB2AXI_BRESP_ERR_INT_ENA_REG - DR_REG_HP_SYS_BASE) / 4) + 1) - - const static sleep_retention_entries_config_t hp_system_regs_retention[] = { - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_HPSYS_LINK(0), DR_REG_HP_SYS_BASE, DR_REG_HP_SYS_BASE, N_REGS_HP_SYSTEM(), 0, 0), .owner = ENTRY(0) } /* hp system */ - }; - - esp_err_t err = sleep_retention_entries_create(hp_system_regs_retention, ARRAY_SIZE(hp_system_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_HP_SYSTEM); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (HP system) retention"); - ESP_LOGI(TAG, "HP System sleep retention initialization"); - return ESP_OK; -} - -esp_err_t sleep_sys_periph_uart0_retention_init(void) -{ - #define N_REGS_UART() (((UART_CLK_CONF_REG(0) - REG_UART_BASE(0)) / 4) + 1) - - const static sleep_retention_entries_config_t uart_regs_retention[] = { - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_UART_LINK(0x00), REG_UART_BASE(0), REG_UART_BASE(0), N_REGS_UART(), 0, 0), .owner = ENTRY(0) }, /* uart */ - /* Note: uart register should set update reg to make the configuration take effect */ - [1] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_UART_LINK(0x01), UART_REG_UPDATE_REG(0), UART_REG_UPDATE, UART_REG_UPDATE_M, 1, 0), .owner = ENTRY(0) }, - [2] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_UART_LINK(0x02), UART_REG_UPDATE_REG(0), 0x0, UART_REG_UPDATE_M, 1, 0), .owner = ENTRY(0) } - }; - - esp_err_t err = sleep_retention_entries_create(uart_regs_retention, ARRAY_SIZE(uart_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_UART0); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (UART) retention"); - ESP_LOGI(TAG, "UART sleep retention initialization"); - return ESP_OK; -} - -esp_err_t sleep_sys_periph_tg0_retention_init(void) -{ - #define N_REGS_TG0() (((TIMG_REGCLK_REG(0) - REG_TIMG_BASE(0)) / 4) + 1) - - const static sleep_retention_entries_config_t tg_regs_retention[] = { - /*Timer group0 backup. T0_wdt should get of write project firstly. wdt used by RTOS.*/ - [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) }, /* TG0 */ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x01), REG_TIMG_BASE(0), REG_TIMG_BASE(0), N_REGS_TG0(), 0, 0), .owner = ENTRY(0) }, - [2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x02), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) }, - [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x03), TIMG_WDTCONFIG0_REG(0), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) }, - [4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x04), TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) }, - [5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_TIMG_LINK(0x05), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) }, - [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x06), TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), .owner = ENTRY(0) }, - [7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x07), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) }, - }; - - esp_err_t err = sleep_retention_entries_create(tg_regs_retention, ARRAY_SIZE(tg_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_TG0); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (Timer Group0) retention"); - ESP_LOGI(TAG, "Timer Group0 sleep retention initialization"); - return ESP_OK; -} - -esp_err_t sleep_sys_periph_iomux_retention_init(void) -{ - #define N_REGS_IOMUX_0() (((PERIPHS_IO_MUX_U_PAD_GPIO56 - REG_IO_MUX_BASE) / 4) + 1) - #define N_REGS_IOMUX_1() (((GPIO_ZERO_DET1_FILTER_CNT_REG - DR_REG_GPIO_BASE) / 4) + 1) - - const static sleep_retention_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) }, /* 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) }, - }; - - esp_err_t err = sleep_retention_entries_create(iomux_regs_retention, ARRAY_SIZE(iomux_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_IOMUX); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (IO Matrix) retention"); - ESP_LOGI(TAG, "IO Matrix sleep retention initialization"); - return ESP_OK; -} - -esp_err_t sleep_sys_periph_spimem_retention_init(void) -{ - #define N_REGS_SPI1_MEM_0() (((SPI1_MEM_C_SUS_STATUS_REG - DR_REG_FLASH_SPI1_BASE) / 4) + 1) - #define N_REGS_SPI1_MEM_1() (((SPI1_MEM_C_DDR_REG - SPI1_MEM_C_INT_ENA_REG) / 4) + 1) - #define N_REGS_SPI1_MEM_2() (1) - #define N_REGS_SPI1_MEM_3() (1) - - #define N_REGS_SPI0_MEM_0() ((SPI_MEM_C_SMEM_DDR_REG - DR_REG_FLASH_SPI0_BASE) / 4 + 1) - #define N_REGS_SPI0_MEM_1() (((SPI_MEM_C_SMEM_AC_REG - SPI_MEM_C_FMEM__PMS0_ATTR_REG) / 4) + 1) - #define N_REGS_SPI0_MEM_2() (1) - #define N_REGS_SPI0_MEM_3() (((SPI_MEM_C_DATE_REG - SPI_MEM_C_MMU_POWER_CTRL_REG) / 4) + 1) - - const static sleep_retention_entries_config_t 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_FLASH_SPI1_BASE, DR_REG_FLASH_SPI1_BASE, N_REGS_SPI1_MEM_0(), 0, 0), .owner = ENTRY(0) }, /* spi1_mem */ - [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x01), SPI1_MEM_C_INT_ENA_REG, SPI1_MEM_C_INT_ENA_REG, N_REGS_SPI1_MEM_1(), 0, 0), .owner = ENTRY(0) }, - [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x02), SPI1_MEM_C_TIMING_CALI_REG, SPI1_MEM_C_TIMING_CALI_REG, N_REGS_SPI1_MEM_2(), 0, 0), .owner = ENTRY(0) }, - [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x03), SPI1_MEM_C_CLOCK_GATE_REG, SPI1_MEM_C_CLOCK_GATE_REG, N_REGS_SPI1_MEM_3(), 0, 0), .owner = ENTRY(0) }, - - /* Note: SPI mem should not to write mmu SPI_MEM_MMU_ITEM_CONTENT_REG and SPI_MEM_MMU_ITEM_INDEX_REG */ - [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x04), DR_REG_FLASH_SPI0_BASE, DR_REG_FLASH_SPI0_BASE, N_REGS_SPI0_MEM_0(), 0, 0), .owner = ENTRY(0) }, /* spi0_mem */ - [5] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x05), SPI_MEM_C_FMEM__PMS0_ATTR_REG, SPI_MEM_C_FMEM__PMS0_ATTR_REG, N_REGS_SPI0_MEM_1(), 0, 0), .owner = ENTRY(0) }, - [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x06), SPI_MEM_C_CLOCK_GATE_REG, SPI_MEM_C_CLOCK_GATE_REG, N_REGS_SPI0_MEM_2(), 0, 0), .owner = ENTRY(0) }, - [7] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x07), SPI_MEM_C_MMU_POWER_CTRL_REG, SPI_MEM_C_MMU_POWER_CTRL_REG, N_REGS_SPI0_MEM_3(), 0, 0), .owner = ENTRY(0) } - }; - - esp_err_t err = sleep_retention_entries_create(spimem_regs_retention, ARRAY_SIZE(spimem_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SPIMEM); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (SPI mem) retention"); - ESP_LOGI(TAG, "SPI Mem sleep retention initialization"); - return ESP_OK; -} - -esp_err_t sleep_sys_periph_systimer_retention_init(void) -{ - #define N_REGS_SYSTIMER_0() (((SYSTIMER_TARGET2_CONF_REG - SYSTIMER_TARGET0_HI_REG) / 4) + 1) - - const static sleep_retention_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) }, /* 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) }, - [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) }, - [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) }, - - [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) }, - [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) }, - [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) }, - [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) }, - - [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) }, /* 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) }, - [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) }, - [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) }, - - [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) }, - [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) }, - - [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) }, - [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) }, - - [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) }, - - [17] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x11), SYSTIMER_CONF_REG, SYSTIMER_CONF_REG, 1, 0, 0), .owner = ENTRY(0) }, /* 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) } /* Systimer intr enable */ - }; - - esp_err_t err = sleep_retention_entries_create(systimer_regs_retention, ARRAY_SIZE(systimer_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SYSTIMER); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (SysTimer) retention"); - ESP_LOGI(TAG, "SysTimer sleep retention initialization"); - return ESP_OK; -} - -esp_err_t sleep_pau_retention_init(void) -{ - #define N_REGS_PAU() (((PAU_INT_ENA_REG - DR_REG_PAU_BASE) / 4) + 1) - - const static sleep_retention_entries_config_t pau_regs_retention[] = { - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_PAU_LINK(0x0), DR_REG_PAU_BASE, DR_REG_PAU_BASE, N_REGS_PAU(), 0, 0), .owner = ENTRY(0) }, /* pau */ - }; - - esp_err_t err = sleep_retention_entries_create(pau_regs_retention, ARRAY_SIZE(pau_regs_retention), REGDMA_LINK_PRI_7, SLEEP_RETENTION_MODULE_REGDMA_SYSTEM); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for system (PAU) retention"); - ESP_LOGI(TAG, "PAU sleep retention initialization"); - return ESP_OK; -} diff --git a/components/esp_hw_support/sleep_system_peripheral.c b/components/esp_hw_support/sleep_system_peripheral.c index 71344a4383..bf07578136 100644 --- a/components/esp_hw_support/sleep_system_peripheral.c +++ b/components/esp_hw_support/sleep_system_peripheral.c @@ -36,6 +36,7 @@ esp_err_t sleep_sys_periph_hp_system_retention_init(void) return ESP_OK; } +#if SOC_APM_SUPPORTED esp_err_t sleep_sys_periph_tee_apm_retention_init(void) { esp_err_t err = sleep_retention_entries_create(tee_apm_regs_retention, ARRAY_SIZE(tee_apm_regs_retention), REGDMA_LINK_PRI_NON_CRITICAL_TEE_APM, SLEEP_RETENTION_MODULE_TEE_APM); @@ -46,6 +47,7 @@ esp_err_t sleep_sys_periph_tee_apm_retention_init(void) ESP_LOGI(TAG, "TEE/APM sleep retention initialization"); return ESP_OK; } +#endif esp_err_t sleep_sys_periph_uart0_retention_init(void) { @@ -87,6 +89,27 @@ esp_err_t sleep_sys_periph_systimer_retention_init(void) return ESP_OK; } + +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE +esp_err_t sleep_sys_periph_l2_cache_retention_init(void) +{ + esp_err_t err = sleep_retention_entries_create(l2_cache_regs_retention, ARRAY_SIZE(l2_cache_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_L2_CACHE); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (L2 Cache) retention"); + ESP_LOGI(TAG, "L2 Cache sleep retention initialization"); + return ESP_OK; +} +#endif + +#if SOC_PAU_IN_TOP_DOMAIN +esp_err_t sleep_pau_retention_init(void) +{ + esp_err_t err = sleep_retention_entries_create(pau_regs_retention, ARRAY_SIZE(pau_regs_retention), REGDMA_LINK_PRI_7, SLEEP_RETENTION_MODULE_REGDMA_SYSTEM); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for system (PAU) retention"); + ESP_LOGI(TAG, "PAU sleep retention initialization"); + return ESP_OK; +} +#endif + esp_err_t sleep_sys_periph_retention_init(void) { esp_err_t err; @@ -94,8 +117,14 @@ esp_err_t sleep_sys_periph_retention_init(void) if(err) goto error; err = sleep_sys_periph_hp_system_retention_init(); if(err) goto error; +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + err = sleep_sys_periph_l2_cache_retention_init(); + if(err) goto error; +#endif +#if SOC_APM_SUPPORTED err = sleep_sys_periph_tee_apm_retention_init(); if(err) goto error; +#endif err = sleep_sys_periph_uart0_retention_init(); if(err) goto error; err = sleep_sys_periph_tg0_retention_init(); @@ -117,15 +146,25 @@ error: bool peripheral_domain_pd_allowed(void) { const uint32_t modules = sleep_retention_get_modules(); - const uint32_t mask = (const uint32_t) ( - SLEEP_RETENTION_MODULE_INTR_MATRIX | \ - SLEEP_RETENTION_MODULE_HP_SYSTEM | \ - SLEEP_RETENTION_MODULE_TEE_APM | \ - SLEEP_RETENTION_MODULE_UART0 | \ - SLEEP_RETENTION_MODULE_TG0 | \ - SLEEP_RETENTION_MODULE_IOMUX | \ - SLEEP_RETENTION_MODULE_SPIMEM | \ - SLEEP_RETENTION_MODULE_SYSTIMER); + uint32_t mask = 0; + + mask |= SLEEP_RETENTION_MODULE_INTR_MATRIX; + mask |= SLEEP_RETENTION_MODULE_HP_SYSTEM; +#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE + mask |= SLEEP_RETENTION_MODULE_L2_CACHE; +#endif +#if SOC_APM_SUPPORTED + mask |= SLEEP_RETENTION_MODULE_TEE_APM; +#endif + mask |= SLEEP_RETENTION_MODULE_UART0; + mask |= SLEEP_RETENTION_MODULE_TG0; + mask |= SLEEP_RETENTION_MODULE_IOMUX; + mask |= SLEEP_RETENTION_MODULE_SPIMEM; + mask |= SLEEP_RETENTION_MODULE_SYSTIMER; +#if SOC_PAU_IN_TOP_DOMAIN + mask |= SLEEP_RETENTION_MODULE_REGDMA_SYSTEM; +#endif + return ((modules & mask) == mask); } diff --git a/components/hal/include/hal/pmu_types.h b/components/hal/include/hal/pmu_types.h index afaf58ceff..cb1fab415e 100644 --- a/components/hal/include/hal/pmu_types.h +++ b/components/hal/include/hal/pmu_types.h @@ -33,10 +33,13 @@ typedef enum { PMU_MODE_LP_MAX, } pmu_lp_mode_t; +/** + * @brief PMU power domain of HP system + */ #if CONFIG_IDF_TARGET_ESP32P4 typedef enum { PMU_HP_PD_TOP = 0, /*!< Power domain of digital top */ - PMU_HP_PD_CNNT = 1, /*!< Power domain of high-speed IO peripherals such as USB/SDIO/Ethernet etc.*/ + PMU_HP_PD_CNNT = 1, /*!< Power domain of high-speed IO peripherals such as USB/SDIO/Ethernet etc.*/ PMU_HP_PD_HPMEM = 2, } pmu_hp_power_domain_t; #else diff --git a/components/soc/esp32p4/include/soc/retention_periph_defs.h b/components/soc/esp32p4/include/soc/retention_periph_defs.h new file mode 100644 index 0000000000..c382029dbc --- /dev/null +++ b/components/soc/esp32p4/include/soc/retention_periph_defs.h @@ -0,0 +1,38 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "esp_bit_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum periph_retention_module_bitmap { + /* clock module, which includes system and modem */ + SLEEP_RETENTION_MODULE_CLOCK_SYSTEM = BIT(1), + SLEEP_RETENTION_MODULE_REGDMA_SYSTEM = BIT(2), + + /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM, + * TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */ + SLEEP_RETENTION_MODULE_INTR_MATRIX = BIT(10), + SLEEP_RETENTION_MODULE_HP_SYSTEM = BIT(11), + SLEEP_RETENTION_MODULE_TEE_APM = BIT(12), + SLEEP_RETENTION_MODULE_UART0 = BIT(13), + SLEEP_RETENTION_MODULE_TG0 = BIT(14), + SLEEP_RETENTION_MODULE_IOMUX = BIT(15), + SLEEP_RETENTION_MODULE_SPIMEM = BIT(16), + SLEEP_RETENTION_MODULE_SYSTIMER = BIT(17), + SLEEP_RETENTION_MODULE_L2_CACHE = BIT(18), + + SLEEP_RETENTION_MODULE_ALL = (uint32_t)-1 +} periph_retention_module_bitmap_t; + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32p4/include/soc/system_periph_retention.h b/components/soc/esp32p4/include/soc/system_periph_retention.h new file mode 100644 index 0000000000..136832f334 --- /dev/null +++ b/components/soc/esp32p4/include/soc/system_periph_retention.h @@ -0,0 +1,110 @@ +/* + * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#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 2 +extern const regdma_entries_config_t intr_matrix_regs_retention[INT_MTX_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to l2_cache configuration registers retention + * context definition. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define L2_CACHE_RETENTION_LINK_LEN 1 +extern const regdma_entries_config_t l2_cache_regs_retention[L2_CACHE_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 uart configuration registers retention + * context definition. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define UART_RETENTION_LINK_LEN 3 +extern const regdma_entries_config_t uart_regs_retention[UART_RETENTION_LINK_LEN]; + +/** + * @brief Provide access to timer group configuration registers retention + * context definition. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define TIMG_RETENTION_LINK_LEN 8 +extern const regdma_entries_config_t tg_regs_retention[TIMG_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 2 +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 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]; + +/** + * @brief Provide access to pau configuration registers retention + * context definition. + * + * This is an internal function of the sleep retention driver, and is not + * useful for external use. + */ +#define PAU_RETENTION_LINK_LEN 1 +extern const regdma_entries_config_t pau_regs_retention[L2_CACHE_RETENTION_LINK_LEN]; + +#ifdef __cplusplus +} +#endif diff --git a/components/soc/esp32p4/system_retention_periph.c b/components/soc/esp32p4/system_retention_periph.c new file mode 100644 index 0000000000..b1a1b89dbf --- /dev/null +++ b/components/soc/esp32p4/system_retention_periph.c @@ -0,0 +1,133 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/cache_reg.h" +#include "soc/gpio_reg.h" +#include "soc/hp_system_reg.h" +#include "soc/io_mux_reg.h" +#include "soc/interrupt_core0_reg.h" +#include "soc/interrupt_core1_reg.h" +#include "soc/pau_reg.h" +#include "soc/regdma.h" +#include "soc/system_periph_retention.h" +#include "soc/spi_mem_reg.h" +#include "soc/systimer_reg.h" +#include "soc/timer_group_reg.h" +#include "soc/timer_periph.h" +#include "soc/uart_reg.h" + +/* Interrupt Matrix Registers Context */ +#define N_REGS_INTR_CORE0() (((INTERRUPT_CORE0_CLOCK_GATE_REG - DR_REG_INTERRUPT_CORE0_BASE) / 4) + 1) +#define N_REGS_INTR_CORE1() (((INTERRUPT_CORE1_CLOCK_GATE_REG - DR_REG_INTERRUPT_CORE1_BASE) / 4) + 1) +const regdma_entries_config_t intr_matrix_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_INTMTX_LINK(0x00), DR_REG_INTERRUPT_CORE0_BASE, DR_REG_INTERRUPT_CORE0_BASE, N_REGS_INTR_CORE0(), 0, 0), .owner = ENTRY(0) }, /* intr matrix */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_INTMTX_LINK(0x01), DR_REG_INTERRUPT_CORE1_BASE, DR_REG_INTERRUPT_CORE1_BASE, N_REGS_INTR_CORE1(), 0, 0), .owner = ENTRY(0) } /* intr matrix */ +}; +_Static_assert(ARRAY_SIZE(intr_matrix_regs_retention) == INT_MTX_RETENTION_LINK_LEN, "Inconsistent INT_MTX retention link length definitions"); + +/* L2 Cache Registers Context */ +#define N_REGS_L2_CACHE() (((CACHE_L2_CACHE_DATA_MEM_POWER_CTRL_REG - CACHE_L2_CACHE_CTRL_REG) / 4) + 1) +const regdma_entries_config_t l2_cache_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_HPSYS_LINK(0), CACHE_L2_CACHE_CTRL_REG, CACHE_L2_CACHE_CTRL_REG, N_REGS_L2_CACHE(), 0, 0), .owner = ENTRY(0) } /* hp system */ +}; +_Static_assert(ARRAY_SIZE(l2_cache_regs_retention) == HP_SYSTEM_RETENTION_LINK_LEN, "Inconsistent L2 CACHE retention link length definitions"); + +/* HP System Registers Context */ +#define N_REGS_HP_SYSTEM() (((HP_SYSTEM_AHB2AXI_BRESP_ERR_INT_ENA_REG - DR_REG_HP_SYS_BASE) / 4) + 1) +const regdma_entries_config_t hp_system_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_HPSYS_LINK(0), DR_REG_HP_SYS_BASE, DR_REG_HP_SYS_BASE, N_REGS_HP_SYSTEM(), 0, 0), .owner = ENTRY(0) } /* hp system */ +}; +_Static_assert(ARRAY_SIZE(hp_system_regs_retention) == HP_SYSTEM_RETENTION_LINK_LEN, "Inconsistent HP_SYSTEM retention link length definitions"); + +/* UART0 Registers Context */ +#define N_REGS_UART() (((UART_CLK_CONF_REG(0) - REG_UART_BASE(0)) / 4) + 1) +const regdma_entries_config_t uart_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_UART_LINK(0x00), REG_UART_BASE(0), REG_UART_BASE(0), N_REGS_UART(), 0, 0), .owner = ENTRY(0) }, /* uart */ + /* Note: uart register should set update reg to make the configuration take effect */ + [1] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_UART_LINK(0x01), UART_REG_UPDATE_REG(0), UART_REG_UPDATE, UART_REG_UPDATE_M, 1, 0), .owner = ENTRY(0) }, + [2] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_UART_LINK(0x02), UART_REG_UPDATE_REG(0), 0x0, UART_REG_UPDATE_M, 1, 0), .owner = ENTRY(0) } +}; +_Static_assert(ARRAY_SIZE(uart_regs_retention) == UART_RETENTION_LINK_LEN, "Inconsistent UART retention link length definitions"); + +/* Timergroup Registers Context */ +#define N_REGS_TG0() (((TIMG_REGCLK_REG(0) - REG_TIMG_BASE(0)) / 4) + 1) +const regdma_entries_config_t tg_regs_retention[] = { + /*Timer group0 backup. T0_wdt should get of write project firstly. wdt used by RTOS.*/ + [0] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x00), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) }, /* TG0 */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x01), REG_TIMG_BASE(0), REG_TIMG_BASE(0), N_REGS_TG0(), 0, 0), .owner = ENTRY(0) }, + [2] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x02), TIMG_WDTWPROTECT_REG(0), TIMG_WDT_WKEY_VALUE, TIMG_WDT_WKEY_M, 1, 0), .owner = ENTRY(0) }, + [3] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x03), TIMG_WDTCONFIG0_REG(0), TIMG_WDT_CONF_UPDATE_EN, TIMG_WDT_CONF_UPDATE_EN_M, 1, 0), .owner = ENTRY(0) }, + [4] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x04), TIMG_T0UPDATE_REG(0), TIMG_T0_UPDATE, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) }, + [5] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_TIMG_LINK(0x05), TIMG_T0UPDATE_REG(0), 0x0, TIMG_T0_UPDATE_M, 0, 1), .owner = ENTRY(0) }, + [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TIMG_LINK(0x06), TIMG_T0LO_REG(0), TIMG_T0LOADLO_REG(0), 2, 0, 0), .owner = ENTRY(0) }, + [7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x07), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) }, +}; +_Static_assert(ARRAY_SIZE(tg_regs_retention) == TIMG_RETENTION_LINK_LEN, "Inconsistent Timergroup retention link length definitions"); + +/* IO MUX Registers Context */ +#define N_REGS_IOMUX_0() (((PERIPHS_IO_MUX_U_PAD_GPIO56 - REG_IO_MUX_BASE) / 4) + 1) +#define N_REGS_IOMUX_1() (((GPIO_ZERO_DET1_FILTER_CNT_REG - DR_REG_GPIO_BASE) / 4) + 1) +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) }, /* 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) }, +}; +_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() (((SPI1_MEM_C_SUS_STATUS_REG - DR_REG_FLASH_SPI1_BASE) / 4) + 1) +#define N_REGS_SPI1_MEM_1() (((SPI1_MEM_C_DDR_REG - SPI1_MEM_C_INT_ENA_REG) / 4) + 1) +#define N_REGS_SPI1_MEM_2() (1) +#define N_REGS_SPI1_MEM_3() (1) +#define N_REGS_SPI0_MEM_0() ((SPI_MEM_C_SMEM_DDR_REG - DR_REG_FLASH_SPI0_BASE) / 4 + 1) +#define N_REGS_SPI0_MEM_1() (((SPI_MEM_C_SMEM_AC_REG - SPI_MEM_C_FMEM__PMS0_ATTR_REG) / 4) + 1) +#define N_REGS_SPI0_MEM_2() (1) +#define N_REGS_SPI0_MEM_3() (((SPI_MEM_C_DATE_REG - SPI_MEM_C_MMU_POWER_CTRL_REG) / 4) + 1) +const regdma_entries_config_t 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_FLASH_SPI1_BASE, DR_REG_FLASH_SPI1_BASE, N_REGS_SPI1_MEM_0(), 0, 0), .owner = ENTRY(0) }, /* spi1_mem */ + [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x01), SPI1_MEM_C_INT_ENA_REG, SPI1_MEM_C_INT_ENA_REG, N_REGS_SPI1_MEM_1(), 0, 0), .owner = ENTRY(0) }, + [2] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x02), SPI1_MEM_C_TIMING_CALI_REG, SPI1_MEM_C_TIMING_CALI_REG, N_REGS_SPI1_MEM_2(), 0, 0), .owner = ENTRY(0) }, + [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x03), SPI1_MEM_C_CLOCK_GATE_REG, SPI1_MEM_C_CLOCK_GATE_REG, N_REGS_SPI1_MEM_3(), 0, 0), .owner = ENTRY(0) }, + + /* Note: SPI mem should not to write mmu SPI_MEM_MMU_ITEM_CONTENT_REG and SPI_MEM_MMU_ITEM_INDEX_REG */ + [4] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x04), DR_REG_FLASH_SPI0_BASE, DR_REG_FLASH_SPI0_BASE, N_REGS_SPI0_MEM_0(), 0, 0), .owner = ENTRY(0) }, /* spi0_mem */ + [5] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x05), SPI_MEM_C_FMEM__PMS0_ATTR_REG, SPI_MEM_C_FMEM__PMS0_ATTR_REG, N_REGS_SPI0_MEM_1(), 0, 0), .owner = ENTRY(0) }, + [6] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x06), SPI_MEM_C_CLOCK_GATE_REG, SPI_MEM_C_CLOCK_GATE_REG, N_REGS_SPI0_MEM_2(), 0, 0), .owner = ENTRY(0) }, + [7] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x07), SPI_MEM_C_MMU_POWER_CTRL_REG, SPI_MEM_C_MMU_POWER_CTRL_REG, N_REGS_SPI0_MEM_3(), 0, 0), .owner = ENTRY(0) } +}; +_Static_assert(ARRAY_SIZE(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) }, /* 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) }, + [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) }, + [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) }, + [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) }, + [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) }, + [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) }, + [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) }, + [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) }, /* 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) }, + [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) }, + [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) }, + [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) }, + [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) }, + [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) }, + [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) }, + [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) }, + [17] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x11), SYSTIMER_CONF_REG, SYSTIMER_CONF_REG, 1, 0, 0), .owner = ENTRY(0) }, /* 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) } /* Systimer intr enable */ +}; +_Static_assert(ARRAY_SIZE(systimer_regs_retention) == SYSTIMER_RETENTION_LINK_LEN, "Inconsistent Systimer retention link length definitions"); + +/* PAU Registers Context */ +#define N_REGS_PAU() (((PAU_INT_ENA_REG - DR_REG_PAU_BASE) / 4) + 1) +const regdma_entries_config_t pau_regs_retention[] = { + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_PAU_LINK(0x0), DR_REG_PAU_BASE, DR_REG_PAU_BASE, N_REGS_PAU(), 0, 0), .owner = ENTRY(0) }, /* pau */ +}; +_Static_assert(ARRAY_SIZE(pau_regs_retention) == HP_SYSTEM_RETENTION_LINK_LEN, "Inconsistent PAU retention link length definitions"); diff --git a/components/soc/include/soc/regdma.h b/components/soc/include/soc/regdma.h index 1f3ea3bb75..1662f733af 100644 --- a/components/soc/include/soc/regdma.h +++ b/components/soc/include/soc/regdma.h @@ -30,6 +30,7 @@ extern "C" { #define REGDMA_PCR_LINK(_pri) ((0x01 << 8) | _pri) #define REGDMA_MODEMSYSCON_LINK(_pri) ((0x02 << 8) | _pri) #define REGDMA_MODEMLPCON_LINK(_pri) ((0x03 << 8) | _pri) +#define REGDMA_PAU_LINK(_pri) ((0x04 << 8) | _pri) #define REGDMA_INTMTX_LINK(_pri) ((0x0d << 8) | _pri) #define REGDMA_HPSYS_LINK(_pri) ((0x0e << 8) | _pri) From 4a64d2fe2c8d4f3ab50f82da6f511bf13045dad9 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Wed, 20 Mar 2024 20:36:45 +0800 Subject: [PATCH 7/8] change(hal): control PAU bus clock by hal layer --- components/esp_hw_support/port/pau_regdma.c | 2 +- components/esp_system/port/soc/esp32c6/clk.c | 3 ++- components/esp_system/port/soc/esp32h2/clk.c | 3 ++- components/hal/esp32c6/include/hal/clk_gate_ll.h | 10 +--------- components/hal/esp32c6/include/hal/pau_ll.h | 14 +++++++++++++- components/hal/esp32c61/include/hal/clk_gate_ll.h | 8 -------- components/hal/esp32h2/include/hal/clk_gate_ll.h | 10 +--------- components/hal/esp32h2/include/hal/pau_ll.h | 14 +++++++++++++- components/hal/esp32p4/include/hal/clk_gate_ll.h | 8 -------- components/hal/esp32p4/include/hal/pau_ll.h | 13 +++++++++++++ components/hal/include/hal/pau_hal.h | 7 +++++++ components/soc/esp32c6/include/soc/periph_defs.h | 1 - components/soc/esp32c61/include/soc/periph_defs.h | 1 - components/soc/esp32h2/include/soc/periph_defs.h | 1 - components/soc/esp32p4/include/soc/periph_defs.h | 1 - 15 files changed, 53 insertions(+), 43 deletions(-) diff --git a/components/esp_hw_support/port/pau_regdma.c b/components/esp_hw_support/port/pau_regdma.c index 152dbf65be..2850d9dfb4 100644 --- a/components/esp_hw_support/port/pau_regdma.c +++ b/components/esp_hw_support/port/pau_regdma.c @@ -31,7 +31,7 @@ pau_context_t * __attribute__((weak)) IRAM_ATTR PAU_instance(void) if (pau_hal.dev == NULL) { pau_hal.dev = &PAU; - periph_module_enable(PERIPH_REGDMA_MODULE); + pau_hal_enable_bus_clock(true); #if SOC_PAU_IN_TOP_DOMAIN pau_hal_lp_sys_initialize(); #endif diff --git a/components/esp_system/port/soc/esp32c6/clk.c b/components/esp_system/port/soc/esp32c6/clk.c index 66f86cd18e..cd4b3d994a 100644 --- a/components/esp_system/port/soc/esp32c6/clk.c +++ b/components/esp_system/port/soc/esp32c6/clk.c @@ -35,6 +35,7 @@ #include "hal/mcpwm_ll.h" #include "hal/parlio_ll.h" #include "hal/gdma_ll.h" +#include "hal/pau_ll.h" #include "hal/spi_ll.h" #include "hal/clk_gate_ll.h" #include "hal/lp_core_ll.h" @@ -255,11 +256,11 @@ __attribute__((weak)) void esp_perip_clk_init(void) #endif spi_ll_enable_bus_clock(SPI2_HOST, false); temperature_sensor_ll_bus_clk_enable(false); + pau_ll_enable_bus_clock(false); periph_ll_disable_clk_set_rst(PERIPH_UHCI0_MODULE); periph_ll_disable_clk_set_rst(PERIPH_SARADC_MODULE); periph_ll_disable_clk_set_rst(PERIPH_SDIO_SLAVE_MODULE); - periph_ll_disable_clk_set_rst(PERIPH_REGDMA_MODULE); #if !CONFIG_ESP_SYSTEM_HW_PC_RECORD /* Disable ASSIST Debug module clock if PC recoreding function is not used, * if stack guard function needs it, it will be re-enabled at esp_hw_stack_guard_init */ diff --git a/components/esp_system/port/soc/esp32h2/clk.c b/components/esp_system/port/soc/esp32h2/clk.c index 4cd35b577b..9164b80856 100644 --- a/components/esp_system/port/soc/esp32h2/clk.c +++ b/components/esp_system/port/soc/esp32h2/clk.c @@ -37,6 +37,7 @@ #include "hal/mcpwm_ll.h" #include "hal/parlio_ll.h" #include "hal/gdma_ll.h" +#include "hal/pau_ll.h" #include "hal/spi_ll.h" #include "hal/clk_gate_ll.h" #include "hal/temperature_sensor_ll.h" @@ -247,10 +248,10 @@ __attribute__((weak)) void esp_perip_clk_init(void) #endif spi_ll_enable_bus_clock(SPI2_HOST, false); temperature_sensor_ll_bus_clk_enable(false); + pau_ll_enable_bus_clock(false); periph_ll_disable_clk_set_rst(PERIPH_UHCI0_MODULE); periph_ll_disable_clk_set_rst(PERIPH_SARADC_MODULE); - periph_ll_disable_clk_set_rst(PERIPH_REGDMA_MODULE); #if !CONFIG_ESP_SYSTEM_HW_PC_RECORD /* Disable ASSIST Debug module clock if PC recoreding function is not used, * if stack guard function needs it, it will be re-enabled at esp_hw_stack_guard_init */ diff --git a/components/hal/esp32c6/include/hal/clk_gate_ll.h b/components/hal/esp32c6/include/hal/clk_gate_ll.h index 071a0e8d88..ecac26fd45 100644 --- a/components/hal/esp32c6/include/hal/clk_gate_ll.h +++ b/components/hal/esp32c6/include/hal/clk_gate_ll.h @@ -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 */ @@ -78,8 +78,6 @@ static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph) return PCR_TSENS_CLK_EN; case PERIPH_SDIO_SLAVE_MODULE: return PCR_SDIO_SLAVE_CLK_EN; - case PERIPH_REGDMA_MODULE: - return PCR_REGDMA_CLK_EN; case PERIPH_ASSIST_DEBUG_MODULE: return PCR_ASSIST_CLK_EN; default: @@ -161,8 +159,6 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en return PCR_DS_RST_EN; case PERIPH_SDIO_SLAVE_MODULE: return PCR_SDIO_SLAVE_RST_EN; - case PERIPH_REGDMA_MODULE: - return PCR_REGDMA_RST_EN; case PERIPH_ASSIST_DEBUG_MODULE: return PCR_ASSIST_RST_EN; default: @@ -229,8 +225,6 @@ static inline uint32_t periph_ll_get_clk_en_reg(periph_module_t periph) return PCR_TSENS_CLK_CONF_REG; case PERIPH_SDIO_SLAVE_MODULE: return PCR_SDIO_SLAVE_CONF_REG; - case PERIPH_REGDMA_MODULE: - return PCR_REGDMA_CONF_REG; case PERIPH_ASSIST_DEBUG_MODULE: return PCR_ASSIST_CONF_REG; default: @@ -297,8 +291,6 @@ static inline uint32_t periph_ll_get_rst_en_reg(periph_module_t periph) return PCR_TSENS_CLK_CONF_REG; case PERIPH_SDIO_SLAVE_MODULE: return PCR_SDIO_SLAVE_CONF_REG; - case PERIPH_REGDMA_MODULE: - return PCR_REGDMA_CONF_REG; case PERIPH_ASSIST_DEBUG_MODULE: return PCR_ASSIST_CONF_REG; default: diff --git a/components/hal/esp32c6/include/hal/pau_ll.h b/components/hal/esp32c6/include/hal/pau_ll.h index 998fa628c8..f47c7e9746 100644 --- a/components/hal/esp32c6/include/hal/pau_ll.h +++ b/components/hal/esp32c6/include/hal/pau_ll.h @@ -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 */ @@ -13,6 +13,7 @@ #include "soc/soc.h" #include "soc/pau_reg.h" #include "soc/pau_struct.h" +#include "soc/pcr_struct.h" #include "hal/pau_types.h" #include "hal/assert.h" @@ -20,6 +21,17 @@ extern "C" { #endif +static inline void pau_ll_enable_bus_clock(bool enable) +{ + if (enable) { + PCR.regdma_conf.regdma_clk_en = 1; + PCR.regdma_conf.regdma_rst_en = 0; + } else { + PCR.regdma_conf.regdma_clk_en = 0; + PCR.regdma_conf.regdma_rst_en = 1; + } +} + static inline uint32_t pau_ll_get_regdma_backup_flow_error(pau_dev_t *dev) { return dev->regdma_conf.flow_err; diff --git a/components/hal/esp32c61/include/hal/clk_gate_ll.h b/components/hal/esp32c61/include/hal/clk_gate_ll.h index 9dad7ff71b..e6403b46b6 100644 --- a/components/hal/esp32c61/include/hal/clk_gate_ll.h +++ b/components/hal/esp32c61/include/hal/clk_gate_ll.h @@ -54,8 +54,6 @@ static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph) return PCR_ECC_CLK_EN; case PERIPH_TEMPSENSOR_MODULE: return PCR_TSENS_CLK_EN; - case PERIPH_REGDMA_MODULE: - return PCR_REGDMA_CLK_EN; case PERIPH_ASSIST_DEBUG_MODULE: return PCR_ASSIST_CLK_EN; default: @@ -103,8 +101,6 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en CLEAR_PERI_REG_MASK(PCR_HMAC_CONF_REG, PCR_HMAC_RST_EN); } return PCR_SHA_RST_EN; - case PERIPH_REGDMA_MODULE: - return PCR_REGDMA_RST_EN; case PERIPH_ASSIST_DEBUG_MODULE: return PCR_ASSIST_RST_EN; default: @@ -145,8 +141,6 @@ static inline uint32_t periph_ll_get_clk_en_reg(periph_module_t periph) return PCR_ECC_CONF_REG; case PERIPH_TEMPSENSOR_MODULE: return PCR_TSENS_CLK_CONF_REG; - case PERIPH_REGDMA_MODULE: - return PCR_REGDMA_CONF_REG; case PERIPH_ASSIST_DEBUG_MODULE: return PCR_ASSIST_CONF_REG; default: @@ -187,8 +181,6 @@ static inline uint32_t periph_ll_get_rst_en_reg(periph_module_t periph) return PCR_ECC_CONF_REG; case PERIPH_TEMPSENSOR_MODULE: return PCR_TSENS_CLK_CONF_REG; - case PERIPH_REGDMA_MODULE: - return PCR_REGDMA_CONF_REG; case PERIPH_ASSIST_DEBUG_MODULE: return PCR_ASSIST_CONF_REG; default: diff --git a/components/hal/esp32h2/include/hal/clk_gate_ll.h b/components/hal/esp32h2/include/hal/clk_gate_ll.h index d49ae217b6..3eef499230 100644 --- a/components/hal/esp32h2/include/hal/clk_gate_ll.h +++ b/components/hal/esp32h2/include/hal/clk_gate_ll.h @@ -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 */ @@ -78,8 +78,6 @@ static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph) return PCR_ECDSA_CLK_EN; case PERIPH_TEMPSENSOR_MODULE: return PCR_TSENS_CLK_EN; - case PERIPH_REGDMA_MODULE: - return PCR_REGDMA_CLK_EN; // case PERIPH_RNG_MODULE: // return PCR_WIFI_CLK_RNG_EN; // case PERIPH_WIFI_MODULE: @@ -153,8 +151,6 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en CLEAR_PERI_REG_MASK(PCR_ECDSA_CONF_REG, PCR_ECDSA_RST_EN); } return PCR_ECC_RST_EN; - case PERIPH_REGDMA_MODULE: - return PCR_REGDMA_RST_EN; case PERIPH_AES_MODULE: if (enable == true) { // Clear reset on digital signature, otherwise AES unit is held in reset @@ -268,8 +264,6 @@ static inline uint32_t periph_ll_get_clk_en_reg(periph_module_t periph) return PCR_ECDSA_CONF_REG; case PERIPH_TEMPSENSOR_MODULE: return PCR_TSENS_CLK_CONF_REG; - case PERIPH_REGDMA_MODULE: - return PCR_REGDMA_CONF_REG; case PERIPH_ASSIST_DEBUG_MODULE: return PCR_ASSIST_CONF_REG; default: @@ -337,8 +331,6 @@ static inline uint32_t periph_ll_get_rst_en_reg(periph_module_t periph) return PCR_ECDSA_CONF_REG; case PERIPH_TEMPSENSOR_MODULE: return PCR_TSENS_CLK_CONF_REG; - case PERIPH_REGDMA_MODULE: - return PCR_REGDMA_CONF_REG; case PERIPH_ASSIST_DEBUG_MODULE: return PCR_ASSIST_CONF_REG; default: diff --git a/components/hal/esp32h2/include/hal/pau_ll.h b/components/hal/esp32h2/include/hal/pau_ll.h index fdc44feec6..d0c4d1bcef 100644 --- a/components/hal/esp32h2/include/hal/pau_ll.h +++ b/components/hal/esp32h2/include/hal/pau_ll.h @@ -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 */ @@ -13,6 +13,7 @@ #include "soc/soc.h" #include "soc/pau_reg.h" #include "soc/pau_struct.h" +#include "soc/pcr_struct.h" #include "hal/pau_types.h" #include "hal/assert.h" @@ -20,6 +21,17 @@ extern "C" { #endif +static inline void pau_ll_enable_bus_clock(bool enable) +{ + if (enable) { + PCR.regdma_conf.regdma_clk_en = 1; + PCR.regdma_conf.regdma_rst_en = 0; + } else { + PCR.regdma_conf.regdma_clk_en = 0; + PCR.regdma_conf.regdma_rst_en = 1; + } +} + static inline __attribute__((always_inline)) uint32_t pau_ll_get_regdma_backup_flow_error(pau_dev_t *dev) { return dev->regdma_conf.flow_err; diff --git a/components/hal/esp32p4/include/hal/clk_gate_ll.h b/components/hal/esp32p4/include/hal/clk_gate_ll.h index f91e6d1753..caf46ad96e 100644 --- a/components/hal/esp32p4/include/hal/clk_gate_ll.h +++ b/components/hal/esp32p4/include/hal/clk_gate_ll.h @@ -47,8 +47,6 @@ static inline uint32_t periph_ll_get_clk_en_mask(periph_module_t periph) return HP_SYS_CLKRST_REG_CRYPTO_ECDSA_CLK_EN; case PERIPH_ISP_MODULE: return HP_SYS_CLKRST_REG_ISP_CLK_EN; - case PERIPH_REGDMA_MODULE: - return HP_SYS_CLKRST_REG_REGDMA_SYS_CLK_EN; default: return 0; } @@ -105,8 +103,6 @@ static inline uint32_t periph_ll_get_rst_en_mask(periph_module_t periph, bool en return HP_SYS_CLKRST_REG_RST_EN_ECDSA; case PERIPH_EMAC_MODULE: return LP_CLKRST_RST_EN_EMAC; - case PERIPH_REGDMA_MODULE: - return HP_SYS_CLKRST_REG_RST_EN_REGDMA; default: return 0; } @@ -132,8 +128,6 @@ static inline uint32_t periph_ll_get_clk_en_reg(periph_module_t periph) return HP_SYS_CLKRST_PERI_CLK_CTRL25_REG; case PERIPH_EMAC_MODULE: return LP_CLKRST_HP_CLK_CTRL_REG; - case PERIPH_REGDMA_MODULE: - return HP_SYS_CLKRST_SOC_CLK_CTRL0_REG; default: abort(); return 0; @@ -160,8 +154,6 @@ static inline uint32_t periph_ll_get_rst_en_reg(periph_module_t periph) return HP_SYS_CLKRST_HP_RST_EN2_REG; case PERIPH_EMAC_MODULE: return LP_CLKRST_HP_SDMMC_EMAC_RST_CTRL_REG; - case PERIPH_REGDMA_MODULE: - return HP_SYS_CLKRST_HP_RST_EN0_REG; default: abort(); return 0; diff --git a/components/hal/esp32p4/include/hal/pau_ll.h b/components/hal/esp32p4/include/hal/pau_ll.h index ebd48057e2..0753735eed 100644 --- a/components/hal/esp32p4/include/hal/pau_ll.h +++ b/components/hal/esp32p4/include/hal/pau_ll.h @@ -11,15 +11,28 @@ #include #include #include "soc/soc.h" +#include "soc/hp_sys_clkrst_struct.h" #include "soc/pau_reg.h" #include "soc/pau_struct.h" #include "hal/pau_types.h" +#include "hal/pau_hal.h" #include "hal/assert.h" #ifdef __cplusplus extern "C" { #endif +static inline void pau_ll_enable_bus_clock(bool enable) +{ + if (enable) { + HP_SYS_CLKRST.soc_clk_ctrl1.reg_regdma_sys_clk_en = 1; + HP_SYS_CLKRST.hp_rst_en0.reg_rst_en_regdma = 0; + } else { + HP_SYS_CLKRST.soc_clk_ctrl1.reg_regdma_sys_clk_en = 0; + HP_SYS_CLKRST.hp_rst_en0.reg_rst_en_regdma = 1; + } +} + static inline uint32_t pau_ll_get_regdma_backup_flow_error(pau_dev_t *dev) { return dev->regdma_conf.flow_err; diff --git a/components/hal/include/hal/pau_hal.h b/components/hal/include/hal/pau_hal.h index 9c87e1c393..e95ed32698 100644 --- a/components/hal/include/hal/pau_hal.h +++ b/components/hal/include/hal/pau_hal.h @@ -22,6 +22,13 @@ typedef struct { pau_dev_t *dev; } pau_hal_context_t; +/** + * @brief Enable the bus clock of REGDMA module + * @param hal regdma hal context + * @param enable enable or disable the module clock + */ +#define pau_hal_enable_bus_clock(enable) pau_ll_enable_bus_clock(enable) + /** * @brief Set regdma entry link address * diff --git a/components/soc/esp32c6/include/soc/periph_defs.h b/components/soc/esp32c6/include/soc/periph_defs.h index 40f2aaa8fa..3fefbbd326 100644 --- a/components/soc/esp32c6/include/soc/periph_defs.h +++ b/components/soc/esp32c6/include/soc/periph_defs.h @@ -44,7 +44,6 @@ typedef enum { PERIPH_SYSTIMER_MODULE, PERIPH_SARADC_MODULE, PERIPH_TEMPSENSOR_MODULE, - PERIPH_REGDMA_MODULE, PERIPH_ASSIST_DEBUG_MODULE, /* LP peripherals */ PERIPH_LP_I2C0_MODULE, diff --git a/components/soc/esp32c61/include/soc/periph_defs.h b/components/soc/esp32c61/include/soc/periph_defs.h index 2950d1cb4c..224941bd91 100644 --- a/components/soc/esp32c61/include/soc/periph_defs.h +++ b/components/soc/esp32c61/include/soc/periph_defs.h @@ -32,7 +32,6 @@ typedef enum { PERIPH_SYSTIMER_MODULE, PERIPH_SARADC_MODULE, PERIPH_TEMPSENSOR_MODULE, - PERIPH_REGDMA_MODULE, PERIPH_ASSIST_DEBUG_MODULE, /* Peripherals clock managed by the modem_clock driver must be listed last in the enumeration */ PERIPH_WIFI_MODULE, diff --git a/components/soc/esp32h2/include/soc/periph_defs.h b/components/soc/esp32h2/include/soc/periph_defs.h index 8f53ce666f..ea39288868 100644 --- a/components/soc/esp32h2/include/soc/periph_defs.h +++ b/components/soc/esp32h2/include/soc/periph_defs.h @@ -43,7 +43,6 @@ typedef enum { PERIPH_SYSTIMER_MODULE, PERIPH_SARADC_MODULE, PERIPH_TEMPSENSOR_MODULE, - PERIPH_REGDMA_MODULE, PERIPH_ASSIST_DEBUG_MODULE, /* Peripherals clock managed by the modem_clock driver must be listed last in the enumeration */ PERIPH_BT_MODULE, diff --git a/components/soc/esp32p4/include/soc/periph_defs.h b/components/soc/esp32p4/include/soc/periph_defs.h index c3536df898..cadf54fdf7 100644 --- a/components/soc/esp32p4/include/soc/periph_defs.h +++ b/components/soc/esp32p4/include/soc/periph_defs.h @@ -69,7 +69,6 @@ typedef enum { PERIPH_UHCI_MODULE, PERIPH_PCNT_MODULE, PERIPH_ASSIST_DEBUG_MODULE, - PERIPH_REGDMA_MODULE, /* LP peripherals */ PERIPH_LP_I2C0_MODULE, PERIPH_LP_UART0_MODULE, From a8bcf67cb5507fed2b2db10716a59dd3edde0838 Mon Sep 17 00:00:00 2001 From: wuzhenghui Date: Thu, 29 Feb 2024 14:43:38 +0800 Subject: [PATCH 8/8] ci: enable esp_pm pytest for esp32p4 --- components/esp_pm/test_apps/.build-test-rules.yml | 8 ++++---- components/esp_pm/test_apps/esp_pm/main/test_pm.c | 6 +++++- components/esp_pm/test_apps/esp_pm/pytest_esp_pm.py | 2 -- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/components/esp_pm/test_apps/.build-test-rules.yml b/components/esp_pm/test_apps/.build-test-rules.yml index fdac75267f..4413898e4d 100644 --- a/components/esp_pm/test_apps/.build-test-rules.yml +++ b/components/esp_pm/test_apps/.build-test-rules.yml @@ -1,7 +1,7 @@ # Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps components/esp_pm/test_apps: - disable_test: - - if: IDF_TARGET == "esp32p4" - temporary: true - reason: test not pass, should be re-enable # TODO: IDF-8976 + enable: + - if: INCLUDE_DEFAULT == 1 + depends_components: + - esp_pm diff --git a/components/esp_pm/test_apps/esp_pm/main/test_pm.c b/components/esp_pm/test_apps/esp_pm/main/test_pm.c index 48f89ffb4f..d65bf44c0f 100644 --- a/components/esp_pm/test_apps/esp_pm/main/test_pm.c +++ b/components/esp_pm/test_apps/esp_pm/main/test_pm.c @@ -69,6 +69,8 @@ static const int test_freqs[] = {32, CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ, 64, 48, 32 #elif CONFIG_IDF_TARGET_ESP32C2 static const int test_freqs[] = {CONFIG_XTAL_FREQ, CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ, 80, CONFIG_XTAL_FREQ, 80, CONFIG_XTAL_FREQ / 2, CONFIG_XTAL_FREQ}; // C2 xtal has 40/26MHz option +#elif CONFIG_IDF_TARGET_ESP32P4 +static const int test_freqs[] = {40, CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ, 90, 40, 90, 10, 90, 20, 40, 360, 90, 180, 90, 40}; #else static const int test_freqs[] = {240, 40, 160, 240, 80, 40, 240, 40, 80, 10, 80, 20, 40}; #endif @@ -154,7 +156,7 @@ TEST_CASE("Automatic light occurs when tasks are suspended", "[pm]") const int us_per_tick = 1 * portTICK_PERIOD_MS * 1000; printf("%d %d\n", ticks_to_delay * us_per_tick, timer_diff_us); - TEST_ASSERT(timer_diff_us < ticks_to_delay * us_per_tick); + TEST_ASSERT(timer_diff_us <= ticks_to_delay * us_per_tick); } light_sleep_disable(); @@ -239,6 +241,7 @@ TEST_CASE("Can wake up from automatic light sleep by GPIO", "[pm][ignore]") #endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2, ESP32S3) #endif //CONFIG_ULP_COPROC_TYPE_FSM +#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32P4) //TODO: IDF-9628 typedef struct { int delay_us; int result; @@ -292,6 +295,7 @@ TEST_CASE("vTaskDelay duration is correct with light sleep enabled", "[pm]") light_sleep_disable(); } +#endif /* This test is similar to the one in test_esp_timer.c, but since we can't use * ref_clock, this test uses RTC clock for timing. Also enables automatic diff --git a/components/esp_pm/test_apps/esp_pm/pytest_esp_pm.py b/components/esp_pm/test_apps/esp_pm/pytest_esp_pm.py index 9d6fb7ad88..466fbef64e 100644 --- a/components/esp_pm/test_apps/esp_pm/pytest_esp_pm.py +++ b/components/esp_pm/test_apps/esp_pm/pytest_esp_pm.py @@ -1,11 +1,9 @@ # SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: Apache-2.0 - import pytest from pytest_embedded import Dut -@pytest.mark.temp_skip_ci(targets=['esp32p4'], reason='esp32p4 support TBD') # TODO: IDF-8976 @pytest.mark.generic @pytest.mark.supported_targets @pytest.mark.parametrize('config', [