diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild index 38f5aa2ec9..761f187033 100644 --- a/components/bootloader/Kconfig.projbuild +++ b/components/bootloader/Kconfig.projbuild @@ -94,6 +94,7 @@ menu "Bootloader config" choice BOOTLOADER_VDDSDIO_BOOST bool "VDDSDIO LDO voltage" default BOOTLOADER_VDDSDIO_BOOST_1_9V + depends on SOC_CONFIGURABLE_VDDSDIO_SUPPORTED help If this option is enabled, and VDDSDIO LDO is set to 1.8V (using eFuse or MTDI bootstrapping pin), bootloader will change LDO settings to diff --git a/components/bootloader/subproject/main/ld/esp32c6/bootloader.ld b/components/bootloader/subproject/main/ld/esp32c6/bootloader.ld index 5702fd715c..ba4a1b2af9 100644 --- a/components/bootloader/subproject/main/ld/esp32c6/bootloader.ld +++ b/components/bootloader/subproject/main/ld/esp32c6/bootloader.ld @@ -27,7 +27,7 @@ bootloader_usable_dram_end = 0x4087c610; bootloader_stack_overhead = 0x2000; /* For safety margin between bootloader data section and startup stacks */ bootloader_dram_seg_len = 0x5000; bootloader_iram_loader_seg_len = 0x7000; -bootloader_iram_seg_len = 0x2000; +bootloader_iram_seg_len = 0x2100; /* Start of the lower region is determined by region size and the end of the higher region */ bootloader_dram_seg_end = bootloader_usable_dram_end - bootloader_stack_overhead; diff --git a/components/bootloader_support/src/bootloader_clock_init.c b/components/bootloader_support/src/bootloader_clock_init.c index c5f276304d..075f2c9f0b 100644 --- a/components/bootloader_support/src/bootloader_clock_init.c +++ b/components/bootloader_support/src/bootloader_clock_init.c @@ -95,8 +95,8 @@ __attribute__((weak)) void bootloader_clock_configure(void) CLEAR_PERI_REG_MASK(LP_TIMER_LP_INT_ENA_REG, LP_TIMER_MAIN_TIMER_LP_INT_ENA); /* MAIN_TIMER */ CLEAR_PERI_REG_MASK(LP_ANALOG_PERI_LP_ANA_LP_INT_ENA_REG, LP_ANALOG_PERI_LP_ANA_BOD_MODE0_LP_INT_ENA); /* BROWN_OUT */ CLEAR_PERI_REG_MASK(LP_WDT_INT_ENA_REG, LP_WDT_LP_WDT_INT_ENA); /* WDT */ - // CLEAR_PERI_REG_MASK(PMU_HP_INT_ENA_REG, PMU_SOC_WAKEUP_INT_ENA); // TODO: IDF-5348 /* SLP_REJECT */ - // CLEAR_PERI_REG_MASK(PMU_SOC_SLEEP_REJECT_INT_ENA, PMU_SOC_SLEEP_REJECT_INT_ENA); /* SLP_WAKEUP */ + CLEAR_PERI_REG_MASK(PMU_HP_INT_ENA_REG, PMU_SOC_WAKEUP_INT_ENA); /* SLP_REJECT */ + CLEAR_PERI_REG_MASK(PMU_HP_INT_ENA_REG, PMU_SOC_SLEEP_REJECT_INT_ENA); /* SLP_WAKEUP */ // SET CLR SET_PERI_REG_MASK(LP_WDT_INT_CLR_REG, LP_WDT_SUPER_WDT_INT_CLR); /* SWD */ SET_PERI_REG_MASK(LP_TIMER_LP_INT_CLR_REG, LP_TIMER_MAIN_TIMER_LP_INT_CLR); /* MAIN_TIMER */ @@ -108,13 +108,13 @@ __attribute__((weak)) void bootloader_clock_configure(void) CLEAR_PERI_REG_MASK(LP_ANALOG_PERI_LP_ANA_LP_INT_ENA_REG, LP_ANALOG_PERI_LP_ANA_BOD_MODE0_LP_INT_ENA); /* BROWN_OUT */ CLEAR_PERI_REG_MASK(LP_WDT_INT_ENA_REG, LP_WDT_LP_WDT_INT_ENA); /* WDT */ CLEAR_PERI_REG_MASK(PMU_HP_INT_ENA_REG, PMU_SOC_WAKEUP_INT_ENA); /* SLP_REJECT */ - CLEAR_PERI_REG_MASK(PMU_SOC_SLEEP_REJECT_INT_ENA, PMU_SOC_SLEEP_REJECT_INT_ENA); /* SLP_WAKEUP */ + CLEAR_PERI_REG_MASK(PMU_HP_INT_ENA_REG, PMU_SOC_SLEEP_REJECT_INT_ENA); /* SLP_WAKEUP */ // SET CLR SET_PERI_REG_MASK(LP_WDT_INT_CLR_REG, LP_WDT_SUPER_WDT_INT_CLR); /* SWD */ SET_PERI_REG_MASK(LP_ANALOG_PERI_LP_ANA_LP_INT_CLR_REG, LP_ANALOG_PERI_LP_ANA_BOD_MODE0_LP_INT_CLR); /* BROWN_OUT */ SET_PERI_REG_MASK(LP_WDT_INT_CLR_REG, LP_WDT_LP_WDT_INT_CLR); /* WDT */ - // SET_PERI_REG_MASK(PMU_HP_INT_CLR_REG, PMU_SOC_WAKEUP_INT_CLR); // TODO: IDF-5348 /* SLP_REJECT */ - // SET_PERI_REG_MASK(PMU_SOC_SLEEP_REJECT_INT_CLR, PMU_SOC_SLEEP_REJECT_INT_CLR); /* SLP_WAKEUP */ + SET_PERI_REG_MASK(PMU_HP_INT_CLR_REG, PMU_SOC_WAKEUP_INT_CLR); /* SLP_REJECT */ + SET_PERI_REG_MASK(PMU_SOC_SLEEP_REJECT_INT_CLR, PMU_SOC_SLEEP_REJECT_INT_CLR); /* SLP_WAKEUP */ #else REG_WRITE(RTC_CNTL_INT_ENA_REG, 0); REG_WRITE(RTC_CNTL_INT_CLR_REG, UINT32_MAX); diff --git a/components/bootloader_support/src/esp32c6/bootloader_esp32c6.c b/components/bootloader_support/src/esp32c6/bootloader_esp32c6.c index eee533e640..105438bae6 100644 --- a/components/bootloader_support/src/esp32c6/bootloader_esp32c6.c +++ b/components/bootloader_support/src/esp32c6/bootloader_esp32c6.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -237,8 +237,8 @@ static inline void bootloader_hardware_init(void) esp_rom_spiflash_fix_dummylen(1, 1); #endif - // TODO: IDF-5990 need update, enable i2c mst clk by force on temporarily - SET_PERI_REG_MASK(MODEM_LPCON_CLK_CONF_FORCE_ON_REG, MODEM_LPCON_CLK_I2C_MST_FO); + /* Enable analog i2c master clock */ + SET_PERI_REG_MASK(MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN); SET_PERI_REG_MASK(MODEM_LPCON_I2C_MST_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_SEL_160M); } diff --git a/components/driver/test_apps/gpio/main/test_gpio.c b/components/driver/test_apps/gpio/main/test_gpio.c index 48ecd99a78..ede7e2e527 100644 --- a/components/driver/test_apps/gpio/main/test_gpio.c +++ b/components/driver/test_apps/gpio/main/test_gpio.c @@ -844,7 +844,7 @@ TEST_CASE("GPIO_USB_DP_pin_pullup_disable_test", "[gpio]") } #endif //SOC_USB_SERIAL_JTAG_SUPPORTED -#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32C6, ESP32H2) // TODO: IDF-5348, IDF-6267 Remove when light sleep is supported +#if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32H2) // TODO: IDF-6267 Remove when light sleep is supported // Ignored in CI because it needs manually connect TEST_GPIO_INPUT_LEVEL_LOW_PIN to 3.3v to wake up from light sleep TEST_CASE("GPIO_light_sleep_wake_up_test", "[gpio][ignore]") { diff --git a/components/driver/twai.c b/components/driver/twai.c index 418f4b24fe..40092377a1 100644 --- a/components/driver/twai.c +++ b/components/driver/twai.c @@ -470,7 +470,7 @@ esp_err_t twai_driver_install(const twai_general_config_t *g_config, const twai_ p_twai_obj_dummy->module = twai_controller_periph_signals.controllers[controller_id].module; -#ifdef CONFIG_PM_ENABLE +#if CONFIG_PM_ENABLE && SOC_TWAI_CLK_SUPPORT_APB if (clk_src == TWAI_CLK_SRC_APB) { // TODO: pm_lock name should also reflect the controller ID ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "twai", &(p_twai_obj_dummy->pm_lock)); @@ -478,7 +478,7 @@ esp_err_t twai_driver_install(const twai_general_config_t *g_config, const twai_ goto err; } } -#endif //CONFIG_PM_ENABLE +#endif //CONFIG_PM_ENABLE && SOC_TWAI_CLK_SUPPORT_APB //Initialize TWAI peripheral registers, and allocate interrupt TWAI_ENTER_CRITICAL(); diff --git a/components/esp_hw_support/CMakeLists.txt b/components/esp_hw_support/CMakeLists.txt index 315cd7732d..fb5e8056fc 100644 --- a/components/esp_hw_support/CMakeLists.txt +++ b/components/esp_hw_support/CMakeLists.txt @@ -30,8 +30,8 @@ if(NOT BOOTLOADER_BUILD) "port/${target}/clk_tree.c" "port/clk_tree_common.c") - if(NOT CONFIG_IDF_TARGET_ESP32 AND NOT CONFIG_IDF_TARGET_ESP32S2) - list(APPEND srcs "sleep_retention.c") + if(CONFIG_SOC_PM_SUPPORT_CPU_PD) + list(APPEND srcs "sleep_cpu.c") endif() # [refactor-todo]: requires "driver" for GPIO and RTC (by sleep_gpio and sleep_modes) @@ -73,6 +73,14 @@ if(NOT BOOTLOADER_BUILD) list(APPEND srcs "esp_ds.c") endif() + if(CONFIG_SOC_PM_CPU_RETENTION_BY_SW) + list(APPEND srcs "sleep_cpu_asm.S") + set_property(TARGET ${COMPONENT_LIB} + APPEND PROPERTY INTERFACE_LINK_LIBRARIES "-u rv_core_critical_regs_save") + set_property(TARGET ${COMPONENT_LIB} + APPEND PROPERTY INTERFACE_LINK_LIBRARIES "-u rv_core_critical_regs_restore") + endif() + if(CONFIG_SOC_MODEM_CLOCK_IS_INDEPENDENT) list(APPEND srcs "modem_clock.c") endif() diff --git a/components/esp_hw_support/Kconfig b/components/esp_hw_support/Kconfig index 19bcccb506..93224e6e97 100644 --- a/components/esp_hw_support/Kconfig +++ b/components/esp_hw_support/Kconfig @@ -67,7 +67,7 @@ menu "Hardware Settings" config ESP_SLEEP_GPIO_RESET_WORKAROUND bool "light sleep GPIO reset workaround" - default y if IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 # TODO: IDF-5641 (esp32c6) + default y if IDF_TARGET_ESP32C2 || IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C6 select PM_SLP_DISABLE_GPIO if FREERTOS_USE_TICKLESS_IDLE help esp32c2, esp32c3 and esp32s3 will reset at wake-up if GPIO is received a small electrostatic diff --git a/components/esp_hw_support/include/esp_private/esp_pmu.h b/components/esp_hw_support/include/esp_private/esp_pmu.h new file mode 100644 index 0000000000..7179e9cc33 --- /dev/null +++ b/components/esp_hw_support/include/esp_private/esp_pmu.h @@ -0,0 +1,220 @@ +/* + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include +#include + +#include "soc/soc_caps.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if SOC_PMU_SUPPORTED +#include "hal/pmu_hal.h" +#include "pmu_param.h" + +#define RTC_SLEEP_PD_DIG PMU_SLEEP_PD_TOP //!< Deep sleep (power down digital domain) +#define RTC_SLEEP_PD_RTC_PERIPH PMU_SLEEP_PD_LP_PERIPH //!< Power down RTC peripherals +// #define RTC_SLEEP_PD_RTC_SLOW_MEM BIT(2) //!< Power down RTC SLOW memory +// #define RTC_SLEEP_PD_RTC_FAST_MEM BIT(3) //!< Power down RTC FAST memory +// #define RTC_SLEEP_PD_RTC_MEM_FOLLOW_CPU BIT(4) //!< RTC FAST and SLOW memories are automatically powered up and down along with the CPU +#define RTC_SLEEP_PD_VDDSDIO PMU_SLEEP_PD_VDDSDIO //!< Power down VDDSDIO regulator +#define RTC_SLEEP_PD_CPU PMU_SLEEP_PD_CPU //!< Power down CPU when in lightsleep, but not restart +#define RTC_SLEEP_PD_DIG_PERIPH PMU_SLEEP_PD_HP_PERIPH //!< Power down DIG peripherals +#define RTC_SLEEP_PD_INT_8M PMU_SLEEP_PD_RC_FAST //!< Power down Internal 20M oscillator +#define RTC_SLEEP_PD_XTAL PMU_SLEEP_PD_XTAL //!< Power down main XTAL + +//These flags are not power domains, but will affect some sleep parameters +#define RTC_SLEEP_DIG_USE_8M BIT(16) +#define RTC_SLEEP_USE_ADC_TESEN_MONITOR BIT(17) +#define RTC_SLEEP_NO_ULTRA_LOW BIT(18) //!< Avoid using ultra low power in deep sleep, in which RTCIO cannot be used as input, and RTCMEM can't work under high temperature + +#define RTC_GPIO_TRIG_EN PMU_GPIO_WAKEUP_EN //!< GPIO wakeup +#define RTC_TIMER_TRIG_EN PMU_LP_TIMER_WAKEUP_EN //!< Timer wakeup +#define RTC_WIFI_TRIG_EN PMU_WIFI_SOC_WAKEUP_EN //!< WIFI wakeup (light sleep only) +#define RTC_UART0_TRIG_EN PMU_UART0_WAKEUP_EN //!< UART0 wakeup (light sleep only) +#define RTC_UART1_TRIG_EN PMU_UART1_WAKEUP_EN //!< UART1 wakeup (light sleep only) +#define RTC_BT_TRIG_EN PMU_BLE_SOC_WAKEUP_EN //!< BT wakeup (light sleep only) +#define RTC_USB_TRIG_EN PMU_USB_WAKEUP_EN +#define RTC_XTAL32K_DEAD_TRIG_EN 0 // TODO +#define RTC_BROWNOUT_DET_TRIG_EN 0 // TODO + +/** + * RTC_SLEEP_REJECT_MASK records sleep reject sources supported by chip + */ +#define RTC_SLEEP_REJECT_MASK (RTC_GPIO_TRIG_EN | \ + RTC_TIMER_TRIG_EN | \ + RTC_WIFI_TRIG_EN | \ + RTC_UART0_TRIG_EN | \ + RTC_UART1_TRIG_EN | \ + RTC_BT_TRIG_EN | \ + RTC_XTAL32K_DEAD_TRIG_EN | \ + RTC_USB_TRIG_EN | \ + RTC_BROWNOUT_DET_TRIG_EN) + + +#define PMU_GPIO_WAKEUP_EN BIT(2) +#define PMU_WIFI_BEACON_WAKEUP_EN BIT(3) +#define PMU_LP_TIMER_WAKEUP_EN BIT(4) +#define PMU_WIFI_SOC_WAKEUP_EN BIT(5) +#define PMU_UART0_WAKEUP_EN BIT(6) +#define PMU_UART1_WAKEUP_EN BIT(7) +#define PMU_SDIO_WAKEUP_EN BIT(8) +#define PMU_BLE_SOC_WAKEUP_EN BIT(10) +#define PMU_USB_WAKEUP_EN BIT(14) + + +#define PMU_SLEEP_PD_TOP BIT(0) +#define PMU_SLEEP_PD_VDDSDIO BIT(1) +#define PMU_SLEEP_PD_MODEM BIT(2) +#define PMU_SLEEP_PD_HP_PERIPH BIT(3) +#define PMU_SLEEP_PD_CPU BIT(4) +#define PMU_SLEEP_PD_AON BIT(5) +#define PMU_SLEEP_PD_MEM_G0 BIT(6) +#define PMU_SLEEP_PD_MEM_G1 BIT(7) +#define PMU_SLEEP_PD_MEM_G2 BIT(8) +#define PMU_SLEEP_PD_MEM_G3 BIT(9) +#define PMU_SLEEP_PD_XTAL BIT(10) +#define PMU_SLEEP_PD_RC_FAST BIT(11) +#define PMU_SLEEP_PD_XTAL32K BIT(12) +#define PMU_SLEEP_PD_RC32K BIT(13) +#define PMU_SLEEP_PD_LP_PERIPH BIT(14) + +typedef struct { + pmu_hal_context_t *hal; + void *mc; +} pmu_context_t; + +pmu_context_t * PMU_instance(void); + +typedef enum pmu_hp_sysclk_src { + PMU_HP_SYSCLK_XTAL = 0, + PMU_HP_SYSCLK_PLL, + PMU_HP_SYSCLK_FOSC +} pmu_hp_sysclk_src_t; + +typedef enum pmu_sleep_protect_mode { + PMU_SLEEP_PROTECT_HP_SLEEP = 0, + PMU_SLEEP_PROTECT_XTAL, + PMU_SLEEP_PROTECT_HP_LP_SLEEP, + PMU_SLEEP_PROTECT_DISABLE +} pmu_sleep_protect_mode_t; + +typedef enum pmu_sleep_regdma_entry { + PMU_SLEEP_REGDMA_ENTRY_0 = 0, + PMU_SLEEP_REGDMA_ENTRY_1, + PMU_SLEEP_REGDMA_ENTRY_2, + PMU_SLEEP_REGDMA_ENTRY_3, + PMU_SLEEP_REGDMA_ENTRY_MAX +} pmu_sleep_regdma_entry_t; + +/** + * @brief PMU ICG modem code of HP system + */ +typedef enum { + PMU_HP_ICG_MODEM_CODE_SLEEP = 0, + PMU_HP_ICG_MODEM_CODE_MODEM = 1, + PMU_HP_ICG_MODEM_CODE_ACTIVE = 2, +} pmu_hp_icg_modem_mode_t; + + +/** + * @brief Enable_regdma_backup. + */ +void pmu_sleep_enable_regdma_backup(void); + +/** + * @brief Disable_regdma_backup. + */ +void pmu_sleep_disable_regdma_backup(void); + +/** + * @brief Calculate the hardware time overhead during sleep to compensate for sleep time + * + * @param pd_flags flags indicates the power domain that will be powered down + * @param slowclk_period re-calibrated slow clock period + * @param fastclk_period re-calibrated fast clock period + * + * @return hardware time overhead in us + */ +uint32_t pmu_sleep_calculate_hw_wait_time(uint32_t pd_flags, uint32_t slowclk_period, uint32_t fastclk_period); + +/** + * @brief Get default sleep configuration + * @param config pmu_sleep_config instance + * @param pd_flags flags indicates the power domain that will be powered down + * @param adjustment total software and hardware time overhead + * @param slowclk_period re-calibrated slow clock period in microseconds, + * Q13.19 fixed point format + * @param fastclk_period re-calibrated fast clock period in microseconds, + * Q13.19 fixed point format + * @param dslp configuration for deep sleep mode + + * @return hardware time overhead in us + */ +const pmu_sleep_config_t* pmu_sleep_config_default(pmu_sleep_config_t *config, uint32_t pd_flags, uint32_t adjustment, uint32_t slowclk_period, uint32_t fastclk_period, bool dslp); + +/** + * @brief Prepare the chip to enter sleep mode + * + * This function configures various power/analog parameters and lp/lp system configuration + * used in sleep state machines + * + * This function does not actually enter sleep mode; this is done using + * pmu_sleep_start function. Software may do some other actions between + * pmu_sleep_init and pmu_sleep_start, such as set wakeup timer and configure + * wakeup sources. + * + * @param config sleep mode configuration + * + * @param dslp is initialize for deep sleep mode + */ +void pmu_sleep_init(const pmu_sleep_config_t *config, bool dslp); + +/** + * @brief Enter deep or light sleep mode + * + * This function enters the sleep mode previously configured using pmu_sleep_init + * function. Before entering sleep, software should configure wake up sources + * appropriately (set up GPIO wakeup registers, timer wakeup registers, + * and so on). + * + * If deep sleep mode was configured using pmu_sleep_init, and sleep is not + * rejected by hardware (based on reject_opt flags), this function never returns. + * When the chip wakes up from deep sleep, CPU is reset and execution starts + * from ROM bootloader. + * + * If light sleep mode was configured using pmu_sleep_init, this function + * returns on wakeup, or if sleep is rejected by hardware. + * + * @param wakeup_opt bit mask wake up reasons to enable (RTC_xxx_TRIG_EN flags + * combined with OR) + * @param reject_opt bit mask of sleep reject reasons, used to + * prevent wakeup source set before the sleep request) + * @param lslp_mem_inf_fpu If non-zero then the low power config is restored + * immediately on wake. Recommended for light sleep, + * has no effect if the system goes into deep sleep. + * + * @return non-zero if sleep was rejected by hardware + */ +uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp); + +/** + * @brief Initialize PMU related power/clock/digital parameters and functions + */ +void pmu_init(void); + + +#endif //#if SOC_PMU_SUPPORTED + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/include/esp_private/sleep_cpu.h b/components/esp_hw_support/include/esp_private/sleep_cpu.h new file mode 100644 index 0000000000..0e05797443 --- /dev/null +++ b/components/esp_hw_support/include/esp_private/sleep_cpu.h @@ -0,0 +1,63 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#include +#include "sdkconfig.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @file sleep_cpu.h + * + * This file contains declarations of cpu retention related functions in light sleep mode. + */ + +#if SOC_PM_SUPPORT_CPU_PD + +/** + * @brief Whether to allow the cpu power domain to be powered off. + * + * In light sleep mode, only when the system can provide enough memory + * for cpu retention, the cpu power domain can be powered off. + */ +bool cpu_domain_pd_allowed(void); + +#endif + +#if SOC_PM_SUPPORT_CPU_PD && SOC_PM_CPU_RETENTION_BY_RTCCNTL + +/** + * @brief Enable cpu retention of some modules. + * + * In light sleep mode, before the system goes to sleep, enable the cpu + * retention of modules such as CPU and I/D-cache tag memory. + */ +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. + */ +void sleep_disable_cpu_retention(void); + +#endif // SOC_PM_SUPPORT_CPU_PD && SOC_PM_CPU_RETENTION_BY_RTCCNTL + + +#if SOC_PM_SUPPORT_CPU_PD && SOC_PM_CPU_RETENTION_BY_SW + +esp_err_t esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uint32_t, uint32_t, bool), + uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp); + +#endif // SOC_PM_SUPPORT_CPU_PD && SOC_PM_CPU_RETENTION_BY_SW + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/include/esp_private/sleep_retention.h b/components/esp_hw_support/include/esp_private/sleep_retention.h deleted file mode 100644 index 001e559c0c..0000000000 --- a/components/esp_hw_support/include/esp_private/sleep_retention.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once -#include -#include "sdkconfig.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @file sleep_retention.h - * - * This file contains declarations of memory retention related functions in light sleeo mode. - */ - -#if SOC_PM_SUPPORT_CPU_PD - -/** - * @brief Whether to allow the cpu power domain to be powered off. - * - * In light sleep mode, only when the system can provide enough memory - * for cpu retention, the cpu power domain can be powered off. - */ -bool cpu_domain_pd_allowed(void); - -#endif - -#if SOC_PM_SUPPORT_CPU_PD || SOC_PM_SUPPORT_TAGMEM_PD - -/** - * @brief Enable memory retention of some modules. - * - * In light sleep mode, before the system goes to sleep, enable the memory - * retention of modules such as CPU and I/D-cache tag memory. - */ -void sleep_enable_memory_retention(void); - -/** - * @brief Disable memory retention of some modules. - * - * In light sleep mode, after the system exits sleep, disable the memory - * retention of moudles such as CPU and I/D-cache tag memory. - */ -void sleep_disable_memory_retention(void); - -#endif // SOC_PM_SUPPORT_CPU_PD || SOC_PM_SUPPORT_TAGMEM_PD - -#ifdef __cplusplus -} -#endif diff --git a/components/esp_hw_support/include/esp_sleep.h b/components/esp_hw_support/include/esp_sleep.h index 17550d8aab..508e50a435 100644 --- a/components/esp_hw_support/include/esp_sleep.h +++ b/components/esp_hw_support/include/esp_sleep.h @@ -48,10 +48,10 @@ typedef enum { #endif ESP_PD_DOMAIN_XTAL, //!< XTAL oscillator #if SOC_PM_SUPPORT_XTAL32K_PD - ESP_PD_DOMAIN_XTAL32K, + ESP_PD_DOMAIN_XTAL32K, //!< External 32 kHz XTAL oscillator #endif #if SOC_PM_SUPPORT_RC32K_PD - ESP_PD_DOMAIN_RC32K, + ESP_PD_DOMAIN_RC32K, //!< Internal 32 kHz RC oscillator #endif #if SOC_PM_SUPPORT_RC_FAST_PD ESP_PD_DOMAIN_RC_FAST, //!< Internal Fast oscillator @@ -59,7 +59,9 @@ typedef enum { #if SOC_PM_SUPPORT_CPU_PD ESP_PD_DOMAIN_CPU, //!< CPU core #endif +#if SOC_PM_SUPPORT_VDDSDIO_PD ESP_PD_DOMAIN_VDDSDIO, //!< VDD_SDIO +#endif ESP_PD_DOMAIN_MAX //!< Number of domains } esp_sleep_pd_domain_t; @@ -484,15 +486,44 @@ void esp_default_wake_deep_sleep(void); void esp_deep_sleep_disable_rom_logging(void); #ifdef SOC_PM_SUPPORT_CPU_PD + +#if SOC_PM_CPU_RETENTION_BY_RTCCNTL /** - * @brief CPU Power down low-level initialize - * - * @param enable enable or disable CPU power down during light sleep + * @brief CPU Power down low-level initialize, enable CPU power down during light sleep * @return * - ESP_OK on success * - ESP_ERR_NO_MEM not enough retention memory */ -esp_err_t esp_sleep_cpu_pd_low_init(bool enable); +esp_err_t esp_sleep_cpu_pd_low_init(void); + +/** + * @brief CPU Power down low-level deinitialize, disable CPU power down during light sleep + * @return + * - ESP_OK on success + * - ESP_ERR_NO_MEM not enough retention memory + */ +esp_err_t esp_sleep_cpu_pd_low_deinit(void); + +#endif + +/** + * @brief CPU Power down initialize + * + * @return + * - ESP_OK on success + * - ESP_ERR_NO_MEM not enough retention memory + */ +esp_err_t esp_sleep_cpu_retention_init(void); + +/** + * @brief CPU Power down de-initialize + * + * @return + * - ESP_OK on success + * + * Release system retention memory. + */ +esp_err_t esp_sleep_cpu_retention_deinit(void); #endif #if SOC_GPIO_SUPPORT_SLP_SWITCH diff --git a/components/esp_hw_support/linker.lf b/components/esp_hw_support/linker.lf index 1c1a0bf464..dde67db6a4 100644 --- a/components/esp_hw_support/linker.lf +++ b/components/esp_hw_support/linker.lf @@ -13,11 +13,14 @@ entries: cpu: esp_cpu_compare_and_set (noflash) esp_memory_utils (noflash) rtc_clk (noflash) - if IDF_TARGET_ESP32C6 = n && IDF_TARGET_ESP32H2 = n: # TODO: IDF-5645 + if SOC_CONFIGURABLE_VDDSDIO_SUPPORTED: rtc_init:rtc_vddsdio_set_config (noflash) + if IDF_TARGET_ESP32C6 = n && IDF_TARGET_ESP32H2 = n: # TODO: IDF-5645 rtc_pm (noflash_text) rtc_sleep (noflash_text) rtc_time (noflash_text) + if SOC_PMU_SUPPORTED = y: + pmu_sleep (noflash) if IDF_TARGET_ESP32 = y || IDF_TARGET_ESP32S2 = y: rtc_wdt (noflash_text) if PERIPH_CTRL_FUNC_IN_IRAM = y: diff --git a/components/esp_hw_support/modem_clock.c b/components/esp_hw_support/modem_clock.c index cd9773ad41..2c66910b9c 100644 --- a/components/esp_hw_support/modem_clock.c +++ b/components/esp_hw_support/modem_clock.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -13,6 +13,7 @@ #include "freertos/FreeRTOS.h" #include "hal/clk_gate_ll.h" #include "esp_private/esp_modem_clock.h" +#include "esp_private/esp_pmu.h" #include "esp_sleep.h" // Please define the frequently called modules in the low bit, @@ -136,30 +137,25 @@ modem_clock_context_t * __attribute__((weak)) IRAM_ATTR MODEM_CLOCK_instance(voi return &modem_clock_context; } - -// TODO: IDF-5351: move to esp_pmu.h after support pmu driver -#define PMU_SLEEP 0 -#define PMU_MODEM 1 -#define PMU_ACTIVE 2 -#define SLEEP_MODE BIT(PMU_SLEEP) -#define MODEM_MODE BIT(PMU_MODEM) -#define ACTIVE_MODE BIT(PMU_ACTIVE) - static void IRAM_ATTR modem_clock_domain_power_state_icg_map_init(modem_clock_context_t *ctx) { + #define ICG_NOGATING_SLEEP (BIT(PMU_HP_ICG_MODEM_CODE_SLEEP)) + #define ICG_NOGATING_MODEM (BIT(PMU_HP_ICG_MODEM_CODE_MODEM)) + #define ICG_NOGATING_ACTIVE (BIT(PMU_HP_ICG_MODEM_CODE_ACTIVE)) + /* the ICG code's bit 0, 1 and 2 indicates the ICG state * of pmu SLEEP, MODEM and ACTIVE mode respectively */ const uint32_t code[MODEM_CLOCK_DOMAIN_MAX] = { - [MODEM_CLOCK_DOMAIN_MODEM_APB] = MODEM_MODE | ACTIVE_MODE, - [MODEM_CLOCK_DOMAIN_MODEM_PERIPH] = ACTIVE_MODE, - [MODEM_CLOCK_DOMAIN_WIFI] = MODEM_MODE | ACTIVE_MODE, - [MODEM_CLOCK_DOMAIN_BT] = MODEM_MODE | ACTIVE_MODE, - [MODEM_CLOCK_DOMAIN_FE] = MODEM_MODE | ACTIVE_MODE, - [MODEM_CLOCK_DOMAIN_IEEE802154] = MODEM_MODE | ACTIVE_MODE, - [MODEM_CLOCK_DOMAIN_LP_APB] = MODEM_MODE | ACTIVE_MODE, - [MODEM_CLOCK_DOMAIN_I2C_MASTER] = MODEM_MODE | ACTIVE_MODE, - [MODEM_CLOCK_DOMAIN_COEX] = MODEM_MODE | ACTIVE_MODE, - [MODEM_CLOCK_DOMAIN_WIFIPWR] = MODEM_MODE | ACTIVE_MODE, + [MODEM_CLOCK_DOMAIN_MODEM_APB] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, + [MODEM_CLOCK_DOMAIN_MODEM_PERIPH] = ICG_NOGATING_ACTIVE, + [MODEM_CLOCK_DOMAIN_WIFI] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, + [MODEM_CLOCK_DOMAIN_BT] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, + [MODEM_CLOCK_DOMAIN_FE] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, + [MODEM_CLOCK_DOMAIN_IEEE802154] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, + [MODEM_CLOCK_DOMAIN_LP_APB] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, + [MODEM_CLOCK_DOMAIN_I2C_MASTER] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, + [MODEM_CLOCK_DOMAIN_COEX] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, + [MODEM_CLOCK_DOMAIN_WIFIPWR] = ICG_NOGATING_ACTIVE | ICG_NOGATING_MODEM, }; for (modem_clock_domain_t domain = MODEM_CLOCK_DOMAIN_MODEM_APB; domain < MODEM_CLOCK_DOMAIN_MAX; domain++) { modem_clock_hal_set_clock_domain_icg_bitmap(ctx->hal, domain, code[domain]); @@ -167,16 +163,8 @@ static void IRAM_ATTR modem_clock_domain_power_state_icg_map_init(modem_clock_co } -#include "soc/pmu_reg.h" void modem_clock_domain_pmu_state_icg_map_init(void) { - // Set modem clock ICG code map, should implement with pmu driver // TODO: IDF-5351 - REG_SET_FIELD(PMU_HP_SLEEP_ICG_MODEM_REG, PMU_HP_SLEEP_DIG_ICG_MODEM_CODE, PMU_SLEEP); - REG_SET_FIELD(PMU_HP_MODEM_ICG_MODEM_REG, PMU_HP_MODEM_DIG_ICG_MODEM_CODE, PMU_MODEM); - REG_SET_FIELD(PMU_HP_ACTIVE_ICG_MODEM_REG, PMU_HP_ACTIVE_DIG_ICG_MODEM_CODE, PMU_ACTIVE); - REG_SET_BIT(PMU_IMM_MODEM_ICG_REG, PMU_UPDATE_DIG_ICG_MODEM_EN); - REG_SET_BIT(PMU_IMM_SLEEP_SYSCLK_REG, PMU_UPDATE_DIG_ICG_SWITCH); - modem_clock_domain_power_state_icg_map_init(MODEM_CLOCK_instance()); } diff --git a/components/esp_hw_support/port/esp32c2/rtc_init.c b/components/esp_hw_support/port/esp32c2/rtc_init.c index 277b2a0acd..abb5370c67 100644 --- a/components/esp_hw_support/port/esp32c2/rtc_init.c +++ b/components/esp_hw_support/port/esp32c2/rtc_init.c @@ -129,16 +129,6 @@ void rtc_init(rtc_config_t cfg) #endif } -rtc_vddsdio_config_t rtc_vddsdio_get_config(void) -{ - rtc_vddsdio_config_t result = {0}; - return result; -} - -void rtc_vddsdio_set_config(rtc_vddsdio_config_t config) -{ -} - static void set_ocode_by_efuse(int ocode_scheme_ver) { assert(ocode_scheme_ver == 1); diff --git a/components/esp_hw_support/port/esp32c3/rtc_init.c b/components/esp_hw_support/port/esp32c3/rtc_init.c index 4692562138..e3f75bb0ff 100644 --- a/components/esp_hw_support/port/esp32c3/rtc_init.c +++ b/components/esp_hw_support/port/esp32c3/rtc_init.c @@ -159,43 +159,6 @@ void rtc_init(rtc_config_t cfg) #endif } -rtc_vddsdio_config_t rtc_vddsdio_get_config(void) -{ - rtc_vddsdio_config_t result; - uint32_t sdio_conf_reg = REG_READ(RTC_CNTL_SDIO_CONF_REG); - result.drefh = (sdio_conf_reg & RTC_CNTL_DREFH_SDIO_M) >> RTC_CNTL_DREFH_SDIO_S; - result.drefm = (sdio_conf_reg & RTC_CNTL_DREFM_SDIO_M) >> RTC_CNTL_DREFM_SDIO_S; - result.drefl = (sdio_conf_reg & RTC_CNTL_DREFL_SDIO_M) >> RTC_CNTL_DREFL_SDIO_S; - if (sdio_conf_reg & RTC_CNTL_SDIO_FORCE) { - // Get configuration from RTC - result.force = 1; - result.enable = (sdio_conf_reg & RTC_CNTL_XPD_SDIO_REG_M) >> RTC_CNTL_XPD_SDIO_REG_S; - result.tieh = (sdio_conf_reg & RTC_CNTL_SDIO_TIEH_M) >> RTC_CNTL_SDIO_TIEH_S; - return result; - } else { - result.force = 0; - } - - // Otherwise, VDD_SDIO is controlled by bootstrapping pin - uint32_t strap_reg = REG_READ(GPIO_STRAP_REG); - result.force = 0; - result.tieh = (strap_reg & BIT(5)) ? RTC_VDDSDIO_TIEH_1_8V : RTC_VDDSDIO_TIEH_3_3V; - result.enable = 1; - return result; -} - -void rtc_vddsdio_set_config(rtc_vddsdio_config_t config) -{ - uint32_t val = 0; - val |= (config.force << RTC_CNTL_SDIO_FORCE_S); - val |= (config.enable << RTC_CNTL_XPD_SDIO_REG_S); - val |= (config.drefh << RTC_CNTL_DREFH_SDIO_S); - val |= (config.drefm << RTC_CNTL_DREFM_SDIO_S); - val |= (config.drefl << RTC_CNTL_DREFL_SDIO_S); - val |= (config.tieh << RTC_CNTL_SDIO_TIEH_S); - val |= RTC_CNTL_SDIO_PD_EN; - REG_WRITE(RTC_CNTL_SDIO_CONF_REG, val); -} static void set_ocode_by_efuse(int calib_version) { diff --git a/components/esp_hw_support/port/esp32c6/CMakeLists.txt b/components/esp_hw_support/port/esp32c6/CMakeLists.txt index fed30227f3..92e9f981b4 100644 --- a/components/esp_hw_support/port/esp32c6/CMakeLists.txt +++ b/components/esp_hw_support/port/esp32c6/CMakeLists.txt @@ -1,10 +1,11 @@ set(srcs "rtc_clk_init.c" "rtc_clk.c" - "rtc_init.c" - # "rtc_pm.c" // TODO: IDF-5645 - # "rtc_sleep.c" // TODO: IDF-5645 + "pmu_param.c" + "pmu_init.c" + "pmu_sleep.c" "rtc_time.c" - "chip_info.c") + "chip_info.c" + ) if(NOT BOOTLOADER_BUILD) list(APPEND srcs "sar_periph_ctrl.c" diff --git a/components/esp_hw_support/port/esp32c6/pmu_init.c b/components/esp_hw_support/port/esp32c6/pmu_init.c new file mode 100644 index 0000000000..b99e6e639d --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/pmu_init.c @@ -0,0 +1,207 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "sdkconfig.h" +#include "esp_attr.h" +#include "soc/soc.h" +#include "soc/pmu_struct.h" +#include "hal/pmu_hal.h" +#include "pmu_param.h" +#include "esp_private/esp_pmu.h" +#include "soc/regi2c_dig_reg.h" +#include "regi2c_ctrl.h" + +static __attribute__((unused)) const char *TAG = "pmu_init"; + +typedef struct { + const pmu_hp_system_power_param_t *power; + const pmu_hp_system_clock_param_t *clock; + const pmu_hp_system_digital_param_t *digital; + const pmu_hp_system_analog_param_t *analog; + const pmu_hp_system_retention_param_t *retent; +} pmu_hp_system_param_t; + +typedef struct { + const pmu_lp_system_power_param_t *power; + const pmu_lp_system_analog_param_t *analog; +} pmu_lp_system_param_t; + +pmu_context_t * __attribute__((weak)) IRAM_ATTR PMU_instance(void) +{ + /* It should be explicitly defined in the internal RAM, because this + * instance will be used in pmu_sleep.c */ + static DRAM_ATTR pmu_hal_context_t pmu_hal = { .dev = &PMU }; + static DRAM_ATTR pmu_sleep_machine_constant_t pmu_mc = PMU_SLEEP_MC_DEFAULT(); + static DRAM_ATTR pmu_context_t pmu_context = { .hal = &pmu_hal, .mc = (void *)&pmu_mc }; + return &pmu_context; +} + +void pmu_hp_system_init(pmu_context_t *ctx, pmu_hp_mode_t mode, pmu_hp_system_param_t *param) +{ + const pmu_hp_system_power_param_t *power = param->power; + const pmu_hp_system_clock_param_t *clock = param->clock; + const pmu_hp_system_digital_param_t *dig = param->digital; + const pmu_hp_system_analog_param_t *anlg = param->analog; + const pmu_hp_system_retention_param_t *ret = param->retent; + + assert(ctx->hal); + /* Default configuration of hp-system power in active, modem and sleep modes */ + pmu_ll_hp_set_dig_power(ctx->hal->dev, mode, power->dig_power.val); + pmu_ll_hp_set_clk_power(ctx->hal->dev, mode, power->clk_power.val); + pmu_ll_hp_set_xtal_xpd (ctx->hal->dev, mode, power->xtal.xpd_xtal); + + /* Default configuration of hp-system clock in active, modem and sleep modes */ + pmu_ll_hp_set_icg_func (ctx->hal->dev, mode, clock->icg_func); + pmu_ll_hp_set_icg_apb (ctx->hal->dev, mode, clock->icg_apb); + pmu_ll_hp_set_icg_modem (ctx->hal->dev, mode, clock->icg_modem.code); + pmu_ll_hp_set_sysclk_nodiv (ctx->hal->dev, mode, clock->sysclk.dig_sysclk_nodiv); + pmu_ll_hp_set_icg_sysclk_enable (ctx->hal->dev, mode, clock->sysclk.icg_sysclk_en); + pmu_ll_hp_set_sysclk_slp_sel (ctx->hal->dev, mode, clock->sysclk.sysclk_slp_sel); + pmu_ll_hp_set_icg_sysclk_slp_sel(ctx->hal->dev, mode, clock->sysclk.icg_slp_sel); + pmu_ll_hp_set_dig_sysclk (ctx->hal->dev, mode, clock->sysclk.dig_sysclk_sel); + + /* Default configuration of hp-system digital sub-system in active, modem + * and sleep modes */ + pmu_ll_hp_set_uart_wakeup_enable(ctx->hal->dev, mode, dig->syscntl.uart_wakeup_en); + pmu_ll_hp_set_hold_all_lp_pad (ctx->hal->dev, mode, dig->syscntl.lp_pad_hold_all); + pmu_ll_hp_set_hold_all_hp_pad (ctx->hal->dev, mode, dig->syscntl.hp_pad_hold_all); + pmu_ll_hp_set_dig_pad_slp_sel (ctx->hal->dev, mode, dig->syscntl.dig_pad_slp_sel); + pmu_ll_hp_set_pause_watchdog (ctx->hal->dev, mode, dig->syscntl.dig_pause_wdt); + pmu_ll_hp_set_cpu_stall (ctx->hal->dev, mode, dig->syscntl.dig_cpu_stall); + + /* Default configuration of hp-system analog sub-system in active, modem and + * sleep modes */ + pmu_ll_hp_set_bias_xpd (ctx->hal->dev, mode, anlg->bias.xpd_bias); + pmu_ll_hp_set_dbg_atten (ctx->hal->dev, mode, anlg->bias.dbg_atten); + pmu_ll_hp_set_current_power_off (ctx->hal->dev, mode, anlg->bias.pd_cur); + pmu_ll_hp_set_bias_sleep_enable (ctx->hal->dev, mode, anlg->bias.bias_sleep); + pmu_ll_hp_set_regulator_sleep_memory_xpd (ctx->hal->dev, mode, anlg->regulator0.slp_mem_xpd); + pmu_ll_hp_set_regulator_sleep_logic_xpd (ctx->hal->dev, mode, anlg->regulator0.slp_logic_xpd); + pmu_ll_hp_set_regulator_xpd (ctx->hal->dev, mode, anlg->regulator0.xpd); + pmu_ll_hp_set_regulator_sleep_memory_dbias(ctx->hal->dev, mode, anlg->regulator0.slp_mem_dbias); + pmu_ll_hp_set_regulator_sleep_logic_dbias (ctx->hal->dev, mode, anlg->regulator0.slp_logic_dbias); + pmu_ll_hp_set_regulator_dbias (ctx->hal->dev, mode, anlg->regulator0.dbias); + pmu_ll_hp_set_regulator_driver_bar (ctx->hal->dev, mode, anlg->regulator1.drv_b); + + /* Default configuration of hp-system retention sub-system in active, modem + * and sleep modes */ + pmu_ll_hp_set_retention_param(ctx->hal->dev, mode, ret->retention.val); + pmu_ll_hp_set_backup_icg_func(ctx->hal->dev, mode, ret->backup_clk); + + /* Some PMU initial parameter configuration */ + pmu_ll_imm_update_dig_icg_modem_code(ctx->hal->dev, true); + pmu_ll_imm_update_dig_icg_switch(ctx->hal->dev, true); + + pmu_ll_hp_set_sleep_protect_mode(ctx->hal->dev, PMU_SLEEP_PROTECT_HP_LP_SLEEP); +} + +void pmu_lp_system_init(pmu_context_t *ctx, pmu_lp_mode_t mode, pmu_lp_system_param_t *param) +{ + const pmu_lp_system_power_param_t *power = param->power; + const pmu_lp_system_analog_param_t *anlg = param->analog; + + assert(ctx->hal); + /* Default configuration of lp-system power in active and sleep modes */ + pmu_ll_lp_set_dig_power(ctx->hal->dev, mode, power->dig_power.val); + pmu_ll_lp_set_clk_power(ctx->hal->dev, mode, power->clk_power.val); + pmu_ll_lp_set_xtal_xpd (ctx->hal->dev, PMU_MODE_LP_SLEEP, power->xtal.xpd_xtal); + + /* Default configuration of lp-system analog sub-system in active and + * sleep modes */ + pmu_ll_lp_set_bias_xpd (ctx->hal->dev, PMU_MODE_LP_SLEEP, anlg->bias.xpd_bias); + pmu_ll_lp_set_dbg_atten (ctx->hal->dev, PMU_MODE_LP_SLEEP, anlg->bias.dbg_atten); + pmu_ll_lp_set_current_power_off (ctx->hal->dev, PMU_MODE_LP_SLEEP, anlg->bias.pd_cur); + pmu_ll_lp_set_bias_sleep_enable (ctx->hal->dev, PMU_MODE_LP_SLEEP, anlg->bias.bias_sleep); + pmu_ll_lp_set_regulator_slp_xpd (ctx->hal->dev, mode, anlg->regulator0.slp_xpd); + pmu_ll_lp_set_regulator_xpd (ctx->hal->dev, mode, anlg->regulator0.xpd); + pmu_ll_lp_set_regulator_sleep_dbias(ctx->hal->dev, mode, anlg->regulator0.slp_dbias); + pmu_ll_lp_set_regulator_dbias (ctx->hal->dev, mode, anlg->regulator0.dbias); + pmu_ll_lp_set_regulator_driver_bar (ctx->hal->dev, mode, anlg->regulator1.drv_b); +} + +static inline void pmu_power_domain_force_default(pmu_context_t *ctx) +{ + assert(ctx); + // for bypass reserved power domain + const pmu_hp_power_domain_t pmu_hp_domains[] = { + PMU_HP_PD_TOP, + PMU_HP_PD_AON, + PMU_HP_PD_CPU, + PMU_HP_PD_WIFI + }; + + for (uint8_t idx = 0; idx < (sizeof(pmu_hp_domains) / sizeof(pmu_hp_power_domain_t)); idx++) { + pmu_ll_hp_set_power_force_reset (ctx->hal->dev, pmu_hp_domains[idx], false); + pmu_ll_hp_set_power_force_isolate (ctx->hal->dev, pmu_hp_domains[idx], false); + pmu_ll_hp_set_power_force_power_up (ctx->hal->dev, pmu_hp_domains[idx], false); + pmu_ll_hp_set_power_force_no_reset (ctx->hal->dev, pmu_hp_domains[idx], false); + pmu_ll_hp_set_power_force_no_isolate(ctx->hal->dev, pmu_hp_domains[idx], false); + pmu_ll_hp_set_power_force_power_down(ctx->hal->dev, pmu_hp_domains[idx], false); + } + /* Isolate all memory banks while sleeping, avoid memory leakage current */ + pmu_ll_hp_set_memory_no_isolate (ctx->hal->dev, 0); + + pmu_ll_lp_set_power_force_reset (ctx->hal->dev, false); + pmu_ll_lp_set_power_force_isolate (ctx->hal->dev, false); + pmu_ll_lp_set_power_force_power_up (ctx->hal->dev, false); + pmu_ll_lp_set_power_force_no_reset (ctx->hal->dev, false); + pmu_ll_lp_set_power_force_no_isolate(ctx->hal->dev, false); + pmu_ll_lp_set_power_force_power_down(ctx->hal->dev, false); +} + +static inline void pmu_hp_system_param_default(pmu_hp_mode_t mode, pmu_hp_system_param_t *param) +{ + param->power = pmu_hp_system_power_param_default(mode); + param->clock = pmu_hp_system_clock_param_default(mode); + param->digital = pmu_hp_system_digital_param_default(mode); + param->analog = pmu_hp_system_analog_param_default(mode); + param->retent = pmu_hp_system_retention_param_default(mode); +} + +static void pmu_hp_system_init_default(pmu_context_t *ctx) +{ + assert(ctx); + pmu_hp_system_param_t param = { 0 }; + for (pmu_hp_mode_t mode = PMU_MODE_HP_ACTIVE; mode < PMU_MODE_HP_MAX; mode++) { + pmu_hp_system_param_default(mode, ¶m); + pmu_hp_system_init(ctx, mode, ¶m); + } +} + +static inline void pmu_lp_system_param_default(pmu_lp_mode_t mode, pmu_lp_system_param_t *param) +{ + param->power = pmu_lp_system_power_param_default(mode); + param->analog = pmu_lp_system_analog_param_default(mode); +} + +static void pmu_lp_system_init_default(pmu_context_t *ctx) +{ + assert(ctx); + pmu_lp_system_param_t param; + for (pmu_lp_mode_t mode = PMU_MODE_LP_ACTIVE; mode < PMU_MODE_LP_MAX; mode++) { + pmu_lp_system_param_default(mode, ¶m); + pmu_lp_system_init(ctx, mode, ¶m); + } +} + +void pmu_init(void) +{ + /* Peripheral reg i2c power up */ + SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_PERIF_I2C_RSTB); + SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C); + REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_RTC_DREG, 1); + REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_DIG_DREG, 1); + REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_RTC_REG, 0); + REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_DIG_REG, 0); + + pmu_hp_system_init_default(PMU_instance()); + pmu_lp_system_init_default(PMU_instance()); + + pmu_power_domain_force_default(PMU_instance()); +} diff --git a/components/esp_hw_support/port/esp32c6/pmu_param.c b/components/esp_hw_support/port/esp32c6/pmu_param.c new file mode 100644 index 0000000000..1121e91109 --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/pmu_param.c @@ -0,0 +1,441 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "sdkconfig.h" +#include "soc/soc.h" +#include "pmu_param.h" +#include "soc/pmu_icg_mapping.h" +#include "esp_private/esp_pmu.h" + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#endif + +#define PMU_HP_ACTIVE_POWER_CONFIG_DEFAULT() { \ + .dig_power = { \ + .vdd_spi_pd_en = 0, \ + .mem_dslp = 0, \ + .mem_pd_en = 0, \ + .wifi_pd_en = 0, \ + .cpu_pd_en = 0, \ + .aon_pd_en = 0, \ + .top_pd_en = 0 \ + }, \ + .clk_power = { \ + .i2c_iso_en = 0, \ + .i2c_retention = 0, \ + .xpd_bb_i2c = 1, \ + .xpd_bbpll_i2c = 1, \ + .xpd_bbpll = 1 \ + }, \ + .xtal = { \ + .xpd_xtal = 1 \ + } \ +} + +#define PMU_HP_MODEM_POWER_CONFIG_DEFAULT() { \ + .dig_power = { \ + .vdd_spi_pd_en = 0, \ + .mem_dslp = 0, \ + .mem_pd_en = 0, \ + .wifi_pd_en = 0, \ + .cpu_pd_en = 1, \ + .aon_pd_en = 0, \ + .top_pd_en = 0 \ + }, \ + .clk_power = { \ + .i2c_iso_en = 0, \ + .i2c_retention = 0, \ + .xpd_bb_i2c = 1, \ + .xpd_bbpll_i2c = 1, \ + .xpd_bbpll = 1 \ + }, \ + .xtal = { \ + .xpd_xtal = 1 \ + } \ +} + +#define PMU_HP_SLEEP_POWER_CONFIG_DEFAULT() { \ + .dig_power = { \ + .vdd_spi_pd_en = 1, \ + .mem_dslp = 0, \ + .mem_pd_en = 0, \ + .wifi_pd_en = 1, \ + .cpu_pd_en = 0, \ + .aon_pd_en = 0, \ + .top_pd_en = 0 \ + }, \ + .clk_power = { \ + .i2c_iso_en = 1, \ + .i2c_retention = 1, \ + .xpd_bb_i2c = 1, \ + .xpd_bbpll_i2c = 0, \ + .xpd_bbpll = 0, \ + }, \ + .xtal = { \ + .xpd_xtal = 0 \ + } \ +} + +const pmu_hp_system_power_param_t * pmu_hp_system_power_param_default(pmu_hp_mode_t mode) +{ + static const pmu_hp_system_power_param_t hp_power[] = { + PMU_HP_ACTIVE_POWER_CONFIG_DEFAULT(), + PMU_HP_MODEM_POWER_CONFIG_DEFAULT(), + PMU_HP_SLEEP_POWER_CONFIG_DEFAULT() + }; + assert(mode < ARRAY_SIZE(hp_power)); + return &hp_power[mode]; +} + +#define PMU_HP_ACTIVE_CLOCK_CONFIG_DEFAULT() { \ + .icg_func = 0xffffffff, \ + .icg_apb = 0xffffffff, \ + .icg_modem = { \ + .code = PMU_HP_ICG_MODEM_CODE_ACTIVE \ + }, \ + .sysclk = { \ + .dig_sysclk_nodiv = 0, \ + .icg_sysclk_en = 1, \ + .sysclk_slp_sel = 0, \ + .icg_slp_sel = 0, \ + .dig_sysclk_sel = PMU_HP_SYSCLK_XTAL \ + } \ +} + +#define PMU_HP_MODEM_CLOCK_CONFIG_DEFAULT() { \ + .icg_func = 0, \ + .icg_apb = 0, \ + .icg_modem = { \ + .code = PMU_HP_ICG_MODEM_CODE_MODEM \ + }, \ + .sysclk = { \ + .dig_sysclk_nodiv = 0, \ + .icg_sysclk_en = 1, \ + .sysclk_slp_sel = 1, \ + .icg_slp_sel = 1, \ + .dig_sysclk_sel = PMU_HP_SYSCLK_PLL \ + } \ +} + +#define PMU_HP_SLEEP_CLOCK_CONFIG_DEFAULT() { \ + .icg_func = 0, \ + .icg_apb = 0, \ + .icg_modem = { \ + .code = PMU_HP_ICG_MODEM_CODE_SLEEP \ + }, \ + .sysclk = { \ + .dig_sysclk_nodiv = 0, \ + .icg_sysclk_en = 0, \ + .sysclk_slp_sel = 1, \ + .icg_slp_sel = 1, \ + .dig_sysclk_sel = PMU_HP_SYSCLK_XTAL \ + } \ +} + +const pmu_hp_system_clock_param_t * pmu_hp_system_clock_param_default(pmu_hp_mode_t mode) +{ + static const pmu_hp_system_clock_param_t hp_clock[] = { + PMU_HP_ACTIVE_CLOCK_CONFIG_DEFAULT(), + PMU_HP_MODEM_CLOCK_CONFIG_DEFAULT(), + PMU_HP_SLEEP_CLOCK_CONFIG_DEFAULT() + }; + assert(mode < ARRAY_SIZE(hp_clock)); + return &hp_clock[mode]; +} + +#define PMU_HP_ACTIVE_DIGITAL_CONFIG_DEFAULT() { \ + .syscntl = { \ + .uart_wakeup_en = 0, \ + .lp_pad_hold_all = 0, \ + .hp_pad_hold_all = 0, \ + .dig_pad_slp_sel = 0, \ + .dig_pause_wdt = 0, \ + .dig_cpu_stall = 0 \ + } \ +} + +#define PMU_HP_MODEM_DIGITAL_CONFIG_DEFAULT() { \ + .syscntl = { \ + .uart_wakeup_en = 1, \ + .lp_pad_hold_all = 0, \ + .hp_pad_hold_all = 0, \ + .dig_pad_slp_sel = 0, \ + .dig_pause_wdt = 1, \ + .dig_cpu_stall = 1 \ + } \ +} + +#define PMU_HP_SLEEP_DIGITAL_CONFIG_DEFAULT() { \ + .syscntl = { \ + .uart_wakeup_en = 1, \ + .lp_pad_hold_all = 0, \ + .hp_pad_hold_all = 0, \ + .dig_pad_slp_sel = 1, \ + .dig_pause_wdt = 1, \ + .dig_cpu_stall = 1 \ + } \ +} + +const pmu_hp_system_digital_param_t * pmu_hp_system_digital_param_default(pmu_hp_mode_t mode) +{ + static const pmu_hp_system_digital_param_t hp_digital[] = { + PMU_HP_ACTIVE_DIGITAL_CONFIG_DEFAULT(), + PMU_HP_MODEM_DIGITAL_CONFIG_DEFAULT(), + PMU_HP_SLEEP_DIGITAL_CONFIG_DEFAULT() + }; + assert(mode < ARRAY_SIZE(hp_digital)); + return &hp_digital[mode]; +} + +#define PMU_HP_ACTIVE_ANALOG_CONFIG_DEFAULT() { \ + .bias = { \ + .xpd_bias = 1, \ + .dbg_atten = 0x0, \ + .pd_cur = 0, \ + .bias_sleep = 0 \ + }, \ + .regulator0 = { \ + .lp_dbias_vol = 0xd, \ + .hp_dbias_vol = 0x1c,\ + .dbias_sel = 1, \ + .dbias_init = 1, \ + .slp_mem_xpd = 0, \ + .slp_logic_xpd = 0, \ + .xpd = 1, \ + .slp_mem_dbias = 0xc, \ + .slp_logic_dbias = 0xc, \ + .dbias = 0x19 \ + }, \ + .regulator1 = { \ + .drv_b = 0x0 \ + } \ +} + +#define PMU_HP_MODEM_ANALOG_CONFIG_DEFAULT() { \ + .bias = { \ + .xpd_bias = 0, \ + .dbg_atten = 0x0, \ + .pd_cur = 0, \ + .bias_sleep = 0 \ + }, \ + .regulator0 = { \ + .slp_mem_xpd = 0, \ + .slp_logic_xpd = 0, \ + .xpd = 1, \ + .slp_mem_dbias = 0xc, \ + .slp_logic_dbias = 0xc, \ + .dbias = 0x1a \ + }, \ + .regulator1 = { \ + .drv_b = 0x0 \ + } \ +} + +#define PMU_HP_SLEEP_ANALOG_CONFIG_DEFAULT() { \ + .bias = { \ + .xpd_bias = 0, \ + .dbg_atten = 0x0, \ + .pd_cur = 0, \ + .bias_sleep = 0 \ + }, \ + .regulator0 = { \ + .slp_mem_xpd = 1, \ + .slp_logic_xpd = 1, \ + .xpd = 0, \ + .slp_mem_dbias = 0x4, \ + .slp_logic_dbias = 0x4, \ + .dbias = 0x1a \ + }, \ + .regulator1 = { \ + .drv_b = 0x0 \ + } \ +} + +const pmu_hp_system_analog_param_t * pmu_hp_system_analog_param_default(pmu_hp_mode_t mode) +{ + static const pmu_hp_system_analog_param_t hp_analog[] = { + PMU_HP_ACTIVE_ANALOG_CONFIG_DEFAULT(), + PMU_HP_MODEM_ANALOG_CONFIG_DEFAULT(), + PMU_HP_SLEEP_ANALOG_CONFIG_DEFAULT() + }; + assert(mode < ARRAY_SIZE(hp_analog)); + return &hp_analog[mode]; +} + +#define PMU_HP_RETENTION_REGDMA_CONFIG(dir, entry) ((((dir)<<2) | (entry & 0x3)) & 0x7) + +#define PMU_HP_ACTIVE_RETENTION_CONFIG_DEFAULT() { \ + .retention = { \ + .hp_sleep2active_backup_modem_clk_code = 2, \ + .hp_modem2active_backup_modem_clk_code = 2, \ + .hp_active_retention_mode = 0, \ + .hp_sleep2active_retention_en = 0, \ + .hp_modem2active_retention_en = 0, \ + .hp_sleep2active_backup_clk_sel = 0, \ + .hp_modem2active_backup_clk_sel = 0, \ + .hp_sleep2active_backup_mode = PMU_HP_RETENTION_REGDMA_CONFIG(0, 0), \ + .hp_modem2active_backup_mode = PMU_HP_RETENTION_REGDMA_CONFIG(0, 2), \ + .hp_sleep2active_backup_en = 0, \ + .hp_modem2active_backup_en = 0, \ + }, \ + .backup_clk = ( \ + BIT(PMU_ICG_FUNC_ENA_REGDMA) | \ + BIT(PMU_ICG_FUNC_ENA_TG0) | \ + BIT(PMU_ICG_FUNC_ENA_TG1) | \ + BIT(PMU_ICG_FUNC_ENA_HPBUS) | \ + BIT(PMU_ICG_FUNC_ENA_MSPI) | \ + BIT(PMU_ICG_FUNC_ENA_IOMUX) | \ + BIT(PMU_ICG_FUNC_ENA_SPI2) | \ + BIT(PMU_ICG_FUNC_ENA_UART0) | \ + BIT(PMU_ICG_FUNC_ENA_SYSTIMER) \ + ) \ +} + +#define PMU_HP_MODEM_RETENTION_CONFIG_DEFAULT() { \ + .retention = { \ + .hp_sleep2modem_backup_modem_clk_code = 1, \ + .hp_modem_retention_mode = 0, \ + .hp_sleep2modem_retention_en = 0, \ + .hp_sleep2modem_backup_clk_sel = 0, \ + .hp_sleep2modem_backup_mode = PMU_HP_RETENTION_REGDMA_CONFIG(0, 1), \ + .hp_sleep2modem_backup_en = 0, \ + }, \ + .backup_clk = ( \ + BIT(PMU_ICG_FUNC_ENA_REGDMA) | \ + BIT(PMU_ICG_FUNC_ENA_TG0) | \ + BIT(PMU_ICG_FUNC_ENA_TG1) | \ + BIT(PMU_ICG_FUNC_ENA_HPBUS) | \ + BIT(PMU_ICG_FUNC_ENA_MSPI) | \ + BIT(PMU_ICG_FUNC_ENA_IOMUX) | \ + BIT(PMU_ICG_FUNC_ENA_SPI2) | \ + BIT(PMU_ICG_FUNC_ENA_UART0) | \ + BIT(PMU_ICG_FUNC_ENA_SYSTIMER) \ + ) \ +} + +#define PMU_HP_SLEEP_RETENTION_CONFIG_DEFAULT() { \ + .retention = { \ + .hp_modem2sleep_backup_modem_clk_code = 0, \ + .hp_active2sleep_backup_modem_clk_code = 2, \ + .hp_sleep_retention_mode = 0, \ + .hp_modem2sleep_retention_en = 0, \ + .hp_active2sleep_retention_en = 0, \ + .hp_modem2sleep_backup_clk_sel = 0, \ + .hp_active2sleep_backup_clk_sel = 0, \ + .hp_modem2sleep_backup_mode = PMU_HP_RETENTION_REGDMA_CONFIG(1, 1), \ + .hp_active2sleep_backup_mode = PMU_HP_RETENTION_REGDMA_CONFIG(1, 0), \ + .hp_modem2sleep_backup_en = 0, \ + .hp_active2sleep_backup_en = 0, \ + }, \ + .backup_clk = ( \ + BIT(PMU_ICG_FUNC_ENA_REGDMA) | \ + BIT(PMU_ICG_FUNC_ENA_TG0) | \ + BIT(PMU_ICG_FUNC_ENA_TG1) | \ + BIT(PMU_ICG_FUNC_ENA_HPBUS) | \ + BIT(PMU_ICG_FUNC_ENA_MSPI) | \ + BIT(PMU_ICG_FUNC_ENA_IOMUX) | \ + BIT(PMU_ICG_FUNC_ENA_SPI2) | \ + BIT(PMU_ICG_FUNC_ENA_UART0) | \ + BIT(PMU_ICG_FUNC_ENA_SYSTIMER) \ + ) \ +} + +const pmu_hp_system_retention_param_t * pmu_hp_system_retention_param_default(pmu_hp_mode_t mode) +{ + static const pmu_hp_system_retention_param_t hp_retention[] = { + PMU_HP_ACTIVE_RETENTION_CONFIG_DEFAULT(), + PMU_HP_MODEM_RETENTION_CONFIG_DEFAULT(), + PMU_HP_SLEEP_RETENTION_CONFIG_DEFAULT() + }; + assert(mode < ARRAY_SIZE(hp_retention)); + return &hp_retention[mode]; +} + + +/** LP system default parameter */ + +#define PMU_LP_ACTIVE_POWER_CONFIG_DEFAULT() { \ + .dig_power = { \ + .mem_dslp = 0, \ + .peri_pd_en = 0, \ + }, \ + .clk_power = { \ + .xpd_xtal32k = 1, \ + .xpd_rc32k = 1, \ + .xpd_fosc = 1, \ + .pd_osc = 0 \ + } \ +} + +#define PMU_LP_SLEEP_POWER_CONFIG_DEFAULT() { \ + .dig_power = { \ + .mem_dslp = 1, \ + .peri_pd_en = 0, \ + }, \ + .clk_power = { \ + .xpd_xtal32k = 0, \ + .xpd_rc32k = 0, \ + .xpd_fosc = 0, \ + .pd_osc = 0 \ + }, \ + .xtal = { \ + .xpd_xtal = 0 \ + } \ +} + +const pmu_lp_system_power_param_t * pmu_lp_system_power_param_default(pmu_lp_mode_t mode) +{ + static const pmu_lp_system_power_param_t lp_power[] = { + PMU_LP_ACTIVE_POWER_CONFIG_DEFAULT(), + PMU_LP_SLEEP_POWER_CONFIG_DEFAULT() + }; + assert(mode < ARRAY_SIZE(lp_power)); + return &lp_power[mode]; +} + +#define PMU_LP_ACTIVE_ANALOG_CONFIG_DEFAULT() { \ + .regulator0 = { \ + .slp_xpd = 0, \ + .xpd = 1, \ + .slp_dbias = 0x0, \ + .dbias = 0x1a \ + }, \ + .regulator1 = { \ + .drv_b = 0x0 \ + } \ +} + +#define PMU_LP_SLEEP_ANALOG_CONFIG_DEFAULT() { \ + .bias = { \ + .xpd_bias = 0, \ + .dbg_atten = 0x0, \ + .pd_cur = 1, \ + .bias_sleep = 1, \ + }, \ + .regulator0 = { \ + .slp_xpd = 1, \ + .xpd = 0, \ + .slp_dbias = 0x0, \ + .dbias = 0x12 \ + }, \ + .regulator1 = { \ + .drv_b = 0x0 \ + } \ +} + +const pmu_lp_system_analog_param_t * pmu_lp_system_analog_param_default(pmu_lp_mode_t mode) +{ + static const pmu_lp_system_analog_param_t lp_analog[] = { + PMU_LP_ACTIVE_ANALOG_CONFIG_DEFAULT(), + PMU_LP_SLEEP_ANALOG_CONFIG_DEFAULT() + }; + assert(mode < ARRAY_SIZE(lp_analog)); + return &lp_analog[mode]; +} diff --git a/components/esp_hw_support/port/esp32c6/pmu_sleep.c b/components/esp_hw_support/port/esp32c6/pmu_sleep.c new file mode 100644 index 0000000000..4e320b7aef --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/pmu_sleep.c @@ -0,0 +1,256 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include "sdkconfig.h" +#include "esp_err.h" +#include "esp_attr.h" +#include "soc/soc.h" +#include "soc/rtc.h" +#include "soc/pmu_struct.h" +#include "esp_private/esp_pmu.h" + +#define HP(state) (PMU_MODE_HP_ ## state) +#define LP(state) (PMU_MODE_LP_ ## state) + +void pmu_sleep_enable_regdma_backup(void) +{ + assert(PMU_instance()->hal); + /* entry 0, 1, 2 is used by pmu HP_SLEEP and HP_ACTIVE, HP_SLEEP + * and HP_MODEM or HP_MODEM and HP_ACTIVE states switching, + * respectively. entry 3 is reserved, not used yet! */ + pmu_hal_hp_set_sleep_active_backup_enable(PMU_instance()->hal); + pmu_hal_hp_set_sleep_modem_backup_enable(PMU_instance()->hal); + pmu_hal_hp_set_modem_active_backup_enable(PMU_instance()->hal); +} + +void pmu_sleep_disable_regdma_backup(void) +{ + assert(PMU_instance()->hal); + pmu_hal_hp_set_sleep_active_backup_disable(PMU_instance()->hal); + pmu_hal_hp_set_sleep_modem_backup_disable(PMU_instance()->hal); + pmu_hal_hp_set_modem_active_backup_disable(PMU_instance()->hal); +} + +uint32_t pmu_sleep_calculate_hw_wait_time(uint32_t pd_flags, uint32_t slowclk_period, uint32_t fastclk_period) +{ + const pmu_sleep_machine_constant_t *mc = (pmu_sleep_machine_constant_t *)PMU_instance()->mc; + + /* LP core hardware wait time, microsecond */ + const int lp_wakeup_wait_time = rtc_time_slowclk_to_us(mc->lp.wakeup_wait_cycle, slowclk_period); + const int lp_clk_switch_time = rtc_time_slowclk_to_us(mc->lp.clk_switch_cycle, slowclk_period); + const int lp_clk_power_on_wait_time = (pd_flags & PMU_SLEEP_PD_XTAL) ? mc->lp.xtal_wait_stable_time_ms \ + : rtc_time_slowclk_to_us(mc->lp.clk_power_on_wait_cycle, slowclk_period); + + const int lp_hw_wait_time = mc->lp.min_slp_time_ms + mc->lp.analog_wait_time_ms + lp_clk_power_on_wait_time \ + + lp_wakeup_wait_time + lp_clk_switch_time + mc->lp.power_supply_wait_time_ms \ + + mc->lp.power_up_wait_time_ms; + + /* HP core hardware wait time, microsecond */ + const int hp_digital_power_up_wait_time_ms = mc->hp.power_supply_wait_time_ms + mc->hp.power_up_wait_time_ms; + const int hp_regdma_wait_time = MAX(mc->hp.regdma_s2m_work_time_ms + mc->hp.regdma_m2a_work_time_ms, mc->hp.regdma_s2a_work_time_ms); + const int hp_clock_wait_time = mc->hp.xtal_wait_stable_time_ms + mc->hp.pll_wait_stable_time_ms; + + const int hp_hw_wait_time = mc->hp.analog_wait_time_ms + MAX(hp_digital_power_up_wait_time_ms + hp_regdma_wait_time, hp_clock_wait_time); + + /* When the SOC wakeup (lp timer or GPIO wakeup) and Modem wakeup (Beacon wakeup) complete, the soc + * wakeup will be delayed until the RF is turned on in Modem state. + * + * modem wakeup TBTT, RF on by HW + * | | + * \|/ \|/ + * PMU_HP_ACTIVE /------ + * PMU_HP_MODEM /------------////////////////// + * PMU_HP_SLEEP ----------------------////////////////// + * /|\ /|\ /|\ /|\ /|\ /|\ + * |<- some hw wait ->| | | |<- M2A switch ->| + * | slow cycles & | soc wakeup | | + * | FOSC cycles |<- S2M switch ->| | + * | | + * |<-- PMU guard time, also the maximum time for the SOC -->| + * | wake-up delay | + */ +#if SOC_PM_SUPPORT_PMU_MODEM_STATE && CONFIG_ESP_WIFI_AUTO_BEACON_ENABLE + const int rf_on_protect_time = mc->hp.regdma_rf_on_work_time_ms; + const int total_hw_wait_time = lp_hw_wait_time + hp_hw_wait_time + mc->hp.clock_domain_sync_time_ms; +#else + const int rf_on_protect_time = 0; + const int total_hw_wait_time = lp_hw_wait_time + hp_hw_wait_time; +#endif + return total_hw_wait_time + rf_on_protect_time; +} + +#define rtc_time_us_to_fastclk(time_us, period) rtc_time_us_to_slowclk((time_us), (period)) + +static inline pmu_sleep_param_config_t * pmu_sleep_param_config_default( + pmu_sleep_param_config_t *param, + pmu_sleep_power_config_t *power, /* We'll use the runtime power parameter to determine some hardware parameters */ + const uint32_t pd_flags, + const uint32_t adjustment, + const uint32_t slowclk_period, + const uint32_t fastclk_period + ) +{ + const pmu_sleep_machine_constant_t *mc = (pmu_sleep_machine_constant_t *)PMU_instance()->mc; + + param->hp_sys.min_slp_slow_clk_cycle = rtc_time_us_to_slowclk(mc->hp.min_slp_time_ms, slowclk_period); + param->hp_sys.analog_wait_target_cycle = rtc_time_us_to_fastclk(mc->hp.analog_wait_time_ms, fastclk_period); + param->hp_sys.digital_power_supply_wait_cycle = rtc_time_us_to_fastclk(mc->hp.power_supply_wait_time_ms, fastclk_period); + param->hp_sys.digital_power_up_wait_cycle = rtc_time_us_to_fastclk(mc->hp.power_up_wait_time_ms, fastclk_period); + param->hp_sys.pll_stable_wait_cycle = rtc_time_us_to_fastclk(mc->hp.pll_wait_stable_time_ms, fastclk_period); + + const int hw_wait_time = pmu_sleep_calculate_hw_wait_time(pd_flags, slowclk_period, fastclk_period); + const int modem_state_skip_time = mc->hp.regdma_m2a_work_time_ms + mc->hp.system_dfs_up_work_time_ms + mc->lp.min_slp_time_ms; + const int modem_wakeup_wait_time = adjustment - hw_wait_time + modem_state_skip_time + mc->hp.regdma_rf_on_work_time_ms; + param->hp_sys.modem_wakeup_wait_cycle = rtc_time_us_to_fastclk(modem_wakeup_wait_time, fastclk_period); + + param->lp_sys.min_slp_slow_clk_cycle = rtc_time_us_to_slowclk(mc->lp.min_slp_time_ms, slowclk_period); + param->lp_sys.analog_wait_target_cycle = rtc_time_us_to_slowclk(mc->lp.analog_wait_time_ms, slowclk_period); + param->lp_sys.digital_power_supply_wait_cycle = rtc_time_us_to_fastclk(mc->lp.power_supply_wait_time_ms, fastclk_period); + param->lp_sys.digital_power_up_wait_cycle = rtc_time_us_to_fastclk(mc->lp.power_up_wait_time_ms, fastclk_period); + + if (power->hp_sys.xtal.xpd_xtal) { + param->hp_lp.xtal_stable_wait_cycle = rtc_time_us_to_fastclk(mc->hp.xtal_wait_stable_time_ms, fastclk_period); + } else { + param->hp_lp.xtal_stable_wait_slow_clk_cycle = rtc_time_us_to_slowclk(mc->lp.xtal_wait_stable_time_ms, slowclk_period); + } + return param; +} + +const pmu_sleep_config_t* pmu_sleep_config_default( + pmu_sleep_config_t *config, + uint32_t pd_flags, + uint32_t adjustment, + uint32_t slowclk_period, + uint32_t fastclk_period, + bool dslp + ) +{ + pmu_sleep_power_config_t power_default = PMU_SLEEP_POWER_CONFIG_DEFAULT(pd_flags); + + uint32_t iram_pd_flags = 0; + iram_pd_flags |= (pd_flags & PMU_SLEEP_PD_MEM_G0) ? BIT(0) : 0; + iram_pd_flags |= (pd_flags & PMU_SLEEP_PD_MEM_G1) ? BIT(1) : 0; + iram_pd_flags |= (pd_flags & PMU_SLEEP_PD_MEM_G2) ? BIT(2) : 0; + iram_pd_flags |= (pd_flags & PMU_SLEEP_PD_MEM_G3) ? BIT(3) : 0; + config->power = power_default; + + pmu_sleep_param_config_t param_default = PMU_SLEEP_PARAM_CONFIG_DEFAULT(pd_flags); + config->param = *pmu_sleep_param_config_default(¶m_default, &power_default, pd_flags, adjustment, slowclk_period, fastclk_period); + + if (dslp) { + pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(pd_flags); + config->analog = analog_default; + } else { + pmu_sleep_analog_config_t analog_default = PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags); + if (!(pd_flags & PMU_SLEEP_PD_MODEM)){ + analog_default.hp_sys.analog.slp_logic_dbias += 2; + } + if (!(pd_flags & PMU_SLEEP_PD_TOP)){ + analog_default.hp_sys.analog.slp_logic_dbias += 2; + } + config->analog = analog_default; + } + return config; +} + +static void pmu_sleep_power_init(pmu_context_t *ctx, const pmu_sleep_power_config_t *power, bool dslp) +{ + pmu_ll_hp_set_dig_power(ctx->hal->dev, HP(SLEEP), power->hp_sys.dig_power.val); + pmu_ll_hp_set_clk_power(ctx->hal->dev, HP(SLEEP), power->hp_sys.clk_power.val); + pmu_ll_hp_set_xtal_xpd (ctx->hal->dev, HP(SLEEP), power->hp_sys.xtal.xpd_xtal); + + pmu_ll_lp_set_dig_power(ctx->hal->dev, LP(ACTIVE), power->lp_sys[LP(ACTIVE)].dig_power.val); + pmu_ll_lp_set_clk_power(ctx->hal->dev, LP(ACTIVE), power->lp_sys[LP(ACTIVE)].clk_power.val); + + pmu_ll_lp_set_dig_power(ctx->hal->dev, LP(SLEEP), power->lp_sys[LP(SLEEP)].dig_power.val); + pmu_ll_lp_set_clk_power(ctx->hal->dev, LP(SLEEP), power->lp_sys[LP(SLEEP)].clk_power.val); + pmu_ll_lp_set_xtal_xpd (ctx->hal->dev, LP(SLEEP), power->lp_sys[LP(SLEEP)].xtal.xpd_xtal); + + if (dslp) { + // TODO: IDF-5349 + } else { + } +} + +static void pmu_sleep_analog_init(pmu_context_t *ctx, const pmu_sleep_analog_config_t *analog, bool dslp) +{ + assert(ctx->hal); + pmu_ll_hp_set_current_power_off (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.pd_cur); + pmu_ll_hp_set_bias_sleep_enable (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.bias_sleep); + pmu_ll_hp_set_regulator_sleep_memory_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.slp_mem_xpd); + pmu_ll_hp_set_regulator_sleep_logic_xpd (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.slp_logic_xpd); + 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_regulator_dbias (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.dbias); + pmu_ll_hp_set_regulator_driver_bar (ctx->hal->dev, HP(SLEEP), analog->hp_sys.analog.drv_b); + + pmu_ll_lp_set_regulator_sleep_dbias(ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.slp_dbias); + pmu_ll_lp_set_regulator_dbias (ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.dbias); + pmu_ll_lp_set_regulator_driver_bar (ctx->hal->dev, LP(ACTIVE), analog->lp_sys[LP(ACTIVE)].analog.drv_b); + + 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_sleep_dbias(ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.slp_dbias); + pmu_ll_lp_set_regulator_dbias (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.dbias); + pmu_ll_lp_set_regulator_driver_bar (ctx->hal->dev, LP(SLEEP), analog->lp_sys[LP(SLEEP)].analog.drv_b); + + if (dslp) { + // TODO: IDF-5349 + } else { + } +} + +static void pmu_sleep_param_init(pmu_context_t *ctx, const pmu_sleep_param_config_t *param, bool dslp) +{ + assert(ctx->hal); + pmu_ll_hp_set_min_sleep_cycle(ctx->hal->dev, param->hp_sys.min_slp_slow_clk_cycle); + pmu_ll_lp_set_min_sleep_cycle(ctx->hal->dev, param->lp_sys.min_slp_slow_clk_cycle); + + pmu_ll_hp_set_analog_wait_target_cycle(ctx->hal->dev, param->hp_sys.analog_wait_target_cycle); + pmu_ll_lp_set_analog_wait_target_cycle(ctx->hal->dev, param->lp_sys.analog_wait_target_cycle); + + pmu_hal_hp_set_digital_power_up_wait_cycle(ctx->hal, param->hp_sys.digital_power_supply_wait_cycle, param->hp_sys.digital_power_up_wait_cycle); + pmu_hal_lp_set_digital_power_up_wait_cycle(ctx->hal, param->lp_sys.digital_power_supply_wait_cycle, param->lp_sys.digital_power_up_wait_cycle); + + pmu_ll_set_modem_wait_target_cycle(ctx->hal->dev, param->hp_sys.modem_wakeup_wait_cycle); + pmu_ll_set_xtal_stable_wait_cycle(ctx->hal->dev, param->hp_lp.xtal_stable_wait_slow_clk_cycle); + pmu_ll_set_pll_stable_wait_cycle(ctx->hal->dev, param->hp_sys.pll_stable_wait_cycle); +} + +void pmu_sleep_init(const pmu_sleep_config_t *config, bool dslp) +{ + assert(PMU_instance()); + pmu_sleep_power_init(PMU_instance(), &config->power, dslp); + pmu_sleep_analog_init(PMU_instance(), &config->analog, dslp); + pmu_sleep_param_init(PMU_instance(), &config->param, dslp); +} + +uint32_t pmu_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp) +{ + assert(PMU_instance()->hal); + pmu_ll_hp_set_wakeup_enable(PMU_instance()->hal->dev, wakeup_opt); + pmu_ll_hp_set_reject_enable(PMU_instance()->hal->dev, reject_opt); + + pmu_ll_hp_clear_wakeup_intr_status(PMU_instance()->hal->dev); + pmu_ll_hp_clear_reject_intr_status(PMU_instance()->hal->dev); + pmu_ll_hp_clear_reject_cause(PMU_instance()->hal->dev); + + /* Start entry into sleep mode */ + pmu_ll_hp_set_sleep_enable(PMU_instance()->hal->dev); + + while (!pmu_ll_hp_is_sleep_wakeup(PMU_instance()->hal->dev) && + !pmu_ll_hp_is_sleep_reject(PMU_instance()->hal->dev)) { + ; + } + + return ESP_OK; +} 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 new file mode 100644 index 0000000000..31f49a0a87 --- /dev/null +++ b/components/esp_hw_support/port/esp32c6/private_include/pmu_param.h @@ -0,0 +1,336 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include +#include "soc/pmu_struct.h" +#include "hal/pmu_hal.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + pmu_hp_dig_power_reg_t dig_power; + pmu_hp_clk_power_reg_t clk_power; + pmu_hp_xtal_reg_t xtal; +} pmu_hp_system_power_param_t; + +const pmu_hp_system_power_param_t* pmu_hp_system_power_param_default(pmu_hp_mode_t mode); + +typedef struct { + uint32_t icg_func; + uint32_t icg_apb; + pmu_hp_icg_modem_reg_t icg_modem; + pmu_hp_sysclk_reg_t sysclk; +} pmu_hp_system_clock_param_t; + +const pmu_hp_system_clock_param_t* pmu_hp_system_clock_param_default(pmu_hp_mode_t mode); + +typedef struct { + pmu_hp_sys_cntl_reg_t syscntl; +} pmu_hp_system_digital_param_t; + +const pmu_hp_system_digital_param_t* pmu_hp_system_digital_param_default(pmu_hp_mode_t mode); + +typedef struct { + pmu_hp_bias_reg_t bias; + pmu_hp_regulator0_reg_t regulator0; + pmu_hp_regulator1_reg_t regulator1; +} pmu_hp_system_analog_param_t; + +const pmu_hp_system_analog_param_t* pmu_hp_system_analog_param_default(pmu_hp_mode_t mode); + +typedef struct { + pmu_hp_backup_reg_t retention; + uint32_t backup_clk; +} pmu_hp_system_retention_param_t; + +const pmu_hp_system_retention_param_t* pmu_hp_system_retention_param_default(pmu_hp_mode_t mode); + +typedef struct { + pmu_lp_dig_power_reg_t dig_power; + pmu_lp_clk_power_reg_t clk_power; + pmu_lp_xtal_reg_t xtal; +} pmu_lp_system_power_param_t; + +const pmu_lp_system_power_param_t* pmu_lp_system_power_param_default(pmu_lp_mode_t mode); + +typedef struct { + pmu_lp_bias_reg_t bias; + pmu_lp_regulator0_reg_t regulator0; + pmu_lp_regulator1_reg_t regulator1; +} pmu_lp_system_analog_param_t; + +const pmu_lp_system_analog_param_t* pmu_lp_system_analog_param_default(pmu_lp_mode_t mode); + +#define PMU_HP_SLEEP_MIN_SLOW_CLK_CYCLES (10) +#define PMU_LP_SLEEP_MIN_SLOW_CLK_CYCLES (10) + +#define PMU_HP_WAKEUP_DELAY_CYCLES (0) +#define PMU_HP_XTAL_STABLE_WAIT_CYCLES (3155) /* Not used, Fast OSC as PMU work clock source is about 201 us, corresponding to PMU_LP_XTAL_STABLE_WAIT_SLOW_CLK_CYCLES */ +#define PMU_HP_PLL_STABLE_WAIT_CYCLES (2) +#define PMU_HP_ANALOG_WAIT_TARGET_CYCLES (2419) /* Fast OSC as PMU work clock source is about 154 us */ +#define PMU_HP_DIGITAL_POWER_SUPPLY_WAIT_CYCLES (32) +#define PMU_HP_DIGITAL_POWER_UP_WAIT_CYCLES (32) +#define PMU_HP_MODEM_WAKEUP_WAIT_CYCLES (20700) /* Fast OSC as PMU work clock source is about 1318.6 us */ + +#define PMU_LP_WAKEUP_DELAY_CYCLES (0) +#define PMU_LP_XTAL_STABLE_WAIT_SLOW_CLK_CYCLES (30) /* Slow OSC as PMU slow clock source is about 201 us */ +#define PMU_LP_ANALOG_WAIT_TARGET_CYCLES (23) /* Slow OSC as PMU slow clock source is about 154 us */ +#define PMU_LP_DIGITAL_POWER_SUPPLY_WAIT_CYCLES (32) /* Fast OSC as PMU work clock source is about 2 us */ +#define PMU_LP_DIGITAL_POWER_UP_WAIT_CYCLES (32) /* Fast OSC as PMU work clock source is about 2 us */ + + +typedef struct { + struct { + pmu_hp_power_t dig_power; + pmu_hp_power_t clk_power; + pmu_hp_power_t xtal; + } hp_sys; + struct { + pmu_lp_power_t dig_power; + pmu_lp_power_t clk_power; + pmu_lp_power_t xtal; + } lp_sys[PMU_MODE_LP_MAX]; +} pmu_sleep_power_config_t; + +#define PMU_SLEEP_POWER_CONFIG_DEFAULT(pd_flags) { \ + .hp_sys = { \ + .dig_power = { \ + .vdd_spi_pd_en = ((pd_flags) & PMU_SLEEP_PD_VDDSDIO) ? 1 : 0, \ + .wifi_pd_en = ((pd_flags) & PMU_SLEEP_PD_MODEM) ? 1 : 0, \ + .cpu_pd_en = ((pd_flags) & PMU_SLEEP_PD_CPU) ? 1 : 0, \ + .aon_pd_en = ((pd_flags) & PMU_SLEEP_PD_AON) ? 1 : 0, \ + .top_pd_en = ((pd_flags) & PMU_SLEEP_PD_TOP) ? 1 : 0, \ + .mem_pd_en = 0, \ + .mem_dslp = 0 \ + }, \ + .clk_power = { \ + .i2c_iso_en = 1, \ + .i2c_retention = 1, \ + .xpd_bb_i2c = 0, \ + .xpd_bbpll_i2c = 0, \ + .xpd_bbpll = 0 \ + }, \ + .xtal = { \ + .xpd_xtal = ((pd_flags) & PMU_SLEEP_PD_XTAL) ? 0 : 1, \ + } \ + }, \ + .lp_sys[PMU_MODE_LP_ACTIVE] = { \ + .dig_power = { \ + .peri_pd_en = 0, \ + .mem_dslp = 0 \ + }, \ + .clk_power = { \ + .xpd_xtal32k = 1, \ + .xpd_rc32k = 1, \ + .xpd_fosc = 1 \ + } \ + }, \ + .lp_sys[PMU_MODE_LP_SLEEP] = { \ + .dig_power = { \ + .peri_pd_en = ((pd_flags) & PMU_SLEEP_PD_LP_PERIPH) ? 1 : 0, \ + .mem_dslp = 1 \ + }, \ + .clk_power = { \ + .xpd_xtal32k = ((pd_flags) & PMU_SLEEP_PD_XTAL32K) ? 0 : 1, \ + .xpd_rc32k = ((pd_flags) & PMU_SLEEP_PD_RC32K) ? 0 : 1, \ + .xpd_fosc = ((pd_flags) & PMU_SLEEP_PD_RC_FAST) ? 0 : 1 \ + }, \ + .xtal = { \ + .xpd_xtal = ((pd_flags) & PMU_SLEEP_PD_XTAL) ? 0 : 1, \ + } \ + } \ +} + +typedef struct { + struct { + pmu_hp_analog_t analog; + } hp_sys; + struct { + pmu_lp_analog_t analog; + } lp_sys[PMU_MODE_LP_MAX]; +} pmu_sleep_analog_config_t; + +#define PMU_SLEEP_ANALOG_LSLP_CONFIG_DEFAULT(pd_flags) { \ + .hp_sys = { \ + .analog = { \ + .xpd_bias = 0x0, \ + .dbg_atten = 0x0, \ + .pd_cur = 1, \ + .bias_sleep = 1, \ + .slp_mem_xpd = 1, \ + .slp_logic_xpd = 1, \ + .slp_mem_dbias = 0x4, \ + .slp_logic_dbias = 0x4, \ + .xpd = 0, \ + .dbias = 0, \ + .drv_b = 0 \ + } \ + }, \ + .lp_sys[PMU_MODE_LP_ACTIVE] = { \ + .analog = { \ + .slp_xpd = 0, \ + .slp_dbias = 0xc, \ + .xpd = 1, \ + .dbias = 0x1a, \ + .drv_b = 0x0 \ + } \ + }, \ + .lp_sys[PMU_MODE_LP_SLEEP] = { \ + .analog = { \ + .xpd_bias = 0, \ + .dbg_atten = 0x0, \ + .pd_cur = 1, \ + .bias_sleep = 1, \ + .xpd = 0, \ + .dbias = 0x1c, \ + .slp_xpd = 1, \ + .slp_dbias = 0x3, \ + .drv_b = 0x0 \ + } \ + } \ +} + +#define PMU_SLEEP_ANALOG_DSLP_CONFIG_DEFAULT(pd_flags) { \ + .hp_sys = { \ + .analog = { \ + .xpd_bias = 0, \ + .dbg_atten = 0x3, \ + .pd_cur = 1, \ + .bias_sleep = 1, \ + .xpd = 0, \ + .dbias = 0x15, \ + .slp_mem_xpd = 1, \ + .slp_mem_dbias = 0xc, \ + .slp_logic_xpd = 1, \ + .slp_logic_dbias = 0x5, \ + .drv_b = 0x18c \ + } \ + }, \ + .lp_sys[PMU_MODE_LP_ACTIVE] = { \ + .analog = { \ + .xpd = 1, \ + .dbias = 0x1a, \ + .slp_xpd = 0, \ + .slp_dbias = 0, \ + .drv_b = 0x7 \ + } \ + }, \ + .lp_sys[PMU_MODE_LP_SLEEP] = { \ + .analog = { \ + .xpd_bias = 0, \ + .dbg_atten = 0xe, \ + .pd_cur = 1, \ + .bias_sleep = 1, \ + .xpd = 0, \ + .dbias = 0, \ + .slp_xpd = 1, \ + .slp_dbias = 0xe, \ + .drv_b = 0 \ + } \ + } \ +} + +typedef struct { + pmu_hp_param_t hp_sys; + pmu_lp_param_t lp_sys; + pmu_hp_lp_param_t hp_lp; +} pmu_sleep_param_config_t; + +#define PMU_SLEEP_PARAM_CONFIG_DEFAULT(pd_flags) { \ + .hp_sys = { \ + .min_slp_slow_clk_cycle = PMU_HP_SLEEP_MIN_SLOW_CLK_CYCLES, \ + .analog_wait_target_cycle = PMU_HP_ANALOG_WAIT_TARGET_CYCLES, \ + .digital_power_supply_wait_cycle = PMU_HP_DIGITAL_POWER_SUPPLY_WAIT_CYCLES, \ + .digital_power_up_wait_cycle = PMU_HP_DIGITAL_POWER_UP_WAIT_CYCLES, \ + .modem_wakeup_wait_cycle = PMU_HP_MODEM_WAKEUP_WAIT_CYCLES, \ + .pll_stable_wait_cycle = PMU_HP_PLL_STABLE_WAIT_CYCLES \ + }, \ + .lp_sys = { \ + .min_slp_slow_clk_cycle = PMU_LP_SLEEP_MIN_SLOW_CLK_CYCLES, \ + .analog_wait_target_cycle = PMU_LP_ANALOG_WAIT_TARGET_CYCLES, \ + .digital_power_supply_wait_cycle = PMU_LP_DIGITAL_POWER_SUPPLY_WAIT_CYCLES, \ + .digital_power_up_wait_cycle = PMU_LP_DIGITAL_POWER_UP_WAIT_CYCLES \ + }, \ + .hp_lp = { \ + .xtal_stable_wait_slow_clk_cycle = PMU_LP_XTAL_STABLE_WAIT_SLOW_CLK_CYCLES \ + } \ +} + +typedef struct { + pmu_sleep_power_config_t power; + pmu_sleep_analog_config_t analog; + pmu_sleep_param_config_t param; +} pmu_sleep_config_t; + +typedef struct pmu_sleep_machine_constant { + struct { + uint16_t min_slp_time_ms; /* Mininum 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; + uint16_t analog_wait_time_ms; /* LP LDO power up wait time (unit: microsecond) */ + uint16_t xtal_wait_stable_time_ms; /* Main XTAL stabilization wait time (unit: microsecond) */ + uint8_t clk_switch_cycle; /* Clock switch to FOSC (unit: slow clock cycle) */ + uint8_t clk_power_on_wait_cycle; /* Clock power on wait cycle (unit: slow clock cycle) */ + uint16_t power_supply_wait_time_ms; /* (unit: microsecond) */ + uint16_t power_up_wait_time_ms; /* (unit: microsecond) */ + } lp; + struct { + uint16_t min_slp_time_ms; /* Mininum sleep protection time (unit: microsecond) */ + uint16_t clock_domain_sync_time_ms; /* 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_ms; /* System DFS up scaling work time (unit: microsecond) */ + uint16_t analog_wait_time_ms; /* HP LDO power up wait time (unit: microsecond) */ + uint16_t power_supply_wait_time_ms; /* (unit: microsecond) */ + uint16_t power_up_wait_time_ms; /* (unit: microsecond) */ + uint16_t regdma_s2m_work_time_ms; /* Modem Subsystem (S2M switch) REGDMA restore time (unit: microsecond) */ + uint16_t regdma_s2a_work_time_ms; /* SOC System (Digital Peripheral + Modem Subsystem) REGDMA (S2A switch) restore time (unit: microsecond) */ + uint16_t regdma_m2a_work_time_ms; /* Digital Peripheral (M2A switch) REGDMA restore time (unit: microsecond) */ + uint16_t regdma_a2s_work_time_ms; /* SOC System (Digital Peripheral + Modem Subsystem) REGDMA (A2S switch) backup time (unit: microsecond) */ + uint16_t regdma_rf_on_work_time_ms; /* The REGDMA work time of RF enable (unit: microsecond) */ + uint16_t regdma_rf_off_work_time_ms; /* The REGDMA work time of RF disable (unit: microsecond) */ + uint16_t xtal_wait_stable_time_ms; /* Main XTAL stabilization wait time (unit: microsecond) */ + uint16_t pll_wait_stable_time_ms; /* PLL stabilization wait time (unit: microsecond) */ + } hp; +} pmu_sleep_machine_constant_t; + +#define PMU_SLEEP_MC_DEFAULT() { \ + .lp = { \ + .min_slp_time_ms = 450, \ + .wakeup_wait_cycle = 4, \ + .analog_wait_time_ms = 154, \ + .xtal_wait_stable_time_ms = 250, \ + .clk_switch_cycle = 1, \ + .clk_power_on_wait_cycle = 1, \ + .power_supply_wait_time_ms = 2, \ + .power_up_wait_time_ms = 2 \ + }, \ + .hp = { \ + .min_slp_time_ms = 450, \ + .clock_domain_sync_time_ms = 150, \ + .system_dfs_up_work_time_ms = 124, \ + .analog_wait_time_ms = 154, \ + .power_supply_wait_time_ms = 2, \ + .power_up_wait_time_ms = 2, \ + .regdma_s2m_work_time_ms = 172, \ + .regdma_s2a_work_time_ms = 430, \ + .regdma_m2a_work_time_ms = 265, \ + .regdma_a2s_work_time_ms = 338, \ + .regdma_rf_on_work_time_ms = 70, \ + .regdma_rf_off_work_time_ms = 23, \ + .xtal_wait_stable_time_ms = 250, \ + .pll_wait_stable_time_ms = 1 \ + } \ +} + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_hw_support/port/esp32c6/rtc_clk_init.c b/components/esp_hw_support/port/esp32c6/rtc_clk_init.c index 78bb356bcb..a605456a6a 100644 --- a/components/esp_hw_support/port/esp32c6/rtc_clk_init.c +++ b/components/esp_hw_support/port/esp32c6/rtc_clk_init.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -19,14 +19,47 @@ #include "esp_hw_log.h" #include "sdkconfig.h" #include "esp_rom_uart.h" +#include "esp_private/esp_pmu.h" #include "hal/clk_tree_ll.h" +#include "hal/pmu_ll.h" +#include "hal/modem_syscon_ll.h" +#include "hal/modem_lpcon_ll.h" static const char *TAG = "rtc_clk_init"; +/** + * Initialize the ICG map of some modem clock domains in the PMU_ACTIVE state + * + * A pre-initialization interface is used to initialize the ICG map of the + * MODEM_APB, I2C_MST and LP_APB clock domains in the PMU_ACTIVE state, and + * disable the clock gating of these clock domains in the PMU_ACTIVE state, + * because the system clock source (PLL) in the system boot up process needs + * to use the i2c master peripheral. + * + * ICG map of all modem clock domains under different power states (PMU_ACTIVE, + * PMU_MODEM and PMU_SLEEP) will be initialized in esp_perip_clk_init(). + */ +static void rtc_clk_modem_clock_domain_active_state_icg_map_preinit(void) +{ + /* Configure modem ICG code in PMU_ACTIVE state */ + pmu_ll_hp_set_icg_modem(&PMU, PMU_MODE_HP_ACTIVE, PMU_HP_ICG_MODEM_CODE_ACTIVE); + + /* Disable clock gating for MODEM_APB, I2C_MST and LP_APB clock domains in PMU_ACTIVE state */ + modem_syscon_ll_set_modem_apb_icg_bitmap(&MODEM_SYSCON, BIT(PMU_HP_ICG_MODEM_CODE_ACTIVE)); + modem_lpcon_ll_set_i2c_master_icg_bitmap(&MODEM_LPCON, BIT(PMU_HP_ICG_MODEM_CODE_ACTIVE)); + modem_lpcon_ll_set_lp_apb_icg_bitmap(&MODEM_LPCON, BIT(PMU_HP_ICG_MODEM_CODE_ACTIVE)); + + /* Software trigger force update modem ICG code and ICG switch */ + pmu_ll_imm_update_dig_icg_modem_code(&PMU, true); + pmu_ll_imm_update_dig_icg_switch(&PMU, true); +} + void rtc_clk_init(rtc_clk_config_t cfg) { rtc_cpu_freq_config_t old_config, new_config; + rtc_clk_modem_clock_domain_active_state_icg_map_preinit(); + /* Set tuning parameters for RC_FAST, RC_SLOW, and RC32K clocks. * Note: this doesn't attempt to set the clocks to precise frequencies. * Instead, we calibrate these clocks against XTAL frequency later, when necessary. diff --git a/components/esp_hw_support/port/esp32c6/rtc_init.c b/components/esp_hw_support/port/esp32c6/rtc_init.c deleted file mode 100644 index 0d418b5a6a..0000000000 --- a/components/esp_hw_support/port/esp32c6/rtc_init.c +++ /dev/null @@ -1,26 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "soc/rtc.h" -#include "soc/pmu_reg.h" -#include "soc/regi2c_dig_reg.h" -#include "regi2c_ctrl.h" - -// TODO: IDF-5781 - -void rtc_init(rtc_config_t cfg) -{ - /* Peripheral reg i2c power up */ - SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_PERIF_I2C_RSTB); - SET_PERI_REG_MASK(PMU_RF_PWC_REG, PMU_XPD_PERIF_I2C); - - REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_RTC_DREG, 1); - REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_ENIF_DIG_DREG, 1); - REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_RTC_REG, 0); - REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_XPD_DIG_REG, 0); - REG_SET_FIELD(PMU_HP_ACTIVE_HP_REGULATOR0_REG, PMU_HP_ACTIVE_HP_REGULATOR_DBIAS, 25); - REG_SET_FIELD(PMU_HP_SLEEP_LP_REGULATOR0_REG, PMU_HP_SLEEP_LP_REGULATOR_DBIAS, 26); -} diff --git a/components/esp_hw_support/port/esp32c6/rtc_sleep.c b/components/esp_hw_support/port/esp32c6/rtc_sleep.c deleted file mode 100644 index 8a5daa4517..0000000000 --- a/components/esp_hw_support/port/esp32c6/rtc_sleep.c +++ /dev/null @@ -1,7 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -// TODO: IDF-5645 diff --git a/components/esp_hw_support/port/esp32c6/rtc_time.c b/components/esp_hw_support/port/esp32c6/rtc_time.c index 98bf1e6f82..483b9fc0bc 100644 --- a/components/esp_hw_support/port/esp32c6/rtc_time.c +++ b/components/esp_hw_support/port/esp32c6/rtc_time.c @@ -8,8 +8,8 @@ #include "esp32c6/rom/ets_sys.h" #include "soc/rtc.h" #include "soc/lp_timer_reg.h" +#include "hal/lp_timer_hal.h" #include "hal/clk_tree_ll.h" -#include "hal/rtc_cntl_ll.h" #include "soc/timer_group_reg.h" #include "esp_rom_sys.h" #include "assert.h" @@ -207,7 +207,7 @@ uint64_t rtc_time_slowclk_to_us(uint64_t rtc_cycles, uint32_t period) uint64_t rtc_time_get(void) { - return rtc_cntl_ll_get_rtc_time(); + return lp_timer_hal_get_cycle_count(0); } uint64_t rtc_light_slp_time_get(void) diff --git a/components/esp_hw_support/port/esp32h4/rtc_init.c b/components/esp_hw_support/port/esp32h4/rtc_init.c index 04867ab772..40174e3682 100644 --- a/components/esp_hw_support/port/esp32h4/rtc_init.c +++ b/components/esp_hw_support/port/esp32h4/rtc_init.c @@ -174,40 +174,3 @@ void dslp_osc_pd(void){ REG_SET_FIELD(RTC_CNTL_RC32K_CTRL_REG,RTC_CNTL_RC32K_XPD, 0); REG_SET_FIELD(RTC_CNTL_PLL8M_REG, RTC_CNTL_XPD_PLL8M, 0); } -rtc_vddsdio_config_t rtc_vddsdio_get_config(void) -{ - rtc_vddsdio_config_t result; - uint32_t sdio_conf_reg = REG_READ(RTC_CNTL_SDIO_CONF_REG); - result.drefh = (sdio_conf_reg & RTC_CNTL_DREFH_SDIO_M) >> RTC_CNTL_DREFH_SDIO_S; - result.drefm = (sdio_conf_reg & RTC_CNTL_DREFM_SDIO_M) >> RTC_CNTL_DREFM_SDIO_S; - result.drefl = (sdio_conf_reg & RTC_CNTL_DREFL_SDIO_M) >> RTC_CNTL_DREFL_SDIO_S; - if (sdio_conf_reg & RTC_CNTL_SDIO_FORCE) { - // Get configuration from RTC - result.force = 1; - result.enable = (sdio_conf_reg & RTC_CNTL_XPD_SDIO_REG_M) >> RTC_CNTL_XPD_SDIO_REG_S; - result.tieh = (sdio_conf_reg & RTC_CNTL_SDIO_TIEH_M) >> RTC_CNTL_SDIO_TIEH_S; - return result; - } else { - result.force = 0; - } - - // Otherwise, VDD_SDIO is controlled by bootstrapping pin - uint32_t strap_reg = REG_READ(GPIO_STRAP_REG); - result.force = 0; - result.tieh = (strap_reg & BIT(5)) ? RTC_VDDSDIO_TIEH_1_8V : RTC_VDDSDIO_TIEH_3_3V; - result.enable = 1; - return result; -} - -void rtc_vddsdio_set_config(rtc_vddsdio_config_t config) -{ - uint32_t val = 0; - val |= (config.force << RTC_CNTL_SDIO_FORCE_S); - val |= (config.enable << RTC_CNTL_XPD_SDIO_REG_S); - val |= (config.drefh << RTC_CNTL_DREFH_SDIO_S); - val |= (config.drefm << RTC_CNTL_DREFM_SDIO_S); - val |= (config.drefl << RTC_CNTL_DREFL_SDIO_S); - val |= (config.tieh << RTC_CNTL_SDIO_TIEH_S); - val |= RTC_CNTL_SDIO_PD_EN; - REG_WRITE(RTC_CNTL_SDIO_CONF_REG, val); -} diff --git a/components/esp_hw_support/sleep_cpu.c b/components/esp_hw_support/sleep_cpu.c new file mode 100644 index 0000000000..2f01bdc779 --- /dev/null +++ b/components/esp_hw_support/sleep_cpu.c @@ -0,0 +1,646 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include "esp_attr.h" +#include "esp_sleep.h" +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "esp_heap_caps.h" +#include "soc/soc_caps.h" +#include "esp_private/sleep_cpu.h" +#include "sdkconfig.h" + +#if !SOC_PMU_SUPPORTED +#include "hal/rtc_hal.h" +#endif + +#include "soc/rtc_periph.h" + +#ifdef CONFIG_IDF_TARGET_ESP32S3 +#include "esp32s3/rom/cache.h" +#elif CONFIG_IDF_TARGET_ESP32C6 +#include "esp32c6/rom/rtc.h" +#include "riscv/rvsleep-frames.h" +#include "soc/intpri_reg.h" +#include "soc/extmem_reg.h" +#include "soc/plic_reg.h" +#include "soc/clint_reg.h" +#include "esp32c6/rom/cache.h" +#endif + +static __attribute__((unused)) const char *TAG = "sleep"; + +typedef struct { + uint32_t start; + uint32_t end; +} cpu_domain_dev_regs_region_t; + +typedef struct { + cpu_domain_dev_regs_region_t *region; + int region_num; + uint32_t *regs_frame; +} cpu_domain_dev_sleep_frame_t; + +/** + * Internal structure which holds all requested light sleep cpu retention parameters + */ +typedef struct { +#if SOC_PM_SUPPORT_CPU_PD && SOC_PM_CPU_RETENTION_BY_RTCCNTL + rtc_cntl_sleep_retent_t retent; +#elif SOC_PM_SUPPORT_CPU_PD && SOC_PM_CPU_RETENTION_BY_SW + struct { + RvCoreCriticalSleepFrame *critical_frame; + RvCoreNonCriticalSleepFrame *non_critical_frame; + cpu_domain_dev_sleep_frame_t *intpri_frame; + cpu_domain_dev_sleep_frame_t *cache_config_frame; + cpu_domain_dev_sleep_frame_t *plic_frame; + cpu_domain_dev_sleep_frame_t *clint_frame; + } retent; +#endif +} sleep_cpu_retention_t; + +static DRAM_ATTR __attribute__((unused)) sleep_cpu_retention_t s_cpu_retention; + +#if SOC_PM_SUPPORT_TAGMEM_PD && SOC_PM_CPU_RETENTION_BY_RTCCNTL + +#if CONFIG_PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP +static uint32_t cache_tagmem_retention_setup(uint32_t code_seg_vaddr, uint32_t code_seg_size, uint32_t data_seg_vaddr, uint32_t data_seg_size) +{ + uint32_t sets; /* i/d-cache total set counts */ + uint32_t index; /* virtual address mapping i/d-cache row offset */ + uint32_t waysgrp; + uint32_t icache_tagmem_blk_gs, dcache_tagmem_blk_gs; + struct cache_mode imode = { .icache = 1 }; + struct cache_mode dmode = { .icache = 0 }; + + /* calculate/prepare i-cache tag memory retention parameters */ + Cache_Get_Mode(&imode); + sets = imode.cache_size / imode.cache_ways / imode.cache_line_size; + index = (code_seg_vaddr / imode.cache_line_size) % sets; + waysgrp = imode.cache_ways >> 2; + + code_seg_size = ALIGNUP(imode.cache_line_size, code_seg_size); + + s_cpu_retention.retent.tagmem.icache.start_point = index; + s_cpu_retention.retent.tagmem.icache.size = (sets * waysgrp) & 0xff; + s_cpu_retention.retent.tagmem.icache.vld_size = s_cpu_retention.retent.tagmem.icache.size; + if (code_seg_size < imode.cache_size / imode.cache_ways) { + s_cpu_retention.retent.tagmem.icache.vld_size = (code_seg_size / imode.cache_line_size) * waysgrp; + } + s_cpu_retention.retent.tagmem.icache.enable = (code_seg_size != 0) ? 1 : 0; + icache_tagmem_blk_gs = s_cpu_retention.retent.tagmem.icache.vld_size ? s_cpu_retention.retent.tagmem.icache.vld_size : sets * waysgrp; + icache_tagmem_blk_gs = ALIGNUP(4, icache_tagmem_blk_gs); + ESP_LOGD(TAG, "I-cache size:%d KiB, line size:%d B, ways:%d, sets:%d, index:%d, tag block groups:%d", (imode.cache_size>>10), + imode.cache_line_size, imode.cache_ways, sets, index, icache_tagmem_blk_gs); + + /* calculate/prepare d-cache tag memory retention parameters */ + Cache_Get_Mode(&dmode); + sets = dmode.cache_size / dmode.cache_ways / dmode.cache_line_size; + index = (data_seg_vaddr / dmode.cache_line_size) % sets; + waysgrp = dmode.cache_ways >> 2; + + data_seg_size = ALIGNUP(dmode.cache_line_size, data_seg_size); + + s_cpu_retention.retent.tagmem.dcache.start_point = index; + s_cpu_retention.retent.tagmem.dcache.size = (sets * waysgrp) & 0x1ff; + s_cpu_retention.retent.tagmem.dcache.vld_size = s_cpu_retention.retent.tagmem.dcache.size; +#ifndef CONFIG_ESP32S3_DATA_CACHE_16KB + if (data_seg_size < dmode.cache_size / dmode.cache_ways) { + s_cpu_retention.retent.tagmem.dcache.vld_size = (data_seg_size / dmode.cache_line_size) * waysgrp; + } + s_cpu_retention.retent.tagmem.dcache.enable = (data_seg_size != 0) ? 1 : 0; +#else + s_cpu_retention.retent.tagmem.dcache.enable = 1; +#endif + dcache_tagmem_blk_gs = s_cpu_retention.retent.tagmem.dcache.vld_size ? s_cpu_retention.retent.tagmem.dcache.vld_size : sets * waysgrp; + dcache_tagmem_blk_gs = ALIGNUP(4, dcache_tagmem_blk_gs); + ESP_LOGD(TAG, "D-cache size:%d KiB, line size:%d B, ways:%d, sets:%d, index:%d, tag block groups:%d", (dmode.cache_size>>10), + dmode.cache_line_size, dmode.cache_ways, sets, index, dcache_tagmem_blk_gs); + + /* For I or D cache tagmem retention, backup and restore are performed through + * RTC DMA (its bus width is 128 bits), For I/D Cache tagmem blocks (i-cache + * tagmem blocks = 92 bits, d-cache tagmem blocks = 88 bits), RTC DMA automatically + * aligns its bit width to 96 bits, therefore, 3 times RTC DMA can transfer 4 + * i/d-cache tagmem blocks (128 bits * 3 = 96 bits * 4) */ + return (((icache_tagmem_blk_gs + dcache_tagmem_blk_gs) << 2) * 3); +} +#endif // CONFIG_PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP + +static esp_err_t esp_sleep_tagmem_pd_low_init(void) +{ +#if CONFIG_PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP + if (s_cpu_retention.retent.tagmem.link_addr == NULL) { + extern char _stext[], _etext[]; + uint32_t code_start = (uint32_t)_stext; + uint32_t code_size = (uint32_t)(_etext - _stext); +#if !(CONFIG_SPIRAM && CONFIG_SOC_PM_SUPPORT_TAGMEM_PD) + extern char _rodata_start[], _rodata_reserved_end[]; + uint32_t data_start = (uint32_t)_rodata_start; + uint32_t data_size = (uint32_t)(_rodata_reserved_end - _rodata_start); +#else + uint32_t data_start = SOC_DROM_LOW; + uint32_t data_size = SOC_EXTRAM_DATA_SIZE; +#endif + ESP_LOGI(TAG, "Code start at 0x%08"PRIx32", total %"PRIu32", data start at 0x%08"PRIx32", total %"PRIu32" Bytes", + code_start, code_size, data_start, data_size); + uint32_t tagmem_sz = cache_tagmem_retention_setup(code_start, code_size, data_start, data_size); + void *buf = heap_caps_aligned_calloc(SOC_RTC_CNTL_TAGMEM_PD_DMA_ADDR_ALIGN, 1, + tagmem_sz + RTC_HAL_DMA_LINK_NODE_SIZE, + MALLOC_CAP_RETENTION); + if (buf) { + s_cpu_retention.retent.tagmem.link_addr = rtc_cntl_hal_dma_link_init(buf, + buf + RTC_HAL_DMA_LINK_NODE_SIZE, tagmem_sz, NULL); + } else { + s_cpu_retention.retent.tagmem.icache.enable = 0; + s_cpu_retention.retent.tagmem.dcache.enable = 0; + s_cpu_retention.retent.tagmem.link_addr = NULL; + return ESP_ERR_NO_MEM; + } + } +#else // CONFIG_PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP + s_cpu_retention.retent.tagmem.icache.enable = 0; + s_cpu_retention.retent.tagmem.dcache.enable = 0; + s_cpu_retention.retent.tagmem.link_addr = NULL; +#endif // CONFIG_PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP + return ESP_OK; +} + +static esp_err_t esp_sleep_tagmem_pd_low_deinit(void) +{ +#if SOC_PM_SUPPORT_TAGMEM_PD + if (s_cpu_retention.retent.tagmem.link_addr) { + heap_caps_free(s_cpu_retention.retent.tagmem.link_addr); + s_cpu_retention.retent.tagmem.icache.enable = 0; + s_cpu_retention.retent.tagmem.dcache.enable = 0; + s_cpu_retention.retent.tagmem.link_addr = NULL; + } +#endif + return ESP_OK; +} +#endif // SOC_PM_SUPPORT_TAGMEM_PD && SOC_PM_CPU_RETENTION_BY_RTCCNTL + +#if SOC_PM_SUPPORT_CPU_PD && SOC_PM_CPU_RETENTION_BY_RTCCNTL + +esp_err_t esp_sleep_cpu_pd_low_init(void) +{ + if (s_cpu_retention.retent.cpu_pd_mem == NULL) { + void *buf = heap_caps_aligned_calloc(SOC_RTC_CNTL_CPU_PD_DMA_ADDR_ALIGN, 1, + SOC_RTC_CNTL_CPU_PD_RETENTION_MEM_SIZE + RTC_HAL_DMA_LINK_NODE_SIZE, + MALLOC_CAP_RETENTION); + if (buf) { + s_cpu_retention.retent.cpu_pd_mem = rtc_cntl_hal_dma_link_init(buf, + buf + RTC_HAL_DMA_LINK_NODE_SIZE, SOC_RTC_CNTL_CPU_PD_RETENTION_MEM_SIZE, NULL); + } else { + return ESP_ERR_NO_MEM; + } + } + +#if SOC_PM_SUPPORT_TAGMEM_PD && SOC_PM_CPU_RETENTION_BY_RTCCNTL + if (esp_sleep_tagmem_pd_low_init() != ESP_OK) { +#ifdef CONFIG_ESP32S3_DATA_CACHE_16KB + esp_sleep_cpu_pd_low_deinit(); + return ESP_ERR_NO_MEM; +#endif + } +#endif + return ESP_OK; +} + +esp_err_t esp_sleep_cpu_pd_low_deinit(void) +{ + if (s_cpu_retention.retent.cpu_pd_mem) { + heap_caps_free(s_cpu_retention.retent.cpu_pd_mem); + s_cpu_retention.retent.cpu_pd_mem = NULL; + } + +#if SOC_PM_SUPPORT_TAGMEM_PD && SOC_PM_CPU_RETENTION_BY_RTCCNTL + if (esp_sleep_tagmem_pd_low_deinit() != ESP_OK) { +#ifdef CONFIG_ESP32S3_DATA_CACHE_16KB + esp_sleep_cpu_pd_low_deinit(); + return ESP_ERR_NO_MEM; +#endif + } +#endif + return ESP_OK; +} + +void sleep_enable_cpu_retention(void) +{ + rtc_cntl_hal_enable_cpu_retention(&s_cpu_retention.retent); + +#if SOC_PM_SUPPORT_TAGMEM_PD + rtc_cntl_hal_enable_tagmem_retention(&s_cpu_retention.retent); +#endif +} + +void IRAM_ATTR sleep_disable_cpu_retention(void) +{ + rtc_cntl_hal_disable_cpu_retention(&s_cpu_retention.retent); + +#if SOC_PM_SUPPORT_TAGMEM_PD + rtc_cntl_hal_disable_tagmem_retention(&s_cpu_retention.retent); +#endif +} + +#endif + + +#if SOC_PM_SUPPORT_CPU_PD && SOC_PM_CPU_RETENTION_BY_SW + +#define CUSTOM_CSR_PCER_MACHINE 0x7e0 +#define CUSTOM_CSR_PCMR_MACHINE 0x7e1 +#define CUSTOM_CSR_PCCR_MACHINE 0x7e2 +#define CUSTOM_CSR_CPU_TESTBUS_CTRL 0x7e3 +#define CUSTOM_CSR_PCER_USER 0x800 +#define CUSTOM_CSR_PCMR_USER 0x801 +#define CUSTOM_CSR_PCCR_USER 0x802 +#define CUSTOM_CSR_GPIO_OEN_USER 0x803 +#define CUSTOM_CSR_GPIO_IN_USER 0x804 +#define CUSTOM_CSR_GPIO_OUT_USER 0x805 +#define CUSTOM_CSR_CO_EXCEPTION_CAUSE 0x7f0 +#define CUSTOM_CSR_CO_HWLP 0x7f1 +#define CUSTOM_CSR_CO_AIA 0x7f2 + +extern RvCoreCriticalSleepFrame *rv_core_critical_regs_frame; + +static void * cpu_domain_dev_sleep_frame_alloc_and_init(const cpu_domain_dev_regs_region_t *regions, const int region_num) +{ + const int region_sz = sizeof(cpu_domain_dev_regs_region_t) * region_num; + int regs_frame_sz = 0; + for (int num = 0; num < region_num; num++) { + regs_frame_sz += regions[num].end - regions[num].start; + } + void *frame = heap_caps_malloc(sizeof(cpu_domain_dev_sleep_frame_t) + region_sz + regs_frame_sz, MALLOC_CAP_32BIT|MALLOC_CAP_INTERNAL); + if (frame) { + cpu_domain_dev_regs_region_t *region = (cpu_domain_dev_regs_region_t *)(frame + sizeof(cpu_domain_dev_sleep_frame_t)); + memcpy(region, regions, region_num * sizeof(cpu_domain_dev_regs_region_t)); + void *regs_frame = frame + sizeof(cpu_domain_dev_sleep_frame_t) + region_sz; + memset(regs_frame, 0, regs_frame_sz); + *(cpu_domain_dev_sleep_frame_t *)frame = (cpu_domain_dev_sleep_frame_t) { + .region = region, + .region_num = region_num, + .regs_frame = (uint32_t *)regs_frame + }; + } + return frame; +} + +static inline void * cpu_domain_intpri_sleep_frame_alloc_and_init(void) +{ + const static cpu_domain_dev_regs_region_t regions[] = { + { .start = INTPRI_CORE0_CPU_INT_ENABLE_REG, .end = INTPRI_RND_ECO_LOW_REG + 4 }, + { .start = INTPRI_RND_ECO_HIGH_REG, .end = INTPRI_RND_ECO_HIGH_REG + 4 } + }; + return cpu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0])); +} + +static inline void * cpu_domain_cache_config_sleep_frame_alloc_and_init(void) +{ + const static cpu_domain_dev_regs_region_t regions[] = { + { .start = EXTMEM_DCACHE_CTRL_REG, .end = EXTMEM_DCACHE_CTRL_REG + 4 }, + { .start = EXTMEM_CACHE_WRAP_AROUND_CTRL_REG, .end = EXTMEM_CACHE_WRAP_AROUND_CTRL_REG + 4 } + }; + return cpu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0])); +} + +static inline void * cpu_domain_plic_sleep_frame_alloc_and_init(void) +{ + const static cpu_domain_dev_regs_region_t regions[] = { + { .start = PLIC_MXINT_ENABLE_REG, .end = PLIC_MXINT_CLAIM_REG + 4 }, + { .start = PLIC_MXINT_CONF_REG, .end = PLIC_MXINT_CONF_REG + 4 }, + { .start = PLIC_UXINT_ENABLE_REG, .end = PLIC_UXINT_CLAIM_REG + 4 }, + { .start = PLIC_UXINT_CONF_REG, .end = PLIC_UXINT_CONF_REG + 4 } + }; + return cpu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0])); +} + +static inline void * cpu_domain_clint_sleep_frame_alloc_and_init(void) +{ + const static cpu_domain_dev_regs_region_t regions[] = { + { .start = CLINT_MINT_SIP_REG, .end = CLINT_MINT_MTIMECMP_H_REG + 4 }, + { .start = CLINT_UINT_SIP_REG, .end = CLINT_UINT_UTIMECMP_H_REG + 4 } + }; + return cpu_domain_dev_sleep_frame_alloc_and_init(regions, sizeof(regions) / sizeof(regions[0])); +} + +static esp_err_t esp_sleep_cpu_retention_init_impl(void) +{ + if (s_cpu_retention.retent.critical_frame == NULL) { + void *frame = heap_caps_calloc(1, RV_SLEEP_CTX_FRMSZ, MALLOC_CAP_32BIT|MALLOC_CAP_INTERNAL); + if (frame == NULL) { + goto err; + } + s_cpu_retention.retent.critical_frame = (RvCoreCriticalSleepFrame *)frame; + rv_core_critical_regs_frame = (RvCoreCriticalSleepFrame *)frame; + } + if (s_cpu_retention.retent.non_critical_frame == NULL) { + void *frame = heap_caps_calloc(1, sizeof(RvCoreNonCriticalSleepFrame), MALLOC_CAP_32BIT|MALLOC_CAP_INTERNAL); + if (frame == NULL) { + goto err; + } + s_cpu_retention.retent.non_critical_frame = (RvCoreNonCriticalSleepFrame *)frame; + } + if (s_cpu_retention.retent.intpri_frame == NULL) { + void *frame = cpu_domain_intpri_sleep_frame_alloc_and_init(); + if (frame == NULL) { + goto err; + } + s_cpu_retention.retent.intpri_frame = (cpu_domain_dev_sleep_frame_t *)frame; + } + if (s_cpu_retention.retent.cache_config_frame == NULL) { + void *frame = cpu_domain_cache_config_sleep_frame_alloc_and_init(); + if (frame == NULL) { + goto err; + } + s_cpu_retention.retent.cache_config_frame = (cpu_domain_dev_sleep_frame_t *)frame; + } + if (s_cpu_retention.retent.plic_frame == NULL) { + void *frame = cpu_domain_plic_sleep_frame_alloc_and_init(); + if (frame == NULL) { + goto err; + } + s_cpu_retention.retent.plic_frame = (cpu_domain_dev_sleep_frame_t *)frame; + } + if (s_cpu_retention.retent.clint_frame == NULL) { + void *frame = cpu_domain_clint_sleep_frame_alloc_and_init(); + if (frame == NULL) { + goto err; + } + s_cpu_retention.retent.clint_frame = (cpu_domain_dev_sleep_frame_t *)frame; + } + return ESP_OK; +err: + esp_sleep_cpu_retention_deinit(); + return ESP_ERR_NO_MEM; +} + +static esp_err_t esp_sleep_cpu_retention_deinit_impl(void) +{ + if (s_cpu_retention.retent.critical_frame) { + heap_caps_free((void *)s_cpu_retention.retent.critical_frame); + s_cpu_retention.retent.critical_frame = NULL; + rv_core_critical_regs_frame = NULL; + } + if (s_cpu_retention.retent.non_critical_frame) { + heap_caps_free((void *)s_cpu_retention.retent.non_critical_frame); + s_cpu_retention.retent.non_critical_frame = NULL; + } + if (s_cpu_retention.retent.intpri_frame) { + heap_caps_free((void *)s_cpu_retention.retent.intpri_frame); + s_cpu_retention.retent.intpri_frame = NULL; + } + if (s_cpu_retention.retent.cache_config_frame) { + heap_caps_free((void *)s_cpu_retention.retent.cache_config_frame); + s_cpu_retention.retent.cache_config_frame = NULL; + } + if (s_cpu_retention.retent.plic_frame) { + heap_caps_free((void *)s_cpu_retention.retent.plic_frame); + s_cpu_retention.retent.plic_frame = NULL; + } + if (s_cpu_retention.retent.clint_frame) { + heap_caps_free((void *)s_cpu_retention.retent.clint_frame); + s_cpu_retention.retent.clint_frame = NULL; + } + return ESP_OK; +} + +static inline IRAM_ATTR uint32_t save_mstatus_and_disable_global_int(void) +{ + uint32_t mstatus; + __asm__ __volatile__ ( + "csrr %0, mstatus\n" + "csrci mstatus, 0x8\n" + : "=r"(mstatus) + ); + return mstatus; +} + +static inline IRAM_ATTR void restore_mstatus(uint32_t mstatus) +{ + __asm__ __volatile__ ("csrw mstatus, %0\n" :: "r"(mstatus)); +} + +static IRAM_ATTR RvCoreNonCriticalSleepFrame * rv_core_noncritical_regs_save(void) +{ + assert(s_cpu_retention.retent.non_critical_frame); + RvCoreNonCriticalSleepFrame *frame = s_cpu_retention.retent.non_critical_frame; + frame->mscratch = RV_READ_CSR(mscratch); + frame->mideleg = RV_READ_CSR(mideleg); + frame->misa = RV_READ_CSR(misa); + frame->tselect = RV_READ_CSR(tselect); + frame->tdata1 = RV_READ_CSR(tdata1); + frame->tdata2 = RV_READ_CSR(tdata2); + frame->tcontrol = RV_READ_CSR(tcontrol); + frame->pmpcfg0 = RV_READ_CSR(pmpcfg0); + frame->pmpcfg1 = RV_READ_CSR(pmpcfg1); + frame->pmpcfg2 = RV_READ_CSR(pmpcfg2); + frame->pmpcfg3 = RV_READ_CSR(pmpcfg3); + frame->pmpaddr0 = RV_READ_CSR(pmpaddr0); + frame->pmpaddr1 = RV_READ_CSR(pmpaddr1); + frame->pmpaddr2 = RV_READ_CSR(pmpaddr2); + frame->pmpaddr3 = RV_READ_CSR(pmpaddr3); + frame->pmpaddr4 = RV_READ_CSR(pmpaddr4); + frame->pmpaddr5 = RV_READ_CSR(pmpaddr5); + frame->pmpaddr6 = RV_READ_CSR(pmpaddr6); + frame->pmpaddr7 = RV_READ_CSR(pmpaddr7); + frame->pmpaddr8 = RV_READ_CSR(pmpaddr8); + frame->pmpaddr9 = RV_READ_CSR(pmpaddr9); + frame->pmpaddr10 = RV_READ_CSR(pmpaddr10); + frame->pmpaddr11 = RV_READ_CSR(pmpaddr11); + frame->pmpaddr12 = RV_READ_CSR(pmpaddr12); + frame->pmpaddr13 = RV_READ_CSR(pmpaddr13); + frame->pmpaddr14 = RV_READ_CSR(pmpaddr14); + frame->pmpaddr15 = RV_READ_CSR(pmpaddr15); + + frame->utvec = RV_READ_CSR(utvec); + frame->ustatus = RV_READ_CSR(ustatus); + frame->uepc = RV_READ_CSR(uepc); + frame->ucause = RV_READ_CSR(ucause); + + frame->mpcer = RV_READ_CSR(CUSTOM_CSR_PCER_MACHINE); + frame->mpcmr = RV_READ_CSR(CUSTOM_CSR_PCMR_MACHINE); + frame->mpccr = RV_READ_CSR(CUSTOM_CSR_PCCR_MACHINE); + frame->cpu_testbus_ctrl = RV_READ_CSR(CUSTOM_CSR_CPU_TESTBUS_CTRL); + frame->upcer = RV_READ_CSR(CUSTOM_CSR_PCER_USER); + frame->upcmr = RV_READ_CSR(CUSTOM_CSR_PCMR_USER); + frame->upccr = RV_READ_CSR(CUSTOM_CSR_PCCR_USER); + frame->ugpio_oen = RV_READ_CSR(CUSTOM_CSR_GPIO_OEN_USER); + frame->ugpio_in = RV_READ_CSR(CUSTOM_CSR_GPIO_IN_USER); + frame->ugpio_out = RV_READ_CSR(CUSTOM_CSR_GPIO_OUT_USER); + return frame; +} + +static IRAM_ATTR void rv_core_noncritical_regs_restore(RvCoreNonCriticalSleepFrame *frame) +{ + assert(frame); + RV_WRITE_CSR(mscratch, frame->mscratch); + RV_WRITE_CSR(mideleg, frame->mideleg); + RV_WRITE_CSR(misa, frame->misa); + RV_WRITE_CSR(tselect, frame->tselect); + RV_WRITE_CSR(tdata1, frame->tdata1); + RV_WRITE_CSR(tdata2, frame->tdata2); + RV_WRITE_CSR(tcontrol, frame->tcontrol); + RV_WRITE_CSR(pmpcfg0, frame->pmpcfg0); + RV_WRITE_CSR(pmpcfg1, frame->pmpcfg1); + RV_WRITE_CSR(pmpcfg2, frame->pmpcfg2); + RV_WRITE_CSR(pmpcfg3, frame->pmpcfg3); + RV_WRITE_CSR(pmpaddr0, frame->pmpaddr0); + RV_WRITE_CSR(pmpaddr1, frame->pmpaddr1); + RV_WRITE_CSR(pmpaddr2, frame->pmpaddr2); + RV_WRITE_CSR(pmpaddr3, frame->pmpaddr3); + RV_WRITE_CSR(pmpaddr4, frame->pmpaddr4); + RV_WRITE_CSR(pmpaddr5, frame->pmpaddr5); + RV_WRITE_CSR(pmpaddr6, frame->pmpaddr6); + RV_WRITE_CSR(pmpaddr7, frame->pmpaddr7); + RV_WRITE_CSR(pmpaddr8, frame->pmpaddr8); + RV_WRITE_CSR(pmpaddr9, frame->pmpaddr9); + RV_WRITE_CSR(pmpaddr10,frame->pmpaddr10); + RV_WRITE_CSR(pmpaddr11,frame->pmpaddr11); + RV_WRITE_CSR(pmpaddr12,frame->pmpaddr12); + RV_WRITE_CSR(pmpaddr13,frame->pmpaddr13); + RV_WRITE_CSR(pmpaddr14,frame->pmpaddr14); + RV_WRITE_CSR(pmpaddr15,frame->pmpaddr15); + + RV_WRITE_CSR(utvec, frame->utvec); + RV_WRITE_CSR(ustatus, frame->ustatus); + RV_WRITE_CSR(uepc, frame->uepc); + RV_WRITE_CSR(ucause, frame->ucause); + + RV_WRITE_CSR(CUSTOM_CSR_PCER_MACHINE, frame->mpcer); + RV_WRITE_CSR(CUSTOM_CSR_PCMR_MACHINE, frame->mpcmr); + RV_WRITE_CSR(CUSTOM_CSR_PCCR_MACHINE, frame->mpccr); + RV_WRITE_CSR(CUSTOM_CSR_CPU_TESTBUS_CTRL, frame->cpu_testbus_ctrl); + RV_WRITE_CSR(CUSTOM_CSR_PCER_USER, frame->upcer); + RV_WRITE_CSR(CUSTOM_CSR_PCMR_USER, frame->upcmr); + RV_WRITE_CSR(CUSTOM_CSR_PCCR_USER, frame->upccr); + RV_WRITE_CSR(CUSTOM_CSR_GPIO_OEN_USER,frame->ugpio_oen); + RV_WRITE_CSR(CUSTOM_CSR_GPIO_IN_USER, frame->ugpio_in); + RV_WRITE_CSR(CUSTOM_CSR_GPIO_OUT_USER,frame->ugpio_out); +} + +static IRAM_ATTR void cpu_domain_dev_regs_save(cpu_domain_dev_sleep_frame_t *frame) +{ + assert(frame); + cpu_domain_dev_regs_region_t *region = frame->region; + uint32_t *regs_frame = frame->regs_frame; + + int offset = 0; + for (int i = 0; i < frame->region_num; i++) { + for (uint32_t addr = region[i].start; addr < region[i].end; addr+=4) { + regs_frame[offset++] = *(uint32_t *)addr; + } + } +} + +static IRAM_ATTR void cpu_domain_dev_regs_restore(cpu_domain_dev_sleep_frame_t *frame) +{ + assert(frame); + cpu_domain_dev_regs_region_t *region = frame->region; + uint32_t *regs_frame = frame->regs_frame; + + int offset = 0; + for (int i = 0; i < frame->region_num; i++) { + for (uint32_t addr = region[i].start; addr < region[i].end; addr+=4) { + *(uint32_t *)addr = regs_frame[offset++]; + } + } +} + +extern RvCoreCriticalSleepFrame * rv_core_critical_regs_save(void); +extern RvCoreCriticalSleepFrame * rv_core_critical_regs_restore(void); +typedef uint32_t (* sleep_cpu_entry_cb_t)(uint32_t, uint32_t, uint32_t, bool); + +static IRAM_ATTR esp_err_t do_cpu_retention(sleep_cpu_entry_cb_t goto_sleep, + uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp) +{ + RvCoreCriticalSleepFrame * frame = rv_core_critical_regs_save(); + if ((frame->pmufunc & 0x3) == 0x1) { + REG_CLR_BIT(SLEEP_MODE_REG, BIT(0)); /* Tell rom to run light sleep wake stub */ + REG_WRITE(LIGHT_SLEEP_WAKE_STUB_ADDR_REG, (uint32_t)rv_core_critical_regs_restore); + return (*goto_sleep)(wakeup_opt, reject_opt, lslp_mem_inf_fpu, dslp); + } + + return ESP_OK; +} + +esp_err_t IRAM_ATTR esp_sleep_cpu_retention(uint32_t (*goto_sleep)(uint32_t, uint32_t, uint32_t, bool), + uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu, bool dslp) +{ + uint32_t mstatus = save_mstatus_and_disable_global_int(); + + /* wait cache idle */ + Cache_Freeze_ICache_Enable(CACHE_FREEZE_ACK_BUSY); + Cache_Freeze_ICache_Disable(); + + cpu_domain_dev_regs_save(s_cpu_retention.retent.plic_frame); + cpu_domain_dev_regs_save(s_cpu_retention.retent.clint_frame); + cpu_domain_dev_regs_save(s_cpu_retention.retent.intpri_frame); + cpu_domain_dev_regs_save(s_cpu_retention.retent.cache_config_frame); + RvCoreNonCriticalSleepFrame *frame = rv_core_noncritical_regs_save(); + + esp_err_t err = do_cpu_retention(goto_sleep, wakeup_opt, reject_opt, lslp_mem_inf_fpu, dslp); + + rv_core_noncritical_regs_restore(frame); + cpu_domain_dev_regs_restore(s_cpu_retention.retent.cache_config_frame); + cpu_domain_dev_regs_restore(s_cpu_retention.retent.intpri_frame); + cpu_domain_dev_regs_restore(s_cpu_retention.retent.clint_frame); + cpu_domain_dev_regs_restore(s_cpu_retention.retent.plic_frame); + + restore_mstatus(mstatus); + return err; +} + +#endif // SOC_PM_SUPPORT_CPU_PD && SOC_PM_CPU_RETENTION_BY_SW + + +#if SOC_PM_SUPPORT_CPU_PD + +esp_err_t esp_sleep_cpu_retention_init(void) +{ + esp_err_t err = ESP_OK; +#if SOC_PM_CPU_RETENTION_BY_RTCCNTL + err = esp_sleep_cpu_pd_low_init(); +#elif SOC_PM_CPU_RETENTION_BY_SW + err = esp_sleep_cpu_retention_init_impl(); +#endif + return err; +} + +esp_err_t esp_sleep_cpu_retention_deinit(void) +{ + esp_err_t err = ESP_OK; +#if SOC_PM_CPU_RETENTION_BY_RTCCNTL + err = esp_sleep_cpu_pd_low_deinit(); +#elif SOC_PM_CPU_RETENTION_BY_SW + err = esp_sleep_cpu_retention_deinit_impl(); +#endif + return err; +} + +bool cpu_domain_pd_allowed(void) +{ +#if SOC_PM_CPU_RETENTION_BY_RTCCNTL + return (s_cpu_retention.retent.cpu_pd_mem != NULL); +#elif SOC_PM_CPU_RETENTION_BY_SW + return (s_cpu_retention.retent.critical_frame != NULL) && \ + (s_cpu_retention.retent.non_critical_frame != NULL) && \ + (s_cpu_retention.retent.intpri_frame != NULL) && \ + (s_cpu_retention.retent.cache_config_frame != NULL) && \ + (s_cpu_retention.retent.plic_frame != NULL) && \ + (s_cpu_retention.retent.clint_frame != NULL); +#else + return false; +#endif +} + +#endif diff --git a/components/esp_hw_support/sleep_cpu_asm.S b/components/esp_hw_support/sleep_cpu_asm.S new file mode 100644 index 0000000000..c62756d889 --- /dev/null +++ b/components/esp_hw_support/sleep_cpu_asm.S @@ -0,0 +1,239 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/soc.h" +#include "riscv/rvsleep-frames.h" +#include "soc/soc_caps.h" +#include "sdkconfig.h" + +#if !CONFIG_IDF_TARGET_ESP32C6 +#include "soc/lp_aon_reg.h" +#include "soc/extmem_reg.h" +#endif + + .section .data1,"aw" + .global rv_core_critical_regs_frame + .type rv_core_critical_regs_frame,@object + .align 4 +rv_core_critical_regs_frame: + .word 0 + +/* +-------------------------------------------------------------------------------- + This assembly subroutine is used to save the critical registers of the CPU + core to the internal RAM before sleep, and modify the PMU control flag to + indicate that the system needs to sleep. When the subroutine returns, it + will return the memory pointer that saves the context information of the CPU + critical registers. +-------------------------------------------------------------------------------- +*/ + + .section .iram1,"ax" + .global rv_core_critical_regs_save + .type rv_core_critical_regs_save,@function + .align 4 + +rv_core_critical_regs_save: + + /* arrived here in critical section. we need: + save riscv core critical registers to RvCoreCriticalSleepFrame + */ + csrw mscratch, t0 /* use mscratch as temp storage */ + la t0, rv_core_critical_regs_frame + lw t0, 0(t0) /* t0 pointer to RvCoreCriticalSleepFrame object */ + + sw ra, RV_SLP_CTX_RA(t0) + sw sp, RV_SLP_CTX_SP(t0) + sw gp, RV_SLP_CTX_GP(t0) + sw tp, RV_SLP_CTX_TP(t0) + sw t1, RV_SLP_CTX_T1(t0) + sw t2, RV_SLP_CTX_T2(t0) + sw s0, RV_SLP_CTX_S0(t0) + sw s1, RV_SLP_CTX_S1(t0) + sw a0, RV_SLP_CTX_A0(t0) + + /* !! WARNING, do not use the a0 register below, a0 carries important sleep + * information and will be returned as the return value !! */ + mv a0, t0 + + sw a1, RV_SLP_CTX_A1(t0) + sw a2, RV_SLP_CTX_A2(t0) + sw a3, RV_SLP_CTX_A3(t0) + sw a4, RV_SLP_CTX_A4(t0) + sw a5, RV_SLP_CTX_A5(t0) + sw a6, RV_SLP_CTX_A6(t0) + sw a7, RV_SLP_CTX_A7(t0) + sw s2, RV_SLP_CTX_S2(t0) + sw s3, RV_SLP_CTX_S3(t0) + sw s4, RV_SLP_CTX_S4(t0) + sw s5, RV_SLP_CTX_S5(t0) + sw s6, RV_SLP_CTX_S6(t0) + sw s7, RV_SLP_CTX_S7(t0) + sw s8, RV_SLP_CTX_S8(t0) + sw s9, RV_SLP_CTX_S9(t0) + sw s10, RV_SLP_CTX_S10(t0) + sw s11, RV_SLP_CTX_S11(t0) + sw t3, RV_SLP_CTX_T3(t0) + sw t4, RV_SLP_CTX_T4(t0) + sw t5, RV_SLP_CTX_T5(t0) + sw t6, RV_SLP_CTX_T6(t0) + + csrr t1, mstatus + sw t1, RV_SLP_CTX_MSTATUS(t0) + csrr t2, mtvec + sw t2, RV_SLP_CTX_MTVEC(t0) + csrr t3, mcause + sw t3, RV_SLP_CTX_MCAUSE(t0) + + csrr t1, mtval + sw t1, RV_SLP_CTX_MTVAL(t0) + csrr t2, mie + sw t2, RV_SLP_CTX_MIE(t0) + csrr t3, mip + sw t3, RV_SLP_CTX_MIP(t0) + csrr t1, mepc + sw t1, RV_SLP_CTX_MEPC(t0) + + /* + !!! Let idf knows it's going to sleep !!! + + RV_SLP_STK_PMUFUNC field is used to identify whether it is going to sleep or + has just been awakened. We use the lowest 2 bits as indication information, + 3 means being awakened, 1 means going to sleep. + */ + li t1, ~0x3 + lw t2, RV_SLP_CTX_PMUFUNC(t0) + and t2, t1, t2 + ori t2, t2, 0x1 + sw t2, RV_SLP_CTX_PMUFUNC(t0) + + mv t3, t0 + csrr t0, mscratch + sw t0, RV_SLP_CTX_T0(t3) + +#if !CONFIG_IDF_TARGET_ESP32C6 + /* writeback dcache is required here!!! */ + la t0, EXTMEM_CACHE_SYNC_MAP_REG + li t1, 0x10 + sw t1, 0x0(t0) /* set EXTMEM_CACHE_SYNC_MAP_REG bit 4 */ + la t2, EXTMEM_CACHE_SYNC_ADDR_REG + sw zero, 0x0(t2) /* clear EXTMEM_CACHE_SYNC_ADDR_REG */ + la t0, EXTMEM_CACHE_SYNC_SIZE_REG + sw zero, 0x0(t0) /* clear EXTMEM_CACHE_SYNC_SIZE_REG */ + + la t1, EXTMEM_CACHE_SYNC_CTRL_REG + lw t2, 0x0(t1) + ori t2, t2, 0x4 + sw t2, 0x0(t1) + + li t0, 0x10 /* SYNC_DONE bit */ +wait_sync_done: + lw t2, 0x0(t1) + and t2, t0, t2 + beqz t2, wait_sync_done +#endif + + lw t0, RV_SLP_CTX_T0(t3) + lw t1, RV_SLP_CTX_T1(t3) + lw t2, RV_SLP_CTX_T2(t3) + lw t3, RV_SLP_CTX_T3(t3) + + ret + + .size rv_core_critical_regs_save, . - rv_core_critical_regs_save + + +#define CSR_PCER_U 0x800 +#define CSR_PCMR_U 0x801 +#define PCER_CYCLES (1<<0) /* count clock cycles */ +#define PCMR_GLOBAL_EN (1<<0) /* enable count */ +#define pcer CSR_PCER_U +#define pcmr CSR_PCMR_U + +/* +-------------------------------------------------------------------------------- + This assembly subroutine is used to restore the CPU core critical register + context before sleep after system wakes up, modify the PMU control + information, and return the critical register context memory object pointer. + After the subroutine returns, continue to restore other modules of the + system. +-------------------------------------------------------------------------------- +*/ + + .section .iram1,"ax" + .global rv_core_critical_regs_restore + .type rv_core_critical_regs_restore,@function + .align 4 + +rv_core_critical_regs_restore: + + la t0, rv_core_critical_regs_frame + lw t0, 0(t0) /* t0 pointer to RvCoreCriticalSleepFrame object */ + beqz t0, .skip_restore /* make sure we do not jump to zero address */ + + /* + !!! Let idf knows it's sleep awake. !!! + + RV_SLP_STK_PMUFUNC field is used to identify whether it is going to sleep or + has just been awakened. We use the lowest 2 bits as indication information, + 3 means being awakened, 1 means going to sleep. + */ + lw t1, RV_SLP_CTX_PMUFUNC(t0) + ori t1, t1, 0x3 + sw t1, RV_SLP_CTX_PMUFUNC(t0) + + lw t2, RV_SLP_CTX_MEPC(t0) + csrw mepc, t2 + lw t3, RV_SLP_CTX_MIP(t0) + csrw mip, t3 + lw t1, RV_SLP_CTX_MIE(t0) + csrw mie, t1 + lw t2, RV_SLP_CTX_MSTATUS(t0) + csrw mstatus, t2 + + lw t3, RV_SLP_CTX_MTVEC(t0) + csrw mtvec, t3 + lw t1, RV_SLP_CTX_MCAUSE(t0) + csrw mcause, t1 + lw t2, RV_SLP_CTX_MTVAL(t0) + csrw mtval, t2 + + lw t6, RV_SLP_CTX_T6(t0) + lw t5, RV_SLP_CTX_T5(t0) + lw t4, RV_SLP_CTX_T4(t0) + lw t3, RV_SLP_CTX_T3(t0) + lw s11, RV_SLP_CTX_S11(t0) + lw s10, RV_SLP_CTX_S10(t0) + lw s9, RV_SLP_CTX_S9(t0) + lw s8, RV_SLP_CTX_S8(t0) + lw s7, RV_SLP_CTX_S7(t0) + lw s6, RV_SLP_CTX_S6(t0) + lw s5, RV_SLP_CTX_S5(t0) + lw s4, RV_SLP_CTX_S4(t0) + lw s3, RV_SLP_CTX_S3(t0) + lw s2, RV_SLP_CTX_S2(t0) + lw a7, RV_SLP_CTX_A7(t0) + lw a6, RV_SLP_CTX_A6(t0) + lw a5, RV_SLP_CTX_A5(t0) + lw a4, RV_SLP_CTX_A4(t0) + lw a3, RV_SLP_CTX_A3(t0) + lw a2, RV_SLP_CTX_A2(t0) + lw a1, RV_SLP_CTX_A1(t0) + lw a0, RV_SLP_CTX_A0(t0) + lw s1, RV_SLP_CTX_S1(t0) + lw s0, RV_SLP_CTX_S0(t0) + lw t2, RV_SLP_CTX_T2(t0) + lw t1, RV_SLP_CTX_T1(t0) + lw tp, RV_SLP_CTX_TP(t0) + lw gp, RV_SLP_CTX_GP(t0) + lw sp, RV_SLP_CTX_SP(t0) + lw ra, RV_SLP_CTX_RA(t0) + lw t0, RV_SLP_CTX_T0(t0) + +.skip_restore: + ret + + .size rv_core_critical_regs_restore, . - rv_core_critical_regs_restore diff --git a/components/esp_hw_support/sleep_gpio.c b/components/esp_hw_support/sleep_gpio.c index 87c2903814..df3b8801fd 100644 --- a/components/esp_hw_support/sleep_gpio.c +++ b/components/esp_hw_support/sleep_gpio.c @@ -20,10 +20,15 @@ #include "driver/gpio.h" #include "hal/gpio_hal.h" #include "hal/rtc_io_hal.h" + +#if !SOC_PMU_SUPPORTED #include "hal/rtc_hal.h" +#endif + #include "esp_private/gpio.h" #include "esp_private/sleep_gpio.h" #include "esp_private/spi_flash_os.h" +#include "esp_private/startup_internal.h" #include "bootloader_flash.h" static const char *TAG = "sleep"; @@ -180,3 +185,15 @@ void esp_deep_sleep_wakeup_io_reset(void) } #endif } + +#if CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND && !CONFIG_PM_SLP_DISABLE_GPIO +ESP_SYSTEM_INIT_FN(esp_sleep_startup_init, BIT(0), 105) +{ + // Configure to isolate (disable the Input/Output/Pullup/Pulldown + // function of the pin) all GPIO pins in sleep state + esp_sleep_config_gpio_isolate(); + // Enable automatic switching of GPIO configuration + esp_sleep_enable_gpio_switch(true); + return ESP_OK; +} +#endif diff --git a/components/esp_hw_support/sleep_modes.c b/components/esp_hw_support/sleep_modes.c index 22646afa9f..61e8b6084b 100644 --- a/components/esp_hw_support/sleep_modes.c +++ b/components/esp_hw_support/sleep_modes.c @@ -24,7 +24,11 @@ #include "soc/soc_caps.h" #include "driver/rtc_io.h" #include "hal/rtc_io_hal.h" + +#if !SOC_PMU_SUPPORTED #include "hal/rtc_cntl_ll.h" +#include "hal/rtc_hal.h" +#endif #include "driver/uart.h" @@ -33,7 +37,6 @@ #include "regi2c_ctrl.h" //For `REGI2C_ANA_CALI_PD_WORKAROUND`, temp #include "hal/wdt_hal.h" -#include "hal/rtc_hal.h" #include "hal/uart_hal.h" #if SOC_TOUCH_SENSOR_SUPPORTED #include "hal/touch_sensor_hal.h" @@ -46,9 +49,8 @@ #include "esp_rom_uart.h" #include "esp_rom_sys.h" #include "esp_private/brownout.h" -#include "esp_private/sleep_retention.h" +#include "esp_private/sleep_cpu.h" #include "esp_private/esp_clk.h" -#include "esp_private/startup_internal.h" #include "esp_private/esp_task_wdt.h" #ifdef CONFIG_IDF_TARGET_ESP32 @@ -72,6 +74,8 @@ #include "esp32c2/rom/rtc.h" #elif CONFIG_IDF_TARGET_ESP32C6 #include "esp32c6/rom/rtc.h" +#include "hal/lp_timer_hal.h" +#include "esp_private/esp_pmu.h" #elif CONFIG_IDF_TARGET_ESP32H2 #include "esp32h2/rom/rtc.h" #include "esp32h2/rom/cache.h" @@ -87,6 +91,7 @@ // Cycles for RTC Timer clock source (internal oscillator) calibrate #define RTC_CLK_SRC_CAL_CYCLES (10) +#define FAST_CLK_SRC_CAL_CYCLES (2000) /* ~ 127.4 us */ #ifdef CONFIG_IDF_TARGET_ESP32 #define DEFAULT_SLEEP_OUT_OVERHEAD_US (212) @@ -107,8 +112,8 @@ #define DEFAULT_SLEEP_OUT_OVERHEAD_US (118) #define DEFAULT_HARDWARE_OUT_OVERHEAD_US (9) #elif CONFIG_IDF_TARGET_ESP32C6 -#define DEFAULT_SLEEP_OUT_OVERHEAD_US (118)// TODO: IDF-5348 -#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (9) +#define DEFAULT_SLEEP_OUT_OVERHEAD_US (318) +#define DEFAULT_HARDWARE_OUT_OVERHEAD_US (56) #elif CONFIG_IDF_TARGET_ESP32H2 #define DEFAULT_SLEEP_OUT_OVERHEAD_US (118)// TODO: IDF-6267 #define DEFAULT_HARDWARE_OUT_OVERHEAD_US (9) @@ -141,7 +146,12 @@ extern void periph_inform_out_light_sleep_overhead(uint32_t out_light_sleep_time * Internal structure which holds all requested deep sleep parameters */ typedef struct { - esp_sleep_pd_option_t pd_options[ESP_PD_DOMAIN_MAX]; + struct { + esp_sleep_pd_option_t pd_option; + int16_t refs; + uint16_t reserved; /* reserved for 4 bytes aligned */ + } domain[ESP_PD_DOMAIN_MAX]; + portMUX_TYPE lock; uint64_t sleep_duration; uint32_t wakeup_triggers : 15; uint32_t ext1_trigger_mode : 1; @@ -154,6 +164,7 @@ typedef struct { uint32_t ccount_ticks_record; uint32_t sleep_time_overhead_out; uint32_t rtc_clk_cal_period; + uint32_t fast_clk_cal_period; uint64_t rtc_ticks_at_sleep_start; } sleep_config_t; @@ -161,7 +172,13 @@ typedef struct { _Static_assert(22 >= SOC_RTCIO_PIN_COUNT, "Chip has more RTCIOs than 22, should increase ext1_rtc_gpio_mask field size"); static sleep_config_t s_config = { - .pd_options = {[0 ... ESP_PD_DOMAIN_MAX - 1] = ESP_PD_OPTION_AUTO,}, + .domain = { + [0 ... ESP_PD_DOMAIN_MAX - 1] = { + .pd_option = ESP_PD_OPTION_AUTO, + .refs = 0 + } + }, + .lock = portMUX_INITIALIZER_UNLOCKED, .ccount_ticks_record = 0, .sleep_time_overhead_out = DEFAULT_SLEEP_OUT_OVERHEAD_US, .wakeup_triggers = 0 @@ -169,9 +186,7 @@ static sleep_config_t s_config = { /* Internal variable used to track if light sleep wakeup sources are to be expected when determining wakeup cause. */ -#if !CONFIG_IDF_TARGET_ESP32C6 // TODO: WIFI-5150 static bool s_light_sleep_wakeup = false; -#endif /* Updating RTC_MEMORY_CRC_REG register via set_rtc_memory_crc() is not thread-safe, so we need to disable interrupts before going to deep sleep. */ @@ -194,13 +209,11 @@ static uint32_t get_power_down_flags(void); static void ext0_wakeup_prepare(void); static void ext1_wakeup_prepare(void); #endif -#if !CONFIG_IDF_TARGET_ESP32C6 // TODO: WIFI-5150 static void timer_wakeup_prepare(void); -#endif #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 static void touch_wakeup_prepare(void); #endif -#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP && !CONFIG_IDF_TARGET_ESP32C6 // TODO: WIFI-5150 +#if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP static void gpio_deep_sleep_wakeup_prepare(void); #endif @@ -292,7 +305,6 @@ void esp_deep_sleep(uint64_t time_in_us) } // [refactor-todo] provide target logic for body of uart functions below -#if !CONFIG_IDF_TARGET_ESP32C6 // TODO: WIFI-5150 static void IRAM_ATTR flush_uarts(void) { for (int i = 0; i < SOC_UART_NUM; ++i) { @@ -337,7 +349,6 @@ static void IRAM_ATTR resume_uarts(void) uart_ll_force_xon(i); } } -#endif /** * These save-restore workaround should be moved to lower layer @@ -350,8 +361,8 @@ inline static void IRAM_ATTR misc_modules_sleep_prepare(void) #if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL gpio_sleep_mode_config_apply(); #endif -#if SOC_PM_SUPPORT_CPU_PD || SOC_PM_SUPPORT_TAGMEM_PD - sleep_enable_memory_retention(); +#if SOC_PM_SUPPORT_CPU_PD && SOC_PM_CPU_RETENTION_BY_RTCCNTL + sleep_enable_cpu_retention(); #endif #if REGI2C_ANA_CALI_PD_WORKAROUND regi2c_analog_cali_reg_read(); @@ -363,8 +374,8 @@ inline static void IRAM_ATTR misc_modules_sleep_prepare(void) */ inline static void IRAM_ATTR misc_modules_wake_prepare(void) { -#if SOC_PM_SUPPORT_CPU_PD || SOC_PM_SUPPORT_TAGMEM_PD - sleep_disable_memory_retention(); +#if SOC_PM_SUPPORT_CPU_PD && SOC_PM_CPU_RETENTION_BY_RTCCNTL + sleep_disable_cpu_retention(); #endif #if CONFIG_GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL gpio_sleep_mode_config_unapply(); @@ -377,7 +388,7 @@ inline static void IRAM_ATTR misc_modules_wake_prepare(void) #endif } -inline static uint32_t call_rtc_sleep_start(uint32_t reject_triggers, uint32_t lslp_mem_inf_fpu); +inline static uint32_t call_rtc_sleep_start(uint32_t reject_triggers, uint32_t lslp_mem_inf_fpu, bool dslp); inline static bool is_light_sleep(uint32_t pd_flags) { @@ -386,9 +397,6 @@ inline static bool is_light_sleep(uint32_t pd_flags) static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) { -#if CONFIG_IDF_TARGET_ESP32C6 - return 0; // TODO: WIFI-5150 -#else // Stop UART output so that output is not lost due to APB frequency change. // For light sleep, suspend UART output — it will resume after wakeup. // For deep sleep, wait for the contents of UART FIFO to be sent. @@ -492,6 +500,12 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) } // Enter sleep +#if SOC_PMU_SUPPORTED + pmu_sleep_config_t config; + pmu_sleep_init(pmu_sleep_config_default(&config, pd_flags, s_config.sleep_time_adjustment, + s_config.rtc_clk_cal_period, s_config.fast_clk_cal_period, + deep_sleep), deep_sleep); +#else rtc_sleep_config_t config; rtc_sleep_get_default_config(sleep_flags, &config); rtc_sleep_init(config); @@ -500,6 +514,7 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) if (!deep_sleep) { rtc_sleep_low_init(s_config.rtc_clk_cal_period); } +#endif // Configure timer wakeup if (s_config.wakeup_triggers & RTC_TIMER_TRIG_EN) { @@ -513,6 +528,8 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) esp_sleep_isolate_digital_gpio(); #endif +#if !CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5349 + #if SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY extern char _rtc_text_start[]; #if CONFIG_ESP32S3_RTCDATA_IN_FAST_MEM @@ -523,7 +540,7 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) size_t rtc_fast_length = (size_t)_rtc_force_fast_end - (size_t)_rtc_text_start; #endif esp_rom_set_rtc_wake_addr((esp_rom_wake_func_t)esp_wake_stub_entry, rtc_fast_length); - result = call_rtc_sleep_start(reject_triggers, config.lslp_mem_inf_fpu); + result = call_rtc_sleep_start(reject_triggers, config.lslp_mem_inf_fpu, 0); #else #if !CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP /* If not possible stack is in RTC FAST memory, use the ROM function to calculate the CRC and save ~140 bytes IRAM */ @@ -531,14 +548,26 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) // RTC has no rtc memory, IDF-3901 set_rtc_memory_crc(); #endif - result = call_rtc_sleep_start(reject_triggers, config.lslp_mem_inf_fpu); + result = call_rtc_sleep_start(reject_triggers, config.lslp_mem_inf_fpu, 0); #else /* Otherwise, need to call the dedicated soc function for this */ result = rtc_deep_sleep_start(s_config.wakeup_triggers, reject_triggers); #endif #endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY + +#else + result = ESP_OK; +#endif } else { - result = call_rtc_sleep_start(reject_triggers, config.lslp_mem_inf_fpu); +#if SOC_PM_CPU_RETENTION_BY_SW + if (pd_flags & PMU_SLEEP_PD_CPU) { + result = esp_sleep_cpu_retention(pmu_sleep_start, s_config.wakeup_triggers, reject_triggers, config.power.hp_sys.dig_power.mem_dslp, deep_sleep); + } else { + result = call_rtc_sleep_start(reject_triggers, config.power.hp_sys.dig_power.mem_dslp, deep_sleep); + } +#else + result = call_rtc_sleep_start(reject_triggers, config.lslp_mem_inf_fpu, 0); +#endif } // Restore CPU frequency @@ -553,13 +582,14 @@ static uint32_t IRAM_ATTR esp_sleep_start(uint32_t pd_flags) resume_uarts(); return result; -#endif } -inline static uint32_t IRAM_ATTR call_rtc_sleep_start(uint32_t reject_triggers, uint32_t lslp_mem_inf_fpu) +inline static uint32_t IRAM_ATTR call_rtc_sleep_start(uint32_t reject_triggers, uint32_t lslp_mem_inf_fpu, bool dslp) { #ifdef CONFIG_IDF_TARGET_ESP32 return rtc_sleep_start(s_config.wakeup_triggers, reject_triggers); +#elif SOC_PMU_SUPPORTED + return pmu_sleep_start(s_config.wakeup_triggers, reject_triggers, lslp_mem_inf_fpu, dslp); #else return rtc_sleep_start(s_config.wakeup_triggers, reject_triggers, lslp_mem_inf_fpu); #endif @@ -624,26 +654,23 @@ void IRAM_ATTR esp_deep_sleep_start(void) * Helper function which handles entry to and exit from light sleep * Placed into IRAM as flash may need some time to be powered on. */ -#if !CONFIG_IDF_TARGET_ESP32C6 // TODO: WIFI-5150 static esp_err_t esp_light_sleep_inner(uint32_t pd_flags, - uint32_t flash_enable_time_us, - rtc_vddsdio_config_t vddsdio_config) IRAM_ATTR __attribute__((noinline)); + uint32_t flash_enable_time_us) IRAM_ATTR __attribute__((noinline)); static esp_err_t esp_light_sleep_inner(uint32_t pd_flags, - uint32_t flash_enable_time_us, - rtc_vddsdio_config_t vddsdio_config) + uint32_t flash_enable_time_us) { -#if CONFIG_IDF_TARGET_ESP32C6 - return ESP_ERR_NOT_SUPPORTED; // TODO: WIFI-5150 -#else // Enter sleep uint32_t reject = esp_sleep_start(pd_flags); +#if SOC_CONFIGURABLE_VDDSDIO_SUPPORTED + rtc_vddsdio_config_t vddsdio_config = rtc_vddsdio_get_config(); // If VDDSDIO regulator was controlled by RTC registers before sleep, // restore the configuration. if (vddsdio_config.force) { rtc_vddsdio_set_config(vddsdio_config); } +#endif // If SPI flash was powered down, wait for it to become ready if (pd_flags & RTC_SLEEP_PD_VDDSDIO) { @@ -652,9 +679,7 @@ static esp_err_t esp_light_sleep_inner(uint32_t pd_flags, } return reject ? ESP_ERR_SLEEP_REJECT : ESP_OK; -#endif } -#endif /** * vddsdio is used for power supply of spi flash @@ -665,18 +690,16 @@ static esp_err_t esp_light_sleep_inner(uint32_t pd_flags, * x | 1 | pd flash with relaxed conditions(force_pd) * 1 | 0 | pd flash with strict conditions(safe_pd) */ -static inline bool can_power_down_vddsdio(const uint32_t vddsdio_pd_sleep_duration) +static inline bool can_power_down_vddsdio(uint32_t pd_flags, const uint32_t vddsdio_pd_sleep_duration) { bool force_pd = !(s_config.wakeup_triggers & RTC_TIMER_TRIG_EN) || (s_config.sleep_duration > vddsdio_pd_sleep_duration); bool safe_pd = (s_config.wakeup_triggers == RTC_TIMER_TRIG_EN) && (s_config.sleep_duration > vddsdio_pd_sleep_duration); - return (s_config.pd_options[ESP_PD_DOMAIN_VDDSDIO] == ESP_PD_OPTION_OFF) ? force_pd : safe_pd; + return (pd_flags & RTC_SLEEP_PD_VDDSDIO) ? force_pd : safe_pd; } esp_err_t esp_light_sleep_start(void) { -#if CONFIG_IDF_TARGET_ESP32C6 - return ESP_ERR_NOT_SUPPORTED; // TODO: WIFI-5150 -#else + s_config.ccount_ticks_record = esp_cpu_get_cycle_count(); #if CONFIG_ESP_TASK_WDT_USE_ESP_TIMER esp_err_t timerret = ESP_OK; @@ -684,9 +707,7 @@ esp_err_t esp_light_sleep_start(void) timerret = esp_task_wdt_stop(); #endif // CONFIG_ESP_TASK_WDT_USE_ESP_TIMER - s_config.ccount_ticks_record = esp_cpu_get_cycle_count(); - static portMUX_TYPE light_sleep_lock = portMUX_INITIALIZER_UNLOCKED; - portENTER_CRITICAL(&light_sleep_lock); + portENTER_CRITICAL(&s_config.lock); /* Note: We are about to stall the other CPU via the esp_ipc_isr_stall_other_cpu(). However, there is a chance of deadlock if after stalling the other CPU, we attempt to take spinlocks already held by the other CPU that is. @@ -710,7 +731,11 @@ esp_err_t esp_light_sleep_start(void) */ esp_clk_private_lock(); +#if SOC_LP_TIMER_SUPPORTED + s_config.rtc_ticks_at_sleep_start = lp_timer_hal_get_cycle_count(0); +#else s_config.rtc_ticks_at_sleep_start = rtc_time_get(); +#endif uint32_t ccount_at_sleep_start = esp_cpu_get_cycle_count(); uint64_t high_res_time_at_start = esp_timer_get_time(); uint32_t sleep_time_overhead_in = (ccount_at_sleep_start - s_config.ccount_ticks_record) / (esp_clk_cpu_freq() / 1000000ULL); @@ -751,9 +776,16 @@ esp_err_t esp_light_sleep_start(void) * 4. Code execution time which can be measured; */ +#if SOC_PMU_SUPPORTED + s_config.fast_clk_cal_period = rtc_clk_cal(RTC_CAL_RC_FAST, FAST_CLK_SRC_CAL_CYCLES); + int sleep_time_sw_adjustment = LIGHT_SLEEP_TIME_OVERHEAD_US + sleep_time_overhead_in + s_config.sleep_time_overhead_out; + int sleep_time_hw_adjustment = pmu_sleep_calculate_hw_wait_time(pd_flags, s_config.rtc_clk_cal_period, s_config.fast_clk_cal_period); + s_config.sleep_time_adjustment = sleep_time_sw_adjustment + sleep_time_hw_adjustment; +#else uint32_t rtc_cntl_xtl_buf_wait_slp_cycles = rtc_time_us_to_slowclk(RTC_CNTL_XTL_BUF_WAIT_SLP_US, s_config.rtc_clk_cal_period); s_config.sleep_time_adjustment = LIGHT_SLEEP_TIME_OVERHEAD_US + sleep_time_overhead_in + s_config.sleep_time_overhead_out + rtc_time_slowclk_to_us(rtc_cntl_xtl_buf_wait_slp_cycles + RTC_CNTL_CK8M_WAIT_SLP_CYCLES + RTC_CNTL_WAKEUP_DELAY_CYCLES, s_config.rtc_clk_cal_period); +#endif // Decide if VDD_SDIO needs to be powered down; // If it needs to be powered down, adjust sleep time. @@ -781,7 +813,7 @@ esp_err_t esp_light_sleep_start(void) flash_enable_time_us + LIGHT_SLEEP_MIN_TIME_US + s_config.sleep_time_adjustment + rtc_time_slowclk_to_us(RTC_MODULE_SLEEP_PREPARE_CYCLES, s_config.rtc_clk_cal_period)); - if (can_power_down_vddsdio(vddsdio_pd_sleep_duration)) { + if (can_power_down_vddsdio(pd_flags, vddsdio_pd_sleep_duration)) { if (s_config.sleep_time_overhead_out < flash_enable_time_us) { s_config.sleep_time_adjustment += flash_enable_time_us; } @@ -799,8 +831,6 @@ esp_err_t esp_light_sleep_start(void) periph_inform_out_light_sleep_overhead(s_config.sleep_time_adjustment - sleep_time_overhead_in); - rtc_vddsdio_config_t vddsdio_config = rtc_vddsdio_get_config(); - // Safety net: enable WDT in case exit from light sleep fails #if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-5653 wdt_hal_context_t rtc_wdt_ctx = {.inst = WDT_RWDT, .rwdt_dev = &LP_WDT}; @@ -829,14 +859,18 @@ esp_err_t esp_light_sleep_start(void) err = ESP_ERR_SLEEP_TOO_SHORT_SLEEP_DURATION; } else { // Enter sleep, then wait for flash to be ready on wakeup - err = esp_light_sleep_inner(pd_flags, flash_enable_time_us, vddsdio_config); + err = esp_light_sleep_inner(pd_flags, flash_enable_time_us); } // light sleep wakeup flag only makes sense after a successful light sleep s_light_sleep_wakeup = (err == ESP_OK); // System timer has been stopped for the duration of the sleep, correct for that. +#if SOC_LP_TIMER_SUPPORTED + uint64_t rtc_ticks_at_end = lp_timer_hal_get_cycle_count(0); +#else uint64_t rtc_ticks_at_end = rtc_time_get(); +#endif uint64_t rtc_time_diff = rtc_time_slowclk_to_us(rtc_ticks_at_end - s_config.rtc_ticks_at_sleep_start, s_config.rtc_clk_cal_period); /** @@ -856,8 +890,7 @@ esp_err_t esp_light_sleep_start(void) wdt_hal_disable(&rtc_wdt_ctx); wdt_hal_write_protect_enable(&rtc_wdt_ctx); } - portEXIT_CRITICAL(&light_sleep_lock); - s_config.sleep_time_overhead_out = (esp_cpu_get_cycle_count() - s_config.ccount_ticks_record) / (esp_clk_cpu_freq() / 1000000ULL); + portEXIT_CRITICAL(&s_config.lock); #if CONFIG_ESP_TASK_WDT_USE_ESP_TIMER /* Restart the Task Watchdog timer as it was stopped before sleeping. */ @@ -866,8 +899,8 @@ esp_err_t esp_light_sleep_start(void) } #endif // CONFIG_ESP_TASK_WDT_USE_ESP_TIMER + s_config.sleep_time_overhead_out = (esp_cpu_get_cycle_count() - s_config.ccount_ticks_record) / (esp_clk_cpu_freq() / 1000000ULL); return err; -#endif } esp_err_t esp_sleep_disable_wakeup_source(esp_sleep_source_t source) @@ -945,7 +978,6 @@ esp_err_t esp_sleep_enable_timer_wakeup(uint64_t time_in_us) return ESP_OK; } -#if !CONFIG_IDF_TARGET_ESP32C6 // TODO: WIFI-5150 static void timer_wakeup_prepare(void) { int64_t sleep_duration = (int64_t) s_config.sleep_duration - (int64_t) s_config.sleep_time_adjustment; @@ -954,9 +986,13 @@ static void timer_wakeup_prepare(void) } int64_t ticks = rtc_time_us_to_slowclk(sleep_duration, s_config.rtc_clk_cal_period); + +#if SOC_LP_TIMER_SUPPORTED + lp_timer_hal_set_alarm_target(0, s_config.rtc_ticks_at_sleep_start + ticks); +#else rtc_hal_set_wakeup_timer(s_config.rtc_ticks_at_sleep_start + ticks); -} #endif +} #if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3 /* In deep sleep mode, only the sleep channel is supported, and other touch channels should be turned off. */ @@ -1092,7 +1128,7 @@ static void ext1_wakeup_prepare(void) #if SOC_PM_SUPPORT_RTC_PERIPH_PD // Pad configuration depends on RTC_PERIPH state in sleep mode - if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] != ESP_PD_OPTION_ON) { + if (s_config.domain[ESP_PD_DOMAIN_RTC_PERIPH].pd_option != ESP_PD_OPTION_ON) { #if SOC_RTCIO_INPUT_OUTPUT_SUPPORTED // RTC_PERIPH will be powered down, so RTC_IO_ registers will // loose their state. Lock pad configuration. @@ -1139,16 +1175,20 @@ uint64_t esp_sleep_get_ext1_wakeup_status(void) #if SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP uint64_t esp_sleep_get_gpio_wakeup_status(void) { +#if CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5349 + return 0; +#else if (esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_GPIO) { return 0; } return rtc_hal_gpio_get_wakeup_status(); +#endif } -#if !CONFIG_IDF_TARGET_ESP32C6 // TODO: WIFI-5150 static void gpio_deep_sleep_wakeup_prepare(void) { +#if !CONFIG_IDF_TARGET_ESP32C6 // TODO: IDF-5349 for (gpio_num_t gpio_idx = GPIO_NUM_0; gpio_idx < GPIO_NUM_MAX; gpio_idx++) { if (((1ULL << gpio_idx) & s_config.gpio_wakeup_mask) == 0) { continue; @@ -1164,8 +1204,8 @@ static void gpio_deep_sleep_wakeup_prepare(void) } // Clear state from previous wakeup rtc_hal_gpio_clear_wakeup_status(); -} #endif +} esp_err_t esp_deep_sleep_enable_gpio_wakeup(uint64_t gpio_pin_mask, esp_deepsleep_gpio_wake_up_mode_t mode) { @@ -1265,14 +1305,18 @@ esp_err_t esp_sleep_disable_bt_wakeup(void) esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause(void) { -#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-5645 +#if CONFIG_IDF_TARGET_ESP32H2 // TODO: IDF-5645 return ESP_SLEEP_WAKEUP_UNDEFINED; #else if (esp_rom_get_reset_reason(0) != RESET_REASON_CORE_DEEP_SLEEP && !s_light_sleep_wakeup) { return ESP_SLEEP_WAKEUP_UNDEFINED; } +#if SOC_PMU_SUPPORTED + uint32_t wakeup_cause = pmu_ll_hp_get_wakeup_cause(&PMU); +#else uint32_t wakeup_cause = rtc_cntl_ll_get_wakeup_cause(); +#endif if (wakeup_cause & RTC_TIMER_TRIG_EN) { return ESP_SLEEP_WAKEUP_TIMER; @@ -1314,13 +1358,20 @@ esp_sleep_wakeup_cause_t esp_sleep_get_wakeup_cause(void) #endif } -esp_err_t esp_sleep_pd_config(esp_sleep_pd_domain_t domain, - esp_sleep_pd_option_t option) +esp_err_t esp_sleep_pd_config(esp_sleep_pd_domain_t domain, esp_sleep_pd_option_t option) { if (domain >= ESP_PD_DOMAIN_MAX || option > ESP_PD_OPTION_AUTO) { return ESP_ERR_INVALID_ARG; } - s_config.pd_options[domain] = option; + portENTER_CRITICAL_SAFE(&s_config.lock); + int refs = (option == ESP_PD_OPTION_ON) ? s_config.domain[domain].refs++ \ + : (option == ESP_PD_OPTION_OFF) ? --s_config.domain[domain].refs \ + : s_config.domain[domain].refs; + if (refs == 0) { + s_config.domain[domain].pd_option = option; + } + portEXIT_CRITICAL_SAFE(&s_config.lock); + assert(refs >= 0); return ESP_OK; } @@ -1342,9 +1393,9 @@ static uint32_t get_power_down_flags(void) */ volatile size_t rtc_slow_mem_used = (size_t)&_rtc_slow_length; - if ((s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] == ESP_PD_OPTION_AUTO) && + if ((s_config.domain[ESP_PD_DOMAIN_RTC_SLOW_MEM].pd_option == ESP_PD_OPTION_AUTO) && (rtc_slow_mem_used > 0 || (s_config.wakeup_triggers & RTC_ULP_TRIG_EN))) { - s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] = ESP_PD_OPTION_ON; + s_config.domain[ESP_PD_DOMAIN_RTC_SLOW_MEM].pd_option = ESP_PD_OPTION_ON; } #endif @@ -1353,27 +1404,27 @@ static uint32_t get_power_down_flags(void) /* RTC_FAST_MEM is needed for deep sleep stub. If RTC_FAST_MEM is Auto, keep it powered on, so that deep sleep stub can run. In the new chip revision, deep sleep stub will be optional, and this can be changed. */ - if (s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] == ESP_PD_OPTION_AUTO) { - s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] = ESP_PD_OPTION_ON; + if (s_config.domain[ESP_PD_DOMAIN_RTC_FAST_MEM].pd_option == ESP_PD_OPTION_AUTO) { + s_config.domain[ESP_PD_DOMAIN_RTC_FAST_MEM].pd_option = ESP_PD_OPTION_ON; } #else /* If RTC_FAST_MEM is used for heap, force RTC_FAST_MEM to be powered on. */ - s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] = ESP_PD_OPTION_ON; + s_config.domain[ESP_PD_DOMAIN_RTC_FAST_MEM].pd_option = ESP_PD_OPTION_ON; #endif #endif #if SOC_PM_SUPPORT_RTC_PERIPH_PD // RTC_PERIPH is needed for EXT0 wakeup and GPIO wakeup. // If RTC_PERIPH is left auto (EXT0/GPIO aren't enabled), RTC_PERIPH will be powered off by default. - if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] == ESP_PD_OPTION_AUTO) { + if (s_config.domain[ESP_PD_DOMAIN_RTC_PERIPH].pd_option == ESP_PD_OPTION_AUTO) { if (s_config.wakeup_triggers & (RTC_EXT0_TRIG_EN | RTC_GPIO_TRIG_EN)) { - s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] = ESP_PD_OPTION_ON; + s_config.domain[ESP_PD_DOMAIN_RTC_PERIPH].pd_option = ESP_PD_OPTION_ON; } #if CONFIG_IDF_TARGET_ESP32 else if (s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_ULP_TRIG_EN)) { // On ESP32, forcing power up of RTC_PERIPH // prevents ULP timer and touch FSMs from working correctly. - s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] = ESP_PD_OPTION_OFF; + s_config.domain[ESP_PD_DOMAIN_RTC_PERIPH].pd_option = ESP_PD_OPTION_OFF; } #endif //CONFIG_IDF_TARGET_ESP32 } @@ -1381,56 +1432,9 @@ static uint32_t get_power_down_flags(void) #if SOC_PM_SUPPORT_CPU_PD if (!cpu_domain_pd_allowed()) { - s_config.pd_options[ESP_PD_DOMAIN_CPU] = ESP_PD_OPTION_ON; + s_config.domain[ESP_PD_DOMAIN_CPU].pd_option = ESP_PD_OPTION_ON; } #endif - -#ifdef CONFIG_IDF_TARGET_ESP32 - s_config.pd_options[ESP_PD_DOMAIN_XTAL] = ESP_PD_OPTION_OFF; -#endif - - const __attribute__((unused)) char *option_str[] = {"OFF", "ON", "AUTO(OFF)" /* Auto works as OFF */}; - /* This function is called from a critical section, log with ESP_EARLY_LOGD. */ -#if SOC_PM_SUPPORT_RTC_PERIPH_PD - ESP_EARLY_LOGD(TAG, "RTC_PERIPH: %s", option_str[s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH]]); -#endif -#if SOC_PM_SUPPORT_RTC_SLOW_MEM_PD - ESP_EARLY_LOGD(TAG, "RTC_SLOW_MEM: %s", option_str[s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM]]); -#endif -#if SOC_PM_SUPPORT_RTC_FAST_MEM_PD - ESP_EARLY_LOGD(TAG, "RTC_FAST_MEM: %s", option_str[s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM]]); -#endif - - // Prepare flags based on the selected options - uint32_t pd_flags = 0; -#if SOC_PM_SUPPORT_RTC_FAST_MEM_PD - if (s_config.pd_options[ESP_PD_DOMAIN_RTC_FAST_MEM] != ESP_PD_OPTION_ON) { - pd_flags |= RTC_SLEEP_PD_RTC_FAST_MEM; - } -#endif -#if SOC_PM_SUPPORT_RTC_SLOW_MEM_PD - if (s_config.pd_options[ESP_PD_DOMAIN_RTC_SLOW_MEM] != ESP_PD_OPTION_ON) { - pd_flags |= RTC_SLEEP_PD_RTC_SLOW_MEM; - } -#endif -#if SOC_PM_SUPPORT_RTC_PERIPH_PD - if (s_config.pd_options[ESP_PD_DOMAIN_RTC_PERIPH] != ESP_PD_OPTION_ON) { - pd_flags |= RTC_SLEEP_PD_RTC_PERIPH; - } -#endif - -#if SOC_PM_SUPPORT_CPU_PD - if (s_config.pd_options[ESP_PD_DOMAIN_CPU] != ESP_PD_OPTION_ON) { - pd_flags |= RTC_SLEEP_PD_CPU; - } -#endif - if (s_config.pd_options[ESP_PD_DOMAIN_RC_FAST] != ESP_PD_OPTION_ON) { - pd_flags |= RTC_SLEEP_PD_INT_8M; - } - if (s_config.pd_options[ESP_PD_DOMAIN_XTAL] != ESP_PD_OPTION_ON) { - pd_flags |= RTC_SLEEP_PD_XTAL; - } - /** * VDD_SDIO power domain shall be kept on during the light sleep * when CONFIG_ESP_SLEEP_POWER_DOWN_FLASH is not set and off when it is set. @@ -1440,15 +1444,80 @@ static uint32_t get_power_down_flags(void) * In deep sleep mode, the power domain will be turned off, regardless the * value of this field. */ - if (s_config.pd_options[ESP_PD_DOMAIN_VDDSDIO] == ESP_PD_OPTION_AUTO) { +#if SOC_PM_SUPPORT_VDDSDIO_PD + if (s_config.domain[ESP_PD_DOMAIN_VDDSDIO].pd_option == ESP_PD_OPTION_AUTO) { #ifndef CONFIG_ESP_SLEEP_POWER_DOWN_FLASH - s_config.pd_options[ESP_PD_DOMAIN_VDDSDIO] = ESP_PD_OPTION_ON; + s_config.domain[ESP_PD_DOMAIN_VDDSDIO].pd_option = ESP_PD_OPTION_ON; #endif } +#endif - if (s_config.pd_options[ESP_PD_DOMAIN_VDDSDIO] != ESP_PD_OPTION_ON) { +#if SOC_PM_SUPPORT_XTAL_PD +#ifdef CONFIG_IDF_TARGET_ESP32 + s_config.domain[ESP_PD_DOMAIN_XTAL].pd_option = ESP_PD_OPTION_OFF; +#endif +#endif + + const __attribute__((unused)) char *option_str[] = {"OFF", "ON", "AUTO(OFF)" /* Auto works as OFF */}; + /* This function is called from a critical section, log with ESP_EARLY_LOGD. */ +#if SOC_PM_SUPPORT_RTC_PERIPH_PD + ESP_EARLY_LOGD(TAG, "RTC_PERIPH: %s", option_str[s_config.domain[ESP_PD_DOMAIN_RTC_PERIPH].pd_option]); +#endif +#if SOC_PM_SUPPORT_RTC_SLOW_MEM_PD + ESP_EARLY_LOGD(TAG, "RTC_SLOW_MEM: %s", option_str[s_config.domain[ESP_PD_DOMAIN_RTC_SLOW_MEM].pd_option]); +#endif +#if SOC_PM_SUPPORT_RTC_FAST_MEM_PD + ESP_EARLY_LOGD(TAG, "RTC_FAST_MEM: %s", option_str[s_config.domain[ESP_PD_DOMAIN_RTC_FAST_MEM].pd_option]); +#endif + + // Prepare flags based on the selected options + uint32_t pd_flags = 0; +#if SOC_PM_SUPPORT_RTC_FAST_MEM_PD + if (s_config.domain[ESP_PD_DOMAIN_RTC_FAST_MEM].pd_option != ESP_PD_OPTION_ON) { + pd_flags |= RTC_SLEEP_PD_RTC_FAST_MEM; + } +#endif +#if SOC_PM_SUPPORT_RTC_SLOW_MEM_PD + if (s_config.domain[ESP_PD_DOMAIN_RTC_SLOW_MEM].pd_option != ESP_PD_OPTION_ON) { + pd_flags |= RTC_SLEEP_PD_RTC_SLOW_MEM; + } +#endif +#if SOC_PM_SUPPORT_RTC_PERIPH_PD + if (s_config.domain[ESP_PD_DOMAIN_RTC_PERIPH].pd_option != ESP_PD_OPTION_ON) { + pd_flags |= RTC_SLEEP_PD_RTC_PERIPH; + } +#endif + +#if SOC_PM_SUPPORT_CPU_PD + if (s_config.domain[ESP_PD_DOMAIN_CPU].pd_option != ESP_PD_OPTION_ON) { + pd_flags |= RTC_SLEEP_PD_CPU; + } +#endif +#if SOC_PM_SUPPORT_XTAL32K_PD + if (s_config.domain[ESP_PD_DOMAIN_XTAL32K].pd_option != ESP_PD_OPTION_ON) { + pd_flags |= PMU_SLEEP_PD_XTAL32K; + } +#endif +#if SOC_PM_SUPPORT_RC32K_PD + if (s_config.domain[ESP_PD_DOMAIN_RC32K].pd_option != ESP_PD_OPTION_ON) { + pd_flags |= PMU_SLEEP_PD_RC32K; + } +#endif +#if SOC_PM_SUPPORT_RC_FAST_PD + if (s_config.domain[ESP_PD_DOMAIN_RC_FAST].pd_option != ESP_PD_OPTION_ON) { + pd_flags |= RTC_SLEEP_PD_INT_8M; + } +#endif +#if SOC_PM_SUPPORT_XTAL_PD + if (s_config.domain[ESP_PD_DOMAIN_XTAL].pd_option != ESP_PD_OPTION_ON) { + pd_flags |= RTC_SLEEP_PD_XTAL; + } +#endif +#if SOC_PM_SUPPORT_VDDSDIO_PD + if (s_config.domain[ESP_PD_DOMAIN_VDDSDIO].pd_option != ESP_PD_OPTION_ON) { pd_flags |= RTC_SLEEP_PD_VDDSDIO; } +#endif #if ((defined CONFIG_RTC_CLK_SRC_EXT_CRYS) && (defined CONFIG_RTC_EXT_CRYST_ADDIT_CURRENT) && (SOC_PM_SUPPORT_RTC_PERIPH_PD)) if ((s_config.wakeup_triggers & (RTC_TOUCH_TRIG_EN | RTC_ULP_TRIG_EN)) == 0) { @@ -1474,15 +1543,3 @@ void rtc_sleep_enable_ultra_low(bool enable) { s_ultra_low_enabled = enable; } - -#if CONFIG_ESP_SLEEP_GPIO_RESET_WORKAROUND && !CONFIG_PM_SLP_DISABLE_GPIO -ESP_SYSTEM_INIT_FN(esp_sleep_startup_init, BIT(0), 105) -{ - // Configure to isolate (disable the Input/Output/Pullup/Pulldown - // function of the pin) all GPIO pins in sleep state - esp_sleep_config_gpio_isolate(); - // Enable automatic switching of GPIO configuration - esp_sleep_enable_gpio_switch(true); - return ESP_OK; -} -#endif diff --git a/components/esp_hw_support/sleep_retention.c b/components/esp_hw_support/sleep_retention.c deleted file mode 100644 index dd19180abf..0000000000 --- a/components/esp_hw_support/sleep_retention.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include - -#include "esp_attr.h" -#include "esp_sleep.h" -#include "esp_log.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "esp_heap_caps.h" -#include "soc/soc_caps.h" -#include "hal/rtc_hal.h" -#include "esp_private/sleep_retention.h" -#include "sdkconfig.h" - -#ifdef CONFIG_IDF_TARGET_ESP32S3 -#include "esp32s3/rom/cache.h" -#endif - -static __attribute__((unused)) const char *TAG = "sleep"; - -/** - * Internal structure which holds all requested light sleep memory retention parameters - */ -typedef struct { - rtc_cntl_sleep_retent_t retent; -} sleep_retention_t; - -static DRAM_ATTR __attribute__((unused)) sleep_retention_t s_retention; - -#if SOC_PM_SUPPORT_TAGMEM_PD - -#if CONFIG_PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP -static int cache_tagmem_retention_setup(uint32_t code_seg_vaddr, uint32_t code_seg_size, uint32_t data_seg_vaddr, uint32_t data_seg_size) -{ - int sets; /* i/d-cache total set counts */ - int index; /* virtual address mapping i/d-cache row offset */ - int waysgrp; - int icache_tagmem_blk_gs, dcache_tagmem_blk_gs; - struct cache_mode imode = { .icache = 1 }; - struct cache_mode dmode = { .icache = 0 }; - - /* calculate/prepare i-cache tag memory retention parameters */ - Cache_Get_Mode(&imode); - sets = imode.cache_size / imode.cache_ways / imode.cache_line_size; - index = (code_seg_vaddr / imode.cache_line_size) % sets; - waysgrp = imode.cache_ways >> 2; - - code_seg_size = ALIGNUP(imode.cache_line_size, code_seg_size); - - s_retention.retent.tagmem.icache.start_point = index; - s_retention.retent.tagmem.icache.size = (sets * waysgrp) & 0xff; - s_retention.retent.tagmem.icache.vld_size = s_retention.retent.tagmem.icache.size; - if (code_seg_size < imode.cache_size / imode.cache_ways) { - s_retention.retent.tagmem.icache.vld_size = (code_seg_size / imode.cache_line_size) * waysgrp; - } - s_retention.retent.tagmem.icache.enable = (code_seg_size != 0) ? 1 : 0; - icache_tagmem_blk_gs = s_retention.retent.tagmem.icache.vld_size ? s_retention.retent.tagmem.icache.vld_size : sets * waysgrp; - icache_tagmem_blk_gs = ALIGNUP(4, icache_tagmem_blk_gs); - ESP_LOGD(TAG, "I-cache size:%d KiB, line size:%d B, ways:%d, sets:%d, index:%d, tag block groups:%d", (imode.cache_size>>10), - imode.cache_line_size, imode.cache_ways, sets, index, icache_tagmem_blk_gs); - - /* calculate/prepare d-cache tag memory retention parameters */ - Cache_Get_Mode(&dmode); - sets = dmode.cache_size / dmode.cache_ways / dmode.cache_line_size; - index = (data_seg_vaddr / dmode.cache_line_size) % sets; - waysgrp = dmode.cache_ways >> 2; - - data_seg_size = ALIGNUP(dmode.cache_line_size, data_seg_size); - - s_retention.retent.tagmem.dcache.start_point = index; - s_retention.retent.tagmem.dcache.size = (sets * waysgrp) & 0x1ff; - s_retention.retent.tagmem.dcache.vld_size = s_retention.retent.tagmem.dcache.size; -#ifndef CONFIG_ESP32S3_DATA_CACHE_16KB - if (data_seg_size < dmode.cache_size / dmode.cache_ways) { - s_retention.retent.tagmem.dcache.vld_size = (data_seg_size / dmode.cache_line_size) * waysgrp; - } - s_retention.retent.tagmem.dcache.enable = (data_seg_size != 0) ? 1 : 0; -#else - s_retention.retent.tagmem.dcache.enable = 1; -#endif - dcache_tagmem_blk_gs = s_retention.retent.tagmem.dcache.vld_size ? s_retention.retent.tagmem.dcache.vld_size : sets * waysgrp; - dcache_tagmem_blk_gs = ALIGNUP(4, dcache_tagmem_blk_gs); - ESP_LOGD(TAG, "D-cache size:%d KiB, line size:%d B, ways:%d, sets:%d, index:%d, tag block groups:%d", (dmode.cache_size>>10), - dmode.cache_line_size, dmode.cache_ways, sets, index, dcache_tagmem_blk_gs); - - /* For I or D cache tagmem retention, backup and restore are performed through - * RTC DMA (its bus width is 128 bits), For I/D Cache tagmem blocks (i-cache - * tagmem blocks = 92 bits, d-cache tagmem blocks = 88 bits), RTC DMA automatically - * aligns its bit width to 96 bits, therefore, 3 times RTC DMA can transfer 4 - * i/d-cache tagmem blocks (128 bits * 3 = 96 bits * 4) */ - return (((icache_tagmem_blk_gs + dcache_tagmem_blk_gs) << 2) * 3); -} -#endif // CONFIG_PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP - -static esp_err_t esp_sleep_tagmem_pd_low_init(bool enable) -{ - if (enable) { -#if CONFIG_PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP - if (s_retention.retent.tagmem.link_addr == NULL) { - extern char _stext[], _etext[]; - uint32_t code_start = (uint32_t)_stext; - uint32_t code_size = (uint32_t)(_etext - _stext); -#if !(CONFIG_SPIRAM && CONFIG_IDF_TARGET_ESP32S3) - extern char _rodata_start[], _rodata_reserved_end[]; - uint32_t data_start = (uint32_t)_rodata_start; - uint32_t data_size = (uint32_t)(_rodata_reserved_end - _rodata_start); -#else - uint32_t data_start = SOC_DROM_LOW; - uint32_t data_size = SOC_EXTRAM_DATA_SIZE; -#endif - ESP_LOGI(TAG, "Code start at %08x, total %.2f KiB, data start at %08x, total %.2f KiB", - code_start, (float)code_size/1024, data_start, (float)data_size/1024); - int tagmem_sz = cache_tagmem_retention_setup(code_start, code_size, data_start, data_size); - void *buf = heap_caps_aligned_alloc(SOC_RTC_CNTL_TAGMEM_PD_DMA_ADDR_ALIGN, - tagmem_sz + RTC_HAL_DMA_LINK_NODE_SIZE, - MALLOC_CAP_RETENTION); - if (buf) { - memset(buf, 0, tagmem_sz + RTC_HAL_DMA_LINK_NODE_SIZE); - s_retention.retent.tagmem.link_addr = rtc_cntl_hal_dma_link_init(buf, - buf + RTC_HAL_DMA_LINK_NODE_SIZE, tagmem_sz, NULL); - } else { - s_retention.retent.tagmem.icache.enable = 0; - s_retention.retent.tagmem.dcache.enable = 0; - s_retention.retent.tagmem.link_addr = NULL; - return ESP_ERR_NO_MEM; - } - } -#else // CONFIG_PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP - s_retention.retent.tagmem.icache.enable = 0; - s_retention.retent.tagmem.dcache.enable = 0; - s_retention.retent.tagmem.link_addr = NULL; -#endif // CONFIG_PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP - } else { -#if SOC_PM_SUPPORT_TAGMEM_PD - if (s_retention.retent.tagmem.link_addr) { - heap_caps_free(s_retention.retent.tagmem.link_addr); - s_retention.retent.tagmem.icache.enable = 0; - s_retention.retent.tagmem.dcache.enable = 0; - s_retention.retent.tagmem.link_addr = NULL; - } -#endif - } - return ESP_OK; -} - -#endif // SOC_PM_SUPPORT_TAGMEM_PD - -#if SOC_PM_SUPPORT_CPU_PD - -esp_err_t esp_sleep_cpu_pd_low_init(bool enable) -{ - if (enable) { - if (s_retention.retent.cpu_pd_mem == NULL) { - void *buf = heap_caps_aligned_alloc(SOC_RTC_CNTL_CPU_PD_DMA_ADDR_ALIGN, - SOC_RTC_CNTL_CPU_PD_RETENTION_MEM_SIZE + RTC_HAL_DMA_LINK_NODE_SIZE, - MALLOC_CAP_RETENTION); - if (buf) { - memset(buf, 0, SOC_RTC_CNTL_CPU_PD_RETENTION_MEM_SIZE + RTC_HAL_DMA_LINK_NODE_SIZE); - s_retention.retent.cpu_pd_mem = rtc_cntl_hal_dma_link_init(buf, - buf + RTC_HAL_DMA_LINK_NODE_SIZE, SOC_RTC_CNTL_CPU_PD_RETENTION_MEM_SIZE, NULL); - } else { - return ESP_ERR_NO_MEM; - } - } - } else { - if (s_retention.retent.cpu_pd_mem) { - heap_caps_free(s_retention.retent.cpu_pd_mem); - s_retention.retent.cpu_pd_mem = NULL; - } - } -#if SOC_PM_SUPPORT_TAGMEM_PD - if (esp_sleep_tagmem_pd_low_init(enable) != ESP_OK) { -#ifdef CONFIG_ESP32S3_DATA_CACHE_16KB - esp_sleep_cpu_pd_low_init(false); - return ESP_ERR_NO_MEM; -#endif - } -#endif - return ESP_OK; -} - -bool cpu_domain_pd_allowed(void) -{ - return (s_retention.retent.cpu_pd_mem != NULL); -} - -#endif // SOC_PM_SUPPORT_CPU_PD - -#if SOC_PM_SUPPORT_CPU_PD || SOC_PM_SUPPORT_TAGMEM_PD - -void sleep_enable_memory_retention(void) -{ -#if SOC_PM_SUPPORT_CPU_PD - rtc_cntl_hal_enable_cpu_retention(&s_retention.retent); -#endif -#if SOC_PM_SUPPORT_TAGMEM_PD - rtc_cntl_hal_enable_tagmem_retention(&s_retention.retent); -#endif -} - -void IRAM_ATTR sleep_disable_memory_retention(void) -{ -#if SOC_PM_SUPPORT_CPU_PD - rtc_cntl_hal_disable_cpu_retention(&s_retention.retent); -#endif -#if SOC_PM_SUPPORT_TAGMEM_PD - rtc_cntl_hal_disable_tagmem_retention(&s_retention.retent); -#endif -} - -#endif // SOC_PM_SUPPORT_CPU_PD || SOC_PM_SUPPORT_TAGMEM_PD diff --git a/components/esp_hw_support/sleep_wake_stub.c b/components/esp_hw_support/sleep_wake_stub.c index bb6257a7b9..023e766c45 100644 --- a/components/esp_hw_support/sleep_wake_stub.c +++ b/components/esp_hw_support/sleep_wake_stub.c @@ -15,9 +15,19 @@ #include "soc/soc.h" #include "soc/rtc.h" #include "soc/soc_caps.h" -#include "hal/rtc_cntl_ll.h" #include "hal/uart_ll.h" +#if SOC_LP_TIMER_SUPPORTED +#include "hal/lp_timer_ll.h" +#include "hal/lp_timer_hal.h" +#else +#include "hal/rtc_cntl_ll.h" +#endif + +#if SOC_PMU_SUPPORTED +#include "hal/pmu_ll.h" +#endif + #include "sdkconfig.h" #include "esp_rom_uart.h" #include "esp_rom_sys.h" @@ -57,7 +67,12 @@ void RTC_IRAM_ATTR esp_wake_stub_sleep(esp_deep_sleep_wake_stub_fn_t new_stub) #endif // SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_MEM // Go to sleep. +#if SOC_PMU_SUPPORTED + pmu_ll_hp_set_sleep_enable(&PMU); +#else rtc_cntl_ll_sleep_enable(); +#endif + // A few CPU cycles may be necessary for the sleep to start... while (true) {}; // never reaches here. @@ -70,12 +85,23 @@ void RTC_IRAM_ATTR esp_wake_stub_uart_tx_wait_idle(uint8_t uart_no) void RTC_IRAM_ATTR esp_wake_stub_set_wakeup_time(uint64_t time_in_us) { +#if SOC_LP_TIMER_SUPPORTED + uint64_t rtc_count_delta = lp_timer_ll_time_to_count(time_in_us); + uint64_t rtc_curr_count = lp_timer_hal_get_cycle_count(0); + lp_timer_hal_set_alarm_target(0, rtc_curr_count + rtc_count_delta); +#else uint64_t rtc_count_delta = rtc_cntl_ll_time_to_count(time_in_us); uint64_t rtc_curr_count = rtc_cntl_ll_get_rtc_time(); rtc_cntl_ll_set_wakeup_timer(rtc_curr_count + rtc_count_delta); +#endif + } uint32_t RTC_IRAM_ATTR esp_wake_stub_get_wakeup_cause(void) { +#if SOC_PMU_SUPPORTED + return pmu_ll_hp_get_wakeup_cause(&PMU); +#else return rtc_cntl_ll_get_wakeup_cause(); +#endif } diff --git a/components/esp_pm/Kconfig b/components/esp_pm/Kconfig index a92fa47ad0..dbb638c717 100644 --- a/components/esp_pm/Kconfig +++ b/components/esp_pm/Kconfig @@ -2,10 +2,10 @@ menu "Power Management" config PM_ENABLE bool "Support for power management" # SMP FreeRTOS currently does not support power management IDF-4997 - # ESP32C6 currently does not support power management IDF-5347 IDF-6270 - # Note. Disabling this option for C6 will also cause all sdkconfig.release test cases run without pm enabled - # ORed with __DOXYGEN__ to pass C6 docs build, need to remove when pm is supported on C6 - depends on (!FREERTOS_SMP && !IDF_TARGET_ESP32C6 && !IDF_TARGET_ESP32H2) || __DOXYGEN__ + # ESP32H2 currently does not support power management IDF-6270 + # Note. Disabling this option for H2 will also cause all sdkconfig.release test cases run without pm enabled + # ORed with __DOXYGEN__ to pass H2 docs build, need to remove when pm is supported on H2 + depends on (!FREERTOS_SMP && !IDF_TARGET_ESP32H2) || __DOXYGEN__ default n help If enabled, application is compiled with support for power management. @@ -87,7 +87,7 @@ menu "Power Management" config PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP bool "Power down CPU in light sleep" - depends on IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 + depends on IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C6 select PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP if ESP32S3_DATA_CACHE_16KB default y help diff --git a/components/esp_pm/linker.lf b/components/esp_pm/linker.lf index 6ef1e90e06..cad3fb2397 100644 --- a/components/esp_pm/linker.lf +++ b/components/esp_pm/linker.lf @@ -15,16 +15,17 @@ entries: sleep_modes:esp_sleep_enable_timer_wakeup (noflash) sleep_modes:timer_wakeup_prepare (noflash) sleep_modes:get_power_down_flags (noflash) - rtc_init:rtc_vddsdio_get_config (noflash) + if SOC_CONFIGURABLE_VDDSDIO_SUPPORTED: + rtc_init:rtc_vddsdio_get_config (noflash) esp_clk:esp_clk_slowclk_cal_set (noflash) esp_clk:esp_clk_slowclk_cal_get (noflash) esp_clk:esp_rtc_get_time_us (noflash) if GPIO_ESP32_SUPPORT_SWITCH_SLP_PULL = y: sleep_gpio:gpio_sleep_mode_config_apply (noflash) - if SOC_PM_SUPPORT_CPU_PD = y || SOC_PM_SUPPORT_TAGMEM_PD = y: - sleep_retention:sleep_enable_memory_retention (noflash) + if SOC_PM_CPU_RETENTION_BY_RTCCNTL = y && (SOC_PM_SUPPORT_CPU_PD = y || SOC_PM_SUPPORT_TAGMEM_PD = y): + sleep_cpu:sleep_enable_cpu_retention (noflash) if SOC_PM_SUPPORT_CPU_PD = y: - sleep_retention:cpu_domain_pd_allowed (noflash) + sleep_cpu:cpu_domain_pd_allowed (noflash) [mapping:esp_system_pm] archive: libesp_system.a @@ -86,7 +87,8 @@ entries: gpio_hal_workaround:gpio_hal_sleep_pupd_config_unapply (noflash) gpio_hal_workaround:gpio_hal_sleep_mode_setup_wrapper (noflash) gpio_hal_workaround:gpio_hal_fun_pupd_restore (noflash) - if PM_SLP_IRAM_OPT = y && PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP = y: - rtc_cntl_hal:rtc_cntl_hal_enable_cpu_retention (noflash) - if PM_SLP_IRAM_OPT = y && PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP = y: - rtc_cntl_hal:rtc_cntl_hal_enable_tagmem_retention (noflash) + if SOC_PM_CPU_RETENTION_BY_RTCCNTL = y: + if PM_SLP_IRAM_OPT = y && PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP = y: + rtc_cntl_hal:rtc_cntl_hal_enable_cpu_retention (noflash) + if PM_SLP_IRAM_OPT = y && PM_POWER_DOWN_TAGMEM_IN_LIGHT_SLEEP = y: + rtc_cntl_hal:rtc_cntl_hal_enable_tagmem_retention (noflash) diff --git a/components/esp_pm/pm_impl.c b/components/esp_pm/pm_impl.c index 4384fa1eb1..20b0113c67 100644 --- a/components/esp_pm/pm_impl.c +++ b/components/esp_pm/pm_impl.c @@ -288,6 +288,13 @@ esp_err_t esp_pm_configure(const void* vconfig) */ apb_max_freq = 80; } +#elif CONFIG_IDF_TARGET_ESP32C6 + /* Maximum SOC APB clock frequency is 40 MHz, maximum Modem (WiFi, + * Bluetooth, etc..) APB clock frequency is 80 MHz */ + const int soc_apb_clk_freq = esp_clk_apb_freq() / MHZ; + const int modem_apb_clk_freq = MODEM_APB_CLK_FREQ / MHZ; + const int apb_clk_freq = MAX(soc_apb_clk_freq, modem_apb_clk_freq); + int apb_max_freq = MIN(max_freq_mhz, apb_clk_freq); /* CPU frequency in APB_MAX mode */ #else int apb_max_freq = MIN(max_freq_mhz, 80); /* CPU frequency in APB_MAX mode */ #endif @@ -320,9 +327,12 @@ esp_err_t esp_pm_configure(const void* vconfig) #endif #if CONFIG_PM_POWER_DOWN_CPU_IN_LIGHT_SLEEP && SOC_PM_SUPPORT_CPU_PD - esp_err_t ret = esp_sleep_cpu_pd_low_init(config->light_sleep_enable); - if (config->light_sleep_enable && ret != ESP_OK) { - ESP_LOGW(TAG, "Failed to enable CPU power down during light sleep."); + if (config->light_sleep_enable) { + if (esp_sleep_cpu_retention_init() != ESP_OK) { + ESP_LOGW(TAG, "Failed to enable CPU power down during light sleep."); + } + } else { + esp_sleep_cpu_retention_deinit(); } #endif diff --git a/components/esp_rom/include/esp32c6/rom/rtc.h b/components/esp_rom/include/esp32c6/rom/rtc.h index 844f010147..3fba551945 100644 --- a/components/esp_rom/include/esp32c6/rom/rtc.h +++ b/components/esp_rom/include/esp32c6/rom/rtc.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -32,7 +32,7 @@ extern "C" { * Please do not use reserved or used rtc memory or registers. * * * ************************************************************************************* - * RTC Memory & Store Register usage + * LP Memory & Store Register usage ************************************************************************************* * rtc memory addr type size usage * 0x3f421000(0x50000000) Slow SIZE_CP Co-Processor code/Reset Entry @@ -42,25 +42,29 @@ extern "C" { * ************************************************************************************* * RTC store registers usage - * RTC_CNTL_STORE0_REG Reserved - * RTC_CNTL_STORE1_REG RTC_SLOW_CLK calibration value - * RTC_CNTL_STORE2_REG Boot time, low word - * RTC_CNTL_STORE3_REG Boot time, high word - * RTC_CNTL_STORE4_REG External XTAL frequency - * RTC_CNTL_STORE5_REG APB bus frequency - * RTC_CNTL_STORE6_REG FAST_RTC_MEMORY_ENTRY - * RTC_CNTL_STORE7_REG FAST_RTC_MEMORY_CRC + * LP_AON_STORE0_REG Reserved + * LP_AON_STORE1_REG RTC_SLOW_CLK calibration value + * LP_AON_STORE2_REG Boot time, low word + * LP_AON_STORE3_REG Boot time, high word + * LP_AON_STORE4_REG External XTAL frequency + * LP_AON_STORE5_REG FAST_RTC_MEMORY_LENGTH + * LP_AON_STORE6_REG FAST_RTC_MEMORY_ENTRY + * LP_AON_STORE7_REG FAST_RTC_MEMORY_CRC + * LP_AON_STORE8_REG Store light sleep wake stub addr + * LP_AON_STORE9_REG Store the sleep mode at bit[0] (0:light sleep 1:deep sleep) ************************************************************************************* */ -#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_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_ENTRY_LENGTH_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_DISABLE_ROM_LOG ((1 << 0) | (1 << 16)) //!< Disable logging from the ROM code. diff --git a/components/esp_system/fpga_overrides.c b/components/esp_system/fpga_overrides.c index 3e60824033..7439c7cfa3 100644 --- a/components/esp_system/fpga_overrides.c +++ b/components/esp_system/fpga_overrides.c @@ -23,6 +23,7 @@ #include "esp32c2/rom/rtc.h" #elif CONFIG_IDF_TARGET_ESP32C6 #include "esp32c6/rom/rtc.h" +#include "esp_private/esp_pmu.h" #elif CONFIG_IDF_TARGET_ESP32H2 #include "esp32h2/rom/rtc.h" #endif @@ -72,6 +73,9 @@ void IRAM_ATTR bootloader_fill_random(void *buffer, size_t length) void esp_clk_init(void) { s_warn(); +#if SOC_PMU_SUPPORTED + pmu_init(); +#endif } void esp_perip_clk_init(void) diff --git a/components/esp_system/port/soc/esp32c6/clk.c b/components/esp_system/port/soc/esp32c6/clk.c index a6f725fa83..6243a88141 100644 --- a/components/esp_system/port/soc/esp32c6/clk.c +++ b/components/esp_system/port/soc/esp32c6/clk.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -23,6 +23,7 @@ #include "esp_private/esp_modem_clock.h" #include "esp_private/periph_ctrl.h" #include "esp_private/esp_clk.h" +#include "esp_private/esp_pmu.h" #include "esp_rom_uart.h" #include "esp_rom_sys.h" @@ -42,13 +43,7 @@ static const char *TAG = "clk"; __attribute__((weak)) void esp_clk_init(void) { #if !CONFIG_IDF_ENV_FPGA - rtc_config_t cfg = RTC_CONFIG_DEFAULT(); - soc_reset_reason_t rst_reas; - rst_reas = esp_rom_get_reset_reason(0); - if (rst_reas == RESET_REASON_CHIP_POWER_ON) { - cfg.cali_ocode = 1; - } - rtc_init(cfg); + pmu_init(); assert(rtc_clk_xtal_freq_get() == RTC_XTAL_FREQ_40M); diff --git a/components/esp_system/system_init_fn.txt b/components/esp_system/system_init_fn.txt index 3fb5a7a216..cd0fa76947 100644 --- a/components/esp_system/system_init_fn.txt +++ b/components/esp_system/system_init_fn.txt @@ -17,7 +17,7 @@ 100: esp_timer_startup_init in components/esp_timer/src/esp_timer.c on BIT(0) # esp_sleep doesn't have init dependencies -105: esp_sleep_startup_init in components/esp_hw_support/sleep_modes.c on BIT(0) +105: esp_sleep_startup_init in components/esp_hw_support/sleep_gpio.c on BIT(0) # app_trace has to be initialized before systemview 115: esp_apptrace_init in components/app_trace/app_trace.c on ESP_SYSTEM_INIT_ALL_CORES diff --git a/components/esp_system/test/test_sleep.c b/components/esp_system/test/test_sleep.c index 664ca3039f..f364462977 100644 --- a/components/esp_system/test/test_sleep.c +++ b/components/esp_system/test/test_sleep.c @@ -19,7 +19,6 @@ #include "soc/rtc.h" // for wakeup trigger defines #include "soc/rtc_periph.h" // for read rtc registers directly (cause) #include "soc/soc.h" // for direct register read macros -#include "hal/rtc_cntl_ll.h" #include "esp_newlib.h" #include "test_utils.h" #include "sdkconfig.h" @@ -29,6 +28,12 @@ #include "esp_private/esp_clk.h" #include "esp_random.h" +#if SOC_PMU_SUPPORTED +#include "esp_private/esp_pmu.h" +#else +#include "hal/rtc_cntl_ll.h" +#endif + #define ESP_EXT0_WAKEUP_LEVEL_LOW 0 #define ESP_EXT0_WAKEUP_LEVEL_HIGH 1 @@ -445,7 +450,11 @@ __attribute__((unused)) static float get_time_ms(void) __attribute__((unused)) static uint32_t get_cause(void) { +#if SOC_PMU_SUPPORTED + uint32_t wakeup_cause = pmu_ll_hp_get_wakeup_cause(&PMU); +#else uint32_t wakeup_cause = rtc_cntl_ll_get_wakeup_cause(); +#endif return wakeup_cause; } @@ -590,4 +599,4 @@ TEST_CASE("wake up using GPIO (2 or 4 low)", "[deepsleep][ignore]") } #endif // SOC_GPIO_SUPPORT_DEEPSLEEP_WAKEUP #endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C2) -#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C6, ESP32H2) TODO: IDF-5348, IDF-5349 +#endif //!TEMPORARY_DISABLED_FOR_TARGETS(ESP32C6, ESP32H2) TODO: IDF-5349 diff --git a/components/esp_wifi/esp32c6/esp_adapter.c b/components/esp_wifi/esp32c6/esp_adapter.c index ea4a676797..76eb31bd0b 100644 --- a/components/esp_wifi/esp32c6/esp_adapter.c +++ b/components/esp_wifi/esp32c6/esp_adapter.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -33,7 +33,6 @@ #include "esp_phy_init.h" #include "soc/rtc_cntl_periph.h" #include "soc/rtc.h" -#include "esp_private/sleep_retention.h" #include "phy_init_data.h" #include "esp_private/periph_ctrl.h" #include "esp_private/esp_clk.h" diff --git a/components/hal/CMakeLists.txt b/components/hal/CMakeLists.txt index 095233343e..da8ae89434 100644 --- a/components/hal/CMakeLists.txt +++ b/components/hal/CMakeLists.txt @@ -118,6 +118,10 @@ if(NOT BOOTLOADER_BUILD) list(APPEND srcs "${target}/modem_clock_hal.c") endif() + if(CONFIG_SOC_LP_TIMER_SUPPORTED) + list(APPEND srcs "${target}/lp_timer_hal.c") + endif() + if(CONFIG_SOC_BOD_SUPPORTED) list(APPEND srcs "brownout_hal.c") endif() @@ -138,6 +142,10 @@ if(NOT BOOTLOADER_BUILD) list(APPEND srcs "sdio_slave_hal.c") endif() + if(CONFIG_SOC_PMU_SUPPORTED) + list(APPEND srcs "${target}/pmu_hal.c") + endif() + if(${target} STREQUAL "esp32") list(APPEND srcs "touch_sensor_hal.c" @@ -198,7 +206,6 @@ if(NOT BOOTLOADER_BUILD) if(${target} STREQUAL "esp32c6") list(APPEND srcs "spi_flash_hal_gpspi.c" - "esp32c6/rtc_cntl_hal.c" "hmac_hal.c" "ds_hal.c") diff --git a/components/hal/esp32c6/include/hal/lp_timer_hal.h b/components/hal/esp32c6/include/hal/lp_timer_hal.h new file mode 100644 index 0000000000..813b865fef --- /dev/null +++ b/components/hal/esp32c6/include/hal/lp_timer_hal.h @@ -0,0 +1,47 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include +#include "soc/soc.h" +#include "hal/lp_timer_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * @brief set alarm target value + * + * @param timer_id timer num of lp_timer, 0 or 1 for esp32c6 + * + * @param value when counter reaches alarm value, alarm event will be triggered + */ +void lp_timer_hal_set_alarm_target(uint8_t timer_id, uint64_t value); + +/** + * @brief get current counter value + * + * @param timer_id timer num of lp_timer, 0 or 1 for esp32c6 + */ +uint64_t lp_timer_hal_get_cycle_count(uint8_t timer_id); + +/** + * @brief clear alarm interrupt status + */ +void lp_timer_hal_clear_alarm_intr_status(void); + +/** + * @brief clear overflow interrupt status + */ +void lp_timer_hal_clear_overflow_intr_status(void); + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/lp_timer_ll.h b/components/hal/esp32c6/include/hal/lp_timer_ll.h new file mode 100644 index 0000000000..7f2aa34460 --- /dev/null +++ b/components/hal/esp32c6/include/hal/lp_timer_ll.h @@ -0,0 +1,66 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The LL layer for ESP32-C6 LP_Timer register operations + +#pragma once + +#include +#include "soc/soc.h" +#include "soc/rtc.h" +#include "soc/lp_timer_struct.h" +#include "soc/lp_aon_reg.h" +#include "hal/lp_timer_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +FORCE_INLINE_ATTR void lp_timer_ll_set_alarm_target(lp_timer_dev_t *dev, uint8_t timer_id, uint64_t value) +{ + dev->target[timer_id].hi.target_hi = (value >> 32) & 0xFFFF; + dev->target[timer_id].lo.target_lo = value & 0xFFFFFFFF; +} + +FORCE_INLINE_ATTR void lp_timer_ll_set_target_enable(lp_timer_dev_t *dev, uint8_t timer_id, bool en) +{ + dev->target[timer_id].hi.enable = en; +} + +FORCE_INLINE_ATTR uint32_t lp_timer_ll_get_counter_value_low(lp_timer_dev_t *dev, uint8_t timer_id) +{ + return dev->counter[timer_id].lo.counter_lo; +} + +FORCE_INLINE_ATTR uint32_t lp_timer_ll_get_counter_value_high(lp_timer_dev_t *dev, uint8_t timer_id) +{ + return dev->counter[timer_id].hi.counter_hi; +} + +FORCE_INLINE_ATTR void lp_timer_ll_counter_snapshot(lp_timer_dev_t *dev) +{ + dev->update.update = 1; +} + +FORCE_INLINE_ATTR void lp_timer_ll_clear_alarm_intr_status(lp_timer_dev_t *dev) +{ + dev->int_clr.alarm = 1; +} + +FORCE_INLINE_ATTR void lp_timer_ll_clear_overflow_intr_status(lp_timer_dev_t *dev) +{ + dev->int_clr.overflow = 1; +} + +FORCE_INLINE_ATTR uint64_t lp_timer_ll_time_to_count(uint64_t time_in_us) +{ + uint32_t slow_clk_value = REG_READ(LP_AON_STORE1_REG); + return ((time_in_us * (1 << RTC_CLK_CAL_FRACT)) / slow_clk_value); +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/pmu_hal.h b/components/hal/esp32c6/include/hal/pmu_hal.h new file mode 100644 index 0000000000..f4ca27e9e8 --- /dev/null +++ b/components/hal/esp32c6/include/hal/pmu_hal.h @@ -0,0 +1,45 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The HAL layer for PMU + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include "soc/soc_caps.h" +#include "hal/pmu_ll.h" +#include "hal/pmu_types.h" + +typedef struct { + pmu_dev_t *dev; +} pmu_hal_context_t; + +void pmu_hal_hp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle); + +uint32_t pmu_hal_hp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal); + +void pmu_hal_lp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle); + +uint32_t pmu_hal_lp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal); + +void pmu_hal_hp_set_sleep_active_backup_enable(pmu_hal_context_t *hal); + +void pmu_hal_hp_set_sleep_active_backup_disable(pmu_hal_context_t *hal); + +void pmu_hal_hp_set_sleep_modem_backup_enable(pmu_hal_context_t *hal); + +void pmu_hal_hp_set_sleep_modem_backup_disable(pmu_hal_context_t *hal); + +void pmu_hal_hp_set_modem_active_backup_enable(pmu_hal_context_t *hal); + +void pmu_hal_hp_set_modem_active_backup_disable(pmu_hal_context_t *hal); + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/pmu_ll.h b/components/hal/esp32c6/include/hal/pmu_ll.h new file mode 100644 index 0000000000..6e74944f48 --- /dev/null +++ b/components/hal/esp32c6/include/hal/pmu_ll.h @@ -0,0 +1,666 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The LL layer for ESP32-C6 PMU register operations + +#pragma once + +#include +#include +#include "soc/soc.h" +#include "esp_attr.h" +#include "hal/assert.h" +#include "soc/pmu_struct.h" +#include "hal/pmu_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Set the power domain that needs to be powered down in the digital power + * + * @param hw Beginning address of the peripheral registers. + * @param mode The pmu mode + * @param flag Digital power domain flag + * + * @return None + */ +FORCE_INLINE_ATTR void pmu_ll_hp_set_dig_power(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t flag) +{ + hw->hp_sys[mode].dig_power.val = flag; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_icg_func(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t icg_func) +{ + hw->hp_sys[mode].icg_func = icg_func; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_icg_apb(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t bitmap) +{ + hw->hp_sys[mode].icg_apb = bitmap; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_icg_modem(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t code) +{ + hw->hp_sys[mode].icg_modem.code = code; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_uart_wakeup_enable(pmu_dev_t *hw, pmu_hp_mode_t mode, bool wakeup_en) +{ + hw->hp_sys[mode].syscntl.uart_wakeup_en = wakeup_en; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_hold_all_lp_pad(pmu_dev_t *hw, pmu_hp_mode_t mode, bool hold_all) +{ + hw->hp_sys[mode].syscntl.lp_pad_hold_all = hold_all; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_hold_all_hp_pad(pmu_dev_t *hw, pmu_hp_mode_t mode, bool hold_all) +{ + hw->hp_sys[mode].syscntl.hp_pad_hold_all = hold_all; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_dig_pad_slp_sel(pmu_dev_t *hw, pmu_hp_mode_t mode, bool slp_sel) +{ + hw->hp_sys[mode].syscntl.dig_pad_slp_sel = slp_sel; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_pause_watchdog(pmu_dev_t *hw, pmu_hp_mode_t mode, bool pause_wdt) +{ + hw->hp_sys[mode].syscntl.dig_pause_wdt = pause_wdt; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_cpu_stall(pmu_dev_t *hw, pmu_hp_mode_t mode, bool cpu_stall) +{ + hw->hp_sys[mode].syscntl.dig_cpu_stall = cpu_stall; +} + +/** + * @brief Set the power domain that needs to be powered down in the clock power + * + * @param hw Beginning address of the peripheral registers. + * @param mode The pmu mode + * @param flag Clock power domain flag + * + * @return None + */ +FORCE_INLINE_ATTR void pmu_ll_hp_set_clk_power(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t xpd_flag) +{ + hw->hp_sys[mode].clk_power.val = xpd_flag; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_xtal_xpd(pmu_dev_t *hw, pmu_hp_mode_t mode, bool xpd_xtal) +{ + hw->hp_sys[mode].xtal.xpd_xtal = xpd_xtal; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_bias_xpd(pmu_dev_t *hw, pmu_hp_mode_t mode, bool xpd_bias) +{ + hw->hp_sys[mode].bias.xpd_bias = xpd_bias; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_dbg_atten(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t value) +{ + hw->hp_sys[mode].bias.dbg_atten = value; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_current_power_off(pmu_dev_t *hw, pmu_hp_mode_t mode, bool off) +{ + hw->hp_sys[mode].bias.pd_cur = off; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_bias_sleep_enable(pmu_dev_t *hw, pmu_hp_mode_t mode, bool en) +{ + hw->hp_sys[mode].bias.bias_sleep = en; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_retention_param(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t param) +{ + hw->hp_sys[mode].backup.val = param; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_to_active_backup_enable(pmu_dev_t *hw) +{ + hw->hp_sys[PMU_MODE_HP_ACTIVE].backup.hp_sleep2active_backup_en = 1; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_to_active_backup_disable(pmu_dev_t *hw) +{ + hw->hp_sys[PMU_MODE_HP_ACTIVE].backup.hp_sleep2active_backup_en = 0; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_modem_to_active_backup_enable(pmu_dev_t *hw) +{ + hw->hp_sys[PMU_MODE_HP_ACTIVE].backup.hp_modem2active_backup_en = 1; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_modem_to_active_backup_disable(pmu_dev_t *hw) +{ + hw->hp_sys[PMU_MODE_HP_ACTIVE].backup.hp_modem2active_backup_en = 0; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_to_modem_backup_enable(pmu_dev_t *hw) +{ + hw->hp_sys[PMU_MODE_HP_MODEM].backup.hp_sleep2modem_backup_en = 1; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_to_modem_backup_disable(pmu_dev_t *hw) +{ + hw->hp_sys[PMU_MODE_HP_MODEM].backup.hp_sleep2modem_backup_en = 0; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_active_to_sleep_backup_enable(pmu_dev_t *hw) +{ + hw->hp_sys[PMU_MODE_HP_SLEEP].backup.hp_active2sleep_backup_en = 1; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_active_to_sleep_backup_disable(pmu_dev_t *hw) +{ + hw->hp_sys[PMU_MODE_HP_SLEEP].backup.hp_active2sleep_backup_en = 0; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_modem_to_sleep_backup_enable(pmu_dev_t *hw) +{ + hw->hp_sys[PMU_MODE_HP_SLEEP].backup.hp_modem2sleep_backup_en = 1; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_modem_to_sleep_backup_disable(pmu_dev_t *hw) +{ + hw->hp_sys[PMU_MODE_HP_SLEEP].backup.hp_modem2sleep_backup_en = 0; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_backup_icg_func(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t icg_func) +{ + hw->hp_sys[mode].backup_clk = icg_func; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_sysclk_nodiv(pmu_dev_t *hw, pmu_hp_mode_t mode, bool sysclk_nodiv) +{ + hw->hp_sys[mode].sysclk.dig_sysclk_nodiv = sysclk_nodiv; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_icg_sysclk_enable(pmu_dev_t *hw, pmu_hp_mode_t mode, bool icg_sysclk_en) +{ + hw->hp_sys[mode].sysclk.icg_sysclk_en = icg_sysclk_en; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_sysclk_slp_sel(pmu_dev_t *hw, pmu_hp_mode_t mode, bool slp_sel) +{ + hw->hp_sys[mode].sysclk.sysclk_slp_sel = slp_sel; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_icg_sysclk_slp_sel(pmu_dev_t *hw, pmu_hp_mode_t mode, bool slp_sel) +{ + hw->hp_sys[mode].sysclk.icg_slp_sel = slp_sel; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_dig_sysclk(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t sysclk_sel) +{ + hw->hp_sys[mode].sysclk.dig_sysclk_sel = sysclk_sel; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_sleep_logic_xpd(pmu_dev_t *hw, pmu_hp_mode_t mode, bool slp_xpd) +{ + hw->hp_sys[mode].regulator0.slp_logic_xpd = slp_xpd; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_sleep_memory_xpd(pmu_dev_t *hw, pmu_hp_mode_t mode, bool slp_xpd) +{ + hw->hp_sys[mode].regulator0.slp_mem_xpd = slp_xpd; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_xpd(pmu_dev_t *hw, pmu_hp_mode_t mode, bool xpd) +{ + hw->hp_sys[mode].regulator0.xpd = xpd; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_sleep_logic_dbias(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t slp_dbias) +{ + hw->hp_sys[mode].regulator0.slp_logic_dbias = slp_dbias; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_sleep_memory_dbias(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t slp_dbias) +{ + hw->hp_sys[mode].regulator0.slp_mem_dbias = slp_dbias; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_dbias(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t dbias) +{ + hw->hp_sys[mode].regulator0.dbias = dbias; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_regulator_driver_bar(pmu_dev_t *hw, pmu_hp_mode_t mode, uint32_t drv_b) +{ + hw->hp_sys[mode].regulator1.drv_b = drv_b; +} + + +FORCE_INLINE_ATTR void pmu_ll_lp_set_regulator_slp_xpd(pmu_dev_t *hw, pmu_lp_mode_t mode, bool slp_xpd) +{ + hw->lp_sys[mode].regulator0.slp_xpd = slp_xpd; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_regulator_xpd(pmu_dev_t *hw, pmu_lp_mode_t mode, bool xpd) +{ + hw->lp_sys[mode].regulator0.xpd = xpd; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_regulator_sleep_dbias(pmu_dev_t *hw, pmu_lp_mode_t mode, uint32_t slp_dbias) +{ + hw->lp_sys[mode].regulator0.slp_dbias = slp_dbias; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_regulator_dbias(pmu_dev_t *hw, pmu_lp_mode_t mode, uint32_t dbias) +{ + hw->lp_sys[mode].regulator0.dbias = dbias; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_regulator_driver_bar(pmu_dev_t *hw, pmu_lp_mode_t mode, uint32_t drv_b) +{ + hw->lp_sys[mode].regulator1.drv_b = drv_b; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_xtal_xpd(pmu_dev_t *hw, pmu_lp_mode_t mode, bool xpd_xtal) +{ + HAL_ASSERT(mode == PMU_MODE_LP_SLEEP); + hw->lp_sys[mode].xtal.xpd_xtal = xpd_xtal; +} + + +FORCE_INLINE_ATTR void pmu_ll_lp_set_dig_power(pmu_dev_t *hw, pmu_lp_mode_t mode, uint32_t flag) +{ + hw->lp_sys[mode].dig_power.val = flag; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_clk_power(pmu_dev_t *hw, pmu_lp_mode_t mode, uint32_t xpd_flag) +{ + hw->lp_sys[mode].clk_power.val = xpd_flag; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_clk_power(pmu_dev_t *hw, pmu_lp_mode_t mode) +{ + return hw->lp_sys[mode].clk_power.val; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_bias_xpd(pmu_dev_t *hw, pmu_lp_mode_t mode, bool xpd_bias) +{ + HAL_ASSERT(mode == PMU_MODE_LP_SLEEP); + hw->lp_sys[mode].bias.xpd_bias = xpd_bias; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_dbg_atten(pmu_dev_t *hw, pmu_lp_mode_t mode, uint32_t value) +{ + HAL_ASSERT(mode == PMU_MODE_LP_SLEEP); + hw->lp_sys[mode].bias.dbg_atten = value; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_current_power_off(pmu_dev_t *hw, pmu_lp_mode_t mode, bool off) +{ + HAL_ASSERT(mode == PMU_MODE_LP_SLEEP); + hw->lp_sys[mode].bias.pd_cur = off; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_bias_sleep_enable(pmu_dev_t *hw, pmu_lp_mode_t mode, bool en) +{ + HAL_ASSERT(mode == PMU_MODE_LP_SLEEP); + hw->lp_sys[mode].bias.bias_sleep = en; +} + + +/****/ +FORCE_INLINE_ATTR void pmu_ll_imm_set_clk_power(pmu_dev_t *hw, uint32_t flag) +{ + hw->imm.clk_power.val = flag; +} + +FORCE_INLINE_ATTR void pmu_ll_imm_set_icg_slp_sel(pmu_dev_t *hw, bool slp_sel) +{ + if (slp_sel) { + hw->imm.sleep_sysclk.tie_high_icg_slp_sel = 1; + } else { + hw->imm.sleep_sysclk.tie_low_icg_slp_sel = 1; + } +} + +FORCE_INLINE_ATTR void pmu_ll_imm_update_dig_sysclk_sel(pmu_dev_t *hw, bool update) +{ + hw->imm.sleep_sysclk.update_dig_sysclk_sel = update; +} + +FORCE_INLINE_ATTR void pmu_ll_imm_update_dig_icg_switch(pmu_dev_t *hw, bool update) +{ + hw->imm.sleep_sysclk.update_dig_icg_switch = update; +} + +FORCE_INLINE_ATTR void pmu_ll_imm_update_dig_icg_func(pmu_dev_t *hw, bool icg_func_update) +{ + hw->imm.hp_func_icg.update_dig_icg_func_en = icg_func_update; +} + +FORCE_INLINE_ATTR void pmu_ll_imm_update_dig_icg_apb(pmu_dev_t *hw, bool icg_apb_update) +{ + hw->imm.hp_apb_icg.update_dig_icg_apb_en = icg_apb_update; +} + +FORCE_INLINE_ATTR void pmu_ll_imm_update_dig_icg_modem_code(pmu_dev_t *hw, bool icg_modem_update) +{ + hw->imm.modem_icg.update_dig_icg_modem_en = icg_modem_update; +} + +FORCE_INLINE_ATTR void pmu_ll_imm_set_lp_rootclk_sel(pmu_dev_t *hw, bool rootclk_sel) +{ + if (rootclk_sel) { + hw->imm.lp_icg.tie_high_lp_rootclk_sel = 1; + } else { + hw->imm.lp_icg.tie_low_lp_rootclk_sel = 1; + } +} + +FORCE_INLINE_ATTR void pmu_ll_imm_set_hp_pad_hold_all(pmu_dev_t *hw, bool hold_all) +{ + if (hold_all) { + hw->imm.pad_hold_all.tie_high_hp_pad_hold_all = 1; + } else { + hw->imm.pad_hold_all.tie_low_hp_pad_hold_all = 1; + } +} + +FORCE_INLINE_ATTR void pmu_ll_imm_set_lp_pad_hold_all(pmu_dev_t *hw, bool hold_all) +{ + if (hold_all) { + hw->imm.pad_hold_all.tie_high_lp_pad_hold_all = 1; + } else { + hw->imm.pad_hold_all.tie_low_lp_pad_hold_all = 1; + } +} + +/*** */ +FORCE_INLINE_ATTR void pmu_ll_hp_set_power_force_reset(pmu_dev_t *hw, pmu_hp_power_domain_t domain, bool rst) +{ + hw->power.hp_pd[domain].force_reset = rst; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_power_force_isolate(pmu_dev_t *hw, pmu_hp_power_domain_t domain, bool iso) +{ + hw->power.hp_pd[domain].force_iso = iso; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_power_force_power_up(pmu_dev_t *hw, pmu_hp_power_domain_t domain, bool fpu) +{ + hw->power.hp_pd[domain].force_pu = fpu; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_power_force_no_reset(pmu_dev_t *hw, pmu_hp_power_domain_t domain, bool no_rst) +{ + hw->power.hp_pd[domain].force_no_reset = no_rst; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_power_force_no_isolate(pmu_dev_t *hw, pmu_hp_power_domain_t domain, bool no_iso) +{ + hw->power.hp_pd[domain].force_no_iso = no_iso; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_power_force_power_down(pmu_dev_t *hw, pmu_hp_power_domain_t domain, bool fpd) +{ + hw->power.hp_pd[domain].force_pd = fpd; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_power_force_reset(pmu_dev_t *hw, bool rst) +{ + hw->power.lp_peri.force_reset = rst; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_power_force_isolate(pmu_dev_t *hw, bool iso) +{ + hw->power.lp_peri.force_iso = iso; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_power_force_power_up(pmu_dev_t *hw, bool fpu) +{ + hw->power.lp_peri.force_pu = fpu; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_power_force_no_reset(pmu_dev_t *hw, bool no_rst) +{ + hw->power.lp_peri.force_no_reset = no_rst; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_power_force_no_isolate(pmu_dev_t *hw, bool no_iso) +{ + hw->power.lp_peri.force_no_iso = no_iso; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_power_force_power_down(pmu_dev_t *hw, bool fpd) +{ + hw->power.lp_peri.force_pd = fpd; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_memory_isolate(pmu_dev_t *hw, uint32_t iso) +{ + hw->power.mem_cntl.force_hp_mem_iso = iso; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_memory_power_down(pmu_dev_t *hw, uint32_t fpd) +{ + hw->power.mem_cntl.force_hp_mem_pd = fpd; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_memory_no_isolate(pmu_dev_t *hw, uint32_t no_iso) +{ + hw->power.mem_cntl.force_hp_mem_no_iso = no_iso; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_memory_power_up(pmu_dev_t *hw, uint32_t fpu) +{ + hw->power.mem_cntl.force_hp_mem_pu = fpu; +} + +/*** */ +FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_enable(pmu_dev_t *hw) +{ + hw->wakeup.cntl0.sleep_req = 1; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_reject_enable(pmu_dev_t *hw, uint32_t reject) +{ + hw->wakeup.cntl1.sleep_reject_ena = reject; + hw->wakeup.cntl1.slp_reject_en = 1; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_reject_disable(pmu_dev_t *hw) +{ + hw->wakeup.cntl1.slp_reject_en = 0; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_wakeup_enable(pmu_dev_t *hw, uint32_t wakeup) +{ + hw->wakeup.cntl2 = wakeup; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_sleep_protect_mode(pmu_dev_t *hw, int mode) +{ + hw->wakeup.cntl3.sleep_prt_sel = mode; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_min_sleep_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle) +{ + hw->wakeup.cntl3.hp_min_slp_val = slow_clk_cycle; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_clear_reject_cause(pmu_dev_t *hw) +{ + hw->wakeup.cntl4.slp_reject_cause_clr = 1; +} + +FORCE_INLINE_ATTR bool pmu_ll_hp_is_sleep_wakeup(pmu_dev_t *hw) +{ + return (hw->hp_ext.int_raw.wakeup == 1); +} + +FORCE_INLINE_ATTR bool pmu_ll_hp_is_sleep_reject(pmu_dev_t *hw) +{ + return (hw->hp_ext.int_raw.reject == 1); +} + +FORCE_INLINE_ATTR void pmu_ll_hp_clear_wakeup_intr_status(pmu_dev_t *hw) +{ + hw->hp_ext.int_clr.wakeup = 1; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_clear_reject_intr_status(pmu_dev_t *hw) +{ + hw->hp_ext.int_clr.reject = 1; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_wakeup_cause(pmu_dev_t *hw) +{ + return hw->wakeup.status0; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_reject_cause(pmu_dev_t *hw) +{ + return hw->wakeup.status1; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_min_sleep_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle) +{ + hw->wakeup.cntl3.lp_min_slp_val = slow_clk_cycle; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_modify_icg_cntl_wait_cycle(pmu_dev_t *hw, uint32_t cycle) +{ + hw->hp_ext.clk_cntl.modify_icg_cntl_wait = cycle; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_modify_icg_cntl_wait_cycle(pmu_dev_t *hw) +{ + return hw->hp_ext.clk_cntl.modify_icg_cntl_wait; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_switch_icg_cntl_wait_cycle(pmu_dev_t *hw, uint32_t cycle) +{ + hw->hp_ext.clk_cntl.switch_icg_cntl_wait = cycle; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_switch_icg_cntl_wait_cycle(pmu_dev_t *hw) +{ + return hw->hp_ext.clk_cntl.switch_icg_cntl_wait; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_digital_power_down_wait_cycle(pmu_dev_t *hw, uint32_t cycle) +{ + hw->power.wait_timer0.powerdown_timer = cycle; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_digital_power_down_wait_cycle(pmu_dev_t *hw) +{ + return hw->power.wait_timer0.powerdown_timer; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_digital_power_down_wait_cycle(pmu_dev_t *hw, uint32_t cycle) +{ + hw->power.wait_timer1.powerdown_timer = cycle; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_down_wait_cycle(pmu_dev_t *hw) +{ + return hw->power.wait_timer1.powerdown_timer; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_analog_wait_target_cycle(pmu_dev_t *hw, uint32_t slow_clk_cycle) +{ + hw->wakeup.cntl5.lp_ana_wait_target = slow_clk_cycle; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_analog_wait_target_cycle(pmu_dev_t *hw) +{ + return hw->wakeup.cntl5.lp_ana_wait_target; +} + +FORCE_INLINE_ATTR void pmu_ll_set_modem_wait_target_cycle(pmu_dev_t *hw, uint32_t cycle) +{ + hw->wakeup.cntl5.modem_wait_target = cycle; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_get_modem_wait_target_cycle(pmu_dev_t *hw) +{ + return hw->wakeup.cntl5.modem_wait_target; +} + +FORCE_INLINE_ATTR void pmu_ll_set_xtal_stable_wait_cycle(pmu_dev_t *hw, uint32_t cycle) +{ + hw->power.clk_wait.wait_xtal_stable = cycle; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_get_xtal_stable_wait_cycle(pmu_dev_t *hw) +{ + return hw->power.clk_wait.wait_xtal_stable; +} + +FORCE_INLINE_ATTR void pmu_ll_set_pll_stable_wait_cycle(pmu_dev_t *hw, uint32_t cycle) +{ + hw->power.clk_wait.wait_pll_stable = cycle; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_get_pll_stable_wait_cycle(pmu_dev_t *hw) +{ + return hw->power.clk_wait.wait_pll_stable; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_digital_power_supply_wait_cycle(pmu_dev_t *hw, uint32_t cycle) +{ + hw->power.wait_timer1.wait_timer = cycle; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_supply_wait_cycle(pmu_dev_t *hw) +{ + return hw->power.wait_timer1.wait_timer; +} + +FORCE_INLINE_ATTR void pmu_ll_lp_set_digital_power_up_wait_cycle(pmu_dev_t *hw, uint32_t cycle) +{ + hw->power.wait_timer1.powerup_timer = cycle; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_lp_get_digital_power_up_wait_cycle(pmu_dev_t *hw) +{ + return hw->power.wait_timer1.powerup_timer; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_analog_wait_target_cycle(pmu_dev_t *hw, uint32_t cycle) +{ + hw->wakeup.cntl7.ana_wait_target = cycle; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_analog_wait_target_cycle(pmu_dev_t *hw) +{ + return hw->wakeup.cntl7.ana_wait_target; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_digital_power_supply_wait_cycle(pmu_dev_t *hw, uint32_t cycle) +{ + hw->power.wait_timer0.wait_timer = cycle; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_digital_power_supply_wait_cycle(pmu_dev_t *hw) +{ + return hw->power.wait_timer0.wait_timer; +} + +FORCE_INLINE_ATTR void pmu_ll_hp_set_digital_power_up_wait_cycle(pmu_dev_t *hw, uint32_t cycle) +{ + hw->power.wait_timer0.powerup_timer = cycle; +} + +FORCE_INLINE_ATTR uint32_t pmu_ll_hp_get_digital_power_up_wait_cycle(pmu_dev_t *hw) +{ + return hw->power.wait_timer0.powerup_timer; +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c6/include/hal/rtc_cntl_ll.h b/components/hal/esp32c6/include/hal/rtc_cntl_ll.h deleted file mode 100644 index 25a1f55372..0000000000 --- a/components/hal/esp32c6/include/hal/rtc_cntl_ll.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#include "soc/soc.h" -#include "soc/rtc.h" -#include "soc/lp_aon_reg.h" -#include "esp_attr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -FORCE_INLINE_ATTR void rtc_cntl_ll_set_wakeup_timer(uint64_t t) -{ - // TODO: IDF-5645 -} - -FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_gpio_get_wakeup_status(void) -{ - // TODO: IDF-5645 - return 0; -} - -FORCE_INLINE_ATTR void rtc_cntl_ll_gpio_clear_wakeup_status(void) -{ - // TODO: IDF-5645 -} - -FORCE_INLINE_ATTR void rtc_cntl_ll_set_cpu_retention_link_addr(uint32_t addr) -{ - // TODO: IDF-5718 has removed the retention feature -} - -FORCE_INLINE_ATTR void rtc_cntl_ll_enable_cpu_retention_clock(void) -{ - // TODO: IDF-5718 has removed the retention feature -} - -FORCE_INLINE_ATTR void rtc_cntl_ll_enable_cpu_retention(void) -{ - // TODO: IDF-5718 has removed the retention feature -} - -FORCE_INLINE_ATTR void rtc_cntl_ll_disable_cpu_retention(void) -{ - // TODO: IDF-5718 has removed the retention feature -} - -FORCE_INLINE_ATTR void rtc_cntl_ll_reset_system(void) -{ - REG_SET_BIT(LP_AON_SYS_CFG_REG, LP_AON_HPSYS_SW_RESET); -} - -FORCE_INLINE_ATTR void rtc_cntl_ll_reset_cpu(int cpu_no) -{ - REG_SET_BIT(LP_AON_CPUCORE0_CFG_REG, LP_AON_CPU_CORE0_SW_RESET); -} - -FORCE_INLINE_ATTR void rtc_cntl_ll_sleep_enable(void) -{ - // TODO: IDF-6064 -} - -FORCE_INLINE_ATTR uint64_t rtc_cntl_ll_get_rtc_time(void) -{ - // TODO: IDF-6064 - return 0; -} - -FORCE_INLINE_ATTR uint64_t rtc_cntl_ll_time_to_count(uint64_t time_in_us) -{ - // TODO: IDF-6064 - return 0; -} - -FORCE_INLINE_ATTR uint32_t rtc_cntl_ll_get_wakeup_cause(void) -{ - // TODO: IDF-6064 - return 0; -} - -#ifdef __cplusplus -} -#endif diff --git a/components/hal/esp32c6/include/hal/rtc_io_ll.h b/components/hal/esp32c6/include/hal/rtc_io_ll.h index 46a5503162..8d081f90ad 100644 --- a/components/hal/esp32c6/include/hal/rtc_io_ll.h +++ b/components/hal/esp32c6/include/hal/rtc_io_ll.h @@ -247,7 +247,7 @@ static inline void rtcio_ll_force_hold_disable(int rtcio_num) */ static inline void rtcio_ll_deep_sleep_hold_en_all(void) { - PMU.imm_pad_hold_all.tie_high_lp_pad_hold_all = 1; + PMU.imm.pad_hold_all.tie_high_lp_pad_hold_all = 1; } /** @@ -255,7 +255,7 @@ static inline void rtcio_ll_deep_sleep_hold_en_all(void) */ static inline void rtcio_ll_deep_sleep_hold_dis_all(void) { - PMU.imm_pad_hold_all.tie_low_lp_pad_hold_all = 1; + PMU.imm.pad_hold_all.tie_low_lp_pad_hold_all = 1; } /** diff --git a/components/hal/esp32c6/include/hal/uart_ll.h b/components/hal/esp32c6/include/hal/uart_ll.h index 543ebfcbda..20f9729049 100644 --- a/components/hal/esp32c6/include/hal/uart_ll.h +++ b/components/hal/esp32c6/include/hal/uart_ll.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -76,7 +76,7 @@ typedef enum { UART_INTR_RS485_FRM_ERR = (0x1 << 16), UART_INTR_RS485_CLASH = (0x1 << 17), UART_INTR_CMD_CHAR_DET = (0x1 << 18), - // UART_INTR_WAKEUP = (0x1 << 19), // TODO: Test UART wakeup while supporting sleep + UART_INTR_WAKEUP = (0x1 << 19), } uart_intr_t; /** diff --git a/components/hal/esp32c6/lp_timer_hal.c b/components/hal/esp32c6/lp_timer_hal.c new file mode 100644 index 0000000000..caba3725f8 --- /dev/null +++ b/components/hal/esp32c6/lp_timer_hal.c @@ -0,0 +1,46 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "sdkconfig.h" +#include "esp_attr.h" +#include "soc/soc.h" +#include "hal/lp_timer_ll.h" + +static DRAM_ATTR struct { + lp_timer_dev_t *dev; +} lp_timer_context = { .dev = &LP_TIMER }; + +void IRAM_ATTR lp_timer_hal_set_alarm_target(uint8_t timer_id, uint64_t value) +{ + lp_timer_ll_clear_alarm_intr_status(lp_timer_context.dev); + lp_timer_ll_set_alarm_target(lp_timer_context.dev, timer_id, value); + lp_timer_ll_set_target_enable(lp_timer_context.dev, timer_id, true); +} + +uint64_t IRAM_ATTR lp_timer_hal_get_cycle_count(uint8_t timer_id) +{ + lp_timer_ll_counter_snapshot(lp_timer_context.dev); + uint32_t lo = lp_timer_ll_get_counter_value_low(lp_timer_context.dev, timer_id); + uint32_t hi = lp_timer_ll_get_counter_value_high(lp_timer_context.dev, timer_id); + lp_timer_counter_value_t result = { + .lo = lo, + .hi = hi + }; + return result.val; +} + +void IRAM_ATTR lp_timer_hal_clear_alarm_intr_status(void) +{ + lp_timer_ll_clear_alarm_intr_status(lp_timer_context.dev); +} + +void IRAM_ATTR lp_timer_hal_clear_overflow_intr_status(void) +{ + lp_timer_ll_clear_overflow_intr_status(lp_timer_context.dev); +} diff --git a/components/hal/esp32c6/pmu_hal.c b/components/hal/esp32c6/pmu_hal.c new file mode 100644 index 0000000000..4997eacce6 --- /dev/null +++ b/components/hal/esp32c6/pmu_hal.c @@ -0,0 +1,70 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +// The HAL layer for PMU (ESP32-C6 specific part) + +#include "soc/soc.h" +#include "esp_attr.h" +#include "hal/pmu_hal.h" +#include "hal/pmu_types.h" + +void IRAM_ATTR pmu_hal_hp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle) +{ + pmu_ll_hp_set_digital_power_supply_wait_cycle(hal->dev, power_supply_wait_cycle); + pmu_ll_hp_set_digital_power_up_wait_cycle(hal->dev, power_up_wait_cycle); +} + +uint32_t IRAM_ATTR pmu_hal_hp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal) +{ + uint32_t power_supply_wait_cycle = pmu_ll_hp_get_digital_power_supply_wait_cycle(hal->dev); + uint32_t power_up_wait_cycle = pmu_ll_hp_get_digital_power_up_wait_cycle(hal->dev); + return power_supply_wait_cycle + power_up_wait_cycle; +} + +void IRAM_ATTR pmu_hal_lp_set_digital_power_up_wait_cycle(pmu_hal_context_t *hal, uint32_t power_supply_wait_cycle, uint32_t power_up_wait_cycle) +{ + pmu_ll_lp_set_digital_power_supply_wait_cycle(hal->dev, power_supply_wait_cycle); + pmu_ll_lp_set_digital_power_up_wait_cycle(hal->dev, power_up_wait_cycle); +} + +uint32_t IRAM_ATTR pmu_hal_lp_get_digital_power_up_wait_cycle(pmu_hal_context_t *hal) +{ + uint32_t power_supply_wait_cycle = pmu_ll_lp_get_digital_power_supply_wait_cycle(hal->dev); + uint32_t power_up_wait_cycle = pmu_ll_lp_get_digital_power_up_wait_cycle(hal->dev); + return power_supply_wait_cycle + power_up_wait_cycle; +} + +void pmu_hal_hp_set_sleep_active_backup_enable(pmu_hal_context_t *hal) +{ + pmu_ll_hp_set_active_to_sleep_backup_enable(hal->dev); + pmu_ll_hp_set_sleep_to_active_backup_enable(hal->dev); +} + +void pmu_hal_hp_set_sleep_active_backup_disable(pmu_hal_context_t *hal) +{ + pmu_ll_hp_set_sleep_to_active_backup_disable(hal->dev); + pmu_ll_hp_set_active_to_sleep_backup_disable(hal->dev); +} + +void pmu_hal_hp_set_sleep_modem_backup_enable(pmu_hal_context_t *hal) +{ + pmu_ll_hp_set_sleep_to_modem_backup_enable(hal->dev); +} + +void pmu_hal_hp_set_sleep_modem_backup_disable(pmu_hal_context_t *hal) +{ + pmu_ll_hp_set_sleep_to_modem_backup_disable(hal->dev); +} + +void pmu_hal_hp_set_modem_active_backup_enable(pmu_hal_context_t *hal) +{ + pmu_ll_hp_set_modem_to_active_backup_enable(hal->dev); +} + +void pmu_hal_hp_set_modem_active_backup_disable(pmu_hal_context_t *hal) +{ + pmu_ll_hp_set_modem_to_active_backup_disable(hal->dev); +} diff --git a/components/hal/esp32c6/rtc_cntl_hal.c b/components/hal/esp32c6/rtc_cntl_hal.c deleted file mode 100644 index ebcfb668f6..0000000000 --- a/components/hal/esp32c6/rtc_cntl_hal.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -// The HAL layer for RTC CNTL (common part) - -#include "soc/soc_caps.h" -#include "soc/lldesc.h" -#include "hal/dma_types.h" -#include "hal/rtc_hal.h" -#include "hal/assert.h" -#include "esp_attr.h" - -#define RTC_CNTL_HAL_LINK_BUF_SIZE_MIN (SOC_RTC_CNTL_CPU_PD_DMA_BLOCK_SIZE) /* The minimum size of dma link buffer */ - -typedef struct rtc_cntl_link_buf_conf { - uint32_t cfg[4]; /* 4 word for dma link buffer configuration */ -} rtc_cntl_link_buf_conf_t; - -void * rtc_cntl_hal_dma_link_init(void *elem, void *buff, int size, void *next) -{ - HAL_ASSERT(elem != NULL); - HAL_ASSERT(buff != NULL); - HAL_ASSERT(size >= RTC_CNTL_HAL_LINK_BUF_SIZE_MIN); - - lldesc_t *plink = (lldesc_t *)elem; - - plink->eof = next ? 0 : 1; - plink->owner = DMA_DESCRIPTOR_BUFFER_OWNER_DMA; - plink->size = size >> 4; /* in unit of 16 bytes */ - plink->length = size >> 4; - plink->buf = buff; - plink->offset = 0; - plink->sosf = 0; - STAILQ_NEXT(plink, qe) = next; - return (void *)plink; -} - -#if SOC_PM_SUPPORT_CPU_PD - -void rtc_cntl_hal_enable_cpu_retention(void *addr) -{ - // TODO: IDF-5718 has removed the retention feature -} - -void IRAM_ATTR rtc_cntl_hal_disable_cpu_retention(void *addr) -{ - // TODO: IDF-5718 has removed the retention feature -} - -#endif // SOC_PM_SUPPORT_CPU_PD diff --git a/components/hal/include/hal/lp_timer_types.h b/components/hal/include/hal/lp_timer_types.h new file mode 100644 index 0000000000..ebb808ca50 --- /dev/null +++ b/components/hal/include/hal/lp_timer_types.h @@ -0,0 +1,32 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "soc/soc_caps.h" + +/** + * @brief The structure of the counter value in lower power timer + */ +typedef struct { + union { + struct { + uint32_t lo: SOC_LP_TIMER_BIT_WIDTH_LO; /*!< Low part of counter value */ + uint32_t hi: SOC_LP_TIMER_BIT_WIDTH_HI; /*!< High part of counter value */ + uint32_t reserved: 16; + }; + uint64_t val; /*!< counter value */ + }; +} lp_timer_counter_value_t; + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/include/hal/pmu_types.h b/components/hal/include/hal/pmu_types.h new file mode 100644 index 0000000000..75aacbd101 --- /dev/null +++ b/components/hal/include/hal/pmu_types.h @@ -0,0 +1,166 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + * @brief PMU modes of HP system + */ +typedef enum { + PMU_MODE_HP_ACTIVE = 0, /*!< PMU in HP_ACTIVE mode */ + PMU_MODE_HP_MODEM, /*!< PMU in HP_MODEM mode */ + PMU_MODE_HP_SLEEP, /*!< PMU in HP_SLEEP mode */ + PMU_MODE_HP_MAX, +} pmu_hp_mode_t; + +/** + * @brief PMU modes of LP system + */ +typedef enum { + PMU_MODE_LP_ACTIVE = 0, /*!< PMU in LP_ACTIVE mode */ + PMU_MODE_LP_SLEEP, /*!< PMU in LP_SLEEP mode */ + PMU_MODE_LP_MAX, +} pmu_lp_mode_t; + +typedef enum { + PMU_HP_PD_TOP = 0, /* Power domain of digital top */ + PMU_HP_PD_AON, /* Power domain of always-on */ + PMU_HP_PD_CPU, /* Power domain of HP CPU */ + PMU_HP_PD_RESERVED, /* Reserved power domain*/ + PMU_HP_PD_WIFI, /* Power domain of WIFI */ + PMU_HP_PD_MAX +} pmu_hp_power_domain_t; + + +/* Software configuration instance type from pmu_struct.h */ +typedef union { + struct { + uint32_t reserved0 : 21; + uint32_t vdd_spi_pd_en: 1; + uint32_t mem_dslp : 1; + uint32_t mem_pd_en : 4; + uint32_t wifi_pd_en : 1; + uint32_t reserved1 : 1; + uint32_t cpu_pd_en : 1; + uint32_t aon_pd_en : 1; + uint32_t top_pd_en : 1; + }; + struct { + uint32_t reserved2 : 26; + uint32_t i2c_iso_en : 1; + uint32_t i2c_retention: 1; + uint32_t xpd_bb_i2c : 1; + uint32_t xpd_bbpll_i2c: 1; + uint32_t xpd_bbpll : 1; + uint32_t reserved3 : 1; + }; + struct { + uint32_t reserved4 : 31; + uint32_t xpd_xtal : 1; + }; + uint32_t val; +} pmu_hp_power_t; + +typedef union { + struct { + uint32_t reserved0 : 30; + uint32_t mem_dslp : 1; + uint32_t peri_pd_en: 1; + }; + struct { + uint32_t reserved1 : 28; + uint32_t xpd_xtal32k: 1; + uint32_t xpd_rc32k : 1; + uint32_t xpd_fosc : 1; + uint32_t pd_osc : 1; + }; + struct { + uint32_t reserved2 : 31; + uint32_t xpd_xtal : 1; + }; + uint32_t val; +} pmu_lp_power_t; + +typedef struct { + struct { + uint32_t reserved0 : 25; + uint32_t xpd_bias : 1; + uint32_t dbg_atten : 4; + uint32_t pd_cur : 1; + uint32_t bias_sleep: 1; + }; + struct { + uint32_t reserved1 : 16; + uint32_t slp_mem_xpd : 1; + uint32_t slp_logic_xpd : 1; + uint32_t xpd : 1; + uint32_t slp_mem_dbias : 4; + uint32_t slp_logic_dbias: 4; + uint32_t dbias : 5; + }; + struct { + uint32_t reserved2: 8; + uint32_t drv_b : 24; + }; +} pmu_hp_analog_t; + +typedef struct { + struct { + uint32_t reserved0 : 25; + uint32_t xpd_bias : 1; + uint32_t dbg_atten : 4; + uint32_t pd_cur : 1; + uint32_t bias_sleep: 1; + }; + struct { + uint32_t reserved1: 21; + uint32_t slp_xpd : 1; + uint32_t xpd : 1; + uint32_t slp_dbias: 4; + uint32_t dbias : 5; + }; + struct { + uint32_t reserved2: 28; + uint32_t drv_b : 4; + }; +} pmu_lp_analog_t; + +typedef struct { + uint32_t modem_wakeup_wait_cycle; + uint16_t analog_wait_target_cycle; + uint16_t digital_power_down_wait_cycle; + uint16_t digital_power_supply_wait_cycle; + uint16_t digital_power_up_wait_cycle; + uint16_t pll_stable_wait_cycle; + uint8_t modify_icg_cntl_wait_cycle; + uint8_t switch_icg_cntl_wait_cycle; + uint8_t min_slp_slow_clk_cycle; +} pmu_hp_param_t; + +typedef struct { + uint16_t digital_power_supply_wait_cycle; + uint8_t min_slp_slow_clk_cycle; + uint8_t analog_wait_target_cycle; + uint8_t digital_power_down_wait_cycle; + uint8_t digital_power_up_wait_cycle; +} pmu_lp_param_t; + +typedef struct { + union { + uint16_t xtal_stable_wait_slow_clk_cycle; + uint16_t xtal_stable_wait_cycle; + }; +} pmu_hp_lp_param_t; + +#ifdef __cplusplus +} +#endif diff --git a/components/riscv/include/riscv/rvsleep-frames.h b/components/riscv/include/riscv/rvsleep-frames.h new file mode 100644 index 0000000000..06b2b75d8c --- /dev/null +++ b/components/riscv/include/riscv/rvsleep-frames.h @@ -0,0 +1,153 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __RVSLEEP_FRAMES_H__ +#define __RVSLEEP_FRAMES_H__ + +/* Align a value up to nearest n-byte boundary, where n is a power of 2. */ +#define ALIGNUP(n, val) (((val) + (n) - 1) & -(n)) + +#ifdef STRUCT_BEGIN +#undef STRUCT_BEGIN +#undef STRUCT_FIELD +#undef STRUCT_AFIELD +#undef STRUCT_END +#endif + +#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__) +#ifdef __clang__ +#define STRUCT_BEGIN .set RV_STRUCT_OFFSET, 0 +#define STRUCT_FIELD(ctype,size,asname,name) .set asname, RV_STRUCT_OFFSET; .set RV_STRUCT_OFFSET, asname + size +#define STRUCT_AFIELD(ctype,size,asname,name,n) .set asname, RV_STRUCT_OFFSET;\ + .set RV_STRUCT_OFFSET, asname + (size)*(n); +#define STRUCT_END(sname) .set sname##Size, RV_STRUCT_OFFSET; +#else // __clang__ +#define STRUCT_BEGIN .pushsection .text; .struct 0 +#define STRUCT_FIELD(ctype,size,asname,name) asname: .space size +#define STRUCT_AFIELD(ctype,size,asname,name,n) asname: .space (size)*(n) +#define STRUCT_END(sname) sname##Size:; .popsection +#endif // __clang__ +#else +#define STRUCT_BEGIN typedef struct { +#define STRUCT_FIELD(ctype,size,asname,name) ctype name; +#define STRUCT_AFIELD(ctype,size,asname,name,n) ctype name[n]; +#define STRUCT_END(sname) } sname; +#endif + +/* + * ------------------------------------------------------------------------------- + * RISC-V CORE CRITICAL REGISTER CONTEXT LAYOUT FOR SLEEP + * ------------------------------------------------------------------------------- + */ +STRUCT_BEGIN + STRUCT_FIELD (long, 4, RV_SLP_CTX_MEPC, mepc) /* Machine Exception Program Counter */ + STRUCT_FIELD (long, 4, RV_SLP_CTX_RA, ra) /* Return address */ + STRUCT_FIELD (long, 4, RV_SLP_CTX_SP, sp) /* Stack pointer */ + STRUCT_FIELD (long, 4, RV_SLP_CTX_GP, gp) /* Global pointer */ + STRUCT_FIELD (long, 4, RV_SLP_CTX_TP, tp) /* Thread pointer */ + STRUCT_FIELD (long, 4, RV_SLP_CTX_T0, t0) /* Temporary/alternate link register */ + STRUCT_FIELD (long, 4, RV_SLP_CTX_T1, t1) /* t1-2: Temporaries */ + STRUCT_FIELD (long, 4, RV_SLP_CTX_T2, t2) + STRUCT_FIELD (long, 4, RV_SLP_CTX_S0, s0) /* Saved register/frame pointer */ + STRUCT_FIELD (long, 4, RV_SLP_CTX_S1, s1) /* Saved register */ + STRUCT_FIELD (long, 4, RV_SLP_CTX_A0, a0) /* a0-1: Function arguments/return address */ + STRUCT_FIELD (long, 4, RV_SLP_CTX_A1, a1) + STRUCT_FIELD (long, 4, RV_SLP_CTX_A2, a2) /* a2-7: Function arguments */ + STRUCT_FIELD (long, 4, RV_SLP_CTX_A3, a3) + STRUCT_FIELD (long, 4, RV_SLP_CTX_A4, a4) + STRUCT_FIELD (long, 4, RV_SLP_CTX_A5, a5) + STRUCT_FIELD (long, 4, RV_SLP_CTX_A6, a6) + STRUCT_FIELD (long, 4, RV_SLP_CTX_A7, a7) + STRUCT_FIELD (long, 4, RV_SLP_CTX_S2, s2) /* s2-11: Saved registers */ + STRUCT_FIELD (long, 4, RV_SLP_CTX_S3, s3) + STRUCT_FIELD (long, 4, RV_SLP_CTX_S4, s4) + STRUCT_FIELD (long, 4, RV_SLP_CTX_S5, s5) + STRUCT_FIELD (long, 4, RV_SLP_CTX_S6, s6) + STRUCT_FIELD (long, 4, RV_SLP_CTX_S7, s7) + STRUCT_FIELD (long, 4, RV_SLP_CTX_S8, s8) + STRUCT_FIELD (long, 4, RV_SLP_CTX_S9, s9) + STRUCT_FIELD (long, 4, RV_SLP_CTX_S10, s10) + STRUCT_FIELD (long, 4, RV_SLP_CTX_S11, s11) + STRUCT_FIELD (long, 4, RV_SLP_CTX_T3, t3) /* t3-6: Temporaries */ + STRUCT_FIELD (long, 4, RV_SLP_CTX_T4, t4) + STRUCT_FIELD (long, 4, RV_SLP_CTX_T5, t5) + STRUCT_FIELD (long, 4, RV_SLP_CTX_T6, t6) + STRUCT_FIELD (long, 4, RV_SLP_CTX_MSTATUS, mstatus) /* Machine Status */ + STRUCT_FIELD (long, 4, RV_SLP_CTX_MTVEC, mtvec) /* Machine Trap-Vector Base Address */ + STRUCT_FIELD (long, 4, RV_SLP_CTX_MCAUSE, mcause) /* Machine Trap Cause */ + STRUCT_FIELD (long, 4, RV_SLP_CTX_MTVAL, mtval) /* Machine Trap Value */ + STRUCT_FIELD (long, 4, RV_SLP_CTX_MIE, mie) /* Machine intr enable */ + STRUCT_FIELD (long, 4, RV_SLP_CTX_MIP, mip) /* Machine intr pending */ + + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMUFUNC, pmufunc) /* A field is used to identify whether it is going + * to sleep or has just been awakened. We use the + * lowest 2 bits as indication infomation, 3 means + * being awakened, 1 means going to sleep */ +STRUCT_END(RvCoreCriticalSleepFrame) + +#if defined(_ASMLANGUAGE) || defined(__ASSEMBLER__) +#define RV_SLEEP_CTX_SZ1 RvCoreCriticalSleepFrameSize +#else +#define RV_SLEEP_CTX_SZ1 sizeof(RvCoreCriticalSleepFrame) +#endif + +/* + * Sleep stack frame size, after align up to 16 bytes boundary + */ +#define RV_SLEEP_CTX_FRMSZ (ALIGNUP(0x10, RV_SLEEP_CTX_SZ1)) + +/* + * ------------------------------------------------------------------------------- + * RISC-V CORE NON-CRITICAL REGISTER CONTEXT LAYOUT FOR SLEEP + * ------------------------------------------------------------------------------- + */ +STRUCT_BEGIN + STRUCT_FIELD (long, 4, RV_SLP_CTX_MSCRATCH, mscratch) + STRUCT_FIELD (long, 4, RV_SLP_CTX_MIDELEG, mideleg) + STRUCT_FIELD (long, 4, RV_SLP_CTX_MISA, misa) + STRUCT_FIELD (long, 4, RV_SLP_CTX_TSELECT, tselect) + STRUCT_FIELD (long, 4, RV_SLP_CTX_TDATA1, tdata1) + STRUCT_FIELD (long, 4, RV_SLP_CTX_TDATA2, tdata2) + STRUCT_FIELD (long, 4, RV_SLP_CTX_TCONTROL, tcontrol) + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPCFG0, pmpcfg0) + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPCFG1, pmpcfg1) + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPCFG2, pmpcfg2) + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPCFG3, pmpcfg3) + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR0, pmpaddr0) + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR1, pmpaddr1) + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR2, pmpaddr2) + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR3, pmpaddr3) + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR4, pmpaddr4) + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR5, pmpaddr5) + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR6, pmpaddr6) + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR7, pmpaddr7) + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR8, pmpaddr8) + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR9, pmpaddr9) + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR10, pmpaddr10) + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR11, pmpaddr11) + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR12, pmpaddr12) + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR13, pmpaddr13) + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR14, pmpaddr14) + STRUCT_FIELD (long, 4, RV_SLP_CTX_PMPADDR15, pmpaddr15) + + STRUCT_FIELD (long, 4, RV_SLP_CTX_UTVEC, utvec) + STRUCT_FIELD (long, 4, RV_SLP_CTX_USTATUS, ustatus) + STRUCT_FIELD (long, 4, RV_SLP_CTX_UEPC, uepc) + STRUCT_FIELD (long, 4, RV_SLP_CTX_UCAUSE, ucause) + + STRUCT_FIELD (long, 4, RV_SLP_CTX_MPCER, mpcer) + STRUCT_FIELD (long, 4, RV_SLP_CTX_MPCMR, mpcmr) + STRUCT_FIELD (long, 4, RV_SLP_CTX_MPCCR, mpccr) + STRUCT_FIELD (long, 4, RV_SLP_CTX_CPU_TESTBUS_CTRL, cpu_testbus_ctrl) + STRUCT_FIELD (long, 4, RV_SLP_CTX_UPCER, upcer) + STRUCT_FIELD (long, 4, RV_SLP_CTX_UPCMR, upcmr) + STRUCT_FIELD (long, 4, RV_SLP_CTX_UPCCR, upccr) + STRUCT_FIELD (long, 4, RV_SLP_CTX_UGPIO_OEN, ugpio_oen) + STRUCT_FIELD (long, 4, RV_SLP_CTX_UGPIO_IN, ugpio_in) + STRUCT_FIELD (long, 4, RV_SLP_CTX_UGPIO_OUT, ugpio_out) +STRUCT_END(RvCoreNonCriticalSleepFrame) + +#endif /* #ifndef __RVSLEEP_FRAMES_H__ */ diff --git a/components/soc/esp32/include/soc/Kconfig.soc_caps.in b/components/soc/esp32/include/soc/Kconfig.soc_caps.in index fdba1a66e4..7d015b5064 100644 --- a/components/soc/esp32/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32/include/soc/Kconfig.soc_caps.in @@ -743,6 +743,14 @@ config SOC_PM_SUPPORT_RC_FAST_PD bool default y +config SOC_PM_SUPPORT_VDDSDIO_PD + bool + default y + +config SOC_CONFIGURABLE_VDDSDIO_SUPPORTED + bool + default y + config SOC_CLK_APLL_SUPPORTED bool default y diff --git a/components/soc/esp32/include/soc/soc_caps.h b/components/soc/esp32/include/soc/soc_caps.h index f0c8ceed68..ccabb3b234 100644 --- a/components/soc/esp32/include/soc/soc_caps.h +++ b/components/soc/esp32/include/soc/soc_caps.h @@ -373,6 +373,9 @@ #define SOC_PM_SUPPORT_RTC_FAST_MEM_PD (1) #define SOC_PM_SUPPORT_RTC_SLOW_MEM_PD (1) #define SOC_PM_SUPPORT_RC_FAST_PD (1) +#define SOC_PM_SUPPORT_VDDSDIO_PD (1) + +#define SOC_CONFIGURABLE_VDDSDIO_SUPPORTED (1) /*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/ #define SOC_CLK_APLL_SUPPORTED (1) diff --git a/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in index beb59bbec8..63a076c011 100644 --- a/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in @@ -607,6 +607,10 @@ config SOC_PM_SUPPORT_RC_FAST_PD bool default y +config SOC_PM_SUPPORT_VDDSDIO_PD + bool + default y + config SOC_CLK_RC_FAST_D256_SUPPORTED bool default y diff --git a/components/soc/esp32c2/include/soc/rtc.h b/components/soc/esp32c2/include/soc/rtc.h index 2331a29758..b922a3b2eb 100644 --- a/components/soc/esp32c2/include/soc/rtc.h +++ b/components/soc/esp32c2/include/soc/rtc.h @@ -722,37 +722,6 @@ typedef struct { */ void rtc_init(rtc_config_t cfg); -/** - * Structure describing vddsdio configuration - */ -typedef struct { - uint32_t force : 1; //!< If 1, use configuration from RTC registers; if 0, use EFUSE/bootstrapping pins. - uint32_t enable : 1; //!< Enable VDDSDIO regulator - uint32_t tieh : 1; //!< Select VDDSDIO voltage. One of RTC_VDDSDIO_TIEH_1_8V, RTC_VDDSDIO_TIEH_3_3V - uint32_t drefh : 2; //!< Tuning parameter for VDDSDIO regulator - uint32_t drefm : 2; //!< Tuning parameter for VDDSDIO regulator - uint32_t drefl : 2; //!< Tuning parameter for VDDSDIO regulator -} rtc_vddsdio_config_t; - -/** - * Get current VDDSDIO configuration - * If VDDSDIO configuration is overridden by RTC, get values from RTC - * Otherwise, if VDDSDIO is configured by EFUSE, get values from EFUSE - * Otherwise, use default values and the level of MTDI bootstrapping pin. - * @return currently used VDDSDIO configuration - */ -rtc_vddsdio_config_t rtc_vddsdio_get_config(void); - -/** - * Set new VDDSDIO configuration using RTC registers. - * If config.force == 1, this overrides configuration done using bootstrapping - * pins and EFUSE. - * - * @param config new VDDSDIO configuration - */ -void rtc_vddsdio_set_config(rtc_vddsdio_config_t config); - - // -------------------------- CLOCK TREE DEFS ALIAS ---------------------------- // **WARNING**: The following are only for backwards compatibility. // Please use the declarations in soc/clk_tree_defs.h instead. diff --git a/components/soc/esp32c2/include/soc/soc_caps.h b/components/soc/esp32c2/include/soc/soc_caps.h index ff1e37c06e..a7fdb1db60 100644 --- a/components/soc/esp32c2/include/soc/soc_caps.h +++ b/components/soc/esp32c2/include/soc/soc_caps.h @@ -289,6 +289,7 @@ #define SOC_PM_SUPPORT_WIFI_PD (0) #define SOC_PM_SUPPORT_BT_PD (0) #define SOC_PM_SUPPORT_RC_FAST_PD (1) +#define SOC_PM_SUPPORT_VDDSDIO_PD (1) /*--------------------------- CLOCK SUBSYSTEM CAPS -------------------------- */ #define SOC_CLK_RC_FAST_D256_SUPPORTED (1) diff --git a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in index db80787dc3..ec92b0171e 100644 --- a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in @@ -863,6 +863,14 @@ config SOC_PM_SUPPORT_RC_FAST_PD bool default y +config SOC_PM_SUPPORT_VDDSDIO_PD + bool + default y + +config SOC_PM_CPU_RETENTION_BY_RTCCNTL + bool + default y + config SOC_CLK_RC_FAST_D256_SUPPORTED bool default y diff --git a/components/soc/esp32c3/include/soc/rtc.h b/components/soc/esp32c3/include/soc/rtc.h index 0e10a3181e..8b56920082 100644 --- a/components/soc/esp32c3/include/soc/rtc.h +++ b/components/soc/esp32c3/include/soc/rtc.h @@ -764,37 +764,6 @@ typedef struct { */ void rtc_init(rtc_config_t cfg); -/** - * Structure describing vddsdio configuration - */ -typedef struct { - uint32_t force : 1; //!< If 1, use configuration from RTC registers; if 0, use EFUSE/bootstrapping pins. - uint32_t enable : 1; //!< Enable VDDSDIO regulator - uint32_t tieh : 1; //!< Select VDDSDIO voltage. One of RTC_VDDSDIO_TIEH_1_8V, RTC_VDDSDIO_TIEH_3_3V - uint32_t drefh : 2; //!< Tuning parameter for VDDSDIO regulator - uint32_t drefm : 2; //!< Tuning parameter for VDDSDIO regulator - uint32_t drefl : 2; //!< Tuning parameter for VDDSDIO regulator -} rtc_vddsdio_config_t; - -/** - * Get current VDDSDIO configuration - * If VDDSDIO configuration is overridden by RTC, get values from RTC - * Otherwise, if VDDSDIO is configured by EFUSE, get values from EFUSE - * Otherwise, use default values and the level of MTDI bootstrapping pin. - * @return currently used VDDSDIO configuration - */ -rtc_vddsdio_config_t rtc_vddsdio_get_config(void); - -/** - * Set new VDDSDIO configuration using RTC registers. - * If config.force == 1, this overrides configuration done using bootstrapping - * pins and EFUSE. - * - * @param config new VDDSDIO configuration - */ -void rtc_vddsdio_set_config(rtc_vddsdio_config_t config); - - // -------------------------- CLOCK TREE DEFS ALIAS ---------------------------- // **WARNING**: The following are only for backwards compatibility. // Please use the declarations in soc/clk_tree_defs.h instead. diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index d68a455cdf..eb5d1ef03e 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -383,6 +383,9 @@ #define SOC_PM_SUPPORT_WIFI_PD (1) #define SOC_PM_SUPPORT_BT_PD (1) #define SOC_PM_SUPPORT_RC_FAST_PD (1) +#define SOC_PM_SUPPORT_VDDSDIO_PD (1) + +#define SOC_PM_CPU_RETENTION_BY_RTCCNTL (1) /*--------------------------- CLOCK SUBSYSTEM CAPS -------------------------- */ #define SOC_CLK_RC_FAST_D256_SUPPORTED (1) diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index e29c80be02..c7781b8e8d 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -147,6 +147,14 @@ config SOC_APM_SUPPORTED bool default y +config SOC_PMU_SUPPORTED + bool + default y + +config SOC_LP_TIMER_SUPPORTED + bool + default y + config SOC_XTAL_SUPPORT_40M bool default y @@ -659,14 +667,6 @@ config SOC_MCPWM_CLK_SUPPORT_XTAL bool default y -config SOC_RTC_CNTL_CPU_PD_DMA_BUS_WIDTH - int - default 128 - -config SOC_RTC_CNTL_CPU_PD_REG_FILE_NUM - int - default 108 - config SOC_RSA_MAX_BIT_LEN int default 3072 @@ -839,6 +839,14 @@ config SOC_SYSTIMER_SUPPORT_ETM bool default y +config SOC_LP_TIMER_BIT_WIDTH_LO + int + default 32 + +config SOC_LP_TIMER_BIT_WIDTH_HI + int + default 16 + config SOC_TIMER_GROUPS int default 2 @@ -963,6 +971,10 @@ config SOC_UART_SUPPORT_XTAL_CLK bool default y +config SOC_UART_SUPPORT_WAKEUP_INT + bool + default y + config SOC_UART_SUPPORT_FSM_TX_WAIT_SEND bool default y @@ -991,11 +1003,7 @@ config SOC_PM_SUPPORT_CPU_PD bool default y -config SOC_PM_SUPPORT_WIFI_PD - bool - default y - -config SOC_PM_SUPPORT_BT_PD +config SOC_PM_SUPPORT_MODEM_PD bool default y @@ -1011,10 +1019,18 @@ config SOC_PM_SUPPORT_RC_FAST_PD bool default y +config SOC_PM_SUPPORT_VDDSDIO_PD + bool + default y + config SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY bool default y +config SOC_PM_CPU_RETENTION_BY_SW + bool + default y + config SOC_CLK_RC_FAST_SUPPORT_CALIBRATION bool default y diff --git a/components/soc/esp32c6/include/soc/lp_timer_struct.h b/components/soc/esp32c6/include/soc/lp_timer_struct.h index a45c0b407e..98961dc895 100644 --- a/components/soc/esp32c6/include/soc/lp_timer_struct.h +++ b/components/soc/esp32c6/include/soc/lp_timer_struct.h @@ -1,5 +1,5 @@ /** - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -10,346 +10,99 @@ extern "C" { #endif -/** Group: configure_register */ -/** Type of tar0_low register - * need_des - */ -typedef union { - struct { - /** main_timer_tar_low0 : R/W; bitpos: [31:0]; default: 0; - * need_des - */ - uint32_t main_timer_tar_low0:32; - }; - uint32_t val; -} lp_timer_tar0_low_reg_t; +typedef struct { + union { + struct { + uint32_t target_lo: 32; + }; + uint32_t val; + } lo; + union { + struct { + uint32_t target_hi: 16; + uint32_t reserved0: 15; + uint32_t enable : 1; + }; + uint32_t val; + } hi; +} lp_timer_target_reg_t; -/** Type of tar0_high register - * need_des - */ typedef union { struct { - /** main_timer_tar_high0 : R/W; bitpos: [15:0]; default: 0; - * need_des - */ - uint32_t main_timer_tar_high0:16; - uint32_t reserved_16:15; - /** main_timer_tar_en0 : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t main_timer_tar_en0:1; - }; - uint32_t val; -} lp_timer_tar0_high_reg_t; - -/** Type of tar1_low register - * need_des - */ -typedef union { - struct { - /** main_timer_tar_low1 : R/W; bitpos: [31:0]; default: 0; - * need_des - */ - uint32_t main_timer_tar_low1:32; - }; - uint32_t val; -} lp_timer_tar1_low_reg_t; - -/** Type of tar1_high register - * need_des - */ -typedef union { - struct { - /** main_timer_tar_high1 : R/W; bitpos: [15:0]; default: 0; - * need_des - */ - uint32_t main_timer_tar_high1:16; - uint32_t reserved_16:15; - /** main_timer_tar_en1 : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t main_timer_tar_en1:1; - }; - uint32_t val; -} lp_timer_tar1_high_reg_t; - -/** Type of update register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:28; - /** main_timer_update : WT; bitpos: [28]; default: 0; - * need_des - */ - uint32_t main_timer_update:1; - /** main_timer_xtal_off : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t main_timer_xtal_off:1; - /** main_timer_sys_stall : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t main_timer_sys_stall:1; - /** main_timer_sys_rst : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t main_timer_sys_rst:1; + uint32_t reserved0: 28; + uint32_t update : 1; + uint32_t xtal_off : 1; + uint32_t sys_stall: 1; + uint32_t sys_rst : 1; }; uint32_t val; } lp_timer_update_reg_t; -/** Type of main_buf0_low register - * need_des - */ +typedef struct { + union { + struct { + uint32_t counter_lo: 32; + }; + uint32_t val; + } lo; + union { + struct { + uint32_t counter_hi: 16; + uint32_t reserved0 : 16; + }; + uint32_t val; + } hi; +} lp_timer_counter_reg_t; + typedef union { struct { - /** main_timer_buf0_low : RO; bitpos: [31:0]; default: 0; - * need_des - */ - uint32_t main_timer_buf0_low:32; + uint32_t reserved0: 31; + uint32_t trigger : 1; }; uint32_t val; -} lp_timer_main_buf0_low_reg_t; +} lp_timer_overflow_reg_t; -/** Type of main_buf0_high register - * need_des - */ typedef union { struct { - /** main_timer_buf0_high : RO; bitpos: [15:0]; default: 0; - * need_des - */ - uint32_t main_timer_buf0_high:16; - uint32_t reserved_16:16; + uint32_t reserved0: 30; + uint32_t overflow : 1; + uint32_t alarm : 1; }; uint32_t val; -} lp_timer_main_buf0_high_reg_t; +} lp_timer_intr_reg_t; -/** Type of main_buf1_low register - * need_des - */ typedef union { struct { - /** main_timer_buf1_low : RO; bitpos: [31:0]; default: 0; - * need_des - */ - uint32_t main_timer_buf1_low:32; + uint32_t reserved0: 30; + uint32_t overflow : 1; + uint32_t alarm : 1; }; uint32_t val; -} lp_timer_main_buf1_low_reg_t; +} lp_timer_lp_intr_reg_t; -/** Type of main_buf1_high register - * need_des - */ -typedef union { - struct { - /** main_timer_buf1_high : RO; bitpos: [15:0]; default: 0; - * need_des - */ - uint32_t main_timer_buf1_high:16; - uint32_t reserved_16:16; - }; - uint32_t val; -} lp_timer_main_buf1_high_reg_t; +typedef volatile struct lp_timer_dev_t{ + lp_timer_target_reg_t target[2]; + lp_timer_update_reg_t update; + lp_timer_counter_reg_t counter[2]; + lp_timer_overflow_reg_t overflow; + lp_timer_intr_reg_t int_raw; + lp_timer_intr_reg_t int_st; + lp_timer_intr_reg_t int_en; + lp_timer_intr_reg_t int_clr; + lp_timer_lp_intr_reg_t lp_int_raw; + lp_timer_lp_intr_reg_t lp_int_st; + lp_timer_lp_intr_reg_t lp_int_en; + lp_timer_lp_intr_reg_t lp_int_clr; -/** Type of main_overflow register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:31; - /** main_timer_alarm_load : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t main_timer_alarm_load:1; - }; - uint32_t val; -} lp_timer_main_overflow_reg_t; + uint32_t reserved[237]; -/** Type of int_raw register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:30; - /** overflow_raw : R/WTC/SS; bitpos: [30]; default: 0; - * need_des - */ - uint32_t overflow_raw:1; - /** soc_wakeup_int_raw : R/WTC/SS; bitpos: [31]; default: 0; - * need_des - */ - uint32_t soc_wakeup_int_raw:1; - }; - uint32_t val; -} lp_timer_int_raw_reg_t; - -/** Type of int_st register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:30; - /** overflow_st : RO; bitpos: [30]; default: 0; - * need_des - */ - uint32_t overflow_st:1; - /** soc_wakeup_int_st : RO; bitpos: [31]; default: 0; - * need_des - */ - uint32_t soc_wakeup_int_st:1; - }; - uint32_t val; -} lp_timer_int_st_reg_t; - -/** Type of int_ena register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:30; - /** overflow_ena : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t overflow_ena:1; - /** soc_wakeup_int_ena : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t soc_wakeup_int_ena:1; - }; - uint32_t val; -} lp_timer_int_ena_reg_t; - -/** Type of int_clr register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:30; - /** overflow_clr : WT; bitpos: [30]; default: 0; - * need_des - */ - uint32_t overflow_clr:1; - /** soc_wakeup_int_clr : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t soc_wakeup_int_clr:1; - }; - uint32_t val; -} lp_timer_int_clr_reg_t; - -/** Type of lp_int_raw register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:30; - /** main_timer_overflow_lp_int_raw : R/WTC/SS; bitpos: [30]; default: 0; - * need_des - */ - uint32_t main_timer_overflow_lp_int_raw:1; - /** main_timer_lp_int_raw : R/WTC/SS; bitpos: [31]; default: 0; - * need_des - */ - uint32_t main_timer_lp_int_raw:1; - }; - uint32_t val; -} lp_timer_lp_int_raw_reg_t; - -/** Type of lp_int_st register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:30; - /** main_timer_overflow_lp_int_st : RO; bitpos: [30]; default: 0; - * need_des - */ - uint32_t main_timer_overflow_lp_int_st:1; - /** main_timer_lp_int_st : RO; bitpos: [31]; default: 0; - * need_des - */ - uint32_t main_timer_lp_int_st:1; - }; - uint32_t val; -} lp_timer_lp_int_st_reg_t; - -/** Type of lp_int_ena register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:30; - /** main_timer_overflow_lp_int_ena : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t main_timer_overflow_lp_int_ena:1; - /** main_timer_lp_int_ena : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t main_timer_lp_int_ena:1; - }; - uint32_t val; -} lp_timer_lp_int_ena_reg_t; - -/** Type of lp_int_clr register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:30; - /** main_timer_overflow_lp_int_clr : WT; bitpos: [30]; default: 0; - * need_des - */ - uint32_t main_timer_overflow_lp_int_clr:1; - /** main_timer_lp_int_clr : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t main_timer_lp_int_clr:1; - }; - uint32_t val; -} lp_timer_lp_int_clr_reg_t; - -/** Type of date register - * need_des - */ -typedef union { - struct { - /** date : R/W; bitpos: [30:0]; default: 34672976; - * need_des - */ - uint32_t date:31; - /** clk_en : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t clk_en:1; - }; - uint32_t val; -} lp_timer_date_reg_t; - - -typedef struct lp_timer_dev_t { - volatile lp_timer_tar0_low_reg_t tar0_low; - volatile lp_timer_tar0_high_reg_t tar0_high; - volatile lp_timer_tar1_low_reg_t tar1_low; - volatile lp_timer_tar1_high_reg_t tar1_high; - volatile lp_timer_update_reg_t update; - volatile lp_timer_main_buf0_low_reg_t main_buf0_low; - volatile lp_timer_main_buf0_high_reg_t main_buf0_high; - volatile lp_timer_main_buf1_low_reg_t main_buf1_low; - volatile lp_timer_main_buf1_high_reg_t main_buf1_high; - volatile lp_timer_main_overflow_reg_t main_overflow; - volatile lp_timer_int_raw_reg_t int_raw; - volatile lp_timer_int_st_reg_t int_st; - volatile lp_timer_int_ena_reg_t int_ena; - volatile lp_timer_int_clr_reg_t int_clr; - volatile lp_timer_lp_int_raw_reg_t lp_int_raw; - volatile lp_timer_lp_int_st_reg_t lp_int_st; - volatile lp_timer_lp_int_ena_reg_t lp_int_ena; - volatile lp_timer_lp_int_clr_reg_t lp_int_clr; - uint32_t reserved_048[237]; - volatile lp_timer_date_reg_t date; + union { + struct { + uint32_t date : 31; + uint32_t clk_en: 1; + }; + uint32_t val; + } date; } lp_timer_dev_t; extern lp_timer_dev_t LP_TIMER; diff --git a/components/soc/esp32c6/include/soc/pmu_struct.h b/components/soc/esp32c6/include/soc/pmu_struct.h index f265b8fd00..db1c3869e0 100644 --- a/components/soc/esp32c6/include/soc/pmu_struct.h +++ b/components/soc/esp32c6/include/soc/pmu_struct.h @@ -1,2816 +1,754 @@ /** - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ #pragma once #include +#include #ifdef __cplusplus extern "C" { #endif -/** Group: configure_register */ -/** Type of hp_active_dig_power register - * need_des - */ +#include "soc.h" +#include "soc/pmu_reg.h" + typedef union { struct { - uint32_t reserved_0:21; - /** hp_active_vdd_spi_pd_en : R/W; bitpos: [21]; default: 0; - * need_des - */ - uint32_t hp_active_vdd_spi_pd_en:1; - /** hp_active_hp_mem_dslp : R/W; bitpos: [22]; default: 0; - * need_des - */ - uint32_t hp_active_hp_mem_dslp:1; - /** hp_active_pd_hp_mem_pd_en : R/W; bitpos: [26:23]; default: 0; - * need_des - */ - uint32_t hp_active_pd_hp_mem_pd_en:4; - /** hp_active_pd_hp_wifi_pd_en : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t hp_active_pd_hp_wifi_pd_en:1; - uint32_t reserved_28:1; - /** hp_active_pd_hp_cpu_pd_en : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_active_pd_hp_cpu_pd_en:1; - /** hp_active_pd_hp_aon_pd_en : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t hp_active_pd_hp_aon_pd_en:1; - /** hp_active_pd_top_pd_en : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t hp_active_pd_top_pd_en:1; + uint32_t reserved0 : 21; + uint32_t vdd_spi_pd_en: 1; + uint32_t mem_dslp : 1; + uint32_t mem_pd_en : 4; + uint32_t wifi_pd_en : 1; + uint32_t reserved1 : 1; + uint32_t cpu_pd_en : 1; + uint32_t aon_pd_en : 1; + uint32_t top_pd_en : 1; }; uint32_t val; -} pmu_hp_active_dig_power_reg_t; +} pmu_hp_dig_power_reg_t; -/** Type of hp_active_icg_hp_func register - * need_des - */ typedef union { struct { - /** hp_active_dig_icg_func_en : R/W; bitpos: [31:0]; default: 4294967295; - * need_des - */ - uint32_t hp_active_dig_icg_func_en:32; + uint32_t reserved0: 30; + uint32_t code : 2; }; uint32_t val; -} pmu_hp_active_icg_hp_func_reg_t; +} pmu_hp_icg_modem_reg_t; -/** Type of hp_active_icg_hp_apb register - * need_des - */ typedef union { struct { - /** hp_active_dig_icg_apb_en : R/W; bitpos: [31:0]; default: 4294967295; - * need_des - */ - uint32_t hp_active_dig_icg_apb_en:32; + uint32_t reserved0 : 24; + uint32_t uart_wakeup_en : 1; + uint32_t lp_pad_hold_all: 1; + uint32_t hp_pad_hold_all: 1; + uint32_t dig_pad_slp_sel: 1; + uint32_t dig_pause_wdt : 1; + uint32_t dig_cpu_stall : 1; + uint32_t reserved1 : 2; }; uint32_t val; -} pmu_hp_active_icg_hp_apb_reg_t; +} pmu_hp_sys_cntl_reg_t; -/** Type of hp_active_icg_modem register - * need_des - */ typedef union { struct { - uint32_t reserved_0:30; - /** hp_active_dig_icg_modem_code : R/W; bitpos: [31:30]; default: 0; - * need_des - */ - uint32_t hp_active_dig_icg_modem_code:2; + uint32_t reserved0 : 26; + uint32_t i2c_iso_en : 1; + uint32_t i2c_retention: 1; + uint32_t xpd_bb_i2c : 1; + uint32_t xpd_bbpll_i2c: 1; + uint32_t xpd_bbpll : 1; + uint32_t reserved1 : 1; }; uint32_t val; -} pmu_hp_active_icg_modem_reg_t; +} pmu_hp_clk_power_reg_t; -/** Type of hp_active_hp_sys_cntl register - * need_des - */ typedef union { struct { - uint32_t reserved_0:24; - /** hp_active_uart_wakeup_en : R/W; bitpos: [24]; default: 0; - * need_des - */ - uint32_t hp_active_uart_wakeup_en:1; - /** hp_active_lp_pad_hold_all : R/W; bitpos: [25]; default: 0; - * need_des - */ - uint32_t hp_active_lp_pad_hold_all:1; - /** hp_active_hp_pad_hold_all : R/W; bitpos: [26]; default: 0; - * need_des - */ - uint32_t hp_active_hp_pad_hold_all:1; - /** hp_active_dig_pad_slp_sel : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t hp_active_dig_pad_slp_sel:1; - /** hp_active_dig_pause_wdt : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t hp_active_dig_pause_wdt:1; - /** hp_active_dig_cpu_stall : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_active_dig_cpu_stall:1; - uint32_t reserved_30:2; + uint32_t reserved0 : 25; + uint32_t xpd_bias : 1; + uint32_t dbg_atten : 4; + uint32_t pd_cur : 1; + uint32_t bias_sleep: 1; }; uint32_t val; -} pmu_hp_active_hp_sys_cntl_reg_t; +} pmu_hp_bias_reg_t; -/** Type of hp_active_hp_ck_power register - * need_des - */ typedef union { - struct { - uint32_t reserved_0:26; - /** hp_active_i2c_iso_en : R/W; bitpos: [26]; default: 0; - * need_des - */ - uint32_t hp_active_i2c_iso_en:1; - /** hp_active_i2c_retention : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t hp_active_i2c_retention:1; - /** hp_active_xpd_bb_i2c : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t hp_active_xpd_bb_i2c:1; - /** hp_active_xpd_bbpll_i2c : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_active_xpd_bbpll_i2c:1; - /** hp_active_xpd_bbpll : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t hp_active_xpd_bbpll:1; - uint32_t reserved_31:1; + struct { /* HP: Active State */ + uint32_t reserved0 : 4; + uint32_t hp_sleep2active_backup_modem_clk_code: 2; + uint32_t hp_modem2active_backup_modem_clk_code: 2; + uint32_t reserved1 : 2; + uint32_t hp_active_retention_mode : 1; + uint32_t hp_sleep2active_retention_en : 1; + uint32_t hp_modem2active_retention_en : 1; + uint32_t reserved2 : 1; + uint32_t hp_sleep2active_backup_clk_sel : 2; + uint32_t hp_modem2active_backup_clk_sel : 2; + uint32_t reserved3 : 2; + uint32_t hp_sleep2active_backup_mode : 3; + uint32_t hp_modem2active_backup_mode : 3; + uint32_t reserved4 : 3; + uint32_t hp_sleep2active_backup_en : 1; + uint32_t hp_modem2active_backup_en : 1; + uint32_t reserved5 : 1; + }; + struct { /* HP: Modem State */ + uint32_t reserved6 : 4; + uint32_t hp_sleep2modem_backup_modem_clk_code : 2; + uint32_t reserved7 : 4; + uint32_t hp_modem_retention_mode : 1; + uint32_t hp_sleep2modem_retention_en : 1; + uint32_t reserved8 : 2; + uint32_t hp_sleep2modem_backup_clk_sel : 2; + uint32_t reserved9 : 4; + uint32_t hp_sleep2modem_backup_mode : 3; + uint32_t reserved10 : 6; + uint32_t hp_sleep2modem_backup_en : 1; + uint32_t reserved11 : 2; + }; + struct { /* HP: Sleep State */ + uint32_t reserved12 : 6; + uint32_t hp_modem2sleep_backup_modem_clk_code : 2; + uint32_t hp_active2sleep_backup_modem_clk_code: 2; + uint32_t hp_sleep_retention_mode : 1; + uint32_t reserved13 : 1; + uint32_t hp_modem2sleep_retention_en : 1; + uint32_t hp_active2sleep_retention_en : 1; + uint32_t reserved14 : 2; + uint32_t hp_modem2sleep_backup_clk_sel : 2; + uint32_t hp_active2sleep_backup_clk_sel : 2; + uint32_t reserved15 : 3; + uint32_t hp_modem2sleep_backup_mode : 3; + uint32_t hp_active2sleep_backup_mode : 3; + uint32_t reserved16 : 1; + uint32_t hp_modem2sleep_backup_en : 1; + uint32_t hp_active2sleep_backup_en : 1; }; uint32_t val; -} pmu_hp_active_hp_ck_power_reg_t; +} pmu_hp_backup_reg_t; -/** Type of hp_active_bias register - * need_des - */ typedef union { struct { - uint32_t reserved_0:25; - /** hp_active_xpd_bias : R/W; bitpos: [25]; default: 0; - * need_des - */ - uint32_t hp_active_xpd_bias:1; - /** hp_active_dbg_atten : R/W; bitpos: [29:26]; default: 0; - * need_des - */ - uint32_t hp_active_dbg_atten:4; - /** hp_active_pd_cur : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t hp_active_pd_cur:1; - /** hp_active_bias_sleep : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t hp_active_bias_sleep:1; + uint32_t reserved0 : 26; + uint32_t dig_sysclk_nodiv: 1; + uint32_t icg_sysclk_en : 1; + uint32_t sysclk_slp_sel : 1; + uint32_t icg_slp_sel : 1; + uint32_t dig_sysclk_sel : 2; }; uint32_t val; -} pmu_hp_active_bias_reg_t; +} pmu_hp_sysclk_reg_t; -/** Type of hp_active_backup register - * need_des - */ typedef union { struct { - uint32_t reserved_0:4; - /** hp_sleep2active_backup_modem_clk_code : R/W; bitpos: [5:4]; default: 0; - * need_des - */ - uint32_t hp_sleep2active_backup_modem_clk_code:2; - /** hp_modem2active_backup_modem_clk_code : R/W; bitpos: [7:6]; default: 0; - * need_des - */ - uint32_t hp_modem2active_backup_modem_clk_code:2; - uint32_t reserved_8:2; - /** hp_active_retention_mode : R/W; bitpos: [10]; default: 0; - * need_des - */ - uint32_t hp_active_retention_mode:1; - /** hp_sleep2active_retention_en : R/W; bitpos: [11]; default: 0; - * need_des - */ - uint32_t hp_sleep2active_retention_en:1; - /** hp_modem2active_retention_en : R/W; bitpos: [12]; default: 0; - * need_des - */ - uint32_t hp_modem2active_retention_en:1; - uint32_t reserved_13:1; - /** hp_sleep2active_backup_clk_sel : R/W; bitpos: [15:14]; default: 0; - * need_des - */ - uint32_t hp_sleep2active_backup_clk_sel:2; - /** hp_modem2active_backup_clk_sel : R/W; bitpos: [17:16]; default: 0; - * need_des - */ - uint32_t hp_modem2active_backup_clk_sel:2; - uint32_t reserved_18:2; - /** hp_sleep2active_backup_mode : R/W; bitpos: [22:20]; default: 0; - * need_des - */ - uint32_t hp_sleep2active_backup_mode:3; - /** hp_modem2active_backup_mode : R/W; bitpos: [25:23]; default: 0; - * need_des - */ - uint32_t hp_modem2active_backup_mode:3; - uint32_t reserved_26:3; - /** hp_sleep2active_backup_en : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_sleep2active_backup_en:1; - /** hp_modem2active_backup_en : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t hp_modem2active_backup_en:1; - uint32_t reserved_31:1; + uint32_t reserved0 : 4; /* Only HP_ACTIVE modem under hp system is valid */ + uint32_t lp_dbias_vol : 5; /* Only HP_ACTIVE modem under hp system is valid */ + uint32_t hp_dbias_vol : 5; /* Only HP_ACTIVE modem under hp system is valid */ + uint32_t dbias_sel : 1; /* Only HP_ACTIVE modem under hp system is valid */ + uint32_t dbias_init : 1; /* Only HP_ACTIVE modem under hp system is valid */ + uint32_t slp_mem_xpd : 1; + uint32_t slp_logic_xpd : 1; + uint32_t xpd : 1; + uint32_t slp_mem_dbias : 4; + uint32_t slp_logic_dbias: 4; + uint32_t dbias : 5; }; uint32_t val; -} pmu_hp_active_backup_reg_t; +} pmu_hp_regulator0_reg_t; -/** Type of hp_active_backup_clk register - * need_des - */ typedef union { struct { - /** hp_active_backup_icg_func_en : R/W; bitpos: [31:0]; default: 0; - * need_des - */ - uint32_t hp_active_backup_icg_func_en:32; + uint32_t reserved0: 8; + uint32_t drv_b : 24; }; uint32_t val; -} pmu_hp_active_backup_clk_reg_t; +} pmu_hp_regulator1_reg_t; -/** Type of hp_active_sysclk register - * need_des - */ typedef union { struct { - uint32_t reserved_0:26; - /** hp_active_dig_sys_clk_no_div : R/W; bitpos: [26]; default: 0; - * need_des - */ - uint32_t hp_active_dig_sys_clk_no_div:1; - /** hp_active_icg_sys_clock_en : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t hp_active_icg_sys_clock_en:1; - /** hp_active_sys_clk_slp_sel : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t hp_active_sys_clk_slp_sel:1; - /** hp_active_icg_slp_sel : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_active_icg_slp_sel:1; - /** hp_active_dig_sys_clk_sel : R/W; bitpos: [31:30]; default: 0; - * need_des - */ - uint32_t hp_active_dig_sys_clk_sel:2; + uint32_t reserved0: 31; + uint32_t xpd_xtal : 1; }; uint32_t val; -} pmu_hp_active_sysclk_reg_t; +} pmu_hp_xtal_reg_t; -/** Type of hp_active_hp_regulator0 register - * need_des - */ +typedef volatile struct pmu_hp_hw_regmap_t{ + pmu_hp_dig_power_reg_t dig_power; + uint32_t icg_func; + uint32_t icg_apb; + pmu_hp_icg_modem_reg_t icg_modem; + pmu_hp_sys_cntl_reg_t syscntl; + pmu_hp_clk_power_reg_t clk_power; + pmu_hp_bias_reg_t bias; + pmu_hp_backup_reg_t backup; + uint32_t backup_clk; + pmu_hp_sysclk_reg_t sysclk; + pmu_hp_regulator0_reg_t regulator0; + pmu_hp_regulator1_reg_t regulator1; + pmu_hp_xtal_reg_t xtal; +} pmu_hp_hw_regmap_t; + +/** */ typedef union { struct { - uint32_t reserved_0:4; - /** lp_dbias_vol : RO; bitpos: [8:4]; default: 24; - * need_des - */ - uint32_t lp_dbias_vol:5; - /** hp_dbias_vol : RO; bitpos: [13:9]; default: 24; - * need_des - */ - uint32_t hp_dbias_vol:5; - /** dig_regulator0_dbias_sel : R/W; bitpos: [14]; default: 1; - * need_des - */ - uint32_t dig_regulator0_dbias_sel:1; - /** dig_dbias_init : WT; bitpos: [15]; default: 0; - * need_des - */ - uint32_t dig_dbias_init:1; - /** hp_active_hp_regulator_slp_mem_xpd : R/W; bitpos: [16]; default: 1; - * need_des - */ - uint32_t hp_active_hp_regulator_slp_mem_xpd:1; - /** hp_active_hp_regulator_slp_logic_xpd : R/W; bitpos: [17]; default: 1; - * need_des - */ - uint32_t hp_active_hp_regulator_slp_logic_xpd:1; - /** hp_active_hp_regulator_xpd : R/W; bitpos: [18]; default: 1; - * need_des - */ - uint32_t hp_active_hp_regulator_xpd:1; - /** hp_active_hp_regulator_slp_mem_dbias : R/W; bitpos: [22:19]; default: 12; - * need_des - */ - uint32_t hp_active_hp_regulator_slp_mem_dbias:4; - /** hp_active_hp_regulator_slp_logic_dbias : R/W; bitpos: [26:23]; default: 12; - * need_des - */ - uint32_t hp_active_hp_regulator_slp_logic_dbias:4; - /** hp_active_hp_regulator_dbias : R/W; bitpos: [31:27]; default: 24; - * need_des - */ - uint32_t hp_active_hp_regulator_dbias:5; + uint32_t reserved0: 21; + uint32_t slp_xpd : 1; + uint32_t xpd : 1; + uint32_t slp_dbias: 4; + uint32_t dbias : 5; }; uint32_t val; -} pmu_hp_active_hp_regulator0_reg_t; +} pmu_lp_regulator0_reg_t; -/** Type of hp_active_hp_regulator1 register - * need_des - */ typedef union { struct { - uint32_t reserved_0:8; - /** hp_active_hp_regulator_drv_b : R/W; bitpos: [31:8]; default: 0; - * need_des - */ - uint32_t hp_active_hp_regulator_drv_b:24; + uint32_t reserved0: 28; + uint32_t drv_b : 4; }; uint32_t val; -} pmu_hp_active_hp_regulator1_reg_t; +} pmu_lp_regulator1_reg_t; -/** Type of hp_active_xtal register - * need_des - */ typedef union { struct { - uint32_t reserved_0:31; - /** hp_active_xpd_xtal : R/W; bitpos: [31]; default: 1; - * need_des - */ - uint32_t hp_active_xpd_xtal:1; + uint32_t reserved0: 31; + uint32_t xpd_xtal : 1; }; uint32_t val; -} pmu_hp_active_xtal_reg_t; +} pmu_lp_xtal_reg_t; -/** Type of hp_modem_dig_power register - * need_des - */ typedef union { struct { - uint32_t reserved_0:21; - /** hp_modem_vdd_spi_pd_en : R/W; bitpos: [21]; default: 0; - * need_des - */ - uint32_t hp_modem_vdd_spi_pd_en:1; - /** hp_modem_hp_mem_dslp : R/W; bitpos: [22]; default: 0; - * need_des - */ - uint32_t hp_modem_hp_mem_dslp:1; - /** hp_modem_pd_hp_mem_pd_en : R/W; bitpos: [26:23]; default: 0; - * need_des - */ - uint32_t hp_modem_pd_hp_mem_pd_en:4; - /** hp_modem_pd_hp_wifi_pd_en : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t hp_modem_pd_hp_wifi_pd_en:1; - uint32_t reserved_28:1; - /** hp_modem_pd_hp_cpu_pd_en : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_modem_pd_hp_cpu_pd_en:1; - /** hp_modem_pd_hp_aon_pd_en : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t hp_modem_pd_hp_aon_pd_en:1; - /** hp_modem_pd_top_pd_en : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t hp_modem_pd_top_pd_en:1; + uint32_t reserved0 : 30; + uint32_t mem_dslp : 1; + uint32_t peri_pd_en: 1; }; uint32_t val; -} pmu_hp_modem_dig_power_reg_t; +} pmu_lp_dig_power_reg_t; -/** Type of hp_modem_icg_hp_func register - * need_des - */ typedef union { struct { - /** hp_modem_dig_icg_func_en : R/W; bitpos: [31:0]; default: 4294967295; - * need_des - */ - uint32_t hp_modem_dig_icg_func_en:32; + uint32_t reserved0 : 28; + uint32_t xpd_xtal32k: 1; + uint32_t xpd_rc32k : 1; + uint32_t xpd_fosc : 1; + uint32_t pd_osc : 1; }; uint32_t val; -} pmu_hp_modem_icg_hp_func_reg_t; +} pmu_lp_clk_power_reg_t; -/** Type of hp_modem_icg_hp_apb register - * need_des - */ typedef union { struct { - /** hp_modem_dig_icg_apb_en : R/W; bitpos: [31:0]; default: 4294967295; - * need_des - */ - uint32_t hp_modem_dig_icg_apb_en:32; + uint32_t reserved0 : 25; + uint32_t xpd_bias : 1; + uint32_t dbg_atten : 4; + uint32_t pd_cur : 1; + uint32_t bias_sleep: 1; }; uint32_t val; -} pmu_hp_modem_icg_hp_apb_reg_t; +} pmu_lp_bias_reg_t; + +typedef volatile struct pmu_lp_hw_regmap_t{ + pmu_lp_regulator0_reg_t regulator0; + pmu_lp_regulator1_reg_t regulator1; + pmu_lp_xtal_reg_t xtal; /* Only LP_SLEEP mode under lp system is valid */ + pmu_lp_dig_power_reg_t dig_power; + pmu_lp_clk_power_reg_t clk_power; + pmu_lp_bias_reg_t bias; /* Only LP_SLEEP mode under lp system is valid */ +} pmu_lp_hw_regmap_t; + -/** Type of hp_modem_icg_modem register - * need_des - */ typedef union { struct { - uint32_t reserved_0:30; - /** hp_modem_dig_icg_modem_code : R/W; bitpos: [31:30]; default: 0; - * need_des - */ - uint32_t hp_modem_dig_icg_modem_code:2; + uint32_t tie_low_global_bbpll_icg : 1; + uint32_t tie_low_global_xtal_icg : 1; + uint32_t tie_low_i2c_retention : 1; + uint32_t tie_low_xpd_bb_i2c : 1; + uint32_t tie_low_xpd_bbpll_i2c : 1; + uint32_t tie_low_xpd_bbpll : 1; + uint32_t tie_low_xpd_xtal : 1; + uint32_t reserved0 : 18; + uint32_t tie_high_global_bbpll_icg: 1; + uint32_t tie_high_global_xtal_icg : 1; + uint32_t tie_high_i2c_retention : 1; + uint32_t tie_high_xpd_bb_i2c : 1; + uint32_t tie_high_xpd_bbpll_i2c : 1; + uint32_t tie_high_xpd_bbpll : 1; + uint32_t tie_high_xpd_xtal : 1; }; uint32_t val; -} pmu_hp_modem_icg_modem_reg_t; +} pmu_imm_hp_clk_power_reg_t; -/** Type of hp_modem_hp_sys_cntl register - * need_des - */ typedef union { struct { - uint32_t reserved_0:24; - /** hp_modem_uart_wakeup_en : R/W; bitpos: [24]; default: 0; - * need_des - */ - uint32_t hp_modem_uart_wakeup_en:1; - /** hp_modem_lp_pad_hold_all : R/W; bitpos: [25]; default: 0; - * need_des - */ - uint32_t hp_modem_lp_pad_hold_all:1; - /** hp_modem_hp_pad_hold_all : R/W; bitpos: [26]; default: 0; - * need_des - */ - uint32_t hp_modem_hp_pad_hold_all:1; - /** hp_modem_dig_pad_slp_sel : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t hp_modem_dig_pad_slp_sel:1; - /** hp_modem_dig_pause_wdt : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t hp_modem_dig_pause_wdt:1; - /** hp_modem_dig_cpu_stall : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_modem_dig_cpu_stall:1; - uint32_t reserved_30:2; - }; - uint32_t val; -} pmu_hp_modem_hp_sys_cntl_reg_t; - -/** Type of hp_modem_hp_ck_power register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:26; - /** hp_modem_i2c_iso_en : R/W; bitpos: [26]; default: 0; - * need_des - */ - uint32_t hp_modem_i2c_iso_en:1; - /** hp_modem_i2c_retention : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t hp_modem_i2c_retention:1; - /** hp_modem_xpd_bb_i2c : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t hp_modem_xpd_bb_i2c:1; - /** hp_modem_xpd_bbpll_i2c : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_modem_xpd_bbpll_i2c:1; - /** hp_modem_xpd_bbpll : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t hp_modem_xpd_bbpll:1; - uint32_t reserved_31:1; - }; - uint32_t val; -} pmu_hp_modem_hp_ck_power_reg_t; - -/** Type of hp_modem_bias register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:25; - /** hp_modem_xpd_bias : R/W; bitpos: [25]; default: 0; - * need_des - */ - uint32_t hp_modem_xpd_bias:1; - /** hp_modem_dbg_atten : R/W; bitpos: [29:26]; default: 0; - * need_des - */ - uint32_t hp_modem_dbg_atten:4; - /** hp_modem_pd_cur : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t hp_modem_pd_cur:1; - /** hp_modem_bias_sleep : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t hp_modem_bias_sleep:1; - }; - uint32_t val; -} pmu_hp_modem_bias_reg_t; - -/** Type of hp_modem_backup register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:4; - /** hp_sleep2modem_backup_modem_clk_code : R/W; bitpos: [5:4]; default: 0; - * need_des - */ - uint32_t hp_sleep2modem_backup_modem_clk_code:2; - uint32_t reserved_6:4; - /** hp_modem_retention_mode : R/W; bitpos: [10]; default: 0; - * need_des - */ - uint32_t hp_modem_retention_mode:1; - /** hp_sleep2modem_retention_en : R/W; bitpos: [11]; default: 0; - * need_des - */ - uint32_t hp_sleep2modem_retention_en:1; - uint32_t reserved_12:2; - /** hp_sleep2modem_backup_clk_sel : R/W; bitpos: [15:14]; default: 0; - * need_des - */ - uint32_t hp_sleep2modem_backup_clk_sel:2; - uint32_t reserved_16:4; - /** hp_sleep2modem_backup_mode : R/W; bitpos: [22:20]; default: 0; - * need_des - */ - uint32_t hp_sleep2modem_backup_mode:3; - uint32_t reserved_23:6; - /** hp_sleep2modem_backup_en : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_sleep2modem_backup_en:1; - uint32_t reserved_30:2; - }; - uint32_t val; -} pmu_hp_modem_backup_reg_t; - -/** Type of hp_modem_backup_clk register - * need_des - */ -typedef union { - struct { - /** hp_modem_backup_icg_func_en : R/W; bitpos: [31:0]; default: 0; - * need_des - */ - uint32_t hp_modem_backup_icg_func_en:32; - }; - uint32_t val; -} pmu_hp_modem_backup_clk_reg_t; - -/** Type of hp_modem_sysclk register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:26; - /** hp_modem_dig_sys_clk_no_div : R/W; bitpos: [26]; default: 0; - * need_des - */ - uint32_t hp_modem_dig_sys_clk_no_div:1; - /** hp_modem_icg_sys_clock_en : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t hp_modem_icg_sys_clock_en:1; - /** hp_modem_sys_clk_slp_sel : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t hp_modem_sys_clk_slp_sel:1; - /** hp_modem_icg_slp_sel : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_modem_icg_slp_sel:1; - /** hp_modem_dig_sys_clk_sel : R/W; bitpos: [31:30]; default: 0; - * need_des - */ - uint32_t hp_modem_dig_sys_clk_sel:2; - }; - uint32_t val; -} pmu_hp_modem_sysclk_reg_t; - -/** Type of hp_modem_hp_regulator0 register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:16; - /** hp_modem_hp_regulator_slp_mem_xpd : R/W; bitpos: [16]; default: 1; - * need_des - */ - uint32_t hp_modem_hp_regulator_slp_mem_xpd:1; - /** hp_modem_hp_regulator_slp_logic_xpd : R/W; bitpos: [17]; default: 1; - * need_des - */ - uint32_t hp_modem_hp_regulator_slp_logic_xpd:1; - /** hp_modem_hp_regulator_xpd : R/W; bitpos: [18]; default: 1; - * need_des - */ - uint32_t hp_modem_hp_regulator_xpd:1; - /** hp_modem_hp_regulator_slp_mem_dbias : R/W; bitpos: [22:19]; default: 12; - * need_des - */ - uint32_t hp_modem_hp_regulator_slp_mem_dbias:4; - /** hp_modem_hp_regulator_slp_logic_dbias : R/W; bitpos: [26:23]; default: 12; - * need_des - */ - uint32_t hp_modem_hp_regulator_slp_logic_dbias:4; - /** hp_modem_hp_regulator_dbias : R/W; bitpos: [31:27]; default: 24; - * need_des - */ - uint32_t hp_modem_hp_regulator_dbias:5; - }; - uint32_t val; -} pmu_hp_modem_hp_regulator0_reg_t; - -/** Type of hp_modem_hp_regulator1 register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:8; - /** hp_modem_hp_regulator_drv_b : R/W; bitpos: [31:8]; default: 0; - * need_des - */ - uint32_t hp_modem_hp_regulator_drv_b:24; - }; - uint32_t val; -} pmu_hp_modem_hp_regulator1_reg_t; - -/** Type of hp_modem_xtal register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:31; - /** hp_modem_xpd_xtal : R/W; bitpos: [31]; default: 1; - * need_des - */ - uint32_t hp_modem_xpd_xtal:1; - }; - uint32_t val; -} pmu_hp_modem_xtal_reg_t; - -/** Type of hp_sleep_dig_power register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:21; - /** hp_sleep_vdd_spi_pd_en : R/W; bitpos: [21]; default: 0; - * need_des - */ - uint32_t hp_sleep_vdd_spi_pd_en:1; - /** hp_sleep_hp_mem_dslp : R/W; bitpos: [22]; default: 0; - * need_des - */ - uint32_t hp_sleep_hp_mem_dslp:1; - /** hp_sleep_pd_hp_mem_pd_en : R/W; bitpos: [26:23]; default: 0; - * need_des - */ - uint32_t hp_sleep_pd_hp_mem_pd_en:4; - /** hp_sleep_pd_hp_wifi_pd_en : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t hp_sleep_pd_hp_wifi_pd_en:1; - uint32_t reserved_28:1; - /** hp_sleep_pd_hp_cpu_pd_en : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_sleep_pd_hp_cpu_pd_en:1; - /** hp_sleep_pd_hp_aon_pd_en : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t hp_sleep_pd_hp_aon_pd_en:1; - /** hp_sleep_pd_top_pd_en : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t hp_sleep_pd_top_pd_en:1; - }; - uint32_t val; -} pmu_hp_sleep_dig_power_reg_t; - -/** Type of hp_sleep_icg_hp_func register - * need_des - */ -typedef union { - struct { - /** hp_sleep_dig_icg_func_en : R/W; bitpos: [31:0]; default: 4294967295; - * need_des - */ - uint32_t hp_sleep_dig_icg_func_en:32; - }; - uint32_t val; -} pmu_hp_sleep_icg_hp_func_reg_t; - -/** Type of hp_sleep_icg_hp_apb register - * need_des - */ -typedef union { - struct { - /** hp_sleep_dig_icg_apb_en : R/W; bitpos: [31:0]; default: 4294967295; - * need_des - */ - uint32_t hp_sleep_dig_icg_apb_en:32; - }; - uint32_t val; -} pmu_hp_sleep_icg_hp_apb_reg_t; - -/** Type of hp_sleep_icg_modem register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:30; - /** hp_sleep_dig_icg_modem_code : R/W; bitpos: [31:30]; default: 0; - * need_des - */ - uint32_t hp_sleep_dig_icg_modem_code:2; - }; - uint32_t val; -} pmu_hp_sleep_icg_modem_reg_t; - -/** Type of hp_sleep_hp_sys_cntl register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:24; - /** hp_sleep_uart_wakeup_en : R/W; bitpos: [24]; default: 0; - * need_des - */ - uint32_t hp_sleep_uart_wakeup_en:1; - /** hp_sleep_lp_pad_hold_all : R/W; bitpos: [25]; default: 0; - * need_des - */ - uint32_t hp_sleep_lp_pad_hold_all:1; - /** hp_sleep_hp_pad_hold_all : R/W; bitpos: [26]; default: 0; - * need_des - */ - uint32_t hp_sleep_hp_pad_hold_all:1; - /** hp_sleep_dig_pad_slp_sel : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t hp_sleep_dig_pad_slp_sel:1; - /** hp_sleep_dig_pause_wdt : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t hp_sleep_dig_pause_wdt:1; - /** hp_sleep_dig_cpu_stall : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_sleep_dig_cpu_stall:1; - uint32_t reserved_30:2; - }; - uint32_t val; -} pmu_hp_sleep_hp_sys_cntl_reg_t; - -/** Type of hp_sleep_hp_ck_power register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:26; - /** hp_sleep_i2c_iso_en : R/W; bitpos: [26]; default: 0; - * need_des - */ - uint32_t hp_sleep_i2c_iso_en:1; - /** hp_sleep_i2c_retention : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t hp_sleep_i2c_retention:1; - /** hp_sleep_xpd_bb_i2c : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t hp_sleep_xpd_bb_i2c:1; - /** hp_sleep_xpd_bbpll_i2c : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_sleep_xpd_bbpll_i2c:1; - /** hp_sleep_xpd_bbpll : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t hp_sleep_xpd_bbpll:1; - uint32_t reserved_31:1; - }; - uint32_t val; -} pmu_hp_sleep_hp_ck_power_reg_t; - -/** Type of hp_sleep_bias register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:25; - /** hp_sleep_xpd_bias : R/W; bitpos: [25]; default: 0; - * need_des - */ - uint32_t hp_sleep_xpd_bias:1; - /** hp_sleep_dbg_atten : R/W; bitpos: [29:26]; default: 0; - * need_des - */ - uint32_t hp_sleep_dbg_atten:4; - /** hp_sleep_pd_cur : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t hp_sleep_pd_cur:1; - /** hp_sleep_bias_sleep : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t hp_sleep_bias_sleep:1; - }; - uint32_t val; -} pmu_hp_sleep_bias_reg_t; - -/** Type of hp_sleep_backup register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:6; - /** hp_modem2sleep_backup_modem_clk_code : R/W; bitpos: [7:6]; default: 0; - * need_des - */ - uint32_t hp_modem2sleep_backup_modem_clk_code:2; - /** hp_active2sleep_backup_modem_clk_code : R/W; bitpos: [9:8]; default: 0; - * need_des - */ - uint32_t hp_active2sleep_backup_modem_clk_code:2; - /** hp_sleep_retention_mode : R/W; bitpos: [10]; default: 0; - * need_des - */ - uint32_t hp_sleep_retention_mode:1; - uint32_t reserved_11:1; - /** hp_modem2sleep_retention_en : R/W; bitpos: [12]; default: 0; - * need_des - */ - uint32_t hp_modem2sleep_retention_en:1; - /** hp_active2sleep_retention_en : R/W; bitpos: [13]; default: 0; - * need_des - */ - uint32_t hp_active2sleep_retention_en:1; - uint32_t reserved_14:2; - /** hp_modem2sleep_backup_clk_sel : R/W; bitpos: [17:16]; default: 0; - * need_des - */ - uint32_t hp_modem2sleep_backup_clk_sel:2; - /** hp_active2sleep_backup_clk_sel : R/W; bitpos: [19:18]; default: 0; - * need_des - */ - uint32_t hp_active2sleep_backup_clk_sel:2; - uint32_t reserved_20:3; - /** hp_modem2sleep_backup_mode : R/W; bitpos: [25:23]; default: 0; - * need_des - */ - uint32_t hp_modem2sleep_backup_mode:3; - /** hp_active2sleep_backup_mode : R/W; bitpos: [28:26]; default: 0; - * need_des - */ - uint32_t hp_active2sleep_backup_mode:3; - uint32_t reserved_29:1; - /** hp_modem2sleep_backup_en : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t hp_modem2sleep_backup_en:1; - /** hp_active2sleep_backup_en : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t hp_active2sleep_backup_en:1; - }; - uint32_t val; -} pmu_hp_sleep_backup_reg_t; - -/** Type of hp_sleep_backup_clk register - * need_des - */ -typedef union { - struct { - /** hp_sleep_backup_icg_func_en : R/W; bitpos: [31:0]; default: 0; - * need_des - */ - uint32_t hp_sleep_backup_icg_func_en:32; - }; - uint32_t val; -} pmu_hp_sleep_backup_clk_reg_t; - -/** Type of hp_sleep_sysclk register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:26; - /** hp_sleep_dig_sys_clk_no_div : R/W; bitpos: [26]; default: 0; - * need_des - */ - uint32_t hp_sleep_dig_sys_clk_no_div:1; - /** hp_sleep_icg_sys_clock_en : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t hp_sleep_icg_sys_clock_en:1; - /** hp_sleep_sys_clk_slp_sel : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t hp_sleep_sys_clk_slp_sel:1; - /** hp_sleep_icg_slp_sel : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_sleep_icg_slp_sel:1; - /** hp_sleep_dig_sys_clk_sel : R/W; bitpos: [31:30]; default: 0; - * need_des - */ - uint32_t hp_sleep_dig_sys_clk_sel:2; - }; - uint32_t val; -} pmu_hp_sleep_sysclk_reg_t; - -/** Type of hp_sleep_hp_regulator0 register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:16; - /** hp_sleep_hp_regulator_slp_mem_xpd : R/W; bitpos: [16]; default: 1; - * need_des - */ - uint32_t hp_sleep_hp_regulator_slp_mem_xpd:1; - /** hp_sleep_hp_regulator_slp_logic_xpd : R/W; bitpos: [17]; default: 1; - * need_des - */ - uint32_t hp_sleep_hp_regulator_slp_logic_xpd:1; - /** hp_sleep_hp_regulator_xpd : R/W; bitpos: [18]; default: 1; - * need_des - */ - uint32_t hp_sleep_hp_regulator_xpd:1; - /** hp_sleep_hp_regulator_slp_mem_dbias : R/W; bitpos: [22:19]; default: 12; - * need_des - */ - uint32_t hp_sleep_hp_regulator_slp_mem_dbias:4; - /** hp_sleep_hp_regulator_slp_logic_dbias : R/W; bitpos: [26:23]; default: 12; - * need_des - */ - uint32_t hp_sleep_hp_regulator_slp_logic_dbias:4; - /** hp_sleep_hp_regulator_dbias : R/W; bitpos: [31:27]; default: 24; - * need_des - */ - uint32_t hp_sleep_hp_regulator_dbias:5; - }; - uint32_t val; -} pmu_hp_sleep_hp_regulator0_reg_t; - -/** Type of hp_sleep_hp_regulator1 register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:8; - /** hp_sleep_hp_regulator_drv_b : R/W; bitpos: [31:8]; default: 0; - * need_des - */ - uint32_t hp_sleep_hp_regulator_drv_b:24; - }; - uint32_t val; -} pmu_hp_sleep_hp_regulator1_reg_t; - -/** Type of hp_sleep_xtal register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:31; - /** hp_sleep_xpd_xtal : R/W; bitpos: [31]; default: 1; - * need_des - */ - uint32_t hp_sleep_xpd_xtal:1; - }; - uint32_t val; -} pmu_hp_sleep_xtal_reg_t; - -/** Type of hp_sleep_lp_regulator0 register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:21; - /** hp_sleep_lp_regulator_slp_xpd : R/W; bitpos: [21]; default: 1; - * need_des - */ - uint32_t hp_sleep_lp_regulator_slp_xpd:1; - /** hp_sleep_lp_regulator_xpd : R/W; bitpos: [22]; default: 1; - * need_des - */ - uint32_t hp_sleep_lp_regulator_xpd:1; - /** hp_sleep_lp_regulator_slp_dbias : R/W; bitpos: [26:23]; default: 12; - * need_des - */ - uint32_t hp_sleep_lp_regulator_slp_dbias:4; - /** hp_sleep_lp_regulator_dbias : R/W; bitpos: [31:27]; default: 24; - * need_des - */ - uint32_t hp_sleep_lp_regulator_dbias:5; - }; - uint32_t val; -} pmu_hp_sleep_lp_regulator0_reg_t; - -/** Type of hp_sleep_lp_regulator1 register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:28; - /** hp_sleep_lp_regulator_drv_b : R/W; bitpos: [31:28]; default: 0; - * need_des - */ - uint32_t hp_sleep_lp_regulator_drv_b:4; - }; - uint32_t val; -} pmu_hp_sleep_lp_regulator1_reg_t; - -/** Type of hp_sleep_lp_dcdc_reserve register - * need_des - */ -typedef union { - struct { - /** hp_sleep_lp_dcdc_reserve : WT; bitpos: [31:0]; default: 0; - * need_des - */ - uint32_t hp_sleep_lp_dcdc_reserve:32; - }; - uint32_t val; -} pmu_hp_sleep_lp_dcdc_reserve_reg_t; - -/** Type of hp_sleep_lp_dig_power register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:30; - /** hp_sleep_lp_mem_dslp : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t hp_sleep_lp_mem_dslp:1; - /** hp_sleep_pd_lp_peri_pd_en : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t hp_sleep_pd_lp_peri_pd_en:1; - }; - uint32_t val; -} pmu_hp_sleep_lp_dig_power_reg_t; - -/** Type of hp_sleep_lp_ck_power register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:28; - /** hp_sleep_xpd_xtal32k : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t hp_sleep_xpd_xtal32k:1; - /** hp_sleep_xpd_rc32k : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t hp_sleep_xpd_rc32k:1; - /** hp_sleep_xpd_fosc_clk : R/W; bitpos: [30]; default: 1; - * need_des - */ - uint32_t hp_sleep_xpd_fosc_clk:1; - /** hp_sleep_pd_osc_clk : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t hp_sleep_pd_osc_clk:1; - }; - uint32_t val; -} pmu_hp_sleep_lp_ck_power_reg_t; - -/** Type of lp_sleep_lp_bias_reserve register - * need_des - */ -typedef union { - struct { - /** lp_sleep_lp_bias_reserve : WT; bitpos: [31:0]; default: 0; - * need_des - */ - uint32_t lp_sleep_lp_bias_reserve:32; - }; - uint32_t val; -} pmu_lp_sleep_lp_bias_reserve_reg_t; - -/** Type of lp_sleep_lp_regulator0 register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:21; - /** lp_sleep_lp_regulator_slp_xpd : R/W; bitpos: [21]; default: 1; - * need_des - */ - uint32_t lp_sleep_lp_regulator_slp_xpd:1; - /** lp_sleep_lp_regulator_xpd : R/W; bitpos: [22]; default: 1; - * need_des - */ - uint32_t lp_sleep_lp_regulator_xpd:1; - /** lp_sleep_lp_regulator_slp_dbias : R/W; bitpos: [26:23]; default: 12; - * need_des - */ - uint32_t lp_sleep_lp_regulator_slp_dbias:4; - /** lp_sleep_lp_regulator_dbias : R/W; bitpos: [31:27]; default: 24; - * need_des - */ - uint32_t lp_sleep_lp_regulator_dbias:5; - }; - uint32_t val; -} pmu_lp_sleep_lp_regulator0_reg_t; - -/** Type of lp_sleep_lp_regulator1 register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:28; - /** lp_sleep_lp_regulator_drv_b : R/W; bitpos: [31:28]; default: 0; - * need_des - */ - uint32_t lp_sleep_lp_regulator_drv_b:4; - }; - uint32_t val; -} pmu_lp_sleep_lp_regulator1_reg_t; - -/** Type of lp_sleep_xtal register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:31; - /** lp_sleep_xpd_xtal : R/W; bitpos: [31]; default: 1; - * need_des - */ - uint32_t lp_sleep_xpd_xtal:1; - }; - uint32_t val; -} pmu_lp_sleep_xtal_reg_t; - -/** Type of lp_sleep_lp_dig_power register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:30; - /** lp_sleep_lp_mem_dslp : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t lp_sleep_lp_mem_dslp:1; - /** lp_sleep_pd_lp_peri_pd_en : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t lp_sleep_pd_lp_peri_pd_en:1; - }; - uint32_t val; -} pmu_lp_sleep_lp_dig_power_reg_t; - -/** Type of lp_sleep_lp_ck_power register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:28; - /** lp_sleep_xpd_xtal32k : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t lp_sleep_xpd_xtal32k:1; - /** lp_sleep_xpd_rc32k : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t lp_sleep_xpd_rc32k:1; - /** lp_sleep_xpd_fosc_clk : R/W; bitpos: [30]; default: 1; - * need_des - */ - uint32_t lp_sleep_xpd_fosc_clk:1; - /** lp_sleep_pd_osc_clk : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t lp_sleep_pd_osc_clk:1; - }; - uint32_t val; -} pmu_lp_sleep_lp_ck_power_reg_t; - -/** Type of lp_sleep_bias register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:25; - /** lp_sleep_xpd_bias : R/W; bitpos: [25]; default: 0; - * need_des - */ - uint32_t lp_sleep_xpd_bias:1; - /** lp_sleep_dbg_atten : R/W; bitpos: [29:26]; default: 0; - * need_des - */ - uint32_t lp_sleep_dbg_atten:4; - /** lp_sleep_pd_cur : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t lp_sleep_pd_cur:1; - /** lp_sleep_bias_sleep : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t lp_sleep_bias_sleep:1; - }; - uint32_t val; -} pmu_lp_sleep_bias_reg_t; - -/** Type of imm_hp_ck_power register - * need_des - */ -typedef union { - struct { - /** tie_low_global_bbpll_icg : WT; bitpos: [0]; default: 0; - * need_des - */ - uint32_t tie_low_global_bbpll_icg:1; - /** tie_low_global_xtal_icg : WT; bitpos: [1]; default: 0; - * need_des - */ - uint32_t tie_low_global_xtal_icg:1; - /** tie_low_i2c_retention : WT; bitpos: [2]; default: 0; - * need_des - */ - uint32_t tie_low_i2c_retention:1; - /** tie_low_xpd_bb_i2c : WT; bitpos: [3]; default: 0; - * need_des - */ - uint32_t tie_low_xpd_bb_i2c:1; - /** tie_low_xpd_bbpll_i2c : WT; bitpos: [4]; default: 0; - * need_des - */ - uint32_t tie_low_xpd_bbpll_i2c:1; - /** tie_low_xpd_bbpll : WT; bitpos: [5]; default: 0; - * need_des - */ - uint32_t tie_low_xpd_bbpll:1; - /** tie_low_xpd_xtal : WT; bitpos: [6]; default: 0; - * need_des - */ - uint32_t tie_low_xpd_xtal:1; - uint32_t reserved_7:18; - /** tie_high_global_bbpll_icg : WT; bitpos: [25]; default: 0; - * need_des - */ - uint32_t tie_high_global_bbpll_icg:1; - /** tie_high_global_xtal_icg : WT; bitpos: [26]; default: 0; - * need_des - */ - uint32_t tie_high_global_xtal_icg:1; - /** tie_high_i2c_retention : WT; bitpos: [27]; default: 0; - * need_des - */ - uint32_t tie_high_i2c_retention:1; - /** tie_high_xpd_bb_i2c : WT; bitpos: [28]; default: 0; - * need_des - */ - uint32_t tie_high_xpd_bb_i2c:1; - /** tie_high_xpd_bbpll_i2c : WT; bitpos: [29]; default: 0; - * need_des - */ - uint32_t tie_high_xpd_bbpll_i2c:1; - /** tie_high_xpd_bbpll : WT; bitpos: [30]; default: 0; - * need_des - */ - uint32_t tie_high_xpd_bbpll:1; - /** tie_high_xpd_xtal : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t tie_high_xpd_xtal:1; - }; - uint32_t val; -} pmu_imm_hp_ck_power_reg_t; - -/** Type of imm_sleep_sysclk register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:28; - /** update_dig_icg_switch : WT; bitpos: [28]; default: 0; - * need_des - */ - uint32_t update_dig_icg_switch:1; - /** tie_low_icg_slp_sel : WT; bitpos: [29]; default: 0; - * need_des - */ - uint32_t tie_low_icg_slp_sel:1; - /** tie_high_icg_slp_sel : WT; bitpos: [30]; default: 0; - * need_des - */ - uint32_t tie_high_icg_slp_sel:1; - /** update_dig_sys_clk_sel : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t update_dig_sys_clk_sel:1; + uint32_t reserved0 : 28; + uint32_t update_dig_icg_switch: 1; + uint32_t tie_low_icg_slp_sel : 1; + uint32_t tie_high_icg_slp_sel : 1; + uint32_t update_dig_sysclk_sel: 1; }; uint32_t val; } pmu_imm_sleep_sysclk_reg_t; -/** Type of imm_hp_func_icg register - * need_des - */ typedef union { struct { - uint32_t reserved_0:31; - /** update_dig_icg_func_en : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t update_dig_icg_func_en:1; + uint32_t reserved0 : 31; + uint32_t update_dig_icg_func_en: 1; }; uint32_t val; } pmu_imm_hp_func_icg_reg_t; -/** Type of imm_hp_apb_icg register - * need_des - */ typedef union { struct { - uint32_t reserved_0:31; - /** update_dig_icg_apb_en : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t update_dig_icg_apb_en:1; + uint32_t reserved0 : 31; + uint32_t update_dig_icg_apb_en: 1; }; uint32_t val; } pmu_imm_hp_apb_icg_reg_t; -/** Type of imm_modem_icg register - * need_des - */ typedef union { struct { - uint32_t reserved_0:31; - /** update_dig_icg_modem_en : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t update_dig_icg_modem_en:1; + uint32_t reserved0 : 31; + uint32_t update_dig_icg_modem_en: 1; }; uint32_t val; } pmu_imm_modem_icg_reg_t; -/** Type of imm_lp_icg register - * need_des - */ typedef union { struct { - uint32_t reserved_0:30; - /** tie_low_lp_rootclk_sel : WT; bitpos: [30]; default: 0; - * need_des - */ - uint32_t tie_low_lp_rootclk_sel:1; - /** tie_high_lp_rootclk_sel : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t tie_high_lp_rootclk_sel:1; + uint32_t reserved0 : 30; + uint32_t tie_low_lp_rootclk_sel : 1; + uint32_t tie_high_lp_rootclk_sel: 1; }; uint32_t val; } pmu_imm_lp_icg_reg_t; -/** Type of imm_pad_hold_all register - * need_des - */ typedef union { struct { - uint32_t reserved_0:28; - /** tie_high_lp_pad_hold_all : WT; bitpos: [28]; default: 0; - * need_des - */ - uint32_t tie_high_lp_pad_hold_all:1; - /** tie_low_lp_pad_hold_all : WT; bitpos: [29]; default: 0; - * need_des - */ - uint32_t tie_low_lp_pad_hold_all:1; - /** tie_high_hp_pad_hold_all : WT; bitpos: [30]; default: 0; - * need_des - */ - uint32_t tie_high_hp_pad_hold_all:1; - /** tie_low_hp_pad_hold_all : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t tie_low_hp_pad_hold_all:1; + uint32_t reserved0 : 28; + uint32_t tie_high_lp_pad_hold_all: 1; + uint32_t tie_low_lp_pad_hold_all : 1; + uint32_t tie_high_hp_pad_hold_all: 1; + uint32_t tie_low_hp_pad_hold_all : 1; }; uint32_t val; } pmu_imm_pad_hold_all_reg_t; -/** Type of imm_i2c_iso register - * need_des - */ typedef union { struct { - uint32_t reserved_0:30; - /** tie_high_i2c_iso_en : WT; bitpos: [30]; default: 0; - * need_des - */ - uint32_t tie_high_i2c_iso_en:1; - /** tie_low_i2c_iso_en : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t tie_low_i2c_iso_en:1; + uint32_t reserved0 : 30; + uint32_t tie_high_i2c_iso_en: 1; + uint32_t tie_low_i2c_iso_en : 1; }; uint32_t val; -} pmu_imm_i2c_iso_reg_t; +} pmu_imm_i2c_isolate_reg_t; + +typedef volatile struct pmu_imm_hw_regmap_t{ + pmu_imm_hp_clk_power_reg_t clk_power; + pmu_imm_sleep_sysclk_reg_t sleep_sysclk; + pmu_imm_hp_func_icg_reg_t hp_func_icg; + pmu_imm_hp_apb_icg_reg_t hp_apb_icg; + pmu_imm_modem_icg_reg_t modem_icg; + pmu_imm_lp_icg_reg_t lp_icg; + pmu_imm_pad_hold_all_reg_t pad_hold_all; + pmu_imm_i2c_isolate_reg_t i2c_iso; +} pmu_imm_hw_regmap_t; -/** Type of power_wait_timer0 register - * need_des - */ typedef union { struct { - uint32_t reserved_0:5; - /** dg_hp_powerdown_timer : R/W; bitpos: [13:5]; default: 255; - * need_des - */ - uint32_t dg_hp_powerdown_timer:9; - /** dg_hp_powerup_timer : R/W; bitpos: [22:14]; default: 255; - * need_des - */ - uint32_t dg_hp_powerup_timer:9; - /** dg_hp_wait_timer : R/W; bitpos: [31:23]; default: 255; - * need_des - */ - uint32_t dg_hp_wait_timer:9; + uint32_t reserved0 : 5; + uint32_t powerdown_timer: 9; + uint32_t powerup_timer : 9; + uint32_t wait_timer : 9; }; uint32_t val; } pmu_power_wait_timer0_reg_t; -/** Type of power_wait_timer1 register - * need_des - */ typedef union { struct { - uint32_t reserved_0:9; - /** dg_lp_powerdown_timer : R/W; bitpos: [15:9]; default: 255; - * need_des - */ - uint32_t dg_lp_powerdown_timer:7; - /** dg_lp_powerup_timer : R/W; bitpos: [22:16]; default: 255; - * need_des - */ - uint32_t dg_lp_powerup_timer:7; - /** dg_lp_wait_timer : R/W; bitpos: [31:23]; default: 255; - * need_des - */ - uint32_t dg_lp_wait_timer:9; + uint32_t reserved0 : 9; + uint32_t powerdown_timer: 7; + uint32_t powerup_timer : 7; + uint32_t wait_timer : 9; }; uint32_t val; } pmu_power_wait_timer1_reg_t; -/** Type of power_pd_top_cntl register - * need_des - */ typedef union { struct { - /** force_top_reset : R/W; bitpos: [0]; default: 0; - * need_des - */ - uint32_t force_top_reset:1; - /** force_top_iso : R/W; bitpos: [1]; default: 0; - * need_des - */ - uint32_t force_top_iso:1; - /** force_top_pu : R/W; bitpos: [2]; default: 1; - * need_des - */ - uint32_t force_top_pu:1; - /** force_top_no_reset : R/W; bitpos: [3]; default: 1; - * need_des - */ - uint32_t force_top_no_reset:1; - /** force_top_no_iso : R/W; bitpos: [4]; default: 1; - * need_des - */ - uint32_t force_top_no_iso:1; - /** force_top_pd : R/W; bitpos: [5]; default: 0; - * need_des - */ - uint32_t force_top_pd:1; - /** pd_top_mask : R/W; bitpos: [10:6]; default: 0; - * need_des - */ - uint32_t pd_top_mask:5; - uint32_t reserved_11:16; - /** pd_top_pd_mask : R/W; bitpos: [31:27]; default: 0; - * need_des - */ - uint32_t pd_top_pd_mask:5; + uint32_t force_reset : 1; + uint32_t force_iso : 1; + uint32_t force_pu : 1; + uint32_t force_no_reset: 1; + uint32_t force_no_iso : 1; + uint32_t force_pd : 1; + uint32_t mask : 5; /* Invalid of lp peripherals */ + uint32_t reserved0 : 16; /* Invalid of lp peripherals */ + uint32_t pd_mask : 5; /* Invalid of lp peripherals */ }; uint32_t val; -} pmu_power_pd_top_cntl_reg_t; +} pmu_power_domain_cntl_reg_t; -/** Type of power_pd_hpaon_cntl register - * need_des - */ typedef union { struct { - /** force_hp_aon_reset : R/W; bitpos: [0]; default: 0; - * need_des - */ - uint32_t force_hp_aon_reset:1; - /** force_hp_aon_iso : R/W; bitpos: [1]; default: 0; - * need_des - */ - uint32_t force_hp_aon_iso:1; - /** force_hp_aon_pu : R/W; bitpos: [2]; default: 1; - * need_des - */ - uint32_t force_hp_aon_pu:1; - /** force_hp_aon_no_reset : R/W; bitpos: [3]; default: 1; - * need_des - */ - uint32_t force_hp_aon_no_reset:1; - /** force_hp_aon_no_iso : R/W; bitpos: [4]; default: 1; - * need_des - */ - uint32_t force_hp_aon_no_iso:1; - /** force_hp_aon_pd : R/W; bitpos: [5]; default: 0; - * need_des - */ - uint32_t force_hp_aon_pd:1; - /** pd_hp_aon_mask : R/W; bitpos: [10:6]; default: 0; - * need_des - */ - uint32_t pd_hp_aon_mask:5; - uint32_t reserved_11:16; - /** pd_hp_aon_pd_mask : R/W; bitpos: [31:27]; default: 0; - * need_des - */ - uint32_t pd_hp_aon_pd_mask:5; + uint32_t force_hp_mem_iso : 4; + uint32_t force_hp_mem_pd : 4; + uint32_t reserved0 : 16; + uint32_t force_hp_mem_no_iso: 4; + uint32_t force_hp_mem_pu : 4; }; uint32_t val; -} pmu_power_pd_hpaon_cntl_reg_t; +} pmu_power_memory_cntl_reg_t; -/** Type of power_pd_hpcpu_cntl register - * need_des - */ typedef union { struct { - /** force_hp_cpu_reset : R/W; bitpos: [0]; default: 0; - * need_des - */ - uint32_t force_hp_cpu_reset:1; - /** force_hp_cpu_iso : R/W; bitpos: [1]; default: 0; - * need_des - */ - uint32_t force_hp_cpu_iso:1; - /** force_hp_cpu_pu : R/W; bitpos: [2]; default: 1; - * need_des - */ - uint32_t force_hp_cpu_pu:1; - /** force_hp_cpu_no_reset : R/W; bitpos: [3]; default: 1; - * need_des - */ - uint32_t force_hp_cpu_no_reset:1; - /** force_hp_cpu_no_iso : R/W; bitpos: [4]; default: 1; - * need_des - */ - uint32_t force_hp_cpu_no_iso:1; - /** force_hp_cpu_pd : R/W; bitpos: [5]; default: 0; - * need_des - */ - uint32_t force_hp_cpu_pd:1; - /** pd_hp_cpu_mask : R/W; bitpos: [10:6]; default: 0; - * need_des - */ - uint32_t pd_hp_cpu_mask:5; - uint32_t reserved_11:16; - /** pd_hp_cpu_pd_mask : R/W; bitpos: [31:27]; default: 0; - * need_des - */ - uint32_t pd_hp_cpu_pd_mask:5; + uint32_t mem2_pd_mask: 5; + uint32_t mem1_pd_mask: 5; + uint32_t mem0_pd_mask: 5; + uint32_t reserved0 : 2; + uint32_t mem2_mask : 5; + uint32_t mem1_mask : 5; + uint32_t mem0_mask : 5; }; uint32_t val; -} pmu_power_pd_hpcpu_cntl_reg_t; +} pmu_power_memory_mask_reg_t; -/** Type of power_pd_hpperi_reserve register - * need_des - */ typedef union { struct { - /** hp_peri_reserve : WT; bitpos: [31:0]; default: 0; - * need_des - */ - uint32_t hp_peri_reserve:32; - }; - uint32_t val; -} pmu_power_pd_hpperi_reserve_reg_t; - -/** Type of power_pd_hpwifi_cntl register - * need_des - */ -typedef union { - struct { - /** force_hp_wifi_reset : R/W; bitpos: [0]; default: 0; - * need_des - */ - uint32_t force_hp_wifi_reset:1; - /** force_hp_wifi_iso : R/W; bitpos: [1]; default: 0; - * need_des - */ - uint32_t force_hp_wifi_iso:1; - /** force_hp_wifi_pu : R/W; bitpos: [2]; default: 1; - * need_des - */ - uint32_t force_hp_wifi_pu:1; - /** force_hp_wifi_no_reset : R/W; bitpos: [3]; default: 1; - * need_des - */ - uint32_t force_hp_wifi_no_reset:1; - /** force_hp_wifi_no_iso : R/W; bitpos: [4]; default: 1; - * need_des - */ - uint32_t force_hp_wifi_no_iso:1; - /** force_hp_wifi_pd : R/W; bitpos: [5]; default: 0; - * need_des - */ - uint32_t force_hp_wifi_pd:1; - /** pd_hp_wifi_mask : R/W; bitpos: [10:6]; default: 0; - * need_des - */ - uint32_t pd_hp_wifi_mask:5; - uint32_t reserved_11:16; - /** pd_hp_wifi_pd_mask : R/W; bitpos: [31:27]; default: 0; - * need_des - */ - uint32_t pd_hp_wifi_pd_mask:5; - }; - uint32_t val; -} pmu_power_pd_hpwifi_cntl_reg_t; - -/** Type of power_pd_lpperi_cntl register - * need_des - */ -typedef union { - struct { - /** force_lp_peri_reset : R/W; bitpos: [0]; default: 0; - * need_des - */ - uint32_t force_lp_peri_reset:1; - /** force_lp_peri_iso : R/W; bitpos: [1]; default: 0; - * need_des - */ - uint32_t force_lp_peri_iso:1; - /** force_lp_peri_pu : R/W; bitpos: [2]; default: 1; - * need_des - */ - uint32_t force_lp_peri_pu:1; - /** force_lp_peri_no_reset : R/W; bitpos: [3]; default: 1; - * need_des - */ - uint32_t force_lp_peri_no_reset:1; - /** force_lp_peri_no_iso : R/W; bitpos: [4]; default: 1; - * need_des - */ - uint32_t force_lp_peri_no_iso:1; - /** force_lp_peri_pd : R/W; bitpos: [5]; default: 0; - * need_des - */ - uint32_t force_lp_peri_pd:1; - uint32_t reserved_6:26; - }; - uint32_t val; -} pmu_power_pd_lpperi_cntl_reg_t; - -/** Type of power_pd_mem_cntl register - * need_des - */ -typedef union { - struct { - /** force_hp_mem_iso : R/W; bitpos: [3:0]; default: 0; - * need_des - */ - uint32_t force_hp_mem_iso:4; - /** force_hp_mem_pd : R/W; bitpos: [7:4]; default: 0; - * need_des - */ - uint32_t force_hp_mem_pd:4; - uint32_t reserved_8:16; - /** force_hp_mem_no_iso : R/W; bitpos: [27:24]; default: 15; - * need_des - */ - uint32_t force_hp_mem_no_iso:4; - /** force_hp_mem_pu : R/W; bitpos: [31:28]; default: 15; - * need_des - */ - uint32_t force_hp_mem_pu:4; - }; - uint32_t val; -} pmu_power_pd_mem_cntl_reg_t; - -/** Type of power_pd_mem_mask register - * need_des - */ -typedef union { - struct { - /** pd_hp_mem2_pd_mask : R/W; bitpos: [4:0]; default: 0; - * need_des - */ - uint32_t pd_hp_mem2_pd_mask:5; - /** pd_hp_mem1_pd_mask : R/W; bitpos: [9:5]; default: 0; - * need_des - */ - uint32_t pd_hp_mem1_pd_mask:5; - /** pd_hp_mem0_pd_mask : R/W; bitpos: [14:10]; default: 0; - * need_des - */ - uint32_t pd_hp_mem0_pd_mask:5; - uint32_t reserved_15:2; - /** pd_hp_mem2_mask : R/W; bitpos: [21:17]; default: 0; - * need_des - */ - uint32_t pd_hp_mem2_mask:5; - /** pd_hp_mem1_mask : R/W; bitpos: [26:22]; default: 0; - * need_des - */ - uint32_t pd_hp_mem1_mask:5; - /** pd_hp_mem0_mask : R/W; bitpos: [31:27]; default: 0; - * need_des - */ - uint32_t pd_hp_mem0_mask:5; - }; - uint32_t val; -} pmu_power_pd_mem_mask_reg_t; - -/** Type of power_hp_pad register - * need_des - */ -typedef union { - struct { - /** force_hp_pad_no_iso_all : R/W; bitpos: [0]; default: 0; - * need_des - */ - uint32_t force_hp_pad_no_iso_all:1; - /** force_hp_pad_iso_all : R/W; bitpos: [1]; default: 0; - * need_des - */ - uint32_t force_hp_pad_iso_all:1; - uint32_t reserved_2:30; + uint32_t force_hp_pad_no_iso_all: 1; + uint32_t force_hp_pad_iso_all : 1; + uint32_t reserved0 : 30; }; uint32_t val; } pmu_power_hp_pad_reg_t; -/** Type of power_vdd_spi_cntl register - * need_des - */ typedef union { struct { - uint32_t reserved_0:18; - /** vdd_spi_pwr_wait : R/W; bitpos: [28:18]; default: 255; - * need_des - */ - uint32_t vdd_spi_pwr_wait:11; - /** vdd_spi_pwr_sw : R/W; bitpos: [30:29]; default: 3; - * need_des - */ - uint32_t vdd_spi_pwr_sw:2; - /** vdd_spi_pwr_sel_sw : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t vdd_spi_pwr_sel_sw:1; + uint32_t reserved0 : 18; + uint32_t pwr_wait : 11; + uint32_t pwr_sw : 2; + uint32_t pwr_sel_sw: 1; }; uint32_t val; } pmu_power_vdd_spi_cntl_reg_t; -/** Type of power_ck_wait_cntl register - * need_des - */ typedef union { struct { - /** wait_xtl_stable : R/W; bitpos: [15:0]; default: 256; - * need_des - */ - uint32_t wait_xtl_stable:16; - /** wait_pll_stable : R/W; bitpos: [31:16]; default: 256; - * need_des - */ - uint32_t wait_pll_stable:16; + uint32_t wait_xtal_stable: 16; + uint32_t wait_pll_stable : 16; }; uint32_t val; -} pmu_power_ck_wait_cntl_reg_t; +} pmu_power_clk_wait_cntl_reg_t; + +typedef volatile struct pmu_power_hw_regmap_t{ + pmu_power_wait_timer0_reg_t wait_timer0; + pmu_power_wait_timer1_reg_t wait_timer1; + pmu_power_domain_cntl_reg_t hp_pd[5]; + pmu_power_domain_cntl_reg_t lp_peri; + pmu_power_memory_cntl_reg_t mem_cntl; + pmu_power_memory_mask_reg_t mem_mask; + pmu_power_hp_pad_reg_t hp_pad; + pmu_power_vdd_spi_cntl_reg_t vdd_spi; + pmu_power_clk_wait_cntl_reg_t clk_wait; +} pmu_power_hw_regmap_t; -/** Type of slp_wakeup_cntl0 register - * need_des - */ typedef union { struct { - uint32_t reserved_0:31; - /** sleep_req : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t sleep_req:1; + uint32_t reserved0: 31; + uint32_t sleep_req: 1; }; uint32_t val; } pmu_slp_wakeup_cntl0_reg_t; -/** Type of slp_wakeup_cntl1 register - * need_des - */ typedef union { struct { - /** sleep_reject_ena : R/W; bitpos: [30:0]; default: 0; - * need_des - */ - uint32_t sleep_reject_ena:31; - /** slp_reject_en : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t slp_reject_en:1; + uint32_t sleep_reject_ena: 31; + uint32_t slp_reject_en : 1; }; uint32_t val; } pmu_slp_wakeup_cntl1_reg_t; -/** Type of slp_wakeup_cntl2 register - * need_des - */ typedef union { struct { - /** wakeup_ena : R/W; bitpos: [31:0]; default: 0; - * need_des - */ - uint32_t wakeup_ena:32; - }; - uint32_t val; -} pmu_slp_wakeup_cntl2_reg_t; - -/** Type of slp_wakeup_cntl3 register - * need_des - */ -typedef union { - struct { - /** lp_min_slp_val : R/W; bitpos: [7:0]; default: 0; - * need_des - */ - uint32_t lp_min_slp_val:8; - /** hp_min_slp_val : R/W; bitpos: [15:8]; default: 0; - * need_des - */ - uint32_t hp_min_slp_val:8; - /** sleep_prt_sel : R/W; bitpos: [17:16]; default: 0; - * need_des - */ - uint32_t sleep_prt_sel:2; - uint32_t reserved_18:14; + uint32_t lp_min_slp_val: 8; + uint32_t hp_min_slp_val: 8; + uint32_t sleep_prt_sel : 2; + uint32_t reserved0 : 14; }; uint32_t val; } pmu_slp_wakeup_cntl3_reg_t; -/** Type of slp_wakeup_cntl4 register - * need_des - */ typedef union { struct { - uint32_t reserved_0:31; - /** slp_reject_cause_clr : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t slp_reject_cause_clr:1; + uint32_t reserved0 : 31; + uint32_t slp_reject_cause_clr: 1; }; uint32_t val; } pmu_slp_wakeup_cntl4_reg_t; -/** Type of slp_wakeup_cntl5 register - * need_des - */ typedef union { struct { - /** modem_wait_target : R/W; bitpos: [19:0]; default: 128; - * need_des - */ - uint32_t modem_wait_target:20; - uint32_t reserved_20:4; - /** lp_ana_wait_target : R/W; bitpos: [31:24]; default: 1; - * need_des - */ - uint32_t lp_ana_wait_target:8; + uint32_t modem_wait_target : 20; + uint32_t reserved0 : 4; + uint32_t lp_ana_wait_target: 8; }; uint32_t val; } pmu_slp_wakeup_cntl5_reg_t; -/** Type of slp_wakeup_cntl6 register - * need_des - */ typedef union { struct { - /** soc_wakeup_wait : R/W; bitpos: [19:0]; default: 128; - * need_des - */ - uint32_t soc_wakeup_wait:20; - uint32_t reserved_20:10; - /** soc_wakeup_wait_cfg : R/W; bitpos: [31:30]; default: 0; - * need_des - */ - uint32_t soc_wakeup_wait_cfg:2; + uint32_t soc_wakeup_wait : 20; + uint32_t reserved0 : 10; + uint32_t soc_wakeup_wait_cfg: 2; }; uint32_t val; } pmu_slp_wakeup_cntl6_reg_t; -/** Type of slp_wakeup_cntl7 register - * need_des - */ typedef union { struct { - uint32_t reserved_0:16; - /** ana_wait_target : R/W; bitpos: [31:16]; default: 1; - * need_des - */ - uint32_t ana_wait_target:16; + uint32_t reserved0 : 16; + uint32_t ana_wait_target: 16; }; uint32_t val; } pmu_slp_wakeup_cntl7_reg_t; -/** Type of slp_wakeup_status0 register - * need_des - */ +typedef volatile struct pmu_wakeup_hw_regmap_t{ + pmu_slp_wakeup_cntl0_reg_t cntl0; + pmu_slp_wakeup_cntl1_reg_t cntl1; + uint32_t cntl2; + pmu_slp_wakeup_cntl3_reg_t cntl3; + pmu_slp_wakeup_cntl4_reg_t cntl4; + pmu_slp_wakeup_cntl5_reg_t cntl5; + pmu_slp_wakeup_cntl6_reg_t cntl6; + pmu_slp_wakeup_cntl7_reg_t cntl7; + uint32_t status0; + uint32_t status1; +} pmu_wakeup_hw_regmap_t; + typedef union { struct { - /** wakeup_cause : RO; bitpos: [31:0]; default: 0; - * need_des - */ - uint32_t wakeup_cause:32; + uint32_t i2c_por_wait_target: 8; + uint32_t reserved0 : 24; }; uint32_t val; -} pmu_slp_wakeup_status0_reg_t; +} pmu_hp_clk_poweron_reg_t; -/** Type of slp_wakeup_status1 register - * need_des - */ typedef union { struct { - /** reject_cause : RO; bitpos: [31:0]; default: 0; - * need_des - */ - uint32_t reject_cause:32; + uint32_t modify_icg_cntl_wait: 8; + uint32_t switch_icg_cntl_wait: 8; + uint32_t reserved0 : 16; }; uint32_t val; -} pmu_slp_wakeup_status1_reg_t; +} pmu_hp_clk_cntl_reg_t; -/** Type of hp_ck_poweron register - * need_des - */ typedef union { struct { - /** i2c_por_wait_target : R/W; bitpos: [7:0]; default: 50; - * need_des - */ - uint32_t i2c_por_wait_target:8; - uint32_t reserved_8:24; - }; - uint32_t val; -} pmu_hp_ck_poweron_reg_t; - -/** Type of hp_ck_cntl register - * need_des - */ -typedef union { - struct { - /** modify_icg_cntl_wait : R/W; bitpos: [7:0]; default: 10; - * need_des - */ - uint32_t modify_icg_cntl_wait:8; - /** switch_icg_cntl_wait : R/W; bitpos: [15:8]; default: 10; - * need_des - */ - uint32_t switch_icg_cntl_wait:8; - uint32_t reserved_16:16; - }; - uint32_t val; -} pmu_hp_ck_cntl_reg_t; - -/** Type of por_status register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:31; - /** por_done : RO; bitpos: [31]; default: 1; - * need_des - */ - uint32_t por_done:1; + uint32_t reserved0: 31; + uint32_t por_done : 1; }; uint32_t val; } pmu_por_status_reg_t; -/** Type of rf_pwc register - * need_des - */ typedef union { struct { - uint32_t reserved_0:26; - /** perif_i2c_rstb : R/W; bitpos: [26]; default: 0; - * need_des - */ - uint32_t perif_i2c_rstb:1; - /** xpd_perif_i2c : R/W; bitpos: [27]; default: 1; - * need_des - */ - uint32_t xpd_perif_i2c:1; - /** xpd_txrf_i2c : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t xpd_txrf_i2c:1; - /** xpd_rfrx_pbus : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t xpd_rfrx_pbus:1; - /** xpd_ckgen_i2c : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t xpd_ckgen_i2c:1; - /** xpd_pll_i2c : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t xpd_pll_i2c:1; + uint32_t reserved0 : 26; + uint32_t perif_i2c_rstb: 1; + uint32_t xpd_perif_i2c : 1; + uint32_t xpd_txrf_i2c : 1; + uint32_t xpd_rfrx_pbus : 1; + uint32_t xpd_ckgen_i2c : 1; + uint32_t xpd_pll_i2c : 1; }; uint32_t val; } pmu_rf_pwc_reg_t; -/** Type of backup_cfg register - * need_des - */ typedef union { struct { - uint32_t reserved_0:31; - /** backup_sys_clk_no_div : R/W; bitpos: [31]; default: 1; - * need_des - */ - uint32_t backup_sys_clk_no_div:1; + uint32_t reserved0 : 31; + uint32_t backup_sysclk_nodiv: 1; }; uint32_t val; } pmu_backup_cfg_reg_t; -/** Type of int_raw register - * need_des - */ typedef union { struct { - uint32_t reserved_0:27; - /** lp_cpu_exc_int_raw : R/WTC/SS; bitpos: [27]; default: 0; - * need_des - */ - uint32_t lp_cpu_exc_int_raw:1; - /** sdio_idle_int_raw : R/WTC/SS; bitpos: [28]; default: 0; - * need_des - */ - uint32_t sdio_idle_int_raw:1; - /** sw_int_raw : R/WTC/SS; bitpos: [29]; default: 0; - * need_des - */ - uint32_t sw_int_raw:1; - /** soc_sleep_reject_int_raw : R/WTC/SS; bitpos: [30]; default: 0; - * need_des - */ - uint32_t soc_sleep_reject_int_raw:1; - /** soc_wakeup_int_raw : R/WTC/SS; bitpos: [31]; default: 0; - * need_des - */ - uint32_t soc_wakeup_int_raw:1; + uint32_t reserved0 : 27; + uint32_t lp_cpu_exc: 1; + uint32_t sdio_idle : 1; + uint32_t sw : 1; + uint32_t reject : 1; + uint32_t wakeup : 1; }; uint32_t val; -} pmu_int_raw_reg_t; +} pmu_hp_intr_reg_t; + +typedef volatile struct pmu_hp_ext_hw_regmap_t{ + pmu_hp_clk_poweron_reg_t clk_poweron; + pmu_hp_clk_cntl_reg_t clk_cntl; + pmu_por_status_reg_t por_status; + pmu_rf_pwc_reg_t rf_pwc; + pmu_backup_cfg_reg_t backup_cfg; + pmu_hp_intr_reg_t int_raw; + pmu_hp_intr_reg_t int_st; + pmu_hp_intr_reg_t int_ena; + pmu_hp_intr_reg_t int_clr; +} pmu_hp_ext_hw_regmap_t; -/** Type of hp_int_st register - * need_des - */ typedef union { struct { - uint32_t reserved_0:27; - /** lp_cpu_exc_int_st : RO; bitpos: [27]; default: 0; - * need_des - */ - uint32_t lp_cpu_exc_int_st:1; - /** sdio_idle_int_st : RO; bitpos: [28]; default: 0; - * need_des - */ - uint32_t sdio_idle_int_st:1; - /** sw_int_st : RO; bitpos: [29]; default: 0; - * need_des - */ - uint32_t sw_int_st:1; - /** soc_sleep_reject_int_st : RO; bitpos: [30]; default: 0; - * need_des - */ - uint32_t soc_sleep_reject_int_st:1; - /** soc_wakeup_int_st : RO; bitpos: [31]; default: 0; - * need_des - */ - uint32_t soc_wakeup_int_st:1; + uint32_t reserved0 : 20; + uint32_t lp_cpu_wakeup : 1; + uint32_t modem_switch_active_end : 1; + uint32_t sleep_switch_active_end : 1; + uint32_t sleep_switch_modem_end : 1; + uint32_t modem_switch_sleep_end : 1; + uint32_t active_swtich_sleep_end : 1; + uint32_t modem_switch_active_start: 1; + uint32_t sleep_switch_active_start: 1; + uint32_t sleep_switch_modem_start : 1; + uint32_t modem_switch_sleep_start : 1; + uint32_t active_switch_sleep_start: 1; + uint32_t sw_trigger : 1; }; uint32_t val; -} pmu_hp_int_st_reg_t; +} pmu_lp_intr_reg_t; -/** Type of hp_int_ena register - * need_des - */ typedef union { struct { - uint32_t reserved_0:27; - /** lp_cpu_exc_int_ena : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t lp_cpu_exc_int_ena:1; - /** sdio_idle_int_ena : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t sdio_idle_int_ena:1; - /** sw_int_ena : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t sw_int_ena:1; - /** soc_sleep_reject_int_ena : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t soc_sleep_reject_int_ena:1; - /** soc_wakeup_int_ena : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t soc_wakeup_int_ena:1; - }; - uint32_t val; -} pmu_hp_int_ena_reg_t; - -/** Type of hp_int_clr register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:27; - /** lp_cpu_exc_int_clr : WT; bitpos: [27]; default: 0; - * need_des - */ - uint32_t lp_cpu_exc_int_clr:1; - /** sdio_idle_int_clr : WT; bitpos: [28]; default: 0; - * need_des - */ - uint32_t sdio_idle_int_clr:1; - /** sw_int_clr : WT; bitpos: [29]; default: 0; - * need_des - */ - uint32_t sw_int_clr:1; - /** soc_sleep_reject_int_clr : WT; bitpos: [30]; default: 0; - * need_des - */ - uint32_t soc_sleep_reject_int_clr:1; - /** soc_wakeup_int_clr : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t soc_wakeup_int_clr:1; - }; - uint32_t val; -} pmu_hp_int_clr_reg_t; - -/** Type of lp_int_raw register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:20; - /** lp_cpu_wakeup_int_raw : R/WTC/SS; bitpos: [20]; default: 0; - * need_des - */ - uint32_t lp_cpu_wakeup_int_raw:1; - /** modem_switch_active_end_int_raw : R/WTC/SS; bitpos: [21]; default: 0; - * need_des - */ - uint32_t modem_switch_active_end_int_raw:1; - /** sleep_switch_active_end_int_raw : R/WTC/SS; bitpos: [22]; default: 0; - * need_des - */ - uint32_t sleep_switch_active_end_int_raw:1; - /** sleep_switch_modem_end_int_raw : R/WTC/SS; bitpos: [23]; default: 0; - * need_des - */ - uint32_t sleep_switch_modem_end_int_raw:1; - /** modem_switch_sleep_end_int_raw : R/WTC/SS; bitpos: [24]; default: 0; - * need_des - */ - uint32_t modem_switch_sleep_end_int_raw:1; - /** active_switch_sleep_end_int_raw : R/WTC/SS; bitpos: [25]; default: 0; - * need_des - */ - uint32_t active_switch_sleep_end_int_raw:1; - /** modem_switch_active_start_int_raw : R/WTC/SS; bitpos: [26]; default: 0; - * need_des - */ - uint32_t modem_switch_active_start_int_raw:1; - /** sleep_switch_active_start_int_raw : R/WTC/SS; bitpos: [27]; default: 0; - * need_des - */ - uint32_t sleep_switch_active_start_int_raw:1; - /** sleep_switch_modem_start_int_raw : R/WTC/SS; bitpos: [28]; default: 0; - * need_des - */ - uint32_t sleep_switch_modem_start_int_raw:1; - /** modem_switch_sleep_start_int_raw : R/WTC/SS; bitpos: [29]; default: 0; - * need_des - */ - uint32_t modem_switch_sleep_start_int_raw:1; - /** active_switch_sleep_start_int_raw : R/WTC/SS; bitpos: [30]; default: 0; - * need_des - */ - uint32_t active_switch_sleep_start_int_raw:1; - /** hp_sw_trigger_int_raw : R/WTC/SS; bitpos: [31]; default: 0; - * need_des - */ - uint32_t hp_sw_trigger_int_raw:1; - }; - uint32_t val; -} pmu_lp_int_raw_reg_t; - -/** Type of lp_int_st register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:20; - /** lp_cpu_wakeup_int_st : RO; bitpos: [20]; default: 0; - * need_des - */ - uint32_t lp_cpu_wakeup_int_st:1; - /** modem_switch_active_end_int_st : RO; bitpos: [21]; default: 0; - * need_des - */ - uint32_t modem_switch_active_end_int_st:1; - /** sleep_switch_active_end_int_st : RO; bitpos: [22]; default: 0; - * need_des - */ - uint32_t sleep_switch_active_end_int_st:1; - /** sleep_switch_modem_end_int_st : RO; bitpos: [23]; default: 0; - * need_des - */ - uint32_t sleep_switch_modem_end_int_st:1; - /** modem_switch_sleep_end_int_st : RO; bitpos: [24]; default: 0; - * need_des - */ - uint32_t modem_switch_sleep_end_int_st:1; - /** active_switch_sleep_end_int_st : RO; bitpos: [25]; default: 0; - * need_des - */ - uint32_t active_switch_sleep_end_int_st:1; - /** modem_switch_active_start_int_st : RO; bitpos: [26]; default: 0; - * need_des - */ - uint32_t modem_switch_active_start_int_st:1; - /** sleep_switch_active_start_int_st : RO; bitpos: [27]; default: 0; - * need_des - */ - uint32_t sleep_switch_active_start_int_st:1; - /** sleep_switch_modem_start_int_st : RO; bitpos: [28]; default: 0; - * need_des - */ - uint32_t sleep_switch_modem_start_int_st:1; - /** modem_switch_sleep_start_int_st : RO; bitpos: [29]; default: 0; - * need_des - */ - uint32_t modem_switch_sleep_start_int_st:1; - /** active_switch_sleep_start_int_st : RO; bitpos: [30]; default: 0; - * need_des - */ - uint32_t active_switch_sleep_start_int_st:1; - /** hp_sw_trigger_int_st : RO; bitpos: [31]; default: 0; - * need_des - */ - uint32_t hp_sw_trigger_int_st:1; - }; - uint32_t val; -} pmu_lp_int_st_reg_t; - -/** Type of lp_int_ena register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:20; - /** lp_cpu_wakeup_int_ena : R/W; bitpos: [20]; default: 0; - * need_des - */ - uint32_t lp_cpu_wakeup_int_ena:1; - /** modem_switch_active_end_int_ena : R/W; bitpos: [21]; default: 0; - * need_des - */ - uint32_t modem_switch_active_end_int_ena:1; - /** sleep_switch_active_end_int_ena : R/W; bitpos: [22]; default: 0; - * need_des - */ - uint32_t sleep_switch_active_end_int_ena:1; - /** sleep_switch_modem_end_int_ena : R/W; bitpos: [23]; default: 0; - * need_des - */ - uint32_t sleep_switch_modem_end_int_ena:1; - /** modem_switch_sleep_end_int_ena : R/W; bitpos: [24]; default: 0; - * need_des - */ - uint32_t modem_switch_sleep_end_int_ena:1; - /** active_switch_sleep_end_int_ena : R/W; bitpos: [25]; default: 0; - * need_des - */ - uint32_t active_switch_sleep_end_int_ena:1; - /** modem_switch_active_start_int_ena : R/W; bitpos: [26]; default: 0; - * need_des - */ - uint32_t modem_switch_active_start_int_ena:1; - /** sleep_switch_active_start_int_ena : R/W; bitpos: [27]; default: 0; - * need_des - */ - uint32_t sleep_switch_active_start_int_ena:1; - /** sleep_switch_modem_start_int_ena : R/W; bitpos: [28]; default: 0; - * need_des - */ - uint32_t sleep_switch_modem_start_int_ena:1; - /** modem_switch_sleep_start_int_ena : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t modem_switch_sleep_start_int_ena:1; - /** active_switch_sleep_start_int_ena : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t active_switch_sleep_start_int_ena:1; - /** hp_sw_trigger_int_ena : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t hp_sw_trigger_int_ena:1; - }; - uint32_t val; -} pmu_lp_int_ena_reg_t; - -/** Type of lp_int_clr register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:20; - /** lp_cpu_wakeup_int_clr : WT; bitpos: [20]; default: 0; - * need_des - */ - uint32_t lp_cpu_wakeup_int_clr:1; - /** modem_switch_active_end_int_clr : WT; bitpos: [21]; default: 0; - * need_des - */ - uint32_t modem_switch_active_end_int_clr:1; - /** sleep_switch_active_end_int_clr : WT; bitpos: [22]; default: 0; - * need_des - */ - uint32_t sleep_switch_active_end_int_clr:1; - /** sleep_switch_modem_end_int_clr : WT; bitpos: [23]; default: 0; - * need_des - */ - uint32_t sleep_switch_modem_end_int_clr:1; - /** modem_switch_sleep_end_int_clr : WT; bitpos: [24]; default: 0; - * need_des - */ - uint32_t modem_switch_sleep_end_int_clr:1; - /** active_switch_sleep_end_int_clr : WT; bitpos: [25]; default: 0; - * need_des - */ - uint32_t active_switch_sleep_end_int_clr:1; - /** modem_switch_active_start_int_clr : WT; bitpos: [26]; default: 0; - * need_des - */ - uint32_t modem_switch_active_start_int_clr:1; - /** sleep_switch_active_start_int_clr : WT; bitpos: [27]; default: 0; - * need_des - */ - uint32_t sleep_switch_active_start_int_clr:1; - /** sleep_switch_modem_start_int_clr : WT; bitpos: [28]; default: 0; - * need_des - */ - uint32_t sleep_switch_modem_start_int_clr:1; - /** modem_switch_sleep_start_int_clr : WT; bitpos: [29]; default: 0; - * need_des - */ - uint32_t modem_switch_sleep_start_int_clr:1; - /** active_switch_sleep_start_int_clr : WT; bitpos: [30]; default: 0; - * need_des - */ - uint32_t active_switch_sleep_start_int_clr:1; - /** hp_sw_trigger_int_clr : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t hp_sw_trigger_int_clr:1; - }; - uint32_t val; -} pmu_lp_int_clr_reg_t; - -/** Type of lp_cpu_pwr0 register - * need_des - */ -typedef union { - struct { - /** lp_cpu_waiti_rdy : RO; bitpos: [0]; default: 0; - * need_des - */ - uint32_t lp_cpu_waiti_rdy:1; - /** lp_cpu_stall_rdy : RO; bitpos: [1]; default: 0; - * need_des - */ - uint32_t lp_cpu_stall_rdy:1; - uint32_t reserved_2:16; - /** lp_cpu_force_stall : R/W; bitpos: [18]; default: 0; - * need_des - */ - uint32_t lp_cpu_force_stall:1; - /** lp_cpu_slp_waiti_flag_en : R/W; bitpos: [19]; default: 0; - * need_des - */ - uint32_t lp_cpu_slp_waiti_flag_en:1; - /** lp_cpu_slp_stall_flag_en : R/W; bitpos: [20]; default: 1; - * need_des - */ - uint32_t lp_cpu_slp_stall_flag_en:1; - /** lp_cpu_slp_stall_wait : R/W; bitpos: [28:21]; default: 255; - * need_des - */ - uint32_t lp_cpu_slp_stall_wait:8; - /** lp_cpu_slp_stall_en : R/W; bitpos: [29]; default: 0; - * need_des - */ - uint32_t lp_cpu_slp_stall_en:1; - /** lp_cpu_slp_reset_en : R/W; bitpos: [30]; default: 0; - * need_des - */ - uint32_t lp_cpu_slp_reset_en:1; - /** lp_cpu_slp_bypass_intr_en : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t lp_cpu_slp_bypass_intr_en:1; + uint32_t waiti_rdy : 1; + uint32_t stall_rdy : 1; + uint32_t reserved0 : 16; + uint32_t force_stall : 1; + uint32_t slp_waiti_flag_en : 1; + uint32_t slp_stall_flag_en : 1; + uint32_t slp_stall_wait : 8; + uint32_t slp_stall_en : 1; + uint32_t slp_reset_en : 1; + uint32_t slp_bypass_intr_en: 1; }; uint32_t val; } pmu_lp_cpu_pwr0_reg_t; -/** Type of lp_cpu_pwr1 register - * need_des - */ typedef union { struct { - /** lp_cpu_wakeup_en : R/W; bitpos: [15:0]; default: 0; - * need_des - */ - uint32_t lp_cpu_wakeup_en:16; - uint32_t reserved_16:15; - /** lp_cpu_sleep_req : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t lp_cpu_sleep_req:1; + uint32_t wakeup_en: 16; + uint32_t reserved0: 15; + uint32_t sleep_req: 1; }; uint32_t val; } pmu_lp_cpu_pwr1_reg_t; -/** Type of hp_lp_cpu_comm register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:30; - /** lp_trigger_hp : WT; bitpos: [30]; default: 0; - * need_des - */ - uint32_t lp_trigger_hp:1; - /** hp_trigger_lp : WT; bitpos: [31]; default: 0; - * need_des - */ - uint32_t hp_trigger_lp:1; - }; - uint32_t val; -} pmu_hp_lp_cpu_comm_reg_t; +typedef volatile struct pmu_lp_ext_hw_regmap_t{ + pmu_lp_intr_reg_t int_raw; + pmu_lp_intr_reg_t int_st; + pmu_lp_intr_reg_t int_ena; + pmu_lp_intr_reg_t int_clr; + pmu_lp_cpu_pwr0_reg_t pwr0; + pmu_lp_cpu_pwr1_reg_t pwr1; +} pmu_lp_ext_hw_regmap_t; -/** Type of hp_regulator_cfg register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:31; - /** dig_regulator_en_cal : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t dig_regulator_en_cal:1; - }; - uint32_t val; -} pmu_hp_regulator_cfg_reg_t; +typedef volatile struct pmu_dev_t{ + pmu_hp_hw_regmap_t hp_sys[3]; + pmu_lp_hw_regmap_t lp_sys[2]; + pmu_imm_hw_regmap_t imm; + pmu_power_hw_regmap_t power; + pmu_wakeup_hw_regmap_t wakeup; + pmu_hp_ext_hw_regmap_t hp_ext; + pmu_lp_ext_hw_regmap_t lp_ext; -/** Type of main_state register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:11; - /** main_last_st_state : RO; bitpos: [17:11]; default: 1; - * need_des - */ - uint32_t main_last_st_state:7; - /** main_tar_st_state : RO; bitpos: [24:18]; default: 4; - * need_des - */ - uint32_t main_tar_st_state:7; - /** main_cur_st_state : RO; bitpos: [31:25]; default: 4; - * need_des - */ - uint32_t main_cur_st_state:7; - }; - uint32_t val; -} pmu_main_state_reg_t; + union { + struct { + uint32_t reserved0 : 30; + uint32_t lp_trigger_hp: 1; + uint32_t hp_trigger_lp: 1; + }; + uint32_t val; + } hp_lp_cpu_comm; -/** Type of pwr_state register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:13; - /** backup_st_state : RO; bitpos: [17:13]; default: 1; - * need_des - */ - uint32_t backup_st_state:5; - /** lp_pwr_st_state : RO; bitpos: [22:18]; default: 0; - * need_des - */ - uint32_t lp_pwr_st_state:5; - /** hp_pwr_st_state : RO; bitpos: [31:23]; default: 1; - * need_des - */ - uint32_t hp_pwr_st_state:9; - }; - uint32_t val; -} pmu_pwr_state_reg_t; + union { + struct { + uint32_t reserved0 : 31; + uint32_t dig_regulator_en_cal: 1; + }; + uint32_t val; + } hp_regulator_cfg; -/** Type of date register - * need_des - */ -typedef union { - struct { - /** pmu_date : R/W; bitpos: [30:0]; default: 35676752; - * need_des - */ - uint32_t pmu_date:31; - /** clk_en : R/W; bitpos: [31]; default: 0; - * need_des - */ - uint32_t clk_en:1; - }; - uint32_t val; -} pmu_date_reg_t; + union { + struct { + uint32_t reserved0 : 11; + uint32_t last_st : 7; + uint32_t target_st : 7; + uint32_t current_st: 7; + }; + uint32_t val; + } main_state; + union { + struct { + uint32_t reserved0: 13; + uint32_t backup_st: 5; + uint32_t lp_pwr_st: 5; + uint32_t hp_pwr_st: 9; + }; + uint32_t val; + } pwr_state; -/** Group: status_register */ -/** Type of clk_state0 register - * need_des - */ -typedef union { - struct { - /** stable_xpd_bbpll_state : RO; bitpos: [0]; default: 1; - * need_des - */ - uint32_t stable_xpd_bbpll_state:1; - /** stable_xpd_xtal_state : RO; bitpos: [1]; default: 1; - * need_des - */ - uint32_t stable_xpd_xtal_state:1; - uint32_t reserved_2:13; - /** sys_clk_slp_sel_state : RO; bitpos: [15]; default: 0; - * need_des - */ - uint32_t sys_clk_slp_sel_state:1; - /** sys_clk_sel_state : RO; bitpos: [17:16]; default: 0; - * need_des - */ - uint32_t sys_clk_sel_state:2; - /** sys_clk_no_div_state : RO; bitpos: [18]; default: 0; - * need_des - */ - uint32_t sys_clk_no_div_state:1; - /** icg_sys_clk_en_state : RO; bitpos: [19]; default: 0; - * need_des - */ - uint32_t icg_sys_clk_en_state:1; - /** icg_modem_switch_state : RO; bitpos: [20]; default: 0; - * need_des - */ - uint32_t icg_modem_switch_state:1; - /** icg_modem_code_state : RO; bitpos: [22:21]; default: 0; - * need_des - */ - uint32_t icg_modem_code_state:2; - /** icg_slp_sel_state : RO; bitpos: [23]; default: 0; - * need_des - */ - uint32_t icg_slp_sel_state:1; - /** icg_global_xtal_state : RO; bitpos: [24]; default: 0; - * need_des - */ - uint32_t icg_global_xtal_state:1; - /** icg_global_pll_state : RO; bitpos: [25]; default: 0; - * need_des - */ - uint32_t icg_global_pll_state:1; - /** ana_i2c_iso_en_state : RO; bitpos: [26]; default: 0; - * need_des - */ - uint32_t ana_i2c_iso_en_state:1; - /** ana_i2c_retention_state : RO; bitpos: [27]; default: 0; - * need_des - */ - uint32_t ana_i2c_retention_state:1; - /** ana_xpd_bb_i2c_state : RO; bitpos: [28]; default: 0; - * need_des - */ - uint32_t ana_xpd_bb_i2c_state:1; - /** ana_xpd_bbpll_i2c_state : RO; bitpos: [29]; default: 0; - * need_des - */ - uint32_t ana_xpd_bbpll_i2c_state:1; - /** ana_xpd_bbpll_state : RO; bitpos: [30]; default: 0; - * need_des - */ - uint32_t ana_xpd_bbpll_state:1; - /** ana_xpd_xtal_state : RO; bitpos: [31]; default: 0; - * need_des - */ - uint32_t ana_xpd_xtal_state:1; - }; - uint32_t val; -} pmu_clk_state0_reg_t; + union { + struct { + uint32_t stable_xpd_bbpll : 1; + uint32_t stable_xpd_xtal : 1; + uint32_t reserved0 : 13; + uint32_t sysclk_slp_sel : 1; + uint32_t sysclk_sel : 2; + uint32_t sysclk_nodiv : 1; + uint32_t icg_sysclk_en : 1; + uint32_t icg_modem_switch : 1; + uint32_t icg_modem_code : 2; + uint32_t icg_slp_sel : 1; + uint32_t icg_global_xtal : 1; + uint32_t icg_global_pll : 1; + uint32_t ana_i2c_iso_en : 1; + uint32_t ana_i2c_retention: 1; + uint32_t ana_xpd_bb_i2c : 1; + uint32_t ana_xpd_bbpll_i2c: 1; + uint32_t ana_xpd_bbpll : 1; + uint32_t ana_xpd_xtal : 1; + }; + uint32_t val; + } clk_state0; -/** Type of clk_state1 register - * need_des - */ -typedef union { - struct { - /** icg_func_en_state : RO; bitpos: [31:0]; default: 4294967295; - * need_des - */ - uint32_t icg_func_en_state:32; - }; - uint32_t val; -} pmu_clk_state1_reg_t; + uint32_t clk_state1; + uint32_t clk_state2; -/** Type of clk_state2 register - * need_des - */ -typedef union { - struct { - /** icg_apb_en_state : RO; bitpos: [31:0]; default: 4294967295; - * need_des - */ - uint32_t icg_apb_en_state:32; - }; - uint32_t val; -} pmu_clk_state2_reg_t; + union { + struct { + uint32_t reserved0 : 31; + uint32_t stable_vdd_spi_pwr_drv: 1; + }; + uint32_t val; + } vdd_spi_status; -/** Type of vdd_spi_status register - * need_des - */ -typedef union { - struct { - uint32_t reserved_0:31; - /** stable_vdd_spi_pwr_drv : RO; bitpos: [31]; default: 0; - * need_des - */ - uint32_t stable_vdd_spi_pwr_drv:1; - }; - uint32_t val; -} pmu_vdd_spi_status_reg_t; + uint32_t reserved[150]; - -typedef struct pmu_dev_t { - volatile pmu_hp_active_dig_power_reg_t hp_active_dig_power; - volatile pmu_hp_active_icg_hp_func_reg_t hp_active_icg_hp_func; - volatile pmu_hp_active_icg_hp_apb_reg_t hp_active_icg_hp_apb; - volatile pmu_hp_active_icg_modem_reg_t hp_active_icg_modem; - volatile pmu_hp_active_hp_sys_cntl_reg_t hp_active_hp_sys_cntl; - volatile pmu_hp_active_hp_ck_power_reg_t hp_active_hp_ck_power; - volatile pmu_hp_active_bias_reg_t hp_active_bias; - volatile pmu_hp_active_backup_reg_t hp_active_backup; - volatile pmu_hp_active_backup_clk_reg_t hp_active_backup_clk; - volatile pmu_hp_active_sysclk_reg_t hp_active_sysclk; - volatile pmu_hp_active_hp_regulator0_reg_t hp_active_hp_regulator0; - volatile pmu_hp_active_hp_regulator1_reg_t hp_active_hp_regulator1; - volatile pmu_hp_active_xtal_reg_t hp_active_xtal; - volatile pmu_hp_modem_dig_power_reg_t hp_modem_dig_power; - volatile pmu_hp_modem_icg_hp_func_reg_t hp_modem_icg_hp_func; - volatile pmu_hp_modem_icg_hp_apb_reg_t hp_modem_icg_hp_apb; - volatile pmu_hp_modem_icg_modem_reg_t hp_modem_icg_modem; - volatile pmu_hp_modem_hp_sys_cntl_reg_t hp_modem_hp_sys_cntl; - volatile pmu_hp_modem_hp_ck_power_reg_t hp_modem_hp_ck_power; - volatile pmu_hp_modem_bias_reg_t hp_modem_bias; - volatile pmu_hp_modem_backup_reg_t hp_modem_backup; - volatile pmu_hp_modem_backup_clk_reg_t hp_modem_backup_clk; - volatile pmu_hp_modem_sysclk_reg_t hp_modem_sysclk; - volatile pmu_hp_modem_hp_regulator0_reg_t hp_modem_hp_regulator0; - volatile pmu_hp_modem_hp_regulator1_reg_t hp_modem_hp_regulator1; - volatile pmu_hp_modem_xtal_reg_t hp_modem_xtal; - volatile pmu_hp_sleep_dig_power_reg_t hp_sleep_dig_power; - volatile pmu_hp_sleep_icg_hp_func_reg_t hp_sleep_icg_hp_func; - volatile pmu_hp_sleep_icg_hp_apb_reg_t hp_sleep_icg_hp_apb; - volatile pmu_hp_sleep_icg_modem_reg_t hp_sleep_icg_modem; - volatile pmu_hp_sleep_hp_sys_cntl_reg_t hp_sleep_hp_sys_cntl; - volatile pmu_hp_sleep_hp_ck_power_reg_t hp_sleep_hp_ck_power; - volatile pmu_hp_sleep_bias_reg_t hp_sleep_bias; - volatile pmu_hp_sleep_backup_reg_t hp_sleep_backup; - volatile pmu_hp_sleep_backup_clk_reg_t hp_sleep_backup_clk; - volatile pmu_hp_sleep_sysclk_reg_t hp_sleep_sysclk; - volatile pmu_hp_sleep_hp_regulator0_reg_t hp_sleep_hp_regulator0; - volatile pmu_hp_sleep_hp_regulator1_reg_t hp_sleep_hp_regulator1; - volatile pmu_hp_sleep_xtal_reg_t hp_sleep_xtal; - volatile pmu_hp_sleep_lp_regulator0_reg_t hp_sleep_lp_regulator0; - volatile pmu_hp_sleep_lp_regulator1_reg_t hp_sleep_lp_regulator1; - volatile pmu_hp_sleep_lp_dcdc_reserve_reg_t hp_sleep_lp_dcdc_reserve; - volatile pmu_hp_sleep_lp_dig_power_reg_t hp_sleep_lp_dig_power; - volatile pmu_hp_sleep_lp_ck_power_reg_t hp_sleep_lp_ck_power; - volatile pmu_lp_sleep_lp_bias_reserve_reg_t lp_sleep_lp_bias_reserve; - volatile pmu_lp_sleep_lp_regulator0_reg_t lp_sleep_lp_regulator0; - volatile pmu_lp_sleep_lp_regulator1_reg_t lp_sleep_lp_regulator1; - volatile pmu_lp_sleep_xtal_reg_t lp_sleep_xtal; - volatile pmu_lp_sleep_lp_dig_power_reg_t lp_sleep_lp_dig_power; - volatile pmu_lp_sleep_lp_ck_power_reg_t lp_sleep_lp_ck_power; - volatile pmu_lp_sleep_bias_reg_t lp_sleep_bias; - volatile pmu_imm_hp_ck_power_reg_t imm_hp_ck_power; - volatile pmu_imm_sleep_sysclk_reg_t imm_sleep_sysclk; - volatile pmu_imm_hp_func_icg_reg_t imm_hp_func_icg; - volatile pmu_imm_hp_apb_icg_reg_t imm_hp_apb_icg; - volatile pmu_imm_modem_icg_reg_t imm_modem_icg; - volatile pmu_imm_lp_icg_reg_t imm_lp_icg; - volatile pmu_imm_pad_hold_all_reg_t imm_pad_hold_all; - volatile pmu_imm_i2c_iso_reg_t imm_i2c_iso; - volatile pmu_power_wait_timer0_reg_t power_wait_timer0; - volatile pmu_power_wait_timer1_reg_t power_wait_timer1; - volatile pmu_power_pd_top_cntl_reg_t power_pd_top_cntl; - volatile pmu_power_pd_hpaon_cntl_reg_t power_pd_hpaon_cntl; - volatile pmu_power_pd_hpcpu_cntl_reg_t power_pd_hpcpu_cntl; - volatile pmu_power_pd_hpperi_reserve_reg_t power_pd_hpperi_reserve; - volatile pmu_power_pd_hpwifi_cntl_reg_t power_pd_hpwifi_cntl; - volatile pmu_power_pd_lpperi_cntl_reg_t power_pd_lpperi_cntl; - volatile pmu_power_pd_mem_cntl_reg_t power_pd_mem_cntl; - volatile pmu_power_pd_mem_mask_reg_t power_pd_mem_mask; - volatile pmu_power_hp_pad_reg_t power_hp_pad; - volatile pmu_power_vdd_spi_cntl_reg_t power_vdd_spi_cntl; - volatile pmu_power_ck_wait_cntl_reg_t power_ck_wait_cntl; - volatile pmu_slp_wakeup_cntl0_reg_t slp_wakeup_cntl0; - volatile pmu_slp_wakeup_cntl1_reg_t slp_wakeup_cntl1; - volatile pmu_slp_wakeup_cntl2_reg_t slp_wakeup_cntl2; - volatile pmu_slp_wakeup_cntl3_reg_t slp_wakeup_cntl3; - volatile pmu_slp_wakeup_cntl4_reg_t slp_wakeup_cntl4; - volatile pmu_slp_wakeup_cntl5_reg_t slp_wakeup_cntl5; - volatile pmu_slp_wakeup_cntl6_reg_t slp_wakeup_cntl6; - volatile pmu_slp_wakeup_cntl7_reg_t slp_wakeup_cntl7; - volatile pmu_slp_wakeup_status0_reg_t slp_wakeup_status0; - volatile pmu_slp_wakeup_status1_reg_t slp_wakeup_status1; - volatile pmu_hp_ck_poweron_reg_t hp_ck_poweron; - volatile pmu_hp_ck_cntl_reg_t hp_ck_cntl; - volatile pmu_por_status_reg_t por_status; - volatile pmu_rf_pwc_reg_t rf_pwc; - volatile pmu_backup_cfg_reg_t backup_cfg; - volatile pmu_int_raw_reg_t int_raw; - volatile pmu_hp_int_st_reg_t hp_int_st; - volatile pmu_hp_int_ena_reg_t hp_int_ena; - volatile pmu_hp_int_clr_reg_t hp_int_clr; - volatile pmu_lp_int_raw_reg_t lp_int_raw; - volatile pmu_lp_int_st_reg_t lp_int_st; - volatile pmu_lp_int_ena_reg_t lp_int_ena; - volatile pmu_lp_int_clr_reg_t lp_int_clr; - volatile pmu_lp_cpu_pwr0_reg_t lp_cpu_pwr0; - volatile pmu_lp_cpu_pwr1_reg_t lp_cpu_pwr1; - volatile pmu_hp_lp_cpu_comm_reg_t hp_lp_cpu_comm; - volatile pmu_hp_regulator_cfg_reg_t hp_regulator_cfg; - volatile pmu_main_state_reg_t main_state; - volatile pmu_pwr_state_reg_t pwr_state; - volatile pmu_clk_state0_reg_t clk_state0; - volatile pmu_clk_state1_reg_t clk_state1; - volatile pmu_clk_state2_reg_t clk_state2; - volatile pmu_vdd_spi_status_reg_t vdd_spi_status; - uint32_t reserved_1a4[150]; - volatile pmu_date_reg_t date; + union { + struct { + uint32_t pmu_date: 31; + uint32_t clk_en : 1; + }; + uint32_t val; + } date; } pmu_dev_t; extern pmu_dev_t PMU; #ifndef __cplusplus _Static_assert(sizeof(pmu_dev_t) == 0x400, "Invalid size of pmu_dev_t structure"); + +_Static_assert(offsetof(pmu_dev_t, reserved) == (PMU_VDD_SPI_STATUS_REG - DR_REG_PMU_BASE) + 4, "Invalid size of pmu_dev_t structure"); + #endif #ifdef __cplusplus diff --git a/components/soc/esp32c6/include/soc/rtc.h b/components/soc/esp32c6/include/soc/rtc.h index ed53ef2e02..dc4fd5339e 100644 --- a/components/soc/esp32c6/include/soc/rtc.h +++ b/components/soc/esp32c6/include/soc/rtc.h @@ -17,7 +17,7 @@ extern "C" { /** * @file rtc.h - * @brief Low-level RTC power, clock, and sleep functions. + * @brief Low-level RTC power, clock functions. * * Functions in this file facilitate configuration of ESP32's RTC_CNTL peripheral. * RTC_CNTL peripheral handles many functions: @@ -514,204 +514,8 @@ bool rtc_dig_8m_enabled(void); */ uint32_t rtc_clk_freq_cal(uint32_t cal_val); -/** - * @brief Power down flags for rtc_sleep_pd function - */ -typedef struct { - uint32_t dig_fpu : 1; //!< Set to 1 to power UP digital part in sleep - uint32_t rtc_fpu : 1; //!< Set to 1 to power UP RTC memories in sleep - uint32_t cpu_fpu : 1; //!< Set to 1 to power UP digital memories and CPU in sleep - uint32_t i2s_fpu : 1; //!< Set to 1 to power UP I2S in sleep - uint32_t bb_fpu : 1; //!< Set to 1 to power UP WiFi in sleep - uint32_t nrx_fpu : 1; //!< Set to 1 to power UP WiFi in sleep - uint32_t fe_fpu : 1; //!< Set to 1 to power UP WiFi in sleep - uint32_t sram_fpu : 1; //!< Set to 1 to power UP SRAM in sleep - uint32_t rom_ram_fpu : 1; //!< Set to 1 to power UP ROM/IRAM0_DRAM0 in sleep -} rtc_sleep_pu_config_t; -/** - * Initializer for rtc_sleep_pu_config_t which sets all flags to the same value - */ -#define RTC_SLEEP_PU_CONFIG_ALL(val) {\ - .dig_fpu = (val), \ - .rtc_fpu = (val), \ - .cpu_fpu = (val), \ - .i2s_fpu = (val), \ - .bb_fpu = (val), \ - .nrx_fpu = (val), \ - .fe_fpu = (val), \ - .sram_fpu = (val), \ - .rom_ram_fpu = (val), \ -} -void rtc_sleep_pu(rtc_sleep_pu_config_t cfg); - -/** - * @brief sleep configuration for rtc_sleep_init function - */ -typedef struct { - uint32_t lslp_mem_inf_fpu : 1; //!< force normal voltage in sleep mode (digital domain memory) - uint32_t rtc_mem_inf_follow_cpu : 1;//!< keep low voltage in sleep mode (even if ULP/touch is used) - uint32_t rtc_fastmem_pd_en : 1; //!< power down RTC fast memory - uint32_t rtc_slowmem_pd_en : 1; //!< power down RTC slow memory - uint32_t rtc_peri_pd_en : 1; //!< power down RTC peripherals - uint32_t wifi_pd_en : 1; //!< power down WiFi - uint32_t bt_pd_en : 1; //!< power down BT - uint32_t cpu_pd_en : 1; //!< power down CPU, but not restart when lightsleep. - uint32_t int_8m_pd_en : 1; //!< Power down Internal 8M oscillator - uint32_t dig_peri_pd_en : 1; //!< power down digital peripherals - uint32_t deep_slp : 1; //!< power down digital domain - uint32_t wdt_flashboot_mod_en : 1; //!< enable WDT flashboot mode - uint32_t dig_dbias_wak : 5; //!< set bias for digital domain, in active mode - uint32_t dig_dbias_slp : 5; //!< set bias for digital domain, in sleep mode - uint32_t rtc_dbias_wak : 5; //!< set bias for RTC domain, in active mode - uint32_t rtc_dbias_slp : 5; //!< set bias for RTC domain, in sleep mode - uint32_t dbg_atten_monitor : 4; //!< voltage parameter, in monitor mode - uint32_t bias_sleep_monitor : 1; //!< circuit control parameter, in monitor mode - uint32_t dbg_atten_slp : 4; //!< voltage parameter, in sleep mode - uint32_t bias_sleep_slp : 1; //!< circuit control parameter, in sleep mode - uint32_t pd_cur_monitor : 1; //!< circuit control parameter, in monitor mode - uint32_t pd_cur_slp : 1; //!< circuit control parameter, in sleep mode - uint32_t vddsdio_pd_en : 1; //!< power down VDDSDIO regulator - uint32_t xtal_fpu : 1; //!< keep main XTAL powered up in sleep - uint32_t deep_slp_reject : 1; //!< enable deep sleep reject - uint32_t light_slp_reject : 1; //!< enable light sleep reject -} rtc_sleep_config_t; - -#define RTC_SLEEP_PD_DIG BIT(0) //!< Deep sleep (power down digital domain) -#define RTC_SLEEP_PD_RTC_PERIPH BIT(1) //!< Power down RTC peripherals -#define RTC_SLEEP_PD_RTC_SLOW_MEM BIT(2) //!< Power down RTC SLOW memory -#define RTC_SLEEP_PD_RTC_FAST_MEM BIT(3) //!< Power down RTC FAST memory -#define RTC_SLEEP_PD_RTC_MEM_FOLLOW_CPU BIT(4) //!< RTC FAST and SLOW memories are automatically powered up and down along with the CPU -#define RTC_SLEEP_PD_VDDSDIO BIT(5) //!< Power down VDDSDIO regulator -#define RTC_SLEEP_PD_WIFI BIT(6) //!< Power down WIFI -#define RTC_SLEEP_PD_BT BIT(7) //!< Power down BT -#define RTC_SLEEP_PD_CPU BIT(8) //!< Power down CPU when in lightsleep, but not restart -#define RTC_SLEEP_PD_DIG_PERIPH BIT(9) //!< Power down DIG peripherals -#define RTC_SLEEP_PD_INT_8M BIT(10) //!< Power down Internal 8M oscillator -#define RTC_SLEEP_PD_XTAL BIT(11) //!< Power down main XTAL - -//These flags are not power domains, but will affect some sleep parameters -#define RTC_SLEEP_DIG_USE_8M BIT(16) -#define RTC_SLEEP_USE_ADC_TESEN_MONITOR BIT(17) -#define RTC_SLEEP_NO_ULTRA_LOW BIT(18) //!< Avoid using ultra low power in deep sleep, in which RTCIO cannot be used as input, and RTCMEM can't work under high temperature - -/** - * Default initializer for rtc_sleep_config_t - * - * This initializer sets all fields to "reasonable" values (e.g. suggested for - * production use) based on a combination of RTC_SLEEP_PD_x flags. - * - * @param RTC_SLEEP_PD_x flags combined using bitwise OR - */ -void rtc_sleep_get_default_config(uint32_t sleep_flags, rtc_sleep_config_t *out_config); - -/** - * @brief Prepare the chip to enter sleep mode - * - * This function configures various power control state machines to handle - * entry into light sleep or deep sleep mode, switches APB and CPU clock source - * (usually to XTAL), and sets bias voltages for digital and RTC power domains. - * - * This function does not actually enter sleep mode; this is done using - * rtc_sleep_start function. Software may do some other actions between - * rtc_sleep_init and rtc_sleep_start, such as set wakeup timer and configure - * wakeup sources. - * @param cfg sleep mode configuration - */ -void rtc_sleep_init(rtc_sleep_config_t cfg); - -/** - * @brief Low level initialize for rtc state machine waiting cycles after waking up - * - * This function configures the cycles chip need to wait for internal 8MHz - * oscillator and external 40MHz crystal. As we configure fixed time for waiting - * crystal, we need to pass period to calculate cycles. Now this function only - * used in lightsleep mode. - * - * @param slowclk_period re-calibrated slow clock period - */ -void rtc_sleep_low_init(uint32_t slowclk_period); - -/** - * @brief Set target value of RTC counter for RTC_TIMER_TRIG_EN wakeup source - * @param t value of RTC counter at which wakeup from sleep will happen; - * only the lower 48 bits are used - */ -void rtc_sleep_set_wakeup_time(uint64_t t); - -#define RTC_GPIO_TRIG_EN BIT(2) //!< GPIO wakeup -#define RTC_TIMER_TRIG_EN BIT(3) //!< Timer wakeup -#define RTC_WIFI_TRIG_EN BIT(5) //!< WIFI wakeup (light sleep only) -#define RTC_UART0_TRIG_EN BIT(6) //!< UART0 wakeup (light sleep only) -#define RTC_UART1_TRIG_EN BIT(7) //!< UART1 wakeup (light sleep only) -#define RTC_BT_TRIG_EN BIT(10) //!< BT wakeup (light sleep only) -#define RTC_XTAL32K_DEAD_TRIG_EN BIT(12) -#define RTC_USB_TRIG_EN BIT(14) -#define RTC_BROWNOUT_DET_TRIG_EN BIT(16) - -/** - * RTC_SLEEP_REJECT_MASK records sleep reject sources supported by chip - */ -#define RTC_SLEEP_REJECT_MASK (RTC_GPIO_TRIG_EN | \ - RTC_TIMER_TRIG_EN | \ - RTC_WIFI_TRIG_EN | \ - RTC_UART0_TRIG_EN | \ - RTC_UART1_TRIG_EN | \ - RTC_BT_TRIG_EN | \ - RTC_XTAL32K_DEAD_TRIG_EN | \ - RTC_USB_TRIG_EN | \ - RTC_BROWNOUT_DET_TRIG_EN) - -/** - * @brief Enter deep or light sleep mode - * - * This function enters the sleep mode previously configured using rtc_sleep_init - * function. Before entering sleep, software should configure wake up sources - * appropriately (set up GPIO wakeup registers, timer wakeup registers, - * and so on). - * - * If deep sleep mode was configured using rtc_sleep_init, and sleep is not - * rejected by hardware (based on reject_opt flags), this function never returns. - * When the chip wakes up from deep sleep, CPU is reset and execution starts - * from ROM bootloader. - * - * If light sleep mode was configured using rtc_sleep_init, this function - * returns on wakeup, or if sleep is rejected by hardware. - * - * @param wakeup_opt bit mask wake up reasons to enable (RTC_xxx_TRIG_EN flags - * combined with OR) - * @param reject_opt bit mask of sleep reject reasons: - * - RTC_CNTL_GPIO_REJECT_EN - * - RTC_CNTL_SDIO_REJECT_EN - * These flags are used to prevent entering sleep when e.g. - * an external host is communicating via SDIO slave - * @return non-zero if sleep was rejected by hardware - */ -uint32_t rtc_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt, uint32_t lslp_mem_inf_fpu); - -/** - * @brief Enter deep sleep mode - * - * Similar to rtc_sleep_start(), but additionally uses hardware to calculate the CRC value - * of RTC FAST memory. On wake, this CRC is used to determine if a deep sleep wake - * stub is valid to execute (if a wake address is set). - * - * No RAM is accessed while calculating the CRC and going into deep sleep, which makes - * this function safe to use even if the caller's stack is in RTC FAST memory. - * - * @note If no deep sleep wake stub address is set then calling rtc_sleep_start() will - * have the same effect and takes less time as CRC calculation is skipped. - * - * @note This function should only be called after rtc_sleep_init() has been called to - * configure the system for deep sleep. - * - * @param wakeup_opt - same as for rtc_sleep_start - * @param reject_opt - same as for rtc_sleep_start - * - * @return non-zero if sleep was rejected by hardware - */ -uint32_t rtc_deep_sleep_start(uint32_t wakeup_opt, uint32_t reject_opt); /** * RTC power and clock control initialization settings @@ -754,37 +558,6 @@ typedef struct { */ void rtc_init(rtc_config_t cfg); -/** - * Structure describing vddsdio configuration - */ -typedef struct { - uint32_t force : 1; //!< If 1, use configuration from RTC registers; if 0, use EFUSE/bootstrapping pins. - uint32_t enable : 1; //!< Enable VDDSDIO regulator - uint32_t tieh : 1; //!< Select VDDSDIO voltage. One of RTC_VDDSDIO_TIEH_1_8V, RTC_VDDSDIO_TIEH_3_3V - uint32_t drefh : 2; //!< Tuning parameter for VDDSDIO regulator - uint32_t drefm : 2; //!< Tuning parameter for VDDSDIO regulator - uint32_t drefl : 2; //!< Tuning parameter for VDDSDIO regulator -} rtc_vddsdio_config_t; - -/** - * Get current VDDSDIO configuration - * If VDDSDIO configuration is overridden by RTC, get values from RTC - * Otherwise, if VDDSDIO is configured by EFUSE, get values from EFUSE - * Otherwise, use default values and the level of MTDI bootstrapping pin. - * @return currently used VDDSDIO configuration - */ -rtc_vddsdio_config_t rtc_vddsdio_get_config(void); - -/** - * Set new VDDSDIO configuration using RTC registers. - * If config.force == 1, this overrides configuration done using bootstrapping - * pins and EFUSE. - * - * @param config new VDDSDIO configuration - */ -void rtc_vddsdio_set_config(rtc_vddsdio_config_t config); - - // -------------------------- CLOCK TREE DEFS ALIAS ---------------------------- // **WARNING**: The following are only for backwards compatibility. // Please use the declarations in soc/clk_tree_defs.h instead. diff --git a/components/soc/esp32c6/include/soc/soc.h b/components/soc/esp32c6/include/soc/soc.h index e782be8996..8adccb044b 100644 --- a/components/soc/esp32c6/include/soc/soc.h +++ b/components/soc/esp32c6/include/soc/soc.h @@ -141,6 +141,7 @@ #define EFUSE_CLK_FREQ_ROM ( 20*1000000) #define CPU_CLK_FREQ APB_CLK_FREQ #define APB_CLK_FREQ ( 40*1000000 ) +#define MODEM_APB_CLK_FREQ ( 80*1000000 ) #define REF_CLK_FREQ ( 1000000 ) #define RTC_CLK_FREQ (20*1000000) #define XTAL_CLK_FREQ (40*1000000) diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index dc40251e6c..d1dd2a4cd9 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -63,6 +63,8 @@ #define SOC_SDIO_SLAVE_SUPPORTED 1 #define SOC_BOD_SUPPORTED 1 #define SOC_APM_SUPPORTED 1 +#define SOC_PMU_SUPPORTED 1 +#define SOC_LP_TIMER_SUPPORTED 1 /*-------------------------- XTAL CAPS ---------------------------------------*/ #define SOC_XTAL_SUPPORT_40M 1 @@ -281,15 +283,6 @@ #define SOC_MCPWM_CLK_SUPPORT_PLL160M (1) ///< Support PLL160M as clock source #define SOC_MCPWM_CLK_SUPPORT_XTAL (1) ///< Support XTAL as clock source -// TODO: IDF-5348 (Copy from esp32c3, need check) -/*-------------------------- RTC CAPS --------------------------------------*/ -#define SOC_RTC_CNTL_CPU_PD_DMA_BUS_WIDTH (128) -#define SOC_RTC_CNTL_CPU_PD_REG_FILE_NUM (108) -#define SOC_RTC_CNTL_CPU_PD_DMA_ADDR_ALIGN (SOC_RTC_CNTL_CPU_PD_DMA_BUS_WIDTH >> 3) -#define SOC_RTC_CNTL_CPU_PD_DMA_BLOCK_SIZE (SOC_RTC_CNTL_CPU_PD_DMA_BUS_WIDTH >> 3) - -#define SOC_RTC_CNTL_CPU_PD_RETENTION_MEM_SIZE (SOC_RTC_CNTL_CPU_PD_REG_FILE_NUM * (SOC_RTC_CNTL_CPU_PD_DMA_BUS_WIDTH >> 3)) - // TODO: IDF-5359 (Copy from esp32c3, need check) /*--------------------------- RSA CAPS ---------------------------------------*/ #define SOC_RSA_MAX_BIT_LEN (3072) @@ -368,6 +361,10 @@ #define SOC_SYSTIMER_ALARM_MISS_COMPENSATE 1 // Systimer peripheral can generate interrupt immediately if t(target) > t(current) #define SOC_SYSTIMER_SUPPORT_ETM 1 // Systimer comparator can generate ETM event +/*-------------------------- LP_TIMER CAPS ----------------------------------*/ +#define SOC_LP_TIMER_BIT_WIDTH_LO 32 // Bit width of lp_timer low part +#define SOC_LP_TIMER_BIT_WIDTH_HI 16 // Bit width of lp_timer high part + /*--------------------------- TIMER GROUP CAPS ---------------------------------------*/ #define SOC_TIMER_GROUPS (2) #define SOC_TIMER_GROUP_TIMERS_PER_GROUP (1U) @@ -410,14 +407,13 @@ // TODO: IDF-5338 (Copy from esp32c3, need check) /*-------------------------- UART CAPS ---------------------------------------*/ // ESP32-C6 has 2 UARTs -#define SOC_UART_NUM (2) -#define SOC_UART_FIFO_LEN (128) /*!< The UART hardware FIFO length */ -#define SOC_UART_BITRATE_MAX (5000000) /*!< Max bit rate supported by UART */ - -#define SOC_UART_SUPPORT_PLL_F80M_CLK (1) /*!< Support PLL_DIV as the clock source */ -#define SOC_UART_SUPPORT_RTC_CLK (1) /*!< Support RTC clock as the clock source */ -#define SOC_UART_SUPPORT_XTAL_CLK (1) /*!< Support XTAL clock as the clock source */ -// #define SOC_UART_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */ // TODO: Test UART wakeup while supporting sleep +#define SOC_UART_NUM (2) +#define SOC_UART_FIFO_LEN (128) /*!< The UART hardware FIFO length */ +#define SOC_UART_BITRATE_MAX (5000000) /*!< Max bit rate supported by UART */ +#define SOC_UART_SUPPORT_PLL_F80M_CLK (1) /*!< Support PLL_DIV as the clock source */ +#define SOC_UART_SUPPORT_RTC_CLK (1) /*!< Support RTC clock as the clock source */ +#define SOC_UART_SUPPORT_XTAL_CLK (1) /*!< Support XTAL clock as the clock source */ +#define SOC_UART_SUPPORT_WAKEUP_INT (1) /*!< Support UART wakeup interrupt */ // TODO: Test UART wakeup while supporting sleep // UART has an extra TX_WAIT_SEND state when the FIFO is not empty and XOFF is enabled #define SOC_UART_SUPPORT_FSM_TX_WAIT_SEND (1) @@ -438,14 +434,16 @@ #define SOC_PM_SUPPORT_WIFI_WAKEUP (1) #define SOC_PM_SUPPORT_BT_WAKEUP (1) #define SOC_PM_SUPPORT_CPU_PD (1) -#define SOC_PM_SUPPORT_WIFI_PD (1) -#define SOC_PM_SUPPORT_BT_PD (1) +#define SOC_PM_SUPPORT_MODEM_PD (1) #define SOC_PM_SUPPORT_XTAL32K_PD (1) #define SOC_PM_SUPPORT_RC32K_PD (1) #define SOC_PM_SUPPORT_RC_FAST_PD (1) +#define SOC_PM_SUPPORT_VDDSDIO_PD (1) #define SOC_PM_SUPPORT_DEEPSLEEP_CHECK_STUB_ONLY (1) /*! None: diff --git a/examples/wifi/itwt/main/itwt.c b/examples/wifi/itwt/main/itwt.c index ab6ee1d8e7..8ce6db7e26 100644 --- a/examples/wifi/itwt/main/itwt.c +++ b/examples/wifi/itwt/main/itwt.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Unlicense OR CC0-1.0 */ @@ -27,6 +27,7 @@ #include "cmd_system.h" #include "wifi_cmd.h" #include "esp_wifi_he.h" +#include "esp_pm.h" /******************************************************* * Constants @@ -244,10 +245,7 @@ void app_main(void) } // TODO: WIFI-5150 -#if CONFIG_PM_ENABLE - io_toggle_pmu_internal_signal_map_to_io_init(); - io_toggle_gpio_init(); - +#if CONFIG_PM_ENABLE && 0 sleep_clock_system_retention_init(); sleep_clock_modem_retention_init(); sleep_peripheral_retention_init(); diff --git a/examples/wifi/power_save/main/power_save.c b/examples/wifi/power_save/main/power_save.c index 653e67607c..bd39b47d76 100644 --- a/examples/wifi/power_save/main/power_save.c +++ b/examples/wifi/power_save/main/power_save.c @@ -105,6 +105,8 @@ void app_main(void) esp_pm_config_esp32s3_t pm_config = { #elif CONFIG_IDF_TARGET_ESP32C2 esp_pm_config_esp32c2_t pm_config = { +#elif CONFIG_IDF_TARGET_ESP32C6 + esp_pm_config_esp32c6_t pm_config = { #endif .max_freq_mhz = CONFIG_EXAMPLE_MAX_CPU_FREQ_MHZ, .min_freq_mhz = CONFIG_EXAMPLE_MIN_CPU_FREQ_MHZ, diff --git a/tools/ci/check_public_headers_exceptions.txt b/tools/ci/check_public_headers_exceptions.txt index acbbb06184..024e6b9eb6 100644 --- a/tools/ci/check_public_headers_exceptions.txt +++ b/tools/ci/check_public_headers_exceptions.txt @@ -156,3 +156,4 @@ components/espcoredump/include/port/xtensa/esp_core_dump_summary_port.h components/riscv/include/esp_private/panic_reason.h components/riscv/include/riscv/interrupt.h components/riscv/include/riscv/rvruntime-frames.h +components/riscv/include/riscv/rvsleep-frames.h