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

This commit is contained in:
Chen Jichang
2025-05-16 19:07:33 +08:00
parent 5599fd4b1f
commit fe1091c2ff
6 changed files with 46 additions and 2 deletions

View File

@ -143,10 +143,12 @@ esp_err_t esp_lcd_del_dsi_bus(esp_lcd_dsi_bus_handle_t bus)
DSI_RCC_ATOMIC() {
mipi_dsi_ll_enable_bus_clock(bus_id, false);
}
#if CONFIG_PM_ENABLE
if (bus->pm_lock) {
esp_pm_lock_release(bus->pm_lock);
esp_pm_lock_delete(bus->pm_lock);
}
#endif
free(bus);
return ESP_OK;
}

View File

@ -47,7 +47,9 @@ struct esp_lcd_dpi_panel_t {
dw_gdma_link_list_handle_t link_lists[DPI_PANEL_MAX_FB_NUM]; // DMA link list
esp_async_fbcpy_handle_t fbcpy_handle; // Use DMA2D to do frame buffer copy
SemaphoreHandle_t draw_sem; // A semaphore used to synchronize the draw operations when DMA2D is used
#if CONFIG_PM_ENABLE
esp_pm_lock_handle_t pm_lock; // Power management lock
#endif
esp_lcd_dpi_panel_color_trans_done_cb_t on_color_trans_done; // Callback invoked when color data transfer has finished
esp_lcd_dpi_panel_refresh_done_cb_t on_refresh_done; // Callback invoked when one refresh operation finished (kinda like a vsync end)
void *user_ctx; // User context for the callback
@ -375,10 +377,12 @@ static esp_err_t dpi_panel_del(esp_lcd_panel_t *panel)
if (dpi_panel->draw_sem) {
vSemaphoreDeleteWithCaps(dpi_panel->draw_sem);
}
#if CONFIG_PM_ENABLE
if (dpi_panel->pm_lock) {
esp_pm_lock_release(dpi_panel->pm_lock);
esp_pm_lock_delete(dpi_panel->pm_lock);
}
#endif
free(dpi_panel);
return ESP_OK;
}

View File

@ -39,7 +39,9 @@ extern "C" {
typedef struct esp_lcd_dsi_bus_t {
int bus_id;
mipi_dsi_hal_context_t hal;
#if CONFIG_PM_ENABLE
esp_pm_lock_handle_t pm_lock;
#endif
} esp_lcd_dsi_bus_t;
#ifdef __cplusplus

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -71,7 +71,9 @@ struct esp_lcd_i80_bus_t {
int dc_gpio_num; // GPIO used for DC line
int wr_gpio_num; // GPIO used for WR line
intr_handle_t intr; // LCD peripheral interrupt handle
#if CONFIG_PM_ENABLE
esp_pm_lock_handle_t pm_lock; // lock APB frequency when necessary
#endif
size_t max_transfer_bytes; // Maximum number of bytes that can be transferred in one transaction
gdma_link_list_handle_t dma_link; // DMA link list handle
uint8_t *format_buffer;// The driver allocates an internal buffer for DMA to do data format transformer
@ -235,9 +237,11 @@ err:
if (bus->format_buffer) {
free(bus->format_buffer);
}
#if CONFIG_PM_ENABLE
if (bus->pm_lock) {
esp_pm_lock_delete(bus->pm_lock);
}
#endif
free(bus);
}
return ret;
@ -251,9 +255,11 @@ esp_err_t esp_lcd_del_i80_bus(esp_lcd_i80_bus_handle_t bus)
int bus_id = bus->bus_id;
i2s_platform_release_occupation(I2S_CTLR_HP, bus_id);
esp_intr_free(bus->intr);
#if CONFIG_PM_ENABLE
if (bus->pm_lock) {
esp_pm_lock_delete(bus->pm_lock);
}
#endif
free(bus->format_buffer);
gdma_del_link_list(bus->dma_link);
free(bus);
@ -550,10 +556,12 @@ static esp_err_t panel_io_i80_tx_param(esp_lcd_panel_io_t *io, int lcd_cmd, cons
// delay a while, wait for DMA data being feed to I2S FIFO
// in fact, this is only needed when LCD pixel clock is set too high
esp_rom_delay_us(1);
#if CONFIG_PM_ENABLE
// increase the pm lock reference count before starting a new transaction
if (bus->pm_lock) {
esp_pm_lock_acquire(bus->pm_lock);
}
#endif
i2s_ll_tx_start(bus->hal.dev);
// polling the trans done event
while (!(i2s_ll_get_intr_status(bus->hal.dev) & I2S_LL_EVENT_TX_EOF)) {}
@ -574,10 +582,12 @@ static esp_err_t panel_io_i80_tx_param(esp_lcd_panel_io_t *io, int lcd_cmd, cons
// polling the trans done event, but don't clear the event status
while (!(i2s_ll_get_intr_status(bus->hal.dev) & I2S_LL_EVENT_TX_EOF)) {}
}
#if CONFIG_PM_ENABLE
// decrease pm lock reference count
if (bus->pm_lock) {
esp_pm_lock_release(bus->pm_lock);
}
#endif
bus->cur_trans = NULL;
return ESP_OK;
}
@ -624,17 +634,21 @@ static esp_err_t panel_io_i80_tx_color(esp_lcd_panel_io_t *io, int lcd_cmd, cons
i2s_ll_tx_reset(bus->hal.dev); // reset TX engine first
i2s_ll_start_out_link(bus->hal.dev);
esp_rom_delay_us(1);
#if CONFIG_PM_ENABLE
// increase the pm lock reference count before starting a new transaction
if (bus->pm_lock) {
esp_pm_lock_acquire(bus->pm_lock);
}
#endif
i2s_ll_tx_start(bus->hal.dev);
// polling the trans done event
while (!(i2s_ll_get_intr_status(bus->hal.dev) & I2S_LL_EVENT_TX_EOF)) {}
#if CONFIG_PM_ENABLE
// decrease pm lock reference count
if (bus->pm_lock) {
esp_pm_lock_release(bus->pm_lock);
}
#endif
bus->cur_trans = NULL;
// sending LCD color data to queue
@ -770,10 +784,12 @@ static IRAM_ATTR void i2s_lcd_default_isr_handler(void *args)
// process finished transaction
if (trans_desc) {
assert(trans_desc->i80_device == cur_device && "transaction device mismatch");
#if CONFIG_PM_ENABLE
// decrease pm lock reference count
if (bus->pm_lock) {
esp_pm_lock_release(bus->pm_lock);
}
#endif
// device callback
if (trans_desc->trans_done_cb) {
if (trans_desc->trans_done_cb(&cur_device->base, NULL, trans_desc->user_ctx)) {
@ -824,10 +840,12 @@ static IRAM_ATTR void i2s_lcd_default_isr_handler(void *args)
i2s_ll_tx_reset(bus->hal.dev); // reset TX engine first
i2s_ll_start_out_link(bus->hal.dev);
esp_rom_delay_us(1);
#if CONFIG_PM_ENABLE
// increase the pm lock reference count before starting a new transaction
if (bus->pm_lock) {
esp_pm_lock_acquire(bus->pm_lock);
}
#endif
i2s_ll_tx_start(bus->hal.dev);
break; // exit for-each loop
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -84,7 +84,9 @@ struct esp_lcd_i80_bus_t {
lcd_hal_context_t hal; // Hal object
size_t bus_width; // Number of data lines
intr_handle_t intr; // LCD peripheral interrupt handle
#if CONFIG_PM_ENABLE
esp_pm_lock_handle_t pm_lock; // Power management lock
#endif
uint8_t *format_buffer; // The driver allocates an internal buffer for DMA to do data format transformer
uint8_t *format_buffer_nc; // Non-cacheable version of format buffer
size_t resolution_hz; // LCD_CLK resolution, determined by selected clock source
@ -251,9 +253,11 @@ err:
if (bus->format_buffer) {
free(bus->format_buffer);
}
#if CONFIG_PM_ENABLE
if (bus->pm_lock) {
esp_pm_lock_delete(bus->pm_lock);
}
#endif
free(bus);
}
return ret;
@ -275,9 +279,11 @@ esp_err_t esp_lcd_del_i80_bus(esp_lcd_i80_bus_handle_t bus)
gdma_del_channel(bus->dma_chan);
esp_intr_free(bus->intr);
free(bus->format_buffer);
#if CONFIG_PM_ENABLE
if (bus->pm_lock) {
esp_pm_lock_delete(bus->pm_lock);
}
#endif
gdma_del_link_list(bus->dma_link);
free(bus);
ESP_LOGD(TAG, "del i80 bus(%d)", bus_id);
@ -497,17 +503,21 @@ static esp_err_t panel_io_i80_tx_param(esp_lcd_panel_io_t *io, int lcd_cmd, cons
}
};
gdma_link_mount_buffers(bus->dma_link, 0, &mount_config, 1, NULL);
#if CONFIG_PM_ENABLE
// increase the pm lock reference count before starting a new transaction
if (bus->pm_lock) {
esp_pm_lock_acquire(bus->pm_lock);
}
#endif
lcd_start_transaction(bus, trans_desc);
// polling the trans done event, but don't clear the event status
while (!(lcd_ll_get_interrupt_status(bus->hal.dev) & LCD_LL_EVENT_TRANS_DONE)) {}
#if CONFIG_PM_ENABLE
// decrease pm lock reference count
if (bus->pm_lock) {
esp_pm_lock_release(bus->pm_lock);
}
#endif
return ESP_OK;
}
@ -752,10 +762,12 @@ IRAM_ATTR static void i80_lcd_default_isr_handler(void *args)
// process finished transaction
if (trans_desc) {
assert(trans_desc->i80_device == cur_device && "transaction device mismatch");
#if CONFIG_PM_ENABLE
// decrease pm lock reference count
if (bus->pm_lock) {
esp_pm_lock_release(bus->pm_lock);
}
#endif
// device callback
if (trans_desc->trans_done_cb) {
if (trans_desc->trans_done_cb(&cur_device->base, NULL, trans_desc->user_ctx)) {
@ -802,10 +814,12 @@ IRAM_ATTR static void i80_lcd_default_isr_handler(void *args)
gdma_link_mount_buffers(bus->dma_link, 0, &mount_config, 1, NULL);
// enable interrupt again, because the new transaction can trigger new trans done event
esp_intr_enable(bus->intr);
#if CONFIG_PM_ENABLE
// increase the pm lock reference count before starting a new transaction
if (bus->pm_lock) {
esp_pm_lock_acquire(bus->pm_lock);
}
#endif
lcd_start_transaction(bus, trans_desc);
break; // exit for-each loop
}

View File

@ -104,7 +104,9 @@ struct esp_rgb_panel_t {
size_t dma_burst_size; // DMA transfer burst size
int disp_gpio_num; // Display control GPIO, which is used to perform action like "disp_off"
intr_handle_t intr; // LCD peripheral interrupt handle
#if CONFIG_PM_ENABLE
esp_pm_lock_handle_t pm_lock; // Power management lock
#endif
size_t num_dma_nodes; // Number of DMA descriptors that used to carry the frame buffer
gdma_channel_handle_t dma_chan; // DMA channel handle
gdma_link_list_handle_t dma_fb_links[RGB_LCD_PANEL_MAX_FB_NUM]; // DMA link lists for multiple frame buffers
@ -235,10 +237,12 @@ static esp_err_t lcd_rgb_panel_destroy(esp_rgb_panel_t *rgb_panel)
if (rgb_panel->intr) {
esp_intr_free(rgb_panel->intr);
}
#if CONFIG_PM_ENABLE
if (rgb_panel->pm_lock) {
esp_pm_lock_release(rgb_panel->pm_lock);
esp_pm_lock_delete(rgb_panel->pm_lock);
}
#endif
free(rgb_panel);
return ESP_OK;
}