fix(parlio): only call esp_pm APIs when CONFIG_PM_ENABLE is enabled

This commit is contained in:
Chen Jichang
2025-05-16 18:35:29 +08:00
parent a21f7c78f9
commit 70e5042ea9
8 changed files with 21 additions and 10 deletions

View File

@ -101,8 +101,6 @@
#define PARLIO_RCC_ATOMIC()
#endif // SOC_RCC_IS_INDEPENDENT
#define PARLIO_PM_LOCK_NAME_LEN_MAX 16
///!< Logging settings
#define TAG "parlio"
@ -169,13 +167,12 @@ typedef struct parlio_tx_unit_t {
struct parlio_unit_t base; // base unit
size_t data_width; // data width
intr_handle_t intr; // allocated interrupt handle
esp_pm_lock_handle_t pm_lock; // power management lock
gdma_channel_handle_t dma_chan; // DMA channel
gdma_link_list_handle_t dma_link[PARLIO_DMA_LINK_NUM]; // DMA link list handle
size_t int_mem_align; // Alignment for internal memory
size_t ext_mem_align; // Alignment for external memory
#if CONFIG_PM_ENABLE
char pm_lock_name[PARLIO_PM_LOCK_NAME_LEN_MAX]; // pm lock name
esp_pm_lock_handle_t pm_lock; // power management lock
#endif
portMUX_TYPE spinlock; // prevent resource accessing by user and interrupt concurrently
uint32_t out_clk_freq_hz; // output clock frequency

View File

@ -55,10 +55,9 @@ typedef struct parlio_rx_unit_t {
SemaphoreHandle_t mutex; /*!< Mutex lock for concurrence safety,
* which should be acquired and released in a same function */
#if CONFIG_PM_ENABLE
/* Power Management */
esp_pm_lock_handle_t pm_lock; /*!< power management lock */
#if CONFIG_PM_ENABLE
char pm_lock_name[PARLIO_PM_LOCK_NAME_LEN_MAX]; /*!< pm lock name */
#endif
/* Transaction Resources */
@ -526,12 +525,11 @@ static esp_err_t parlio_select_periph_clock(parlio_rx_unit_handle_t rx_unit, con
if (clk_src != PARLIO_CLK_SRC_EXTERNAL) {
// XTAL and PLL clock source will be turned off in light sleep, so basically a NO_LIGHT_SLEEP lock is sufficient
esp_pm_lock_type_t lock_type = ESP_PM_NO_LIGHT_SLEEP;
sprintf(rx_unit->pm_lock_name, "parlio_rx_%d_%d", rx_unit->base.group->group_id, rx_unit->base.unit_id); // e.g. parlio_rx_0_0
#if CONFIG_IDF_TARGET_ESP32P4
// use CPU_MAX lock to ensure PSRAM bandwidth and usability during DFS
lock_type = ESP_PM_CPU_FREQ_MAX;
#endif
esp_err_t ret = esp_pm_lock_create(lock_type, 0, rx_unit->pm_lock_name, &rx_unit->pm_lock);
esp_err_t ret = esp_pm_lock_create(lock_type, 0, parlio_periph_signals.groups[rx_unit->base.group->group_id].module_name, &rx_unit->pm_lock);
ESP_RETURN_ON_ERROR(ret, TAG, "create pm lock failed");
}
#endif
@ -567,10 +565,12 @@ static esp_err_t parlio_destroy_rx_unit(parlio_rx_unit_handle_t rx_unit)
if (rx_unit->trans_sem) {
vSemaphoreDeleteWithCaps(rx_unit->trans_sem);
}
#if CONFIG_PM_ENABLE
/* Free the power management lock */
if (rx_unit->pm_lock) {
ESP_RETURN_ON_ERROR(esp_pm_lock_delete(rx_unit->pm_lock), TAG, "delete pm lock failed");
}
#endif
/* Delete the GDMA channel */
if (rx_unit->dma_chan) {
ESP_RETURN_ON_ERROR(gdma_disconnect(rx_unit->dma_chan), TAG, "disconnect dma channel failed");
@ -713,10 +713,12 @@ esp_err_t parlio_rx_unit_enable(parlio_rx_unit_handle_t rx_unit, bool reset_queu
ESP_GOTO_ON_FALSE(!rx_unit->is_enabled, ESP_ERR_INVALID_STATE, err, TAG, "the unit has enabled or running");
rx_unit->is_enabled = true;
#if CONFIG_PM_ENABLE
/* Acquire the power management lock in case */
if (rx_unit->pm_lock) {
esp_pm_lock_acquire(rx_unit->pm_lock);
}
#endif
/* For non-free running clock, the unit can't stop once enabled, otherwise the data alignment will go wrong */
if (!rx_unit->cfg.flags.free_clk) {
@ -785,10 +787,12 @@ esp_err_t parlio_rx_unit_disable(parlio_rx_unit_handle_t rx_unit)
free(rx_unit->dma_buf);
rx_unit->dma_buf = NULL;
}
#if CONFIG_PM_ENABLE
/* release power management lock */
if (rx_unit->pm_lock) {
esp_pm_lock_release(rx_unit->pm_lock);
}
#endif
/* Erase the current transaction */
memset(&rx_unit->curr_trans, 0, sizeof(parlio_rx_transaction_t));
err:

View File

@ -51,9 +51,11 @@ static esp_err_t parlio_destroy_tx_unit(parlio_tx_unit_t *tx_unit)
if (tx_unit->intr) {
ESP_RETURN_ON_ERROR(esp_intr_free(tx_unit->intr), TAG, "delete interrupt service failed");
}
#if CONFIG_PM_ENABLE
if (tx_unit->pm_lock) {
ESP_RETURN_ON_ERROR(esp_pm_lock_delete(tx_unit->pm_lock), TAG, "delete pm lock failed");
}
#endif
if (tx_unit->dma_chan) {
ESP_RETURN_ON_ERROR(gdma_disconnect(tx_unit->dma_chan), TAG, "disconnect dma channel failed");
ESP_RETURN_ON_ERROR(gdma_del_channel(tx_unit->dma_chan), TAG, "delete dma channel failed");
@ -221,12 +223,11 @@ static esp_err_t parlio_select_periph_clock(parlio_tx_unit_t *tx_unit, const par
if (clk_src != PARLIO_CLK_SRC_EXTERNAL) {
// XTAL and PLL clock source will be turned off in light sleep, so basically a NO_LIGHT_SLEEP lock is sufficient
esp_pm_lock_type_t lock_type = ESP_PM_NO_LIGHT_SLEEP;
sprintf(tx_unit->pm_lock_name, "parlio_tx_%d_%d", tx_unit->base.group->group_id, tx_unit->base.unit_id); // e.g. parlio_tx_0_0
#if CONFIG_IDF_TARGET_ESP32P4
// use CPU_MAX lock to ensure PSRAM bandwidth and usability during DFS
lock_type = ESP_PM_CPU_FREQ_MAX;
#endif
esp_err_t ret = esp_pm_lock_create(lock_type, 0, tx_unit->pm_lock_name, &tx_unit->pm_lock);
esp_err_t ret = esp_pm_lock_create(lock_type, 0, parlio_periph_signals.groups[tx_unit->base.group->group_id].module_name, &tx_unit->pm_lock);
ESP_RETURN_ON_ERROR(ret, TAG, "create pm lock failed");
}
#endif
@ -513,10 +514,12 @@ esp_err_t parlio_tx_unit_enable(parlio_tx_unit_handle_t tx_unit)
ESP_RETURN_ON_FALSE(tx_unit, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
parlio_tx_fsm_t expected_fsm = PARLIO_TX_FSM_INIT;
if (atomic_compare_exchange_strong(&tx_unit->fsm, &expected_fsm, PARLIO_TX_FSM_WAIT)) {
#if CONFIG_PM_ENABLE
// acquire power management lock
if (tx_unit->pm_lock) {
esp_pm_lock_acquire(tx_unit->pm_lock);
}
#endif
parlio_ll_enable_interrupt(hal->regs, PARLIO_LL_EVENT_TX_MASK, true);
atomic_store(&tx_unit->fsm, PARLIO_TX_FSM_ENABLE);
} else {
@ -587,10 +590,12 @@ esp_err_t parlio_tx_unit_disable(parlio_tx_unit_handle_t tx_unit)
// change the EOF condition to be the data length, so the EOF will be triggered normally
parlio_ll_tx_set_eof_condition(hal->regs, PARLIO_LL_TX_EOF_COND_DATA_LEN);
#if CONFIG_PM_ENABLE
// release power management lock
if (tx_unit->pm_lock) {
esp_pm_lock_release(tx_unit->pm_lock);
}
#endif
// finally we switch to the INIT state
atomic_store(&tx_unit->fsm, PARLIO_TX_FSM_INIT);

View File

@ -10,6 +10,7 @@
const parlio_signal_conn_t parlio_periph_signals = {
.groups = {
[0] = {
.module_name = "PARLIO0",
.module = PERIPH_PARLIO_MODULE,
.tx_irq_id = ETS_PARL_IO_TX_INTR_SOURCE,
.rx_irq_id = ETS_PARL_IO_RX_INTR_SOURCE,

View File

@ -10,6 +10,7 @@
const parlio_signal_conn_t parlio_periph_signals = {
.groups = {
[0] = {
.module_name = "PARLIO0",
.module = PERIPH_PARLIO_MODULE,
.tx_irq_id = ETS_PARL_IO_INTR_SOURCE,
.rx_irq_id = ETS_PARL_IO_INTR_SOURCE,

View File

@ -10,6 +10,7 @@
const parlio_signal_conn_t parlio_periph_signals = {
.groups = {
[0] = {
.module_name = "PARLIO0",
.module = PERIPH_PARLIO_MODULE,
.tx_irq_id = ETS_PARL_IO_TX_INTR_SOURCE,
.rx_irq_id = ETS_PARL_IO_RX_INTR_SOURCE,

View File

@ -10,6 +10,7 @@
const parlio_signal_conn_t parlio_periph_signals = {
.groups = {
[0] = {
.module_name = "PARLIO0",
.module = PERIPH_PARLIO_MODULE,
.tx_irq_id = ETS_HP_PARLIO_TX_INTR_SOURCE,
.rx_irq_id = ETS_HP_PARLIO_RX_INTR_SOURCE,

View File

@ -39,6 +39,7 @@ typedef struct {
const int tx_irq_id;
const int rx_irq_id;
const periph_module_t module;
const char *module_name;
} groups[SOC_PARLIO_GROUPS];
} parlio_signal_conn_t;