diff --git a/components/esp_hw_support/include/esp_private/sleep_retention.h b/components/esp_hw_support/include/esp_private/sleep_retention.h index 589411177e..8772263e0c 100644 --- a/components/esp_hw_support/include/esp_private/sleep_retention.h +++ b/components/esp_hw_support/include/esp_private/sleep_retention.h @@ -38,14 +38,8 @@ typedef enum sleep_retention_module { /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM, * TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */ - SLEEP_RETENTION_MODULE_INTR_MATRIX = 16, - SLEEP_RETENTION_MODULE_HP_SYSTEM = 17, - SLEEP_RETENTION_MODULE_TEE_APM = 18, - SLEEP_RETENTION_MODULE_UART0 = 19, - SLEEP_RETENTION_MODULE_TG0 = 20, - SLEEP_RETENTION_MODULE_IOMUX = 21, - SLEEP_RETENTION_MODULE_SPIMEM = 22, - SLEEP_RETENTION_MODULE_SYSTIMER = 23, + SLEEP_RETENTION_MODULE_SYS_PERIPH = 16, + SLEEP_RETENTION_MODULE_GDMA_CH0 = 24, SLEEP_RETENTION_MODULE_GDMA_CH1 = 25, SLEEP_RETENTION_MODULE_GDMA_CH2 = 26, @@ -67,14 +61,8 @@ typedef enum sleep_retention_module_bitmap { /* digital peripheral module, which includes Interrupt Matrix, HP_SYSTEM, * TEE, APM, UART, Timer Group, IOMUX, SPIMEM, SysTimer, etc.. */ - SLEEP_RETENTION_MODULE_BM_INTR_MATRIX = BIT(SLEEP_RETENTION_MODULE_INTR_MATRIX), - SLEEP_RETENTION_MODULE_BM_HP_SYSTEM = BIT(SLEEP_RETENTION_MODULE_HP_SYSTEM), - SLEEP_RETENTION_MODULE_BM_TEE_APM = BIT(SLEEP_RETENTION_MODULE_TEE_APM), - SLEEP_RETENTION_MODULE_BM_UART0 = BIT(SLEEP_RETENTION_MODULE_UART0), - SLEEP_RETENTION_MODULE_BM_TG0 = BIT(SLEEP_RETENTION_MODULE_TG0), - SLEEP_RETENTION_MODULE_BM_IOMUX = BIT(SLEEP_RETENTION_MODULE_IOMUX), - SLEEP_RETENTION_MODULE_BM_SPIMEM = BIT(SLEEP_RETENTION_MODULE_SPIMEM), - SLEEP_RETENTION_MODULE_BM_SYSTIMER = BIT(SLEEP_RETENTION_MODULE_SYSTIMER), + SLEEP_RETENTION_MODULE_BM_SYS_PERIPH = BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH), + SLEEP_RETENTION_MODULE_BM_GDMA_CH0 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH0), SLEEP_RETENTION_MODULE_BM_GDMA_CH1 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH1), SLEEP_RETENTION_MODULE_BM_GDMA_CH2 = BIT(SLEEP_RETENTION_MODULE_GDMA_CH2), diff --git a/components/esp_hw_support/include/esp_private/sleep_sys_periph.h b/components/esp_hw_support/include/esp_private/sleep_sys_periph.h index ee4af519ce..b66826c099 100644 --- a/components/esp_hw_support/include/esp_private/sleep_sys_periph.h +++ b/components/esp_hw_support/include/esp_private/sleep_sys_periph.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -29,15 +29,6 @@ extern "C" { */ bool peripheral_domain_pd_allowed(void); -/** - * @brief Digital peripheral power down initialize - * - * @return ESP_OK on success - * ESP_ERR_INVALID_ARG on invalid sleep_retention_entries_create args - * No memory for the retention link - */ -void sleep_sys_periph_retention_init(void); - #ifdef __cplusplus } #endif diff --git a/components/esp_hw_support/sleep_system_peripheral.c b/components/esp_hw_support/sleep_system_peripheral.c index 408a95e99a..2025e0771c 100644 --- a/components/esp_hw_support/sleep_system_peripheral.c +++ b/components/esp_hw_support/sleep_system_peripheral.c @@ -34,7 +34,7 @@ static __attribute__((unused)) const char *TAG = "sleep_sys_periph"; #define SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT (REGDMA_LINK_PRI_6) -esp_err_t sleep_sys_periph_intr_matrix_retention_init(void) +static __attribute__((unused)) esp_err_t sleep_sys_periph_intr_matrix_retention_init(void *arg) { #define N_REGS_INTR_MATRIX() (((INTMTX_CORE0_CLOCK_GATE_REG - DR_REG_INTERRUPT_MATRIX_BASE) / 4) + 1) @@ -42,13 +42,13 @@ esp_err_t sleep_sys_periph_intr_matrix_retention_init(void) [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_INTMTX_LINK(0), DR_REG_INTERRUPT_MATRIX_BASE, DR_REG_INTERRUPT_MATRIX_BASE, N_REGS_INTR_MATRIX(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* intr matrix */ }; - esp_err_t err = sleep_retention_entries_create(intr_matrix_regs_retention, ARRAY_SIZE(intr_matrix_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_INTR_MATRIX); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (Interrupt matrix) retention"); - ESP_LOGI(TAG, "Interrupt Matrix sleep retention initialization"); + esp_err_t err = sleep_retention_entries_create(intr_matrix_regs_retention, ARRAY_SIZE(intr_matrix_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_SYS_PERIPH); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "Interrupt matrix"); + ESP_LOGD(TAG, "Interrupt Matrix sleep retention initialization"); return ESP_OK; } -esp_err_t sleep_sys_periph_hp_system_retention_init(void) +static __attribute__((unused)) esp_err_t sleep_sys_periph_hp_system_retention_init(void *arg) { #define N_REGS_HP_SYSTEM() (((HP_SYSTEM_MEM_TEST_CONF_REG - DR_REG_HP_SYSTEM_BASE) / 4) + 1) @@ -56,13 +56,13 @@ esp_err_t sleep_sys_periph_hp_system_retention_init(void) [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_HPSYS_LINK(0), DR_REG_HP_SYSTEM_BASE, DR_REG_HP_SYSTEM_BASE, N_REGS_HP_SYSTEM(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* hp system */ }; - esp_err_t err = sleep_retention_entries_create(hp_system_regs_retention, ARRAY_SIZE(hp_system_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_HP_SYSTEM); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (HP system) retention"); - ESP_LOGI(TAG, "HP System sleep retention initialization"); + esp_err_t err = sleep_retention_entries_create(hp_system_regs_retention, ARRAY_SIZE(hp_system_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_SYS_PERIPH); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "HP system"); + ESP_LOGD(TAG, "HP System sleep retention initialization"); return ESP_OK; } -esp_err_t sleep_sys_periph_tee_apm_retention_init(void) +static __attribute__((unused)) esp_err_t sleep_sys_periph_tee_apm_retention_init(void *arg) { #define N_REGS_TEE() (((TEE_CLOCK_GATE_REG - DR_REG_TEE_BASE) / 4) + 1) #define N_REGS_APM() (((HP_APM_CLOCK_GATE_REG - DR_REG_HP_APM_BASE) / 4) + 1) @@ -72,36 +72,36 @@ esp_err_t sleep_sys_periph_tee_apm_retention_init(void) [1] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_TEEAPM_LINK(1), DR_REG_TEE_BASE, DR_REG_TEE_BASE, N_REGS_TEE(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* tee */ }; - esp_err_t err = sleep_retention_entries_create(tee_apm_regs_retention, ARRAY_SIZE(tee_apm_regs_retention), REGDMA_LINK_PRI_4, SLEEP_RETENTION_MODULE_TEE_APM); + esp_err_t err = sleep_retention_entries_create(tee_apm_regs_retention, ARRAY_SIZE(tee_apm_regs_retention), REGDMA_LINK_PRI_4, SLEEP_RETENTION_MODULE_SYS_PERIPH); if (err == ESP_OK) { const static sleep_retention_entries_config_t regs_highpri_retention[] = { [0] = { .config = REGDMA_LINK_WRITE_INIT(REGDMA_TEEAPM_LINK(2), TEE_M4_MODE_CTRL_REG, 0x0, 0xffffffff, 1, 0), .owner = ENTRY(2) } }; - err = sleep_retention_entries_create(regs_highpri_retention, ARRAY_SIZE(regs_highpri_retention), REGDMA_LINK_PRI_2, SLEEP_RETENTION_MODULE_TEE_APM); + err = sleep_retention_entries_create(regs_highpri_retention, ARRAY_SIZE(regs_highpri_retention), REGDMA_LINK_PRI_2, SLEEP_RETENTION_MODULE_SYS_PERIPH); } - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (TEE/APM) retention"); - ESP_LOGI(TAG, "TEE/APM sleep retention initialization"); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "TEE/APM"); + ESP_LOGD(TAG, "TEE/APM sleep retention initialization"); return ESP_OK; } -esp_err_t sleep_sys_periph_uart0_retention_init(void) +static __attribute__((unused)) esp_err_t sleep_sys_periph_uart0_retention_init(void *arg) { #define N_REGS_UART() (((UART_ID_REG(0) - UART_INT_RAW_REG(0)) / 4) + 1) const static sleep_retention_entries_config_t uart_regs_retention[] = { - [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_UART_LINK(0x00), UART_INT_RAW_REG(0), UART_INT_RAW_REG(0), N_REGS_UART(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* uart */ + [0] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_UART_LINK(0x00), UART_INT_RAW_REG(0), UART_INT_RAW_REG(0), N_REGS_UART(), 0, 0), .owner = ENTRY(0) | ENTRY(2) }, /* uart */ /* Note: uart register should set update reg to make the configuration take effect */ [1] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_UART_LINK(0x01), UART_REG_UPDATE_REG(0), UART_REG_UPDATE, UART_REG_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) }, [2] = { .config = REGDMA_LINK_WAIT_INIT (REGDMA_UART_LINK(0x02), UART_REG_UPDATE_REG(0), 0x0, UART_REG_UPDATE_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) } }; - esp_err_t err = sleep_retention_entries_create(uart_regs_retention, ARRAY_SIZE(uart_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_UART0); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (UART) retention"); - ESP_LOGI(TAG, "UART sleep retention initialization"); + esp_err_t err = sleep_retention_entries_create(uart_regs_retention, ARRAY_SIZE(uart_regs_retention), REGDMA_LINK_PRI_5, SLEEP_RETENTION_MODULE_SYS_PERIPH); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "UART"); + ESP_LOGD(TAG, "UART sleep retention initialization"); return ESP_OK; } -esp_err_t sleep_sys_periph_tg0_retention_init(void) +static __attribute__((unused)) esp_err_t sleep_sys_periph_tg0_retention_init(void *arg) { #define N_REGS_TG() (((TIMG_REGCLK_REG(0) - REG_TIMG_BASE(0)) / 4) + 1) @@ -117,13 +117,13 @@ esp_err_t sleep_sys_periph_tg0_retention_init(void) [7] = { .config = REGDMA_LINK_WRITE_INIT (REGDMA_TIMG_LINK(0x07), TIMG_T0LOAD_REG(0), 0x1, TIMG_T0_LOAD_M, 1, 0), .owner = ENTRY(0) | ENTRY(2) } }; - esp_err_t err = sleep_retention_entries_create(tg_regs_retention, ARRAY_SIZE(tg_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_TG0); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (Timer Group) retention"); - ESP_LOGI(TAG, "Timer Group sleep retention initialization"); + esp_err_t err = sleep_retention_entries_create(tg_regs_retention, ARRAY_SIZE(tg_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SYS_PERIPH); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "Timer Group"); + ESP_LOGD(TAG, "Timer Group sleep retention initialization"); return ESP_OK; } -esp_err_t sleep_sys_periph_iomux_retention_init(void) +static __attribute__((unused)) esp_err_t sleep_sys_periph_iomux_retention_init(void *arg) { #if CONFIG_IDF_TARGET_ESP32C6 #define N_REGS_IOMUX_0() (((PERIPHS_IO_MUX_SPID_U - REG_IO_MUX_BASE) / 4) + 1) @@ -143,13 +143,13 @@ esp_err_t sleep_sys_periph_iomux_retention_init(void) [3] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_IOMUX_LINK(0x03), DR_REG_GPIO_BASE, DR_REG_GPIO_BASE, N_REGS_IOMUX_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } }; - esp_err_t err = sleep_retention_entries_create(iomux_regs_retention, ARRAY_SIZE(iomux_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_IOMUX); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (IO Matrix) retention"); - ESP_LOGI(TAG, "IO Matrix sleep retention initialization"); + esp_err_t err = sleep_retention_entries_create(iomux_regs_retention, ARRAY_SIZE(iomux_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SYS_PERIPH); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "IO Matrix"); + ESP_LOGD(TAG, "IO Matrix sleep retention initialization"); return ESP_OK; } -esp_err_t sleep_sys_periph_spimem_retention_init(void) +static __attribute__((unused)) esp_err_t sleep_sys_periph_spimem_retention_init(void *arg) { #define N_REGS_SPI1_MEM_0() (((SPI_MEM_SPI_SMEM_DDR_REG(1) - REG_SPI_MEM_BASE(1)) / 4) + 1) #define N_REGS_SPI1_MEM_1() (((SPI_MEM_SPI_SMEM_AC_REG(1) - SPI_MEM_SPI_FMEM_PMS0_ATTR_REG(1)) / 4) + 1) @@ -175,13 +175,13 @@ esp_err_t sleep_sys_periph_spimem_retention_init(void) [7] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SPIMEM_LINK(0x07), SPI_MEM_MMU_POWER_CTRL_REG(0), SPI_MEM_MMU_POWER_CTRL_REG(0), N_REGS_SPI0_MEM_3(), 0, 0), .owner = ENTRY(0) | ENTRY(2) } }; - esp_err_t err = sleep_retention_entries_create(spimem_regs_retention, ARRAY_SIZE(spimem_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SPIMEM); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (SPI mem) retention"); - ESP_LOGI(TAG, "SPI Mem sleep retention initialization"); + esp_err_t err = sleep_retention_entries_create(spimem_regs_retention, ARRAY_SIZE(spimem_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SYS_PERIPH); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "SPI mem"); + ESP_LOGD(TAG, "SPI Mem sleep retention initialization"); return ESP_OK; } -esp_err_t sleep_sys_periph_systimer_retention_init(void) +static __attribute__((unused)) esp_err_t sleep_sys_periph_systimer_retention_init(void *arg) { #define N_REGS_SYSTIMER_0() (((SYSTIMER_TARGET2_CONF_REG - SYSTIMER_TARGET0_HI_REG) / 4) + 1) @@ -214,30 +214,30 @@ esp_err_t sleep_sys_periph_systimer_retention_init(void) [18] = { .config = REGDMA_LINK_CONTINUOUS_INIT(REGDMA_SYSTIMER_LINK(0x12), SYSTIMER_INT_ENA_REG, SYSTIMER_INT_ENA_REG, 1, 0, 0), .owner = ENTRY(0) | ENTRY(2) } /* Systimer intr enable */ }; - esp_err_t err = sleep_retention_entries_create(systimer_regs_retention, ARRAY_SIZE(systimer_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SYSTIMER); - ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (SysTimer) retention"); - ESP_LOGI(TAG, "SysTimer sleep retention initialization"); + esp_err_t err = sleep_retention_entries_create(systimer_regs_retention, ARRAY_SIZE(systimer_regs_retention), SLEEP_RETENTION_PERIPHERALS_PRIORITY_DEFAULT, SLEEP_RETENTION_MODULE_SYS_PERIPH); + ESP_RETURN_ON_ERROR(err, TAG, "failed to allocate memory for digital peripherals (%s) retention", "SysTimer"); + ESP_LOGD(TAG, "SysTimer sleep retention initialization"); return ESP_OK; } -esp_err_t sleep_sys_periph_retention_init(void) +static __attribute__((unused)) esp_err_t sleep_sys_periph_retention_init(void *arg) { esp_err_t err; - err = sleep_sys_periph_intr_matrix_retention_init(); + err = sleep_sys_periph_intr_matrix_retention_init(arg); if(err) goto error; - err = sleep_sys_periph_hp_system_retention_init(); + err = sleep_sys_periph_hp_system_retention_init(arg); if(err) goto error; - err = sleep_sys_periph_tee_apm_retention_init(); + err = sleep_sys_periph_tee_apm_retention_init(arg); if(err) goto error; - err = sleep_sys_periph_uart0_retention_init(); + err = sleep_sys_periph_uart0_retention_init(arg); if(err) goto error; - err = sleep_sys_periph_tg0_retention_init(); + err = sleep_sys_periph_tg0_retention_init(arg); if(err) goto error; - err = sleep_sys_periph_iomux_retention_init(); + err = sleep_sys_periph_iomux_retention_init(arg); if(err) goto error; - err = sleep_sys_periph_spimem_retention_init(); + err = sleep_sys_periph_spimem_retention_init(arg); if(err) goto error; - err = sleep_sys_periph_systimer_retention_init(); + err = sleep_sys_periph_systimer_retention_init(arg); error: return err; @@ -245,23 +245,27 @@ error: bool peripheral_domain_pd_allowed(void) { + const uint32_t inited_modules = sleep_retention_get_inited_modules(); const uint32_t created_modules = sleep_retention_get_created_modules(); - const uint32_t mask = (const uint32_t) ( - BIT(SLEEP_RETENTION_MODULE_INTR_MATRIX) | \ - BIT(SLEEP_RETENTION_MODULE_HP_SYSTEM) | \ - BIT(SLEEP_RETENTION_MODULE_TEE_APM) | \ - BIT(SLEEP_RETENTION_MODULE_UART0) | \ - BIT(SLEEP_RETENTION_MODULE_TG0) | \ - BIT(SLEEP_RETENTION_MODULE_IOMUX) | \ - BIT(SLEEP_RETENTION_MODULE_SPIMEM) | \ - BIT(SLEEP_RETENTION_MODULE_SYSTIMER)); - return ((created_modules & mask) == mask); + const uint32_t mask = (const uint32_t) (BIT(SLEEP_RETENTION_MODULE_SYS_PERIPH)); + + return ((inited_modules & mask) == (created_modules & mask)); } #if CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP ESP_SYSTEM_INIT_FN(sleep_sys_periph_startup_init, BIT(0), 107) { - sleep_sys_periph_retention_init(); + sleep_retention_module_init_param_t init_param = { + .cbs = { .create = { .handle = sleep_sys_periph_retention_init, .arg = NULL } }, + .depends = BIT(SLEEP_RETENTION_MODULE_CLOCK_SYSTEM) + }; + esp_err_t err = sleep_retention_module_init(SLEEP_RETENTION_MODULE_SYS_PERIPH, &init_param); + if (err == ESP_OK) { + err = sleep_retention_module_allocate(SLEEP_RETENTION_MODULE_SYS_PERIPH); + if (err != ESP_OK) { + ESP_LOGW(TAG, "failed to allocate sleep retention linked list for system peripherals retention"); + } + } return ESP_OK; } #endif