mirror of
https://github.com/espressif/esp-idf.git
synced 2025-08-01 19:54:32 +02:00
fix(parlio): only call esp_pm APIs when CONFIG_PM_ENABLE is enabled
This commit is contained in:
@@ -101,8 +101,6 @@
|
|||||||
#define PARLIO_RCC_ATOMIC()
|
#define PARLIO_RCC_ATOMIC()
|
||||||
#endif // SOC_RCC_IS_INDEPENDENT
|
#endif // SOC_RCC_IS_INDEPENDENT
|
||||||
|
|
||||||
#define PARLIO_PM_LOCK_NAME_LEN_MAX 16
|
|
||||||
|
|
||||||
///!< Logging settings
|
///!< Logging settings
|
||||||
#define TAG "parlio"
|
#define TAG "parlio"
|
||||||
|
|
||||||
@@ -169,13 +167,12 @@ typedef struct parlio_tx_unit_t {
|
|||||||
struct parlio_unit_t base; // base unit
|
struct parlio_unit_t base; // base unit
|
||||||
size_t data_width; // data width
|
size_t data_width; // data width
|
||||||
intr_handle_t intr; // allocated interrupt handle
|
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_channel_handle_t dma_chan; // DMA channel
|
||||||
gdma_link_list_handle_t dma_link[PARLIO_DMA_LINK_NUM]; // DMA link list handle
|
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 int_mem_align; // Alignment for internal memory
|
||||||
size_t ext_mem_align; // Alignment for external memory
|
size_t ext_mem_align; // Alignment for external memory
|
||||||
#if CONFIG_PM_ENABLE
|
#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
|
#endif
|
||||||
portMUX_TYPE spinlock; // prevent resource accessing by user and interrupt concurrently
|
portMUX_TYPE spinlock; // prevent resource accessing by user and interrupt concurrently
|
||||||
uint32_t out_clk_freq_hz; // output clock frequency
|
uint32_t out_clk_freq_hz; // output clock frequency
|
||||||
|
@@ -55,10 +55,9 @@ typedef struct parlio_rx_unit_t {
|
|||||||
SemaphoreHandle_t mutex; /*!< Mutex lock for concurrence safety,
|
SemaphoreHandle_t mutex; /*!< Mutex lock for concurrence safety,
|
||||||
* which should be acquired and released in a same function */
|
* which should be acquired and released in a same function */
|
||||||
|
|
||||||
|
#if CONFIG_PM_ENABLE
|
||||||
/* Power Management */
|
/* Power Management */
|
||||||
esp_pm_lock_handle_t pm_lock; /*!< power management lock */
|
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
|
#endif
|
||||||
|
|
||||||
/* Transaction Resources */
|
/* 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) {
|
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
|
// 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;
|
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
|
#if CONFIG_IDF_TARGET_ESP32P4
|
||||||
// use CPU_MAX lock to ensure PSRAM bandwidth and usability during DFS
|
// use CPU_MAX lock to ensure PSRAM bandwidth and usability during DFS
|
||||||
lock_type = ESP_PM_CPU_FREQ_MAX;
|
lock_type = ESP_PM_CPU_FREQ_MAX;
|
||||||
#endif
|
#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");
|
ESP_RETURN_ON_ERROR(ret, TAG, "create pm lock failed");
|
||||||
}
|
}
|
||||||
#endif
|
#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) {
|
if (rx_unit->trans_sem) {
|
||||||
vSemaphoreDeleteWithCaps(rx_unit->trans_sem);
|
vSemaphoreDeleteWithCaps(rx_unit->trans_sem);
|
||||||
}
|
}
|
||||||
|
#if CONFIG_PM_ENABLE
|
||||||
/* Free the power management lock */
|
/* Free the power management lock */
|
||||||
if (rx_unit->pm_lock) {
|
if (rx_unit->pm_lock) {
|
||||||
ESP_RETURN_ON_ERROR(esp_pm_lock_delete(rx_unit->pm_lock), TAG, "delete pm lock failed");
|
ESP_RETURN_ON_ERROR(esp_pm_lock_delete(rx_unit->pm_lock), TAG, "delete pm lock failed");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
/* Delete the GDMA channel */
|
/* Delete the GDMA channel */
|
||||||
if (rx_unit->dma_chan) {
|
if (rx_unit->dma_chan) {
|
||||||
ESP_RETURN_ON_ERROR(gdma_disconnect(rx_unit->dma_chan), TAG, "disconnect dma channel failed");
|
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");
|
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;
|
rx_unit->is_enabled = true;
|
||||||
|
|
||||||
|
#if CONFIG_PM_ENABLE
|
||||||
/* Acquire the power management lock in case */
|
/* Acquire the power management lock in case */
|
||||||
if (rx_unit->pm_lock) {
|
if (rx_unit->pm_lock) {
|
||||||
esp_pm_lock_acquire(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 */
|
/* 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) {
|
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);
|
free(rx_unit->dma_buf);
|
||||||
rx_unit->dma_buf = NULL;
|
rx_unit->dma_buf = NULL;
|
||||||
}
|
}
|
||||||
|
#if CONFIG_PM_ENABLE
|
||||||
/* release power management lock */
|
/* release power management lock */
|
||||||
if (rx_unit->pm_lock) {
|
if (rx_unit->pm_lock) {
|
||||||
esp_pm_lock_release(rx_unit->pm_lock);
|
esp_pm_lock_release(rx_unit->pm_lock);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
/* Erase the current transaction */
|
/* Erase the current transaction */
|
||||||
memset(&rx_unit->curr_trans, 0, sizeof(parlio_rx_transaction_t));
|
memset(&rx_unit->curr_trans, 0, sizeof(parlio_rx_transaction_t));
|
||||||
err:
|
err:
|
||||||
|
@@ -51,9 +51,11 @@ static esp_err_t parlio_destroy_tx_unit(parlio_tx_unit_t *tx_unit)
|
|||||||
if (tx_unit->intr) {
|
if (tx_unit->intr) {
|
||||||
ESP_RETURN_ON_ERROR(esp_intr_free(tx_unit->intr), TAG, "delete interrupt service failed");
|
ESP_RETURN_ON_ERROR(esp_intr_free(tx_unit->intr), TAG, "delete interrupt service failed");
|
||||||
}
|
}
|
||||||
|
#if CONFIG_PM_ENABLE
|
||||||
if (tx_unit->pm_lock) {
|
if (tx_unit->pm_lock) {
|
||||||
ESP_RETURN_ON_ERROR(esp_pm_lock_delete(tx_unit->pm_lock), TAG, "delete pm lock failed");
|
ESP_RETURN_ON_ERROR(esp_pm_lock_delete(tx_unit->pm_lock), TAG, "delete pm lock failed");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
if (tx_unit->dma_chan) {
|
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_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");
|
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) {
|
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
|
// 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;
|
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
|
#if CONFIG_IDF_TARGET_ESP32P4
|
||||||
// use CPU_MAX lock to ensure PSRAM bandwidth and usability during DFS
|
// use CPU_MAX lock to ensure PSRAM bandwidth and usability during DFS
|
||||||
lock_type = ESP_PM_CPU_FREQ_MAX;
|
lock_type = ESP_PM_CPU_FREQ_MAX;
|
||||||
#endif
|
#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");
|
ESP_RETURN_ON_ERROR(ret, TAG, "create pm lock failed");
|
||||||
}
|
}
|
||||||
#endif
|
#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");
|
ESP_RETURN_ON_FALSE(tx_unit, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||||
parlio_tx_fsm_t expected_fsm = PARLIO_TX_FSM_INIT;
|
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 (atomic_compare_exchange_strong(&tx_unit->fsm, &expected_fsm, PARLIO_TX_FSM_WAIT)) {
|
||||||
|
#if CONFIG_PM_ENABLE
|
||||||
// acquire power management lock
|
// acquire power management lock
|
||||||
if (tx_unit->pm_lock) {
|
if (tx_unit->pm_lock) {
|
||||||
esp_pm_lock_acquire(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);
|
parlio_ll_enable_interrupt(hal->regs, PARLIO_LL_EVENT_TX_MASK, true);
|
||||||
atomic_store(&tx_unit->fsm, PARLIO_TX_FSM_ENABLE);
|
atomic_store(&tx_unit->fsm, PARLIO_TX_FSM_ENABLE);
|
||||||
} else {
|
} 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
|
// 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);
|
parlio_ll_tx_set_eof_condition(hal->regs, PARLIO_LL_TX_EOF_COND_DATA_LEN);
|
||||||
|
|
||||||
|
#if CONFIG_PM_ENABLE
|
||||||
// release power management lock
|
// release power management lock
|
||||||
if (tx_unit->pm_lock) {
|
if (tx_unit->pm_lock) {
|
||||||
esp_pm_lock_release(tx_unit->pm_lock);
|
esp_pm_lock_release(tx_unit->pm_lock);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// finally we switch to the INIT state
|
// finally we switch to the INIT state
|
||||||
atomic_store(&tx_unit->fsm, PARLIO_TX_FSM_INIT);
|
atomic_store(&tx_unit->fsm, PARLIO_TX_FSM_INIT);
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
const parlio_signal_conn_t parlio_periph_signals = {
|
const parlio_signal_conn_t parlio_periph_signals = {
|
||||||
.groups = {
|
.groups = {
|
||||||
[0] = {
|
[0] = {
|
||||||
|
.module_name = "PARLIO0",
|
||||||
.module = PERIPH_PARLIO_MODULE,
|
.module = PERIPH_PARLIO_MODULE,
|
||||||
.tx_irq_id = ETS_PARL_IO_TX_INTR_SOURCE,
|
.tx_irq_id = ETS_PARL_IO_TX_INTR_SOURCE,
|
||||||
.rx_irq_id = ETS_PARL_IO_RX_INTR_SOURCE,
|
.rx_irq_id = ETS_PARL_IO_RX_INTR_SOURCE,
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
const parlio_signal_conn_t parlio_periph_signals = {
|
const parlio_signal_conn_t parlio_periph_signals = {
|
||||||
.groups = {
|
.groups = {
|
||||||
[0] = {
|
[0] = {
|
||||||
|
.module_name = "PARLIO0",
|
||||||
.module = PERIPH_PARLIO_MODULE,
|
.module = PERIPH_PARLIO_MODULE,
|
||||||
.tx_irq_id = ETS_PARL_IO_INTR_SOURCE,
|
.tx_irq_id = ETS_PARL_IO_INTR_SOURCE,
|
||||||
.rx_irq_id = ETS_PARL_IO_INTR_SOURCE,
|
.rx_irq_id = ETS_PARL_IO_INTR_SOURCE,
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
const parlio_signal_conn_t parlio_periph_signals = {
|
const parlio_signal_conn_t parlio_periph_signals = {
|
||||||
.groups = {
|
.groups = {
|
||||||
[0] = {
|
[0] = {
|
||||||
|
.module_name = "PARLIO0",
|
||||||
.module = PERIPH_PARLIO_MODULE,
|
.module = PERIPH_PARLIO_MODULE,
|
||||||
.tx_irq_id = ETS_PARL_IO_TX_INTR_SOURCE,
|
.tx_irq_id = ETS_PARL_IO_TX_INTR_SOURCE,
|
||||||
.rx_irq_id = ETS_PARL_IO_RX_INTR_SOURCE,
|
.rx_irq_id = ETS_PARL_IO_RX_INTR_SOURCE,
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
const parlio_signal_conn_t parlio_periph_signals = {
|
const parlio_signal_conn_t parlio_periph_signals = {
|
||||||
.groups = {
|
.groups = {
|
||||||
[0] = {
|
[0] = {
|
||||||
|
.module_name = "PARLIO0",
|
||||||
.module = PERIPH_PARLIO_MODULE,
|
.module = PERIPH_PARLIO_MODULE,
|
||||||
.tx_irq_id = ETS_HP_PARLIO_TX_INTR_SOURCE,
|
.tx_irq_id = ETS_HP_PARLIO_TX_INTR_SOURCE,
|
||||||
.rx_irq_id = ETS_HP_PARLIO_RX_INTR_SOURCE,
|
.rx_irq_id = ETS_HP_PARLIO_RX_INTR_SOURCE,
|
||||||
|
@@ -39,6 +39,7 @@ typedef struct {
|
|||||||
const int tx_irq_id;
|
const int tx_irq_id;
|
||||||
const int rx_irq_id;
|
const int rx_irq_id;
|
||||||
const periph_module_t module;
|
const periph_module_t module;
|
||||||
|
const char *module_name;
|
||||||
} groups[SOC_PARLIO_GROUPS];
|
} groups[SOC_PARLIO_GROUPS];
|
||||||
} parlio_signal_conn_t;
|
} parlio_signal_conn_t;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user