diff --git a/components/bootloader_support/src/esp32s31/bootloader_esp32s31.c b/components/bootloader_support/src/esp32s31/bootloader_esp32s31.c index 965af764f03..d29f0e9f629 100644 --- a/components/bootloader_support/src/esp32s31/bootloader_esp32s31.c +++ b/components/bootloader_support/src/esp32s31/bootloader_esp32s31.c @@ -57,8 +57,9 @@ static inline void bootloader_hardware_init(void) regi2c_ctrl_ll_master_configure_clock(); #endif - REGI2C_WRITE_MASK(I2C_BIAS, I2C_BIAS_DREG_1P1, 10); - REGI2C_WRITE_MASK(I2C_BIAS, I2C_BIAS_DREG_1P1_PVT, 10); + REGI2C_WRITE_MASK(I2C_MPLL, I2C_MPLL_IR_CAL_EXT_CAP, 3); + REGI2C_WRITE_MASK(I2C_BIAS, I2C_BIAS_DREG_1P1, 12); + REGI2C_WRITE_MASK(I2C_BIAS, I2C_BIAS_DREG_1P1_PVT, 12); /* During mmu_hal_init, a valid clock source is required for the PSRAM, so before shutting down MPLL in rtc_clk_init, the PSRAM clock source diff --git a/components/esp_hal_clock/esp32s31/include/hal/clk_tree_ll.h b/components/esp_hal_clock/esp32s31/include/hal/clk_tree_ll.h index 7c4d9434af1..1cf9202c35f 100644 --- a/components/esp_hal_clock/esp32s31/include/hal/clk_tree_ll.h +++ b/components/esp_hal_clock/esp32s31/include/hal/clk_tree_ll.h @@ -18,13 +18,13 @@ #include "soc/hp_alive_sys_struct.h" #include "hal/regi2c_ctrl.h" #include "soc/regi2c_apll.h" +#include "soc/regi2c_mpll.h" #include "soc/pmu_reg.h" #include "hal/clkout_channel.h" #include "hal/assert.h" #include "hal/log.h" #include "esp32s31/rom/rtc.h" #include "hal/misc.h" - #define MHZ (1000000) #define CLK_LL_PLL_8M_FREQ_MHZ (8) @@ -487,23 +487,9 @@ static inline __attribute__((always_inline)) bool clk_ll_cpll_calibration_is_don */ static inline __attribute__((always_inline)) uint32_t clk_ll_mpll_get_freq_mhz(uint32_t xtal_freq_mhz) { - uint8_t fb_div = REG_GET_FIELD(LP_AONCLKRST_MSPI_DIV_REG, LP_AONCLKRST_MSPI_FB_DIV); - return xtal_freq_mhz * (fb_div + 1) / 2; -} - -/** - * @brief Set MPLL frequency from XTAL source - * - * @param mpll_freq_mhz MPLL frequency, in MHz - * @param xtal_freq_mhz XTAL frequency, in MHz - */ -static inline __attribute__((always_inline)) void clk_ll_mpll_set_config(uint32_t mpll_freq_mhz, uint32_t xtal_freq_mhz) -{ - HAL_ASSERT(xtal_freq_mhz == SOC_XTAL_FREQ_40M); - - uint8_t ref_div = 1; - uint8_t fb_div = mpll_freq_mhz * (ref_div + 1) / xtal_freq_mhz - 1; - REG_SET_FIELD(LP_AONCLKRST_MSPI_DIV_REG, LP_AONCLKRST_MSPI_FB_DIV, fb_div); + uint8_t div = REG_GET_FIELD(LP_AONCLKRST_MSPI_DIV_REG, LP_AONCLKRST_MSPI_FB_DIV); + uint8_t ref_div = REG_GET_FIELD(LP_AONCLKRST_MSPI_DIV_REG, LP_AONCLKRST_MSPI_REF_DIV); + return xtal_freq_mhz * (div + 1) / (ref_div + 1); } /** @@ -532,6 +518,32 @@ static inline __attribute__((always_inline)) bool clk_ll_mpll_calibration_is_don return REG_GET_BIT(HP_SYS_CLKRST_ANA_PLL_CTRL0_REG, HP_SYS_CLKRST_REG_MSPI_CAL_END); } +/** + * @brief Set MPLL frequency from XTAL source + * + * @param mpll_freq_mhz MPLL frequency, in MHz + * @param xtal_freq_mhz XTAL frequency, in MHz + */ +static inline __attribute__((always_inline)) void clk_ll_mpll_set_config(uint32_t mpll_freq_mhz, uint32_t xtal_freq_mhz) +{ + HAL_ASSERT(xtal_freq_mhz == SOC_XTAL_FREQ_40M); + + REGI2C_WRITE_MASK(I2C_MPLL, I2C_MPLL_IR_CAL_EXT_CAP, 3); + REGI2C_WRITE_MASK(I2C_MPLL, I2C_MPLL_IR_CAL_ENX_CAP, 1); + REG_SET_FIELD(LP_AONCLKRST_MSPI_DIV_REG, LP_AONCLKRST_MSPI_FB_DIV, 9); + REGI2C_WRITE_MASK(I2C_MPLL, I2C_MPLL_DHREF, 3); + + REGI2C_WRITE_MASK(I2C_MPLL, I2C_MPLL_IR_CAL_ENX_CAP, 0); + clk_ll_mpll_calibration_start(); + + uint8_t ref_div = 1; + uint8_t fb_div = mpll_freq_mhz * (ref_div + 1) / xtal_freq_mhz - 1; + REG_SET_FIELD(LP_AONCLKRST_MSPI_DIV_REG, LP_AONCLKRST_MSPI_FB_DIV, fb_div); + + while (!clk_ll_mpll_calibration_is_done()); + clk_ll_mpll_calibration_stop(); +} + /** * @brief Get APLL configuration which can be used to calculate APLL frequency * diff --git a/components/esp_hw_support/port/esp32s31/rtc_clk.c b/components/esp_hw_support/port/esp32s31/rtc_clk.c index 80421b6d386..ab6f32616e8 100644 --- a/components/esp_hw_support/port/esp32s31/rtc_clk.c +++ b/components/esp_hw_support/port/esp32s31/rtc_clk.c @@ -657,13 +657,8 @@ void rtc_clk_mpll_configure(uint32_t xtal_freq, uint32_t mpll_freq, bool thread_ } else { ANALOG_CLOCK_ENABLE(); } - /* MPLL calibration start */ - clk_ll_mpll_calibration_start(); + clk_ll_mpll_set_config(mpll_freq, xtal_freq); - /* wait calibration done */ - while(!clk_ll_mpll_calibration_is_done()); - /* MPLL calibration stop */ - clk_ll_mpll_calibration_stop(); if (thread_safe) { _regi2c_ctrl_ll_master_enable_clock(false); diff --git a/components/soc/esp32s31/include/soc/regi2c_mpll.h b/components/soc/esp32s31/include/soc/regi2c_mpll.h new file mode 100644 index 00000000000..3d217f52e72 --- /dev/null +++ b/components/soc/esp32s31/include/soc/regi2c_mpll.h @@ -0,0 +1,34 @@ +/* + * SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 OR MIT + */ + +#pragma once + +/** + * @file regi2c_mpll.h + * @brief Register definitions for MSPI_PLL (MPLL) + * + * This file lists register fields of MPLL, located on an internal configuration + * bus. These definitions are used via macros defined in regi2c_ctrl.h + */ + +#define I2C_MPLL 0xB +#define I2C_MPLL_HOSTID 0 + +#define I2C_MPLL_IR_CAL_EXT_CAP 1 +#define I2C_MPLL_IR_CAL_EXT_CAP_MSB 1 +#define I2C_MPLL_IR_CAL_EXT_CAP_LSB 0 + +#define I2C_MPLL_IR_CAL_ENX_CAP 1 +#define I2C_MPLL_IR_CAL_ENX_CAP_MSB 2 +#define I2C_MPLL_IR_CAL_ENX_CAP_LSB 2 + +#define I2C_MPLL_IR_CAL_RSTB 1 +#define I2C_MPLL_IR_CAL_RSTB_MSB 5 +#define I2C_MPLL_IR_CAL_RSTB_lSB 5 + +#define I2C_MPLL_DHREF 3 +#define I2C_MPLL_DHREF_MSB 5 +#define I2C_MPLL_DHREF_LSB 4