diff --git a/components/esp_hw_support/port/pau_regdma.c b/components/esp_hw_support/port/pau_regdma.c index c41532cbe1..d65a5e9ed7 100644 --- a/components/esp_hw_support/port/pau_regdma.c +++ b/components/esp_hw_support/port/pau_regdma.c @@ -14,11 +14,13 @@ #include "soc/soc_caps.h" #include "esp_private/esp_pau.h" #include "esp_private/periph_ctrl.h" - #if SOC_PAU_IN_TOP_DOMAIN #include "hal/lp_sys_ll.h" #endif +#define PAU_REGDMA_LINK_LOOP (0x3FF) +#define PAU_REGDMA_REG_ACCESS_TIME (0x3FF) + static __attribute__((unused)) const char *TAG = "pau_regdma"; typedef struct { @@ -36,6 +38,7 @@ pau_context_t * __attribute__((weak)) IRAM_ATTR PAU_instance(void) if (pau_hal.dev == NULL) { pau_hal.dev = &PAU; pau_hal_enable_bus_clock(true); + pau_hal_set_regdma_work_timeout(&pau_hal, PAU_REGDMA_LINK_LOOP, PAU_REGDMA_REG_ACCESS_TIME); #if SOC_PM_PAU_REGDMA_LINK_CONFIGURABLE pau_hal_regdma_link_count_config(&pau_hal, SOC_PM_PAU_LINK_NUM); #endif diff --git a/components/hal/esp32c5/include/hal/lp_aon_ll.h b/components/hal/esp32c5/include/hal/lp_aon_ll.h index 7f91a857de..16e1a588ee 100644 --- a/components/hal/esp32c5/include/hal/lp_aon_ll.h +++ b/components/hal/esp32c5/include/hal/lp_aon_ll.h @@ -119,6 +119,30 @@ static inline void lp_aon_ll_set_regdma_link_count(int count) HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.backup_dma_cfg0, branch_link_length_aon, count); } +/** + * @brief Set the maximum number of times a single linked list can run for REGDMA. If a linked list continuously reads in a loop + * for some reason and the execution count exceeds this configured number, a timeout will be triggered. + * @param count: the maximum number of loop + */ +static inline void lp_aon_ll_set_regdma_link_loop_threshold(int count) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.backup_dma_cfg1, link_work_tout_thres_aon, count); +} + +/** + * @brief Set the timeout duration for accessing registers. If REGDMA encounters bus-related issues while accessing + * registers and gets stuck on the bus, a timeout will be triggered. + * @param count: the maximum number of time + */ +static inline void lp_aon_ll_set_regdma_link_reg_access_tout_threshold(int count) +{ + HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.backup_dma_cfg1, link_backup_tout_thres_aon, count); +} + +/** + * @brief Set the regdma_link_addr + * @param addr: the addr of regdma_link + */ static inline void lp_aon_ll_set_regdma_link_addr(uint32_t addr) { HAL_FORCE_MODIFY_U32_REG_FIELD(LP_AON.backup_dma_cfg2, link_addr_aon, addr); diff --git a/components/hal/esp32c5/pau_hal.c b/components/hal/esp32c5/pau_hal.c index 5daf5e24cf..00ce9a47a9 100644 --- a/components/hal/esp32c5/pau_hal.c +++ b/components/hal/esp32c5/pau_hal.c @@ -62,3 +62,10 @@ void pau_hal_regdma_link_count_config(pau_hal_context_t *hal, int count) lp_aon_ll_set_regdma_link_count(count - 1); } #endif + +void pau_hal_set_regdma_work_timeout(pau_hal_context_t *hal, uint32_t loop_num, uint32_t time) +{ + HAL_ASSERT(loop_num > 0 && time > 0); + lp_aon_ll_set_regdma_link_loop_threshold(loop_num); + lp_aon_ll_set_regdma_link_reg_access_tout_threshold(time); +} diff --git a/components/hal/esp32c6/pau_hal.c b/components/hal/esp32c6/pau_hal.c index 1baff61487..44971fd8e3 100644 --- a/components/hal/esp32c6/pau_hal.c +++ b/components/hal/esp32c6/pau_hal.c @@ -57,3 +57,7 @@ void IRAM_ATTR pau_hal_stop_regdma_extra_link(pau_hal_context_t *hal) pau_ll_select_regdma_entry_link(hal->dev, 0); /* restore link select to default */ pau_ll_clear_regdma_backup_done_intr_state(hal->dev); } + +void pau_hal_set_regdma_work_timeout(pau_hal_context_t *hal, uint32_t loop_num, uint32_t time) +{ +} diff --git a/components/hal/esp32h2/pau_hal.c b/components/hal/esp32h2/pau_hal.c index 4426cdbc9f..775126cd51 100644 --- a/components/hal/esp32h2/pau_hal.c +++ b/components/hal/esp32h2/pau_hal.c @@ -42,6 +42,10 @@ void IRAM_ATTR pau_hal_regdma_clock_configure(pau_hal_context_t *hal, bool enabl HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.regdma_conf, regdma_clk_en, enable); } +void pau_hal_set_regdma_work_timeout(pau_hal_context_t *hal, uint32_t loop_num, uint32_t time) +{ +} + void IRAM_ATTR pau_hal_start_regdma_extra_link(pau_hal_context_t *hal, bool backup_or_restore) { pau_ll_clear_regdma_backup_done_intr_state(hal->dev); @@ -63,4 +67,4 @@ void IRAM_ATTR pau_hal_stop_regdma_extra_link(pau_hal_context_t *hal) pau_ll_set_regdma_entry_link_backup_start_disable(hal->dev); pau_ll_select_regdma_entry_link(hal->dev, 0); /* restore link select to default */ pau_ll_clear_regdma_backup_done_intr_state(hal->dev); -} +} \ No newline at end of file diff --git a/components/hal/esp32p4/pau_hal.c b/components/hal/esp32p4/pau_hal.c index 08c6adaf08..cc0a2d3097 100644 --- a/components/hal/esp32p4/pau_hal.c +++ b/components/hal/esp32p4/pau_hal.c @@ -63,6 +63,10 @@ void IRAM_ATTR pau_hal_stop_regdma_extra_link(pau_hal_context_t *hal) pau_ll_clear_regdma_backup_done_intr_state(hal->dev); } +void pau_hal_set_regdma_work_timeout(pau_hal_context_t *hal, uint32_t loop_num, uint32_t time) +{ +} + #if SOC_PAU_IN_TOP_DOMAIN void IRAM_ATTR pau_hal_lp_sys_initialize(void) { diff --git a/components/hal/include/hal/pau_hal.h b/components/hal/include/hal/pau_hal.h index 32167e20b7..b83ecaebf8 100644 --- a/components/hal/include/hal/pau_hal.h +++ b/components/hal/include/hal/pau_hal.h @@ -134,6 +134,15 @@ void pau_hal_regdma_clock_configure(pau_hal_context_t *hal, bool enable); void pau_hal_regdma_link_count_config(pau_hal_context_t *hal, int count); #endif +/** + * @brief Set PAU module link work timeout threshold + * + * @param hal regdma hal context + * @param loop_num the maximum number of regdma link loop num + * @param count the maximum number of register access timeout + */ +void pau_hal_set_regdma_work_timeout(pau_hal_context_t *hal, uint32_t loop_num, uint32_t count); + #if SOC_PAU_IN_TOP_DOMAIN /** * If PAU is in TOP power domain, configuration will be lost after sleep, it is necessary