diff --git a/components/esp_lcd/dsi/esp_lcd_mipi_dsi_bus.c b/components/esp_lcd/dsi/esp_lcd_mipi_dsi_bus.c index 8fa35c55dc..90af97617a 100644 --- a/components/esp_lcd/dsi/esp_lcd_mipi_dsi_bus.c +++ b/components/esp_lcd/dsi/esp_lcd_mipi_dsi_bus.c @@ -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; } diff --git a/components/esp_lcd/dsi/esp_lcd_panel_dpi.c b/components/esp_lcd/dsi/esp_lcd_panel_dpi.c index 8372bdd197..f6d307a6a0 100644 --- a/components/esp_lcd/dsi/esp_lcd_panel_dpi.c +++ b/components/esp_lcd/dsi/esp_lcd_panel_dpi.c @@ -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; } diff --git a/components/esp_lcd/dsi/mipi_dsi_priv.h b/components/esp_lcd/dsi/mipi_dsi_priv.h index bb6fd2fe63..7014cd2422 100644 --- a/components/esp_lcd/dsi/mipi_dsi_priv.h +++ b/components/esp_lcd/dsi/mipi_dsi_priv.h @@ -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 diff --git a/components/esp_lcd/i80/esp_lcd_panel_io_i2s.c b/components/esp_lcd/i80/esp_lcd_panel_io_i2s.c index 730aa7e685..3e6d7da801 100644 --- a/components/esp_lcd/i80/esp_lcd_panel_io_i2s.c +++ b/components/esp_lcd/i80/esp_lcd_panel_io_i2s.c @@ -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 } diff --git a/components/esp_lcd/i80/esp_lcd_panel_io_i80.c b/components/esp_lcd/i80/esp_lcd_panel_io_i80.c index 2e37f4f05e..35a14a0ba5 100644 --- a/components/esp_lcd/i80/esp_lcd_panel_io_i80.c +++ b/components/esp_lcd/i80/esp_lcd_panel_io_i80.c @@ -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 } diff --git a/components/esp_lcd/rgb/esp_lcd_panel_rgb.c b/components/esp_lcd/rgb/esp_lcd_panel_rgb.c index 72df1e8266..dc5b5e52b0 100644 --- a/components/esp_lcd/rgb/esp_lcd_panel_rgb.c +++ b/components/esp_lcd/rgb/esp_lcd_panel_rgb.c @@ -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; }