diff --git a/components/esp_hw_support/port/esp32p4/esp_clk_tree.c b/components/esp_hw_support/port/esp32p4/esp_clk_tree.c index 03b6377107..9d2fc6cc08 100644 --- a/components/esp_hw_support/port/esp32p4/esp_clk_tree.c +++ b/components/esp_hw_support/port/esp32p4/esp_clk_tree.c @@ -33,7 +33,7 @@ esp_err_t esp_clk_tree_src_get_freq_hz(soc_module_clk_t clk_src, esp_clk_tree_sr clk_src_freq = clk_hal_xtal_get_freq_mhz() * MHZ; break; case SOC_MOD_CLK_PLL_F20M: - clk_src_freq = CLK_LL_PLL_20M_FREQ_MHZ * MHZ; + clk_src_freq = CLK_LL_PLL_480M_FREQ_MHZ / clk_ll_pll_f20m_get_divider() * MHZ; break; case SOC_MOD_CLK_PLL_F80M: clk_src_freq = CLK_LL_PLL_80M_FREQ_MHZ * MHZ; diff --git a/components/hal/esp32p4/include/hal/clk_tree_ll.h b/components/hal/esp32p4/include/hal/clk_tree_ll.h index 2447dde728..786444cadc 100644 --- a/components/hal/esp32p4/include/hal/clk_tree_ll.h +++ b/components/hal/esp32p4/include/hal/clk_tree_ll.h @@ -36,7 +36,6 @@ extern "C" { #define CLK_LL_PLL_8M_FREQ_MHZ (8) -#define CLK_LL_PLL_20M_FREQ_MHZ (20) #define CLK_LL_PLL_80M_FREQ_MHZ (80) #define CLK_LL_PLL_160M_FREQ_MHZ (160) #define CLK_LL_PLL_240M_FREQ_MHZ (240) @@ -698,6 +697,27 @@ static inline __attribute__((always_inline)) void clk_ll_pll_f25m_set_divider(ui HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.ref_clk_ctrl0, reg_ref_25m_clk_div_num, divider - 1); } +/** + * @brief Set PLL_F20M_CLK divider. freq of PLL_F20M_CLK = freq of SPLL_CLK / divider + * + * @param divider Divider. CLK_DIV_NUM = divider - 1. + */ +static inline __attribute__((always_inline)) void clk_ll_pll_f20m_set_divider(uint32_t divider) +{ + HAL_ASSERT(divider >= 1); + HAL_FORCE_MODIFY_U32_REG_FIELD(HP_SYS_CLKRST.ref_clk_ctrl1, reg_ref_20m_clk_div_num, divider - 1); +} + +/** + * @brief Get PLL_F20M_CLK divider + * + * @return Divider. Divider = (CLK_DIV_NUM + 1). + */ +static inline __attribute__((always_inline)) uint32_t clk_ll_pll_f20m_get_divider(void) +{ + return HAL_FORCE_READ_U32_REG_FIELD(HP_SYS_CLKRST.ref_clk_ctrl1, reg_ref_20m_clk_div_num) + 1; +} + /** * @brief Select the clock source for RTC_SLOW_CLK * diff --git a/components/hal/mipi_dsi_hal.c b/components/hal/mipi_dsi_hal.c index 0a7f4c3c58..9ca4b6f71e 100644 --- a/components/hal/mipi_dsi_hal.c +++ b/components/hal/mipi_dsi_hal.c @@ -47,13 +47,20 @@ void mipi_dsi_hal_configure_phy_pll(mipi_dsi_hal_context_t *hal, uint32_t phy_cl // 5MHz <= f_ref/N <= 40MHz uint8_t min_N = MAX(1, ref_freq_mhz / 40); uint8_t max_N = ref_freq_mhz / 5; + uint16_t min_delta = UINT16_MAX; for (uint8_t n = min_N; n <= max_N; n++) { uint16_t m = vco_freq_mhz * n / ref_freq_mhz; // M must be even number if ((m & 0x01) == 0) { - pll_M = m; - pll_N = n; - break; + uint16_t delta = vco_freq_mhz - ref_freq_mhz * m / n; + if (delta < min_delta) { + min_delta = delta; + pll_M = m; + pll_N = n; + if (min_delta == 0) { + break; + } + } } } HAL_ASSERT(pll_M && pll_N); diff --git a/components/soc/esp32p4/include/soc/clk_tree_defs.h b/components/soc/esp32p4/include/soc/clk_tree_defs.h index 85ea6b2092..cb782da815 100644 --- a/components/soc/esp32p4/include/soc/clk_tree_defs.h +++ b/components/soc/esp32p4/include/soc/clk_tree_defs.h @@ -143,15 +143,15 @@ typedef enum { SOC_MOD_CLK_RTC_FAST, /*!< RTC_FAST_CLK can be sourced from XTAL, RC_FAST, or LP_PLL by configuring soc_rtc_fast_clk_src_t */ SOC_MOD_CLK_RTC_SLOW, /*!< RTC_SLOW_CLK can be sourced from RC_SLOW, XTAL32K, or RC32K by configuring soc_rtc_slow_clk_src_t */ // For digital domain: peripherals - SOC_MOD_CLK_PLL_F20M, /*!< PLL_F20M_CLK is derived from SPLL (clock gating + "fixed" divider of 24), it has a fixed frequency of 20MHz */ + SOC_MOD_CLK_PLL_F20M, /*!< PLL_F20M_CLK is derived from SPLL (clock gating + default divider 24), its default frequency is 20MHz */ SOC_MOD_CLK_PLL_F25M, /*!< PLL_F25M_CLK is derived from MPLL (clock gating + configurable divider), it will have a frequency of 25MHz */ - SOC_MOD_CLK_PLL_F80M, /*!< PLL_F80M_CLK is derived from SPLL (clock gating + "fixed" divider of 6), it has a fixed frequency of 80MHz */ - SOC_MOD_CLK_PLL_F160M, /*!< PLL_F160M_CLK is derived from SPLL (clock gating + "fixed" divider of 3), it has a fixed frequency of 160MHz */ - SOC_MOD_CLK_PLL_F240M, /*!< PLL_F240M_CLK is derived from SPLL (clock gating + "fixed" divider of 2), it has a fixed frequency of 240MHz */ + SOC_MOD_CLK_PLL_F80M, /*!< PLL_F80M_CLK is derived from SPLL (clock gating + default divider 6), its default frequency is 80MHz */ + SOC_MOD_CLK_PLL_F160M, /*!< PLL_F160M_CLK is derived from SPLL (clock gating + default divider 3), its default frequency is 160MHz */ + SOC_MOD_CLK_PLL_F240M, /*!< PLL_F240M_CLK is derived from SPLL (clock gating + default divider 2), its default frequency is 240MHz */ SOC_MOD_CLK_CPLL, /*!< CPLL is from 40MHz XTAL oscillator frequency multipliers */ - SOC_MOD_CLK_SPLL, /*!< SPLL is from 40MHz XTAL oscillator frequency multipliers, it has a "fixed" frequency of 480MHz */ + SOC_MOD_CLK_SPLL, /*!< SPLL is from 40MHz XTAL oscillator frequency multipliers, its default frequency is 480MHz */ SOC_MOD_CLK_MPLL, /*!< MPLL is from 40MHz XTAL oscillator frequency multipliers */ - SOC_MOD_CLK_SDIO_PLL, /*!< SDIO PLL is from 40MHz XTAL oscillator frequency multipliers, it has a "fixed" frequency of 200MHz */ + SOC_MOD_CLK_SDIO_PLL, /*!< SDIO PLL is from 40MHz XTAL oscillator frequency multipliers, its default frequency is 200MHz */ SOC_MOD_CLK_XTAL32K, /*!< XTAL32K_CLK comes from the external 32kHz crystal, passing a clock gating to the peripherals */ SOC_MOD_CLK_RC_FAST, /*!< RC_FAST_CLK comes from the internal 20MHz rc oscillator, passing a clock gating to the peripherals */ SOC_MOD_CLK_XTAL, /*!< XTAL_CLK comes from the external 40MHz crystal */ @@ -736,7 +736,7 @@ typedef enum { //////////////////////////////////////////////CLOCK OUTPUT/////////////////////////////////////////////////////////// typedef enum { CLKOUT_SIG_MPLL = 0, /*!< MPLL is from 40MHz XTAL oscillator frequency multipliers */ - CLKOUT_SIG_SPLL = 1, /*!< SPLL is from 40MHz XTAL oscillator frequency multipliers, it has a "fixed" frequency of 480MHz */ + CLKOUT_SIG_SPLL = 1, /*!< SPLL is from 40MHz XTAL oscillator frequency multipliers, its default frequency is 480MHz */ CLKOUT_SIG_CPLL = 2, /*!< CPLL_CLK is the output of 40MHz crystal oscillator frequency multiplier, can be 320/360/400MHz */ CLKOUT_SIG_XTAL = 3, /*!< External 40MHz crystal */ CLKOUT_SIG_RC_FAST = 4, /*!< Internal 17.5MHz RC oscillator */