feat(lcd): increase the upper limit of pclk frequency for RGB LCD

This commit is contained in:
morris
2024-12-20 16:46:10 +08:00
parent 25a1ad7e98
commit 00f21c37fe
5 changed files with 26 additions and 32 deletions

View File

@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -13,14 +13,14 @@ void lcd_hal_init(lcd_hal_context_t *hal, int id)
hal->dev = LCD_LL_GET_HW(id);
}
uint32_t lcd_hal_cal_pclk_freq(lcd_hal_context_t *hal, uint32_t src_freq_hz, uint32_t expect_pclk_freq_hz, int lcd_clk_flags, hal_utils_clk_div_t* lcd_clk_div)
uint32_t lcd_hal_cal_pclk_freq(lcd_hal_context_t *hal, uint32_t src_freq_hz, uint32_t expect_pclk_freq_hz, hal_utils_clk_div_t* lcd_clk_div)
{
// formula:
// lcd_clk = module_clock_src / (n + b / a)
// pixel_clk = lcd_clk / mo
uint32_t mo = src_freq_hz / expect_pclk_freq_hz / LCD_LL_CLK_FRAC_DIV_N_MAX + 1;
if (mo == 1 && !(lcd_clk_flags & LCD_HAL_PCLK_FLAG_ALLOW_EQUAL_SYSCLK)) {
mo = 2;
}
// due to some unstable hardware issue, we prefer to start with mo=2 first
uint32_t mo = 2;
hal_utils_clk_info_t lcd_clk_info = {
.src_freq_hz = src_freq_hz,
.exp_freq_hz = expect_pclk_freq_hz * mo,
@@ -29,8 +29,15 @@ uint32_t lcd_hal_cal_pclk_freq(lcd_hal_context_t *hal, uint32_t src_freq_hz, uin
.max_fract = LCD_LL_CLK_FRAC_DIV_AB_MAX,
};
uint32_t real_freq = hal_utils_calc_clk_div_frac_fast(&lcd_clk_info, lcd_clk_div);
HAL_EARLY_LOGD("lcd_hal", "n=%"PRIu32",a=%"PRIu32",b=%"PRIu32",mo=%"PRIu32, lcd_clk_div->integer, lcd_clk_div->denominator, lcd_clk_div->numerator, mo);
if (!real_freq) {
// if mo=2 can't achieve the target frequency, try others
mo = src_freq_hz / expect_pclk_freq_hz / LCD_LL_CLK_FRAC_DIV_N_MAX + 1;
lcd_clk_info.exp_freq_hz = expect_pclk_freq_hz * mo;
real_freq = hal_utils_calc_clk_div_frac_fast(&lcd_clk_info, lcd_clk_div);
}
HAL_EARLY_LOGD("lcd_hal", "n=%"PRIu32",a=%"PRIu32",b=%"PRIu32",mo=%"PRIu32, lcd_clk_div->integer, lcd_clk_div->denominator, lcd_clk_div->numerator, mo);
lcd_ll_set_pixel_clock_prescale(hal->dev, mo);
return real_freq / mo;
}