feat(esp_hw_support): support extra link software trigger for all targets

This commit is contained in:
wuzhenghui
2024-08-12 15:37:08 +08:00
parent 15825dc531
commit 05504d5f68
10 changed files with 78 additions and 15 deletions

View File

@@ -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 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -77,6 +77,16 @@ void pau_regdma_trigger_extra_link_backup(void);
*/ */
void pau_regdma_trigger_extra_link_restore(void); void pau_regdma_trigger_extra_link_restore(void);
#if SOC_PAU_IN_TOP_DOMAIN
/**
* @brief Rentention link entry selection, enable or disable the retention
* link entry configuration in always-on domain
*
* @param enable Set true to use always-on domain link configuration instead
*/
void pau_regdma_enable_aon_link_entry(bool enable);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -164,7 +164,6 @@ uint32_t sleep_retention_get_inited_modules(void);
*/ */
uint32_t sleep_retention_get_created_modules(void); uint32_t sleep_retention_get_created_modules(void);
#if SOC_PM_RETENTION_HAS_CLOCK_BUG
/** /**
* @brief Software trigger REGDMA to do extra linked list retention * @brief Software trigger REGDMA to do extra linked list retention
* *
@@ -172,7 +171,6 @@ uint32_t sleep_retention_get_created_modules(void);
* or false for restore to register from memory * or false for restore to register from memory
*/ */
void sleep_retention_do_extra_retention(bool backup_or_restore); void sleep_retention_do_extra_retention(bool backup_or_restore);
#endif
#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA #if SOC_PM_RETENTION_SW_TRIGGER_REGDMA
/** /**

View File

@@ -15,6 +15,10 @@
#include "esp_private/esp_pau.h" #include "esp_private/esp_pau.h"
#include "esp_private/periph_ctrl.h" #include "esp_private/periph_ctrl.h"
#if SOC_PAU_IN_TOP_DOMAIN
#include "hal/lp_sys_ll.h"
#endif
static __attribute__((unused)) const char *TAG = "pau_regdma"; static __attribute__((unused)) const char *TAG = "pau_regdma";
typedef struct { typedef struct {
@@ -107,3 +111,10 @@ void IRAM_ATTR pau_regdma_trigger_extra_link_restore(void)
pau_hal_start_regdma_extra_link(PAU_instance()->hal, false); pau_hal_start_regdma_extra_link(PAU_instance()->hal, false);
pau_hal_stop_regdma_extra_link(PAU_instance()->hal); pau_hal_stop_regdma_extra_link(PAU_instance()->hal);
} }
#if SOC_PAU_IN_TOP_DOMAIN
void pau_regdma_enable_aon_link_entry(bool enable)
{
lp_sys_ll_set_pau_aon_bypass(enable);
}
#endif

View File

@@ -21,6 +21,10 @@
#include "sdkconfig.h" #include "sdkconfig.h"
#include "esp_pmu.h" #include "esp_pmu.h"
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
#include "hal/cache_ll.h"
#endif
static __attribute__((unused)) const char *TAG = "sleep"; static __attribute__((unused)) const char *TAG = "sleep";
struct sleep_retention_module_object { struct sleep_retention_module_object {
@@ -183,9 +187,7 @@ typedef struct {
struct sleep_retention_module_object instance[32]; struct sleep_retention_module_object instance[32];
#if SOC_PM_RETENTION_HAS_CLOCK_BUG
#define EXTRA_LINK_NUM (REGDMA_LINK_ENTRY_NUM - 1) #define EXTRA_LINK_NUM (REGDMA_LINK_ENTRY_NUM - 1)
#endif
} sleep_retention_t; } sleep_retention_t;
static DRAM_ATTR __attribute__((unused)) sleep_retention_t s_retention = { static DRAM_ATTR __attribute__((unused)) sleep_retention_t s_retention = {
@@ -312,6 +314,7 @@ void sleep_retention_dump_entries(FILE *out)
regdma_link_dump(out, s_retention.lists[s_retention.highpri].entries[entry], entry); regdma_link_dump(out, s_retention.lists[s_retention.highpri].entries[entry], entry);
} }
} }
fflush(out);
_lock_release_recursive(&s_retention.lock); _lock_release_recursive(&s_retention.lock);
} }
@@ -770,22 +773,28 @@ esp_err_t sleep_retention_module_free(sleep_retention_module_t module)
return err; return err;
} }
#if SOC_PM_RETENTION_HAS_CLOCK_BUG
void IRAM_ATTR sleep_retention_do_extra_retention(bool backup_or_restore) void IRAM_ATTR sleep_retention_do_extra_retention(bool backup_or_restore)
{ {
if (s_retention.highpri < SLEEP_RETENTION_REGDMA_LINK_HIGHEST_PRIORITY || if (s_retention.highpri < SLEEP_RETENTION_REGDMA_LINK_HIGHEST_PRIORITY ||
s_retention.highpri > SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY) { s_retention.highpri > SLEEP_RETENTION_REGDMA_LINK_LOWEST_PRIORITY) {
return; return;
} }
#if SOC_PAU_IN_TOP_DOMAIN
pau_regdma_enable_aon_link_entry(false);
#endif
// Set extra linked list head pointer to hardware // Set extra linked list head pointer to hardware
pau_regdma_set_extra_link_addr(s_retention.lists[s_retention.highpri].entries[EXTRA_LINK_NUM]); pau_regdma_set_extra_link_addr(s_retention.lists[s_retention.highpri].entries[EXTRA_LINK_NUM]);
#if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE
/* Data of retention link may be temporarily stored in L1 DCache, which is not accessible by
REGDMA, write it back to L2MEM before starting REGDMA. */
cache_ll_writeback_all(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA, CACHE_LL_ID_ALL);
#endif
if (backup_or_restore) { if (backup_or_restore) {
pau_regdma_trigger_extra_link_backup(); pau_regdma_trigger_extra_link_backup();
} else { } else {
pau_regdma_trigger_extra_link_restore(); pau_regdma_trigger_extra_link_restore();
} }
} }
#endif
#if SOC_PM_RETENTION_SW_TRIGGER_REGDMA #if SOC_PM_RETENTION_SW_TRIGGER_REGDMA
void IRAM_ATTR sleep_retention_do_system_retention(bool backup_or_restore) void IRAM_ATTR sleep_retention_do_system_retention(bool backup_or_restore)

View File

@@ -40,7 +40,10 @@ void pau_hal_start_regdma_extra_link(pau_hal_context_t *hal, bool backup_or_rest
pau_ll_clear_regdma_backup_done_intr_state(hal->dev); pau_ll_clear_regdma_backup_done_intr_state(hal->dev);
/* The link 3 of REGDMA is reserved, we use it as an extra linked list to /* The link 3 of REGDMA is reserved, we use it as an extra linked list to
* provide backup and restore services for BLE, IEEE802.15.4 and possibly * provide backup and restore services for BLE, IEEE802.15.4 and possibly
* other modules */ * other modules.
* It is also used as software trigger REGDMA to backup and restore, and is
* used by the UT to test module driver retention function.
*/
pau_ll_select_regdma_entry_link(hal->dev, 3); pau_ll_select_regdma_entry_link(hal->dev, 3);
pau_ll_set_regdma_entry_link_backup_direction(hal->dev, backup_or_restore); pau_ll_set_regdma_entry_link_backup_direction(hal->dev, backup_or_restore);
pau_ll_set_regdma_entry_link_backup_start_enable(hal->dev); pau_ll_set_regdma_entry_link_backup_start_enable(hal->dev);

View File

@@ -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 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -40,7 +40,10 @@ void IRAM_ATTR pau_hal_start_regdma_extra_link(pau_hal_context_t *hal, bool back
pau_ll_clear_regdma_backup_done_intr_state(hal->dev); pau_ll_clear_regdma_backup_done_intr_state(hal->dev);
/* The link 3 of REGDMA is reserved, we use it as an extra linked list to /* The link 3 of REGDMA is reserved, we use it as an extra linked list to
* provide backup and restore services for BLE, IEEE802.15.4 and possibly * provide backup and restore services for BLE, IEEE802.15.4 and possibly
* other modules */ * other modules.
* It is also used as software trigger REGDMA to backup and restore, and is
* used by the UT to test module driver retention function.
*/
pau_ll_select_regdma_entry_link(hal->dev, 3); pau_ll_select_regdma_entry_link(hal->dev, 3);
pau_ll_set_regdma_entry_link_backup_direction(hal->dev, backup_or_restore); pau_ll_set_regdma_entry_link_backup_direction(hal->dev, backup_or_restore);
pau_ll_set_regdma_entry_link_backup_start_enable(hal->dev); pau_ll_set_regdma_entry_link_backup_start_enable(hal->dev);

View File

@@ -42,7 +42,10 @@ void IRAM_ATTR pau_hal_start_regdma_extra_link(pau_hal_context_t *hal, bool back
pau_ll_clear_regdma_backup_done_intr_state(hal->dev); pau_ll_clear_regdma_backup_done_intr_state(hal->dev);
/* The link 3 of REGDMA is reserved, we use it as an extra linked list to /* The link 3 of REGDMA is reserved, we use it as an extra linked list to
* provide backup and restore services for BLE, IEEE802.15.4 and possibly * provide backup and restore services for BLE, IEEE802.15.4 and possibly
* other modules */ * other modules.
* It is also used as software trigger REGDMA to backup and restore, and is
* used by the UT to test module driver retention function.
*/
pau_ll_select_regdma_entry_link(hal->dev, 3); pau_ll_select_regdma_entry_link(hal->dev, 3);
pau_ll_set_regdma_entry_link_backup_direction(hal->dev, backup_or_restore); pau_ll_set_regdma_entry_link_backup_direction(hal->dev, backup_or_restore);
pau_ll_set_regdma_entry_link_backup_start_enable(hal->dev); pau_ll_set_regdma_entry_link_backup_start_enable(hal->dev);

View File

@@ -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 * SPDX-License-Identifier: Apache-2.0
*/ */
@@ -41,3 +41,26 @@ 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_rst_en, !enable); HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.regdma_conf, regdma_rst_en, !enable);
HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.regdma_conf, regdma_clk_en, enable); HAL_FORCE_MODIFY_U32_REG_FIELD(PCR.regdma_conf, regdma_clk_en, enable);
} }
void IRAM_ATTR pau_hal_start_regdma_extra_link(pau_hal_context_t *hal, bool backup_or_restore)
{
pau_ll_clear_regdma_backup_done_intr_state(hal->dev);
/* The link 3 of REGDMA is reserved, we use it as an extra linked list to
* provide backup and restore services for BLE, IEEE802.15.4 and possibly
* other modules.
* It is also used as software trigger REGDMA to backup and restore, and is
* used by the UT to test module driver retention function.
*/
pau_ll_select_regdma_entry_link(hal->dev, 3);
pau_ll_set_regdma_entry_link_backup_direction(hal->dev, backup_or_restore);
pau_ll_set_regdma_entry_link_backup_start_enable(hal->dev);
while (!(pau_ll_get_regdma_intr_raw_signal(hal->dev) & PAU_DONE_INT_RAW));
}
void IRAM_ATTR pau_hal_stop_regdma_extra_link(pau_hal_context_t *hal)
{
pau_ll_set_regdma_entry_link_backup_start_disable(hal->dev);
pau_ll_select_regdma_entry_link(hal->dev, 0); /* restore link select to default */
pau_ll_clear_regdma_backup_done_intr_state(hal->dev);
}

View File

@@ -46,9 +46,9 @@ void IRAM_ATTR pau_hal_stop_regdma_modem_link(pau_hal_context_t *hal)
void IRAM_ATTR pau_hal_start_regdma_extra_link(pau_hal_context_t *hal, bool backup_or_restore) 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); pau_ll_clear_regdma_backup_done_intr_state(hal->dev);
/* The link 3 of REGDMA is reserved, we use it as an extra linked list to /* The link 3 of REGDMA is reserved, it is used as software trigger REGDMA to backup and
* provide backup and restore services for BLE, IEEE802.15.4 and possibly * restore, and is used by the UT to test module driver retention function.
* other modules */ */
pau_ll_select_regdma_entry_link(hal->dev, 3); pau_ll_select_regdma_entry_link(hal->dev, 3);
pau_ll_set_regdma_entry_link_backup_direction(hal->dev, backup_or_restore); pau_ll_set_regdma_entry_link_backup_direction(hal->dev, backup_or_restore);
pau_ll_set_regdma_entry_link_backup_start_enable(hal->dev); pau_ll_set_regdma_entry_link_backup_start_enable(hal->dev);

View File

@@ -26,6 +26,9 @@ extern "C" {
#define ENTRY(n) (BIT(n)) #define ENTRY(n) (BIT(n))
// Only used for driver retention function testing when lightsleep is not supported
#define REGDMA_SW_TRIGGER_ENTRY (ENTRY(3))
#define REGDMA_PHY_LINK(_pri) ((0x00 << 8) | _pri) #define REGDMA_PHY_LINK(_pri) ((0x00 << 8) | _pri)
#define REGDMA_PCR_LINK(_pri) ((0x01 << 8) | _pri) #define REGDMA_PCR_LINK(_pri) ((0x01 << 8) | _pri)
#define REGDMA_MODEMSYSCON_LINK(_pri) ((0x02 << 8) | _pri) #define REGDMA_MODEMSYSCON_LINK(_pri) ((0x02 << 8) | _pri)