Merge branch 'fix/fix_mpll_cali_flow_s31_v6.1' into 'release/v6.1'

mpll: improved mpll calibration flow on s31 (v6.1)

See merge request espressif/esp-idf!52000
This commit is contained in:
morris
2026-08-27 17:53:03 +08:00
4 changed files with 69 additions and 29 deletions
@@ -58,13 +58,12 @@ static inline void bootloader_hardware_init(void)
regi2c_ctrl_ll_master_configure_clock();
#endif
/* Disable MPLL by default, during mmu_hal_init, a valid clock source is required for the PSRAM,
so before shutting down mpll, the PSRAM clock source should be selected to an always-on source. */
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);
_psram_ctrlr_ll_select_clk_source(PSRAM_CTRLR_LL_MSPI_ID_2, PSRAM_CLK_SRC_XTAL);
_psram_ctrlr_ll_select_clk_source(PSRAM_CTRLR_LL_MSPI_ID_3, PSRAM_CLK_SRC_XTAL);
clk_ll_mpll_disable();
REGI2C_WRITE_MASK(I2C_BIAS, I2C_BIAS_DREG_1P1, 10);
REGI2C_WRITE_MASK(I2C_BIAS, I2C_BIAS_DREG_1P1_PVT, 10);
}
void bootloader_enable_cpu_reset_info(void)
@@ -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)
@@ -436,23 +436,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);
}
/**
@@ -481,6 +467,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
*
@@ -648,13 +648,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);
@@ -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