refactor(uart): minor update on uart retention feature

This commit is contained in:
Song Ruo Jing
2024-10-10 21:02:34 +08:00
parent debd424b43
commit dc15243a64
15 changed files with 34 additions and 39 deletions

View File

@@ -47,9 +47,9 @@ typedef struct {
#endif
};
struct {
uint32_t backup_before_sleep: 1; /*!< If set, the driver will backup/restore the HP UART registers before entering/after exiting sleep mode.
By this approach, the system can power off HP UART's power domain.
This can save power, but at the expense of more RAM being consumed */
uint32_t allow_pd: 1; /*!< If set, driver allows the power domain to be powered off when system enters sleep mode.
This can save power, but at the expense of more RAM being consumed to save register context. */
uint32_t backup_before_sleep: 1; /*!< @deprecated, same meaning as allow_pd */
} flags; /*!< Configuration flags */
} uart_config_t;

View File

@@ -221,7 +221,7 @@ static void uart_module_enable(uart_port_t uart_num)
// Initialize sleep retention module for HP UART
if (uart_num != CONFIG_ESP_CONSOLE_UART_NUM) { // Console uart retention has been taken care in sleep_sys_periph_stdout_console_uart_retention_init
assert(!uart_context[uart_num].retention_link_inited);
sleep_retention_module_t module = UART_LL_SLEEP_RETENTION_MODULE_ID(uart_num);
sleep_retention_module_t module = uart_reg_retention_info[uart_num].module;
sleep_retention_module_init_param_t init_param = {
.cbs = {
.create = {
@@ -260,7 +260,7 @@ static void uart_module_disable(uart_port_t uart_num)
if (uart_num != CONFIG_ESP_CONSOLE_UART_NUM && uart_num < SOC_UART_HP_NUM) {
#if SOC_UART_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
// Uninitialize sleep retention module for HP UART
sleep_retention_module_t module = UART_LL_SLEEP_RETENTION_MODULE_ID(uart_num);
sleep_retention_module_t module = uart_reg_retention_info[uart_num].module;
assert(!uart_context[uart_num].retention_link_created); // HP UART sleep retention should have been freed at this moment
if (uart_context[uart_num].retention_link_inited) {
sleep_retention_module_deinit(module);
@@ -856,8 +856,9 @@ esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_conf
ESP_RETURN_ON_FALSE((uart_config->flow_ctrl < UART_HW_FLOWCTRL_MAX), ESP_FAIL, UART_TAG, "hw_flowctrl mode error");
ESP_RETURN_ON_FALSE((uart_config->data_bits < UART_DATA_BITS_MAX), ESP_FAIL, UART_TAG, "data bit error");
bool allow_pd __attribute__((unused)) = (uart_config->flags.allow_pd || uart_config->flags.backup_before_sleep);
#if !SOC_UART_SUPPORT_SLEEP_RETENTION
ESP_RETURN_ON_FALSE(uart_config->flags.backup_before_sleep == 0, ESP_ERR_NOT_SUPPORTED, UART_TAG, "register back up is not supported");
ESP_RETURN_ON_FALSE(allow_pd == 0, ESP_ERR_NOT_SUPPORTED, UART_TAG, "not able to power down in light sleep");
#endif
uart_module_enable(uart_num);
@@ -866,8 +867,8 @@ esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_conf
// Create sleep retention link if desired
if (uart_num != CONFIG_ESP_CONSOLE_UART_NUM && uart_num < SOC_UART_HP_NUM) {
_lock_acquire(&(uart_context[uart_num].mutex));
sleep_retention_module_t module = UART_LL_SLEEP_RETENTION_MODULE_ID(uart_num);
if (uart_config->flags.backup_before_sleep && !uart_context[uart_num].retention_link_created) {
sleep_retention_module_t module = uart_reg_retention_info[uart_num].module;
if (allow_pd && !uart_context[uart_num].retention_link_created) {
if (uart_context[uart_num].retention_link_inited) {
if (sleep_retention_module_allocate(module) == ESP_OK) {
uart_context[uart_num].retention_link_created = true;
@@ -878,7 +879,7 @@ esp_err_t uart_param_config(uart_port_t uart_num, const uart_config_t *uart_conf
} else {
ESP_LOGW(UART_TAG, "retention module not initialized first, unable to create retention module");
}
} else if (!uart_config->flags.backup_before_sleep && uart_context[uart_num].retention_link_created) {
} else if (!allow_pd && uart_context[uart_num].retention_link_created) {
assert(uart_context[uart_num].retention_link_inited);
sleep_retention_module_free(module);
uart_context[uart_num].retention_link_created = false;
@@ -1805,7 +1806,7 @@ esp_err_t uart_driver_delete(uart_port_t uart_num)
#if SOC_UART_SUPPORT_SLEEP_RETENTION && CONFIG_PM_POWER_DOWN_PERIPHERAL_IN_LIGHT_SLEEP
// Free sleep retention link for HP UART
if (uart_num != CONFIG_ESP_CONSOLE_UART_NUM && uart_num < SOC_UART_HP_NUM) {
sleep_retention_module_t module = UART_LL_SLEEP_RETENTION_MODULE_ID(uart_num);
sleep_retention_module_t module = uart_reg_retention_info[uart_num].module;
_lock_acquire(&(uart_context[uart_num].mutex));
if (uart_context[uart_num].retention_link_created) {
assert(uart_context[uart_num].retention_link_inited);
@@ -1979,7 +1980,7 @@ static esp_err_t uart_create_sleep_retention_link_cb(void *arg)
{
uart_context_t *group = (uart_context_t *)arg;
uart_port_t uart_num = group->port_id;
sleep_retention_module_t module = UART_LL_SLEEP_RETENTION_MODULE_ID(uart_num);
sleep_retention_module_t module = uart_reg_retention_info[uart_num].module;
esp_err_t err = sleep_retention_entries_create(uart_reg_retention_info[uart_num].regdma_entry_array,
uart_reg_retention_info[uart_num].array_size,
REGDMA_LINK_PRI_UART, module);

View File

@@ -17,7 +17,7 @@
static const uart_port_t uart_num = UART_NUM_1;
static void uart_init(bool backup_before_sleep)
static void uart_init(bool allow_pd)
{
uart_config_t uart_config = {
.baud_rate = 115200,
@@ -26,7 +26,7 @@ static void uart_init(bool backup_before_sleep)
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
.source_clk = UART_SCLK_DEFAULT,
.flags.backup_before_sleep = backup_before_sleep,
.flags.allow_pd = allow_pd,
};
TEST_ESP_OK(uart_driver_install(uart_num, 256, 0, 20, NULL, 0));
@@ -120,7 +120,7 @@ TEST_CASE("uart won't be powered down in light sleep if retention not created",
TEST_ESP_OK(esp_sleep_enable_timer_wakeup(1 * 1000 * 1000));
sleep_cpu_configure(true);
uart_init(false); // backup_before_sleep set to false, sleep retention module will be inited, but not created
uart_init(false); // allow_pd set to false, sleep retention module will be inited, but not created
// Ensure UART is fully idle before starting loopback RX/TX test
TEST_ESP_OK(uart_wait_tx_done(uart_num, portMAX_DELAY));

View File

@@ -61,10 +61,6 @@ extern "C" {
#define UART_LL_PCR_REG_GET(hw, reg_suffix, field_suffix) \
(((hw) == &UART0) ? PCR.uart0_##reg_suffix.uart0_##field_suffix : PCR.uart1_##reg_suffix.uart1_##field_suffix)
// UART sleep retention module
#define UART_LL_SLEEP_RETENTION_MODULE_ID(uart_num) ((uart_num == UART_NUM_0) ? SLEEP_RETENTION_MODULE_UART0 : \
(uart_num == UART_NUM_1) ? SLEEP_RETENTION_MODULE_UART1 : -1)
// Define UART interrupts
typedef enum {
UART_INTR_RXFIFO_FULL = (0x1 << 0),

View File

@@ -61,10 +61,6 @@ extern "C" {
#define UART_LL_PCR_REG_GET(hw, reg_suffix, field_suffix) \
(((hw) == &UART0) ? PCR.uart0_##reg_suffix.uart0_##field_suffix : PCR.uart1_##reg_suffix.uart1_##field_suffix)
// UART sleep retention module
#define UART_LL_SLEEP_RETENTION_MODULE_ID(uart_num) ((uart_num == UART_NUM_0) ? SLEEP_RETENTION_MODULE_UART0 : \
(uart_num == UART_NUM_1) ? SLEEP_RETENTION_MODULE_UART1 : -1)
// Define UART interrupts
typedef enum {
UART_INTR_RXFIFO_FULL = (0x1 << 0),

View File

@@ -64,10 +64,6 @@ extern "C" {
((hw) == &UART1) ? PCR.uart1_##reg_suffix.uart1_##field_suffix : \
PCR.uart2_##reg_suffix.uart2_##field_suffix)
// UART sleep retention module
#define UART_LL_SLEEP_RETENTION_MODULE_ID(uart_num) ((uart_num == UART_NUM_0) ? SLEEP_RETENTION_MODULE_UART0 : \
(uart_num == UART_NUM_1) ? SLEEP_RETENTION_MODULE_UART1 : -1)
// Define UART interrupts
typedef enum {
UART_INTR_RXFIFO_FULL = (0x1 << 0),

View File

@@ -57,10 +57,6 @@ extern "C" {
#define UART_LL_PCR_REG_GET(hw, reg_suffix, field_suffix) \
(((hw) == &UART0) ? PCR.uart0_##reg_suffix.uart0_##field_suffix : PCR.uart1_##reg_suffix.uart1_##field_suffix)
// UART sleep retention module
#define UART_LL_SLEEP_RETENTION_MODULE_ID(uart_num) ((uart_num == UART_NUM_0) ? SLEEP_RETENTION_MODULE_UART0 : \
(uart_num == UART_NUM_1) ? SLEEP_RETENTION_MODULE_UART1 : -1)
// Define UART interrupts
typedef enum {
UART_INTR_RXFIFO_FULL = (0x1 << 0),

View File

@@ -45,13 +45,6 @@ extern "C" {
#define UART_LL_FSM_IDLE (0x0)
#define UART_LL_FSM_TX_WAIT_SEND (0xf)
// UART sleep retention module
#define UART_LL_SLEEP_RETENTION_MODULE_ID(uart_num) ((uart_num == UART_NUM_0) ? SLEEP_RETENTION_MODULE_UART0 : \
(uart_num == UART_NUM_1) ? SLEEP_RETENTION_MODULE_UART1 : \
(uart_num == UART_NUM_2) ? SLEEP_RETENTION_MODULE_UART2 : \
(uart_num == UART_NUM_3) ? SLEEP_RETENTION_MODULE_UART3 : \
(uart_num == UART_NUM_4) ? SLEEP_RETENTION_MODULE_UART4 : -1)
// Define UART interrupts
typedef enum {
UART_INTR_RXFIFO_FULL = (0x1 << 0),

View File

@@ -150,10 +150,12 @@ static const regdma_entries_config_t uart1_regdma_entries[] = UART_SLEEP_RETENTI
const uart_reg_retention_info_t uart_reg_retention_info[SOC_UART_HP_NUM] = {
[0] = {
.module = SLEEP_RETENTION_MODULE_UART0,
.regdma_entry_array = uart0_regdma_entries,
.array_size = ARRAY_SIZE(uart0_regdma_entries),
},
[1] = {
.module = SLEEP_RETENTION_MODULE_UART1,
.regdma_entry_array = uart1_regdma_entries,
.array_size = ARRAY_SIZE(uart1_regdma_entries),
},

View File

@@ -151,10 +151,12 @@ static const regdma_entries_config_t uart1_regdma_entries[] = UART_SLEEP_RETENTI
const uart_reg_retention_info_t uart_reg_retention_info[SOC_UART_HP_NUM] = {
[0] = {
.module = SLEEP_RETENTION_MODULE_UART0,
.regdma_entry_array = uart0_regdma_entries,
.array_size = ARRAY_SIZE(uart0_regdma_entries),
},
[1] = {
.module = SLEEP_RETENTION_MODULE_UART1,
.regdma_entry_array = uart1_regdma_entries,
.array_size = ARRAY_SIZE(uart1_regdma_entries),
},

View File

@@ -150,10 +150,12 @@ static const regdma_entries_config_t uart1_regdma_entries[] = UART_SLEEP_RETENTI
const uart_reg_retention_info_t uart_reg_retention_info[SOC_UART_HP_NUM] = {
[0] = {
.module = SLEEP_RETENTION_MODULE_UART0,
.regdma_entry_array = uart0_regdma_entries,
.array_size = ARRAY_SIZE(uart0_regdma_entries),
},
[1] = {
.module = SLEEP_RETENTION_MODULE_UART1,
.regdma_entry_array = uart1_regdma_entries,
.array_size = ARRAY_SIZE(uart1_regdma_entries),
},

View File

@@ -118,10 +118,12 @@ static const regdma_entries_config_t uart1_regdma_entries[] = UART_SLEEP_RETENTI
const uart_reg_retention_info_t uart_reg_retention_info[SOC_UART_HP_NUM] = {
[0] = {
.module = SLEEP_RETENTION_MODULE_UART0,
.regdma_entry_array = uart0_regdma_entries,
.array_size = ARRAY_SIZE(uart0_regdma_entries),
},
[1] = {
.module = SLEEP_RETENTION_MODULE_UART1,
.regdma_entry_array = uart1_regdma_entries,
.array_size = ARRAY_SIZE(uart1_regdma_entries),
},

View File

@@ -253,22 +253,27 @@ static const regdma_entries_config_t uart4_regdma_entries[] = UART_SLEEP_RETENTI
const uart_reg_retention_info_t uart_reg_retention_info[SOC_UART_HP_NUM] = {
[0] = {
.module = SLEEP_RETENTION_MODULE_UART0,
.regdma_entry_array = uart0_regdma_entries,
.array_size = ARRAY_SIZE(uart0_regdma_entries),
},
[1] = {
.module = SLEEP_RETENTION_MODULE_UART1,
.regdma_entry_array = uart1_regdma_entries,
.array_size = ARRAY_SIZE(uart1_regdma_entries),
},
[2] = {
.module = SLEEP_RETENTION_MODULE_UART2,
.regdma_entry_array = uart2_regdma_entries,
.array_size = ARRAY_SIZE(uart2_regdma_entries),
},
[3] = {
.module = SLEEP_RETENTION_MODULE_UART3,
.regdma_entry_array = uart3_regdma_entries,
.array_size = ARRAY_SIZE(uart3_regdma_entries),
},
[4] = {
.module = SLEEP_RETENTION_MODULE_UART4,
.regdma_entry_array = uart4_regdma_entries,
.array_size = ARRAY_SIZE(uart4_regdma_entries),
},

View File

@@ -44,7 +44,7 @@ extern const gdma_signal_conn_t gdma_periph_signals;
typedef struct {
const regdma_entries_config_t *link_list;
uint32_t link_num;
periph_retention_module_t module_id;
const periph_retention_module_t module_id;
} gdma_chx_reg_ctx_link_t;
extern const gdma_chx_reg_ctx_link_t gdma_chx_regs_retention[SOC_GDMA_NUM_GROUPS_MAX][SOC_GDMA_PAIRS_PER_GROUP_MAX];

View File

@@ -12,7 +12,10 @@
#include "soc/uart_pins.h"
#include "soc/uart_struct.h"
#include "soc/uart_reg.h"
#if SOC_PAU_SUPPORTED
#include "soc/regdma.h"
#include "soc/retention_periph_defs.h"
#endif
#ifdef __cplusplus
extern "C" {
@@ -50,8 +53,9 @@ typedef struct {
extern const uart_signal_conn_t uart_periph_signal[SOC_UART_NUM];
#if SOC_UART_SUPPORT_SLEEP_RETENTION
#if SOC_UART_SUPPORT_SLEEP_RETENTION && SOC_PAU_SUPPORTED
typedef struct {
const periph_retention_module_t module;
const regdma_entries_config_t *regdma_entry_array;
uint32_t array_size;
} uart_reg_retention_info_t;