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 9ecab59f6d..1447a122a7 100644 --- a/components/esp_lcd/dsi/esp_lcd_mipi_dsi_bus.c +++ b/components/esp_lcd/dsi/esp_lcd_mipi_dsi_bus.c @@ -55,6 +55,15 @@ esp_err_t esp_lcd_new_dsi_bus(const esp_lcd_dsi_bus_config_t *bus_config, esp_lc mipi_dsi_ll_enable_phy_reference_clock(bus_id, true); } +#if CONFIG_PM_ENABLE + // When MIPI DSI is working, we don't expect the clock source would be turned off + esp_pm_lock_type_t pm_lock_type = ESP_PM_NO_LIGHT_SLEEP; + ret = esp_pm_lock_create(pm_lock_type, 0, "dsi_phy", &dsi_bus->pm_lock); + ESP_GOTO_ON_ERROR(ret, err, TAG, "create PM lock failed"); + // before we configure the PLL, we want the clock source to be stable + esp_pm_lock_acquire(dsi_bus->pm_lock); +#endif + // initialize HAL context mipi_dsi_hal_config_t hal_config = { .bus_id = bus_id, @@ -125,6 +134,10 @@ 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 (bus->pm_lock) { + esp_pm_lock_release(bus->pm_lock); + esp_pm_lock_delete(bus->pm_lock); + } 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 9c70792029..3eed7e6b34 100644 --- a/components/esp_lcd/dsi/esp_lcd_panel_dpi.c +++ b/components/esp_lcd/dsi/esp_lcd_panel_dpi.c @@ -42,6 +42,7 @@ 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 + esp_pm_lock_handle_t pm_lock; // Power management lock 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 @@ -232,6 +233,14 @@ esp_err_t esp_lcd_new_panel_dpi(esp_lcd_dsi_bus_handle_t bus, const esp_lcd_dpi_ mipi_dsi_ll_enable_dpi_clock(bus_id, true); } +#if CONFIG_PM_ENABLE + // When MIPI DSI is working, we don't expect the clock source would be turned off + esp_pm_lock_type_t pm_lock_type = ESP_PM_NO_LIGHT_SLEEP; + ret = esp_pm_lock_create(pm_lock_type, 0, "dsi_dpi", &dpi_panel->pm_lock); + ESP_GOTO_ON_ERROR(ret, err, TAG, "create PM lock failed"); + esp_pm_lock_acquire(dpi_panel->pm_lock); +#endif + // create DMA resources ESP_GOTO_ON_ERROR(dpi_panel_create_dma_link(dpi_panel), err, TAG, "initialize DMA link failed"); @@ -318,6 +327,10 @@ static esp_err_t dpi_panel_del(esp_lcd_panel_t *panel) if (dpi_panel->draw_sem) { vSemaphoreDelete(dpi_panel->draw_sem); } + if (dpi_panel->pm_lock) { + esp_pm_lock_release(dpi_panel->pm_lock); + esp_pm_lock_delete(dpi_panel->pm_lock); + } 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 cdf89e30e3..57a7407864 100644 --- a/components/esp_lcd/dsi/mipi_dsi_priv.h +++ b/components/esp_lcd/dsi/mipi_dsi_priv.h @@ -9,6 +9,7 @@ #include "hal/mipi_dsi_ll.h" #include "esp_heap_caps.h" #include "esp_private/periph_ctrl.h" +#include "esp_pm.h" #if SOC_PERIPH_CLK_CTRL_SHARED #define DSI_CLOCK_SRC_ATOMIC() PERIPH_RCC_ATOMIC() @@ -35,6 +36,7 @@ extern "C" { typedef struct esp_lcd_dsi_bus_t { int bus_id; mipi_dsi_hal_context_t hal; + esp_pm_lock_handle_t pm_lock; } esp_lcd_dsi_bus_t; #ifdef __cplusplus diff --git a/components/esp_lcd/test_apps/mipi_dsi_lcd/sdkconfig.ci.release b/components/esp_lcd/test_apps/mipi_dsi_lcd/sdkconfig.ci.release new file mode 100644 index 0000000000..91d93f163e --- /dev/null +++ b/components/esp_lcd/test_apps/mipi_dsi_lcd/sdkconfig.ci.release @@ -0,0 +1,5 @@ +CONFIG_PM_ENABLE=y +CONFIG_FREERTOS_USE_TICKLESS_IDLE=y +CONFIG_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y +CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y