mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
refactor(lcdcam): move shared core clock setup to drivers
Configure the shared LCDCAM core clock through guarded LCD and CAM LL APIs, and unify LCD functional clock LL calls around group IDs across supported targets. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -125,7 +125,7 @@ esp_err_t esp_lcd_new_i80_bus(const esp_lcd_i80_bus_config_t *bus_config, esp_lc
|
||||
esp_err_t ret = ESP_OK;
|
||||
esp_lcd_i80_bus_t *bus = NULL;
|
||||
#if CONFIG_IDF_TARGET_ESP32S31
|
||||
bool pll_f120m_enabled = false;
|
||||
bool core_clk_enabled = false;
|
||||
#endif
|
||||
ESP_RETURN_ON_FALSE(bus_config && ret_bus, ESP_ERR_INVALID_ARG, TAG, "invalid argument");
|
||||
// although LCD_CAM can support up to 24 data lines, we restrict users to only use 8 or 16 bit width
|
||||
@@ -163,6 +163,10 @@ esp_err_t esp_lcd_new_i80_bus(const esp_lcd_i80_bus_config_t *bus_config, esp_lc
|
||||
if (ref_count == 0) {
|
||||
lcd_ll_enable_bus_clock(bus_id, true);
|
||||
lcd_ll_reset_register(bus_id);
|
||||
#if CONFIG_IDF_TARGET_ESP32S31
|
||||
lcd_ll_select_core_clk_src(bus_id, LCD_CORE_CLK_SRC_DEFAULT);
|
||||
lcd_ll_set_core_clock_divider(bus_id, 2, 0, 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#if I80_USE_RETENTION_LINK
|
||||
@@ -189,9 +193,8 @@ esp_err_t esp_lcd_new_i80_bus(const esp_lcd_i80_bus_config_t *bus_config, esp_lc
|
||||
// initialize HAL layer, so we can call LL APIs later
|
||||
lcd_hal_init(&bus->hal, bus_id);
|
||||
#if CONFIG_IDF_TARGET_ESP32S31
|
||||
// PLL 120M was selected in esp_perip_clk_init on esp32s31.
|
||||
ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)SOC_MOD_CLK_PLL_F120M, true), err, TAG, "clock source enable failed");
|
||||
pll_f120m_enabled = true;
|
||||
ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)LCD_CORE_CLK_SRC_DEFAULT, true), err, TAG, "core clock source enable failed");
|
||||
core_clk_enabled = true;
|
||||
#endif
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
lcd_ll_enable_clock(bus->hal.dev, true);
|
||||
@@ -277,8 +280,8 @@ err:
|
||||
bus->clk_src = SOC_MOD_CLK_INVALID;
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ESP32S31
|
||||
if (pll_f120m_enabled) {
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)SOC_MOD_CLK_PLL_F120M, false);
|
||||
if (core_clk_enabled) {
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)LCD_CORE_CLK_SRC_DEFAULT, false);
|
||||
}
|
||||
#endif
|
||||
#if CONFIG_PM_ENABLE
|
||||
@@ -305,7 +308,7 @@ esp_err_t esp_lcd_del_i80_bus(esp_lcd_i80_bus_handle_t bus)
|
||||
bus->clk_src = SOC_MOD_CLK_INVALID;
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ESP32S31
|
||||
ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)SOC_MOD_CLK_PLL_F120M, false), err, TAG, "clock source disable failed");
|
||||
ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)LCD_CORE_CLK_SRC_DEFAULT, false), err, TAG, "core clock source disable failed");
|
||||
#endif
|
||||
#if I80_USE_RETENTION_LINK
|
||||
const periph_retention_module_t module_id = lcd_i80_reg_retention_info[bus_id].retention_module;
|
||||
@@ -667,9 +670,9 @@ static esp_err_t lcd_i80_select_periph_clock(esp_lcd_i80_bus_handle_t bus, lcd_c
|
||||
ESP_RETURN_ON_ERROR(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)clk_src, ESP_CLK_TREE_SRC_FREQ_PRECISION_CACHED, &src_clk_hz),
|
||||
TAG, "get clock source frequency failed");
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
lcd_ll_select_clk_src(bus->hal.dev, clk_src);
|
||||
lcd_ll_select_clk_src(bus->bus_id, clk_src);
|
||||
// force to use integer division, as fractional division might lead to clock jitter
|
||||
lcd_ll_set_group_clock_coeff(bus->hal.dev, LCD_PERIPH_CLOCK_PRE_SCALE, 0, 0);
|
||||
lcd_ll_set_group_clock_coeff(bus->bus_id, LCD_PERIPH_CLOCK_PRE_SCALE, 0, 0);
|
||||
}
|
||||
|
||||
// save the resolution of the i80 bus
|
||||
|
||||
@@ -170,9 +170,7 @@ struct esp_rgb_panel_t {
|
||||
uint32_t fb_behind_cache: 1; // Whether the frame buffer is behind the cache
|
||||
uint32_t bb_behind_cache: 1; // Whether the bounce buffer is behind the cache
|
||||
uint32_t user_fb: 1; // Whether the frame buffer is provided by user
|
||||
#if CONFIG_IDF_TARGET_ESP32S31
|
||||
uint32_t pll_f120m_enabled: 1; // Whether PLL_F120M was enabled for this panel instance
|
||||
#endif
|
||||
uint32_t core_clk_enabled: 1; // Whether the LCD core clock source was enabled for this panel instance
|
||||
} flags;
|
||||
};
|
||||
|
||||
@@ -261,9 +259,9 @@ static esp_err_t lcd_rgb_panel_destroy(esp_rgb_panel_t *rgb_panel)
|
||||
lcd_ll_enable_clock(rgb_panel->hal.dev, false);
|
||||
}
|
||||
#if CONFIG_IDF_TARGET_ESP32S31
|
||||
if (rgb_panel->flags.pll_f120m_enabled) {
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)SOC_MOD_CLK_PLL_F120M, false);
|
||||
rgb_panel->flags.pll_f120m_enabled = 0;
|
||||
if (rgb_panel->flags.core_clk_enabled) {
|
||||
esp_clk_tree_enable_src((soc_module_clk_t)LCD_CORE_CLK_SRC_DEFAULT, false);
|
||||
rgb_panel->flags.core_clk_enabled = 0;
|
||||
}
|
||||
#endif
|
||||
if (rgb_panel->clk_src) {
|
||||
@@ -407,6 +405,10 @@ esp_err_t esp_lcd_new_rgb_panel(const esp_lcd_rgb_panel_config_t *rgb_panel_conf
|
||||
if (ref_count == 0) {
|
||||
lcd_ll_enable_bus_clock(panel_id, true);
|
||||
lcd_ll_reset_register(panel_id);
|
||||
#if CONFIG_IDF_TARGET_ESP32S31
|
||||
lcd_ll_select_core_clk_src(panel_id, LCD_CORE_CLK_SRC_DEFAULT);
|
||||
lcd_ll_set_core_clock_divider(panel_id, 2, 0, 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -415,9 +417,8 @@ esp_err_t esp_lcd_new_rgb_panel(const esp_lcd_rgb_panel_config_t *rgb_panel_conf
|
||||
lcd_hal_context_t *hal = &rgb_panel->hal;
|
||||
// enable clock
|
||||
#if CONFIG_IDF_TARGET_ESP32S31
|
||||
// PLL 120M was selected in esp_perip_clk_init on esp32s31.
|
||||
ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)SOC_MOD_CLK_PLL_F120M, true), err, TAG, "clock source enable failed");
|
||||
rgb_panel->flags.pll_f120m_enabled = 1;
|
||||
ESP_GOTO_ON_ERROR(esp_clk_tree_enable_src((soc_module_clk_t)LCD_CORE_CLK_SRC_DEFAULT, true), err, TAG, "core clock source enable failed");
|
||||
rgb_panel->flags.core_clk_enabled = 1;
|
||||
#endif
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
lcd_ll_enable_clock(hal->dev, true);
|
||||
@@ -646,7 +647,7 @@ static esp_err_t rgb_panel_init(esp_lcd_panel_t *panel)
|
||||
hal_utils_clk_div_t lcd_clk_div = {};
|
||||
rgb_panel->timings.pclk_hz = lcd_hal_cal_pclk_freq(&rgb_panel->hal, rgb_panel->src_clk_hz, rgb_panel->timings.pclk_hz, &lcd_clk_div);
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
lcd_ll_set_group_clock_coeff(rgb_panel->hal.dev, lcd_clk_div.integer, lcd_clk_div.denominator, lcd_clk_div.numerator);
|
||||
lcd_ll_set_group_clock_coeff(rgb_panel->panel_id, lcd_clk_div.integer, lcd_clk_div.denominator, lcd_clk_div.numerator);
|
||||
}
|
||||
// pixel clock phase and polarity
|
||||
lcd_ll_set_clock_idle_level(rgb_panel->hal.dev, rgb_panel->timings.flags.pclk_idle_high);
|
||||
@@ -1019,7 +1020,7 @@ static esp_err_t lcd_rgb_panel_select_clock_src(esp_rgb_panel_t *rgb_panel, lcd_
|
||||
TAG, "get clock source frequency failed");
|
||||
rgb_panel->src_clk_hz = src_clk_hz;
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
lcd_ll_select_clk_src(rgb_panel->hal.dev, clk_src);
|
||||
lcd_ll_select_clk_src(rgb_panel->panel_id, clk_src);
|
||||
}
|
||||
|
||||
// create pm lock based on different clock source
|
||||
@@ -1376,7 +1377,7 @@ IRAM_ATTR static void lcd_rgb_panel_try_update_pclk(esp_rgb_panel_t *rgb_panel)
|
||||
rgb_panel->flags.need_update_pclk = false;
|
||||
rgb_panel->timings.pclk_hz = lcd_hal_cal_pclk_freq(&rgb_panel->hal, rgb_panel->src_clk_hz, rgb_panel->timings.pclk_hz, &lcd_clk_div);
|
||||
PERIPH_RCC_ATOMIC() {
|
||||
lcd_ll_set_group_clock_coeff(rgb_panel->hal.dev, lcd_clk_div.integer, lcd_clk_div.denominator, lcd_clk_div.numerator);
|
||||
lcd_ll_set_group_clock_coeff(rgb_panel->panel_id, lcd_clk_div.integer, lcd_clk_div.denominator, lcd_clk_div.numerator);
|
||||
}
|
||||
}
|
||||
portEXIT_CRITICAL_ISR(&rgb_panel->spinlock);
|
||||
|
||||
Reference in New Issue
Block a user