mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-30 02:37:19 +02:00
feat(esp_hw_support): use non-lock regi2c fast-up cpll/mpll enable process after sleep wakeup
This commit is contained in:
@ -193,7 +193,7 @@ esp_err_t IRAM_ATTR periph_rtc_mpll_freq_set(uint32_t expt_freq_hz, uint32_t *re
|
||||
* But when more than one peripheral refers MPLL, its frequency is not allowed to change once it is set */
|
||||
if (s_cur_mpll_freq_hz == 0 || s_mpll_ref_cnt < 2) {
|
||||
uint32_t xtal_freq_mhz = clk_ll_xtal_load_freq_mhz();
|
||||
rtc_clk_mpll_configure(xtal_freq_mhz, expt_freq_hz / MHZ);
|
||||
rtc_clk_mpll_configure(xtal_freq_mhz, expt_freq_hz / MHZ, false);
|
||||
s_cur_mpll_freq_hz = clk_ll_mpll_get_freq_mhz(xtal_freq_mhz) * MHZ;
|
||||
} else {
|
||||
ret = ESP_ERR_INVALID_STATE;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -31,7 +31,8 @@ extern "C" {
|
||||
#define regi2c_ctrl_read_reg_mask regi2c_read_reg_mask_raw
|
||||
#define regi2c_ctrl_write_reg regi2c_write_reg_raw
|
||||
#define regi2c_ctrl_write_reg_mask regi2c_write_reg_mask_raw
|
||||
|
||||
#define REGI2C_ENTER_CRITICAL()
|
||||
#define REGI2C_EXIT_CRITICAL()
|
||||
#else
|
||||
|
||||
/* Access internal registers, don't use in application */
|
||||
@ -43,7 +44,8 @@ void regi2c_ctrl_write_reg_mask(uint8_t block, uint8_t host_id, uint8_t reg_add,
|
||||
/* enter the critical section that protects internal registers. Don't use it in SDK. Use the functions above. */
|
||||
void regi2c_enter_critical(void);
|
||||
void regi2c_exit_critical(void);
|
||||
|
||||
#define REGI2C_ENTER_CRITICAL() regi2c_enter_critical()
|
||||
#define REGI2C_EXIT_CRITICAL() regi2c_exit_critical()
|
||||
#endif // BOOTLOADER_BUILD
|
||||
|
||||
/* Convenience macros for the above functions, these use register definitions
|
||||
|
@ -58,8 +58,9 @@ void rtc_clk_mpll_disable(void);
|
||||
*
|
||||
* @param[in] xtal_freq XTAL frequency
|
||||
* @param[in] mpll_freq MPLL frequency
|
||||
* @param[in] thread_safe Set true if called from thread safe context, which will save the time of taking spin lock.
|
||||
*/
|
||||
void rtc_clk_mpll_configure(uint32_t xtal_freq, uint32_t mpll_freq);
|
||||
void rtc_clk_mpll_configure(uint32_t xtal_freq, uint32_t mpll_freq, bool thread_safe);
|
||||
|
||||
/**
|
||||
* Get the MPLL frequency
|
||||
|
@ -463,7 +463,7 @@ TCM_IRAM_ATTR bool pmu_sleep_finish(bool dslp)
|
||||
|
||||
if (s_mpll_freq_mhz_before_sleep && !dslp) {
|
||||
rtc_clk_mpll_enable();
|
||||
rtc_clk_mpll_configure(clk_hal_xtal_get_freq_mhz(), s_mpll_freq_mhz_before_sleep);
|
||||
rtc_clk_mpll_configure(clk_hal_xtal_get_freq_mhz(), s_mpll_freq_mhz_before_sleep, true);
|
||||
#if CONFIG_SPIRAM
|
||||
if (!s_pmu_sleep_regdma_backup_enabled) {
|
||||
// MSPI2 and MSPI3 share the register for core clock. So we only set MSPI2 here.
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -587,9 +587,12 @@ TCM_IRAM_ATTR void rtc_clk_mpll_enable(void)
|
||||
clk_ll_mpll_enable();
|
||||
}
|
||||
|
||||
void rtc_clk_mpll_configure(uint32_t xtal_freq, uint32_t mpll_freq)
|
||||
void rtc_clk_mpll_configure(uint32_t xtal_freq, uint32_t mpll_freq, bool thread_safe)
|
||||
{
|
||||
/* Analog part */
|
||||
if (!thread_safe) {
|
||||
REGI2C_ENTER_CRITICAL();
|
||||
}
|
||||
/* MPLL calibration start */
|
||||
regi2c_ctrl_ll_mpll_calibration_start();
|
||||
clk_ll_mpll_set_config(mpll_freq, xtal_freq);
|
||||
@ -597,6 +600,10 @@ void rtc_clk_mpll_configure(uint32_t xtal_freq, uint32_t mpll_freq)
|
||||
while(!regi2c_ctrl_ll_mpll_calibration_is_done());
|
||||
/* MPLL calibration stop */
|
||||
regi2c_ctrl_ll_mpll_calibration_stop();
|
||||
|
||||
if (!thread_safe) {
|
||||
REGI2C_EXIT_CRITICAL();
|
||||
}
|
||||
s_cur_mpll_freq = mpll_freq;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@ -26,7 +26,7 @@
|
||||
#include "esp32p4/rom/rtc.h"
|
||||
#include "hal/misc.h"
|
||||
#include "hal/efuse_hal.h"
|
||||
|
||||
#include "esp_private/regi2c_ctrl.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -414,9 +414,12 @@ static inline __attribute__((always_inline)) void clk_ll_cpll_set_config(uint32_
|
||||
uint8_t i2c_cpll_lref = (oc_enb_fcal << I2C_CPLL_OC_ENB_FCAL_LSB) | (dchgp << I2C_CPLL_OC_DCHGP_LSB) | (div_ref);
|
||||
uint8_t i2c_cpll_div_7_0 = div7_0;
|
||||
uint8_t i2c_cpll_dcur = (1 << I2C_CPLL_OC_DLREF_SEL_LSB ) | (3 << I2C_CPLL_OC_DHREF_SEL_LSB) | dcur;
|
||||
REGI2C_WRITE(I2C_CPLL, I2C_CPLL_OC_REF_DIV, i2c_cpll_lref);
|
||||
REGI2C_WRITE(I2C_CPLL, I2C_CPLL_OC_DIV_7_0, i2c_cpll_div_7_0);
|
||||
REGI2C_WRITE(I2C_CPLL, I2C_CPLL_OC_DCUR, i2c_cpll_dcur);
|
||||
// There are sequential regi2c operations in `clk_ll_cpll_set_config`, use the raw regi2c API with one lock wrapper to save time.
|
||||
REGI2C_ENTER_CRITICAL();
|
||||
esp_rom_regi2c_write(I2C_CPLL, I2C_CPLL_HOSTID, I2C_CPLL_OC_REF_DIV, i2c_cpll_lref);
|
||||
esp_rom_regi2c_write(I2C_CPLL, I2C_CPLL_HOSTID, I2C_CPLL_OC_DIV_7_0, i2c_cpll_div_7_0);
|
||||
esp_rom_regi2c_write(I2C_CPLL, I2C_CPLL_HOSTID, I2C_CPLL_OC_DCUR, i2c_cpll_dcur);
|
||||
REGI2C_EXIT_CRITICAL();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -443,17 +446,17 @@ static inline __attribute__((always_inline)) void clk_ll_mpll_set_config(uint32_
|
||||
{
|
||||
HAL_ASSERT(xtal_freq_mhz == SOC_XTAL_FREQ_40M);
|
||||
|
||||
uint8_t mpll_dhref_val = REGI2C_READ(I2C_MPLL, I2C_MPLL_DHREF);
|
||||
REGI2C_WRITE(I2C_MPLL, I2C_MPLL_DHREF, mpll_dhref_val | (3 << I2C_MPLL_DHREF_LSB));
|
||||
uint8_t mpll_rstb_val = REGI2C_READ(I2C_MPLL, I2C_MPLL_IR_CAL_RSTB);
|
||||
REGI2C_WRITE(I2C_MPLL, I2C_MPLL_IR_CAL_RSTB, mpll_rstb_val & 0xdf);
|
||||
REGI2C_WRITE(I2C_MPLL, I2C_MPLL_IR_CAL_RSTB, mpll_rstb_val | (1 << I2C_MPLL_IR_CAL_RSTB_lSB));
|
||||
uint8_t mpll_dhref_val = esp_rom_regi2c_read(I2C_MPLL, I2C_MPLL_HOSTID, I2C_MPLL_DHREF);
|
||||
esp_rom_regi2c_write(I2C_MPLL, I2C_MPLL_HOSTID, I2C_MPLL_DHREF, mpll_dhref_val | (3 << I2C_MPLL_DHREF_LSB));
|
||||
uint8_t mpll_rstb_val = esp_rom_regi2c_read(I2C_MPLL, I2C_MPLL_HOSTID, I2C_MPLL_IR_CAL_RSTB);
|
||||
esp_rom_regi2c_write(I2C_MPLL, I2C_MPLL_HOSTID, I2C_MPLL_IR_CAL_RSTB, mpll_rstb_val & 0xdf);
|
||||
esp_rom_regi2c_write(I2C_MPLL, I2C_MPLL_HOSTID, I2C_MPLL_IR_CAL_RSTB, mpll_rstb_val | (1 << I2C_MPLL_IR_CAL_RSTB_lSB));
|
||||
|
||||
// MPLL_Freq = XTAL_Freq * (div + 1) / (ref_div + 1)
|
||||
uint8_t ref_div = 1;
|
||||
uint8_t div = mpll_freq_mhz / 20 - 1;
|
||||
uint8_t val = ((div << 3) | ref_div);
|
||||
REGI2C_WRITE(I2C_MPLL, I2C_MPLL_DIV_REG_ADDR, val);
|
||||
esp_rom_regi2c_write(I2C_MPLL, I2C_MPLL_HOSTID, I2C_MPLL_DIV_REG_ADDR, val);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -29,4 +29,7 @@
|
||||
|
||||
#define REGI2C_READ(block, reg_add) \
|
||||
esp_rom_regi2c_read(block, block##_HOSTID, reg_add)
|
||||
|
||||
#define REGI2C_ENTER_CRITICAL()
|
||||
#define REGI2C_EXIT_CRITICAL()
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user