mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
fix(esp_hw_support): fix the issue of regdma wait node to immediately return to done caused by regdma wait mode comparator
This commit is contained in:
parent
5e5fb89c10
commit
5e82899305
@ -269,6 +269,13 @@ void *regdma_link_new_branch_wait_default(void *backup, uint32_t value, uint32_t
|
||||
*/
|
||||
void *regdma_link_init(const regdma_link_config_t *config, bool branch, uint32_t module, int nentry, ...);
|
||||
|
||||
/**
|
||||
* @brief Get REGDMA linked list node mode through configuration parameters
|
||||
* @param config REGDMA linked node configuration parameters
|
||||
* @return REGDMA linked list node mode
|
||||
*/
|
||||
regdma_link_mode_t regdma_link_get_config_mode(const regdma_link_config_t *config);
|
||||
|
||||
/**
|
||||
* @brief Recurse the REGDMA linked list and call the hook subroutine for each node
|
||||
* @param link The REGDMA linkded list head pointer
|
||||
|
@ -842,3 +842,10 @@ void regdma_link_dump(FILE *out, void *link, int entry)
|
||||
fprintf(out, "This REGDMA linked list is empty!\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
regdma_link_mode_t regdma_link_get_config_mode(const regdma_link_config_t *config)
|
||||
{
|
||||
assert(config != NULL);
|
||||
return (regdma_link_mode_t)config->head.mode;
|
||||
}
|
||||
|
@ -21,6 +21,9 @@
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_pmu.h"
|
||||
|
||||
#if SOC_PM_PAU_REGDMA_UPDATE_CACHE_BEFORE_WAIT_COMPARE && CONFIG_IDF_TARGET_ESP32C5 // TODO: PM-202
|
||||
#include "soc/pmu_reg.h" // for PMU_DATE_REG, it can provide full 32 bit read and write access
|
||||
#endif
|
||||
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
|
||||
#include "hal/cache_ll.h"
|
||||
#endif
|
||||
@ -493,8 +496,9 @@ static void sleep_retention_entries_destroy(sleep_retention_module_t module)
|
||||
|
||||
static esp_err_t sleep_retention_entries_create_impl(const sleep_retention_entries_config_t retent[], int num, regdma_link_priority_t priority, sleep_retention_module_t module)
|
||||
{
|
||||
esp_err_t err = ESP_OK;
|
||||
_lock_acquire_recursive(&s_retention.lock);
|
||||
for (int i = num - 1; i >= 0; i--) {
|
||||
for (int i = num - 1; (i >= 0) && (err == ESP_OK); i--) {
|
||||
#if SOC_PM_RETENTION_HAS_CLOCK_BUG
|
||||
if ((retent[i].owner > BIT(EXTRA_LINK_NUM)) && (retent[i].config.id != 0xffff)) {
|
||||
_lock_release_recursive(&s_retention.lock);
|
||||
@ -502,16 +506,40 @@ static esp_err_t sleep_retention_entries_create_impl(const sleep_retention_entri
|
||||
return ESP_ERR_NOT_SUPPORTED;
|
||||
}
|
||||
#endif
|
||||
void *link = sleep_retention_entries_try_create(&retent[i].config, retent[i].owner, priority, module);
|
||||
if (link == NULL) {
|
||||
_lock_release_recursive(&s_retention.lock);
|
||||
sleep_retention_entries_do_destroy(module);
|
||||
return ESP_ERR_NO_MEM;
|
||||
#if SOC_PM_PAU_REGDMA_UPDATE_CACHE_BEFORE_WAIT_COMPARE && CONFIG_IDF_TARGET_ESP32C5 // TODO: PM-202
|
||||
/* There is a bug in REGDMA wait mode, when two wait nodes need to wait for the
|
||||
* same value (_val & _mask), the second wait node will immediately return to
|
||||
* wait done, The reason is that the wait mode comparison output logic immediate
|
||||
* compares the value of the previous wait register cached inside the
|
||||
* digital logic before reading out he register contents specified by _backup.
|
||||
*/
|
||||
#define config_is_wait_mode(_config) (regdma_link_get_config_mode(_config) == REGDMA_LINK_MODE_WAIT)
|
||||
if ((retent[i].config.id != 0xffff) && config_is_wait_mode(&(retent[i].config)) && (retent[i].config.id != 0xfffe)) {
|
||||
uint32_t value = retent[i].config.write_wait.value;
|
||||
uint32_t mask = retent[i].config.write_wait.mask;
|
||||
bool skip_b = retent[i].config.head.skip_b;
|
||||
bool skip_r = retent[i].config.head.skip_r;
|
||||
sleep_retention_entries_config_t wait_bug_workaround[] = {
|
||||
[0] = { .config = REGDMA_LINK_WRITE_INIT(0xfffe, PMU_DATE_REG, ~value, mask, skip_b, skip_r), .owner = retent[i].owner },
|
||||
[1] = { .config = REGDMA_LINK_WAIT_INIT (0xfffe, PMU_DATE_REG, ~value, mask, skip_b, skip_r), .owner = retent[i].owner }
|
||||
};
|
||||
err = sleep_retention_entries_create_impl(wait_bug_workaround, ARRAY_SIZE(wait_bug_workaround), priority, module);
|
||||
}
|
||||
#endif
|
||||
if (err == ESP_OK) {
|
||||
void *link = sleep_retention_entries_try_create(&retent[i].config, retent[i].owner, priority, module);
|
||||
if (link == NULL) {
|
||||
_lock_release_recursive(&s_retention.lock);
|
||||
sleep_retention_entries_do_destroy(module);
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
sleep_retention_entries_update(retent[i].owner, link, priority);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
sleep_retention_entries_update(retent[i].owner, link, priority);
|
||||
}
|
||||
_lock_release_recursive(&s_retention.lock);
|
||||
return ESP_OK;
|
||||
return err;
|
||||
}
|
||||
|
||||
static esp_err_t sleep_retention_entries_create_bonding(regdma_link_priority_t priority, sleep_retention_module_t module)
|
||||
|
@ -1275,6 +1275,10 @@ config SOC_PM_PAU_REGDMA_LINK_CONFIGURABLE
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PM_PAU_REGDMA_UPDATE_CACHE_BEFORE_WAIT_COMPARE
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
|
||||
bool
|
||||
default y
|
||||
|
@ -566,6 +566,8 @@
|
||||
#define SOC_PM_PAU_LINK_NUM (5)
|
||||
#define SOC_PM_PAU_REGDMA_LINK_CONFIGURABLE (1)
|
||||
|
||||
#define SOC_PM_PAU_REGDMA_UPDATE_CACHE_BEFORE_WAIT_COMPARE (1)
|
||||
|
||||
/*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/
|
||||
#define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (1)
|
||||
#define SOC_MODEM_CLOCK_IS_INDEPENDENT (1)
|
||||
|
@ -1411,6 +1411,10 @@ config SOC_PM_PAU_REGDMA_LINK_WIFIMAC
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PM_PAU_REGDMA_UPDATE_CACHE_BEFORE_WAIT_COMPARE
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_CLK_RC_FAST_SUPPORT_CALIBRATION
|
||||
bool
|
||||
default y
|
||||
|
@ -556,6 +556,8 @@
|
||||
#define SOC_PM_PAU_REGDMA_LINK_MULTI_ADDR (1)
|
||||
#define SOC_PM_PAU_REGDMA_LINK_WIFIMAC (1)
|
||||
|
||||
#define SOC_PM_PAU_REGDMA_UPDATE_CACHE_BEFORE_WAIT_COMPARE (1)
|
||||
|
||||
/*-------------------------- CLOCK SUBSYSTEM CAPS ----------------------------------------*/
|
||||
#define SOC_CLK_RC_FAST_SUPPORT_CALIBRATION (1)
|
||||
#define SOC_MODEM_CLOCK_IS_INDEPENDENT (1)
|
||||
|
@ -1351,6 +1351,10 @@ config SOC_PM_PAU_REGDMA_LINK_WIFIMAC
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PM_PAU_REGDMA_UPDATE_CACHE_BEFORE_WAIT_COMPARE
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_EXT_MEM_CACHE_TAG_IN_CPU_DOMAIN
|
||||
bool
|
||||
default y
|
||||
|
@ -533,6 +533,8 @@
|
||||
#define SOC_PM_PAU_REGDMA_LINK_MULTI_ADDR (1)
|
||||
#define SOC_PM_PAU_REGDMA_LINK_WIFIMAC (1)
|
||||
|
||||
#define SOC_PM_PAU_REGDMA_UPDATE_CACHE_BEFORE_WAIT_COMPARE (1)
|
||||
|
||||
#define SOC_EXT_MEM_CACHE_TAG_IN_CPU_DOMAIN (1)
|
||||
#define SOC_PM_CPU_RETENTION_BY_SW (1)
|
||||
#define SOC_PM_MODEM_RETENTION_BY_REGDMA (1)
|
||||
|
@ -1783,6 +1783,10 @@ config SOC_CPU_IN_TOP_DOMAIN
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PM_PAU_REGDMA_UPDATE_CACHE_BEFORE_WAIT_COMPARE
|
||||
bool
|
||||
default y
|
||||
|
||||
config SOC_PSRAM_VDD_POWER_MPLL
|
||||
bool
|
||||
default y
|
||||
|
@ -684,6 +684,8 @@
|
||||
#define SOC_PAU_IN_TOP_DOMAIN (1)
|
||||
#define SOC_CPU_IN_TOP_DOMAIN (1)
|
||||
|
||||
#define SOC_PM_PAU_REGDMA_UPDATE_CACHE_BEFORE_WAIT_COMPARE (1)
|
||||
|
||||
/*-------------------------- PSRAM CAPS ----------------------------*/
|
||||
#define SOC_PSRAM_VDD_POWER_MPLL (1)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user