From ce0316df99dc3603d61282b0d1267f8f8d9272b5 Mon Sep 17 00:00:00 2001 From: morris Date: Thu, 9 Feb 2023 12:03:39 +0800 Subject: [PATCH] lcd: support PLL240M as i80 clock source on esp32s3 --- components/esp_lcd/src/esp_lcd_panel_io_i2s.c | 13 +++++++------ components/esp_lcd/src/esp_lcd_panel_io_i80.c | 18 ++++++++++++------ components/esp_lcd/src/esp_lcd_panel_rgb.c | 16 ++++++++-------- .../test_apps/i2c_lcd/sdkconfig.defaults | 5 ++++- .../test_apps/i80_lcd/sdkconfig.defaults | 5 ++++- .../test_apps/rgb_lcd/sdkconfig.defaults | 5 ++++- .../test_apps/spi_lcd/sdkconfig.defaults | 5 ++++- .../soc/esp32/include/soc/clk_tree_defs.h | 10 ++++------ .../soc/esp32s2/include/soc/clk_tree_defs.h | 6 ++---- 9 files changed, 49 insertions(+), 34 deletions(-) diff --git a/components/esp_lcd/src/esp_lcd_panel_io_i2s.c b/components/esp_lcd/src/esp_lcd_panel_io_i2s.c index 24f0c57397..4550915e13 100644 --- a/components/esp_lcd/src/esp_lcd_panel_io_i2s.c +++ b/components/esp_lcd/src/esp_lcd_panel_io_i2s.c @@ -348,7 +348,7 @@ static esp_err_t panel_io_i80_register_event_callbacks(esp_lcd_panel_io_handle_t { lcd_panel_io_i80_t *i80_device = __containerof(io, lcd_panel_io_i80_t, base); - if(i80_device->on_color_trans_done != NULL) { + if (i80_device->on_color_trans_done != NULL) { ESP_LOGW(TAG, "Callback on_color_trans_done was already set and now it was owerwritten!"); } @@ -610,17 +610,18 @@ static esp_err_t i2s_lcd_select_periph_clock(esp_lcd_i80_bus_handle_t bus, lcd_c case LCD_CLK_SRC_PLL160M: bus->resolution_hz = 160000000 / LCD_PERIPH_CLOCK_PRE_SCALE; i2s_ll_tx_clk_set_src(bus->hal.dev, I2S_CLK_SRC_PLL_160M); -#if CONFIG_PM_ENABLE - ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "i2s_controller_lcd", &bus->pm_lock); - ESP_RETURN_ON_ERROR(ret, TAG, "create ESP_PM_APB_FREQ_MAX lock failed"); - ESP_LOGD(TAG, "installed ESP_PM_APB_FREQ_MAX lock"); -#endif break; default: ESP_RETURN_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, TAG, "unsupported clock source: %d", src); break; } i2s_ll_set_raw_mclk_div(bus->hal.dev, LCD_PERIPH_CLOCK_PRE_SCALE, 1, 0); + +#if CONFIG_PM_ENABLE + ret = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "i2s_controller_lcd", &bus->pm_lock); + ESP_RETURN_ON_ERROR(ret, TAG, "create pm lock failed"); + ESP_LOGD(TAG, "installed pm lock"); +#endif return ret; } diff --git a/components/esp_lcd/src/esp_lcd_panel_io_i80.c b/components/esp_lcd/src/esp_lcd_panel_io_i80.c index eee30dd27a..12903144a4 100644 --- a/components/esp_lcd/src/esp_lcd_panel_io_i80.c +++ b/components/esp_lcd/src/esp_lcd_panel_io_i80.c @@ -339,7 +339,7 @@ static esp_err_t panel_io_i80_register_event_callbacks(esp_lcd_panel_io_handle_t { lcd_panel_io_i80_t *i80_device = __containerof(io, lcd_panel_io_i80_t, base); - if(i80_device->on_color_trans_done != NULL) { + if (i80_device->on_color_trans_done != NULL) { ESP_LOGW(TAG, "Callback on_color_trans_done was already set and now it was owerwritten!"); } @@ -493,11 +493,9 @@ static esp_err_t lcd_i80_select_periph_clock(esp_lcd_i80_bus_handle_t bus, lcd_c switch (clk_src) { case LCD_CLK_SRC_PLL160M: bus->resolution_hz = 160000000 / LCD_PERIPH_CLOCK_PRE_SCALE; -#if CONFIG_PM_ENABLE - ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "i80_bus_lcd", &bus->pm_lock); - ESP_RETURN_ON_ERROR(ret, TAG, "create ESP_PM_APB_FREQ_MAX lock failed"); - ESP_LOGD(TAG, "installed ESP_PM_APB_FREQ_MAX lock"); -#endif + break; + case LCD_CLK_SRC_PLL240M: + bus->resolution_hz = 240000000 / LCD_PERIPH_CLOCK_PRE_SCALE; break; case LCD_CLK_SRC_XTAL: bus->resolution_hz = esp_clk_xtal_freq() / LCD_PERIPH_CLOCK_PRE_SCALE; @@ -506,6 +504,14 @@ static esp_err_t lcd_i80_select_periph_clock(esp_lcd_i80_bus_handle_t bus, lcd_c ESP_RETURN_ON_FALSE(false, ESP_ERR_NOT_SUPPORTED, TAG, "unsupported clock source: %d", clk_src); break; } + + // create pm lock based on different clock source + // clock sources like PLL and XTAL will be turned off in light sleep +#if CONFIG_PM_ENABLE + ret = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "i80_bus_lcd", &bus->pm_lock); + ESP_RETURN_ON_ERROR(ret, TAG, "create pm lock failed"); + ESP_LOGD(TAG, "installed pm lock"); +#endif return ret; } diff --git a/components/esp_lcd/src/esp_lcd_panel_rgb.c b/components/esp_lcd/src/esp_lcd_panel_rgb.c index c8dd1d9fea..48a31ecc38 100644 --- a/components/esp_lcd/src/esp_lcd_panel_rgb.c +++ b/components/esp_lcd/src/esp_lcd_panel_rgb.c @@ -114,7 +114,7 @@ struct esp_rgb_panel_t { int y_gap; // Extra gap in y coordinate, it's used when calculate the flush window portMUX_TYPE spinlock; // to protect panel specific resource from concurrent access (e.g. between task and ISR) int lcd_clk_flags; // LCD clock calculation flags - int rotate_mask; // panel rotate_mask mask, Or'ed of `panel_rotate_mask_t` + int rotate_mask; // panel rotate_mask mask, Or'ed of `panel_rotate_mask_t` struct { uint32_t disp_en_level: 1; // The level which can turn on the screen by `disp_gpio_num` uint32_t stream_mode: 1; // If set, the LCD transfers data continuously, otherwise, it stops refreshing the LCD when transaction done @@ -936,15 +936,15 @@ static esp_err_t lcd_rgb_panel_select_clock_src(esp_rgb_panel_t *panel, lcd_cloc } lcd_ll_select_clk_src(panel->hal.dev, clk_src); - if (clk_src == LCD_CLK_SRC_PLL240M || clk_src == LCD_CLK_SRC_PLL160M) { + // create pm lock based on different clock source + // clock sources like PLL and XTAL will be turned off in light sleep #if CONFIG_PM_ENABLE - ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "rgb_panel", &panel->pm_lock); - ESP_RETURN_ON_ERROR(ret, TAG, "create ESP_PM_APB_FREQ_MAX lock failed"); - // hold the lock during the whole lifecycle of RGB panel - esp_pm_lock_acquire(panel->pm_lock); - ESP_LOGD(TAG, "installed ESP_PM_APB_FREQ_MAX lock and hold the lock during the whole panel lifecycle"); + ret = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "rgb_panel", &panel->pm_lock); + ESP_RETURN_ON_ERROR(ret, TAG, "create pm lock failed"); + // hold the lock during the whole lifecycle of RGB panel + esp_pm_lock_acquire(panel->pm_lock); + ESP_LOGD(TAG, "installed pm lock and hold the lock during the whole panel lifecycle"); #endif - } return ret; } diff --git a/components/esp_lcd/test_apps/i2c_lcd/sdkconfig.defaults b/components/esp_lcd/test_apps/i2c_lcd/sdkconfig.defaults index b308cb2ddd..ccc43c6fdf 100644 --- a/components/esp_lcd/test_apps/i2c_lcd/sdkconfig.defaults +++ b/components/esp_lcd/test_apps/i2c_lcd/sdkconfig.defaults @@ -1,2 +1,5 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration +# +# CONFIG_ESP_TASK_WDT_INIT is not set CONFIG_FREERTOS_HZ=1000 -CONFIG_ESP_TASK_WDT=n diff --git a/components/esp_lcd/test_apps/i80_lcd/sdkconfig.defaults b/components/esp_lcd/test_apps/i80_lcd/sdkconfig.defaults index b308cb2ddd..ccc43c6fdf 100644 --- a/components/esp_lcd/test_apps/i80_lcd/sdkconfig.defaults +++ b/components/esp_lcd/test_apps/i80_lcd/sdkconfig.defaults @@ -1,2 +1,5 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration +# +# CONFIG_ESP_TASK_WDT_INIT is not set CONFIG_FREERTOS_HZ=1000 -CONFIG_ESP_TASK_WDT=n diff --git a/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.defaults b/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.defaults index b308cb2ddd..ccc43c6fdf 100644 --- a/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.defaults +++ b/components/esp_lcd/test_apps/rgb_lcd/sdkconfig.defaults @@ -1,2 +1,5 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration +# +# CONFIG_ESP_TASK_WDT_INIT is not set CONFIG_FREERTOS_HZ=1000 -CONFIG_ESP_TASK_WDT=n diff --git a/components/esp_lcd/test_apps/spi_lcd/sdkconfig.defaults b/components/esp_lcd/test_apps/spi_lcd/sdkconfig.defaults index b308cb2ddd..ccc43c6fdf 100644 --- a/components/esp_lcd/test_apps/spi_lcd/sdkconfig.defaults +++ b/components/esp_lcd/test_apps/spi_lcd/sdkconfig.defaults @@ -1,2 +1,5 @@ +# This file was generated using idf.py save-defconfig. It can be edited manually. +# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration +# +# CONFIG_ESP_TASK_WDT_INIT is not set CONFIG_FREERTOS_HZ=1000 -CONFIG_ESP_TASK_WDT=n diff --git a/components/soc/esp32/include/soc/clk_tree_defs.h b/components/soc/esp32/include/soc/clk_tree_defs.h index 89e8b06c6b..5dbe4f974e 100644 --- a/components/soc/esp32/include/soc/clk_tree_defs.h +++ b/components/soc/esp32/include/soc/clk_tree_defs.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -155,16 +155,14 @@ typedef enum { /** * @brief Array initializer for all supported clock sources of LCD */ -#define SOC_LCD_CLKS {SOC_MOD_CLK_PLL_D2, SOC_MOD_CLK_APLL, SOC_MOD_CLK_XTAL} +#define SOC_LCD_CLKS {SOC_MOD_CLK_PLL_F160M} /** * @brief Type of LCD clock source */ typedef enum { - LCD_CLK_SRC_PLL160M = SOC_MOD_CLK_PLL_D2, /*!< Select PLL_D2 (default to 160MHz) as the source clock */ - LCD_CLK_SRC_APLL = SOC_MOD_CLK_APLL, /*!< Select APLL as the source clock */ - LCD_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ - LCD_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_D2, /*!< Select PLL_D2 (default to 160MHz) as the default choice */ + LCD_CLK_SRC_PLL160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_160M as the source clock */ + LCD_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_160M as the default choice */ } soc_periph_lcd_clk_src_t; //////////////////////////////////////////////////RMT/////////////////////////////////////////////////////////////////// diff --git a/components/soc/esp32s2/include/soc/clk_tree_defs.h b/components/soc/esp32s2/include/soc/clk_tree_defs.h index ff2f9ae4df..7d00962230 100644 --- a/components/soc/esp32s2/include/soc/clk_tree_defs.h +++ b/components/soc/esp32s2/include/soc/clk_tree_defs.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -155,15 +155,13 @@ typedef enum { /** * @brief Array initializer for all supported clock sources of LCD */ -#define SOC_LCD_CLKS {SOC_MOD_CLK_PLL_F160M, SOC_MOD_CLK_APLL, SOC_MOD_CLK_XTAL} +#define SOC_LCD_CLKS {SOC_MOD_CLK_PLL_F160M} /** * @brief Type of LCD clock source */ typedef enum { LCD_CLK_SRC_PLL160M = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the source clock */ - LCD_CLK_SRC_APLL = SOC_MOD_CLK_APLL, /*!< Select APLL as the source clock */ - LCD_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ LCD_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F160M, /*!< Select PLL_F160M as the default choice */ } soc_periph_lcd_clk_src_t;