mirror of
https://github.com/espressif/esp-idf.git
synced 2025-07-31 19:24:33 +02:00
Merge branch 'bugfix/fix_cpu_switches_freq_bug_s2s3_to_v5.1' into 'release/v5.1'
EspS2/S3: fixed the bug of insufficient voltage when the CPU switches frequency(V5.1) See merge request espressif/esp-idf!26044
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -256,13 +256,41 @@ static void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
|
|||||||
*/
|
*/
|
||||||
static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
|
static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
|
||||||
{
|
{
|
||||||
int dbias = (cpu_freq_mhz == 240) ? DIG_DBIAS_240M : DIG_DBIAS_80M_160M;
|
/* To avoid the problem of insufficient voltage when the CPU frequency is switched:
|
||||||
|
* When the CPU frequency is switched from low to high, it is necessary to
|
||||||
|
* increase the voltage first and then increase the frequency, and the frequency
|
||||||
|
* needs to wait for the voltage to fully increase before proceeding.
|
||||||
|
* When the frequency of the CPU is switched from high to low, it is necessary
|
||||||
|
* to reduce the frequency first and then reduce the voltage.
|
||||||
|
*/
|
||||||
|
|
||||||
|
rtc_cpu_freq_config_t cur_config;
|
||||||
|
rtc_clk_cpu_freq_get_config(&cur_config);
|
||||||
|
/* cpu_frequency < 240M: dbias = DIG_DBIAS_XTAL_80M_160M;
|
||||||
|
* cpu_frequency = 240M: dbias = DIG_DBIAS_240M;
|
||||||
|
*/
|
||||||
|
if (cpu_freq_mhz > cur_config.freq_mhz) {
|
||||||
|
if (cpu_freq_mhz == 240) {
|
||||||
|
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_240M);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DBIAS_WAK, RTC_DBIAS_240M);
|
||||||
|
esp_rom_delay_us(40);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
clk_ll_cpu_set_freq_mhz_from_pll(cpu_freq_mhz);
|
clk_ll_cpu_set_freq_mhz_from_pll(cpu_freq_mhz);
|
||||||
clk_ll_cpu_set_divider(1);
|
clk_ll_cpu_set_divider(1);
|
||||||
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, dbias);
|
|
||||||
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL);
|
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL);
|
||||||
rtc_clk_apb_freq_update(80 * MHZ);
|
rtc_clk_apb_freq_update(80 * MHZ);
|
||||||
esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz);
|
esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz);
|
||||||
|
|
||||||
|
if (cpu_freq_mhz < cur_config.freq_mhz) {
|
||||||
|
if (cur_config.freq_mhz == 240) {
|
||||||
|
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_XTAL_80M_160M);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DBIAS_WAK, RTC_DBIAS_XTAL_80M_160M);
|
||||||
|
esp_rom_delay_us(40);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t* out_config)
|
bool rtc_clk_cpu_freq_mhz_to_config(uint32_t freq_mhz, rtc_cpu_freq_config_t* out_config)
|
||||||
@@ -411,6 +439,9 @@ void rtc_clk_cpu_set_to_default_config(void)
|
|||||||
*/
|
*/
|
||||||
static void rtc_clk_cpu_freq_to_xtal(int cpu_freq, int div)
|
static void rtc_clk_cpu_freq_to_xtal(int cpu_freq, int div)
|
||||||
{
|
{
|
||||||
|
rtc_cpu_freq_config_t cur_config;
|
||||||
|
rtc_clk_cpu_freq_get_config(&cur_config);
|
||||||
|
|
||||||
esp_rom_set_cpu_ticks_per_us(cpu_freq);
|
esp_rom_set_cpu_ticks_per_us(cpu_freq);
|
||||||
/* Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) first. */
|
/* Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) first. */
|
||||||
clk_ll_cpu_set_divider(1);
|
clk_ll_cpu_set_divider(1);
|
||||||
@@ -419,15 +450,25 @@ static void rtc_clk_cpu_freq_to_xtal(int cpu_freq, int div)
|
|||||||
/* switch clock source */
|
/* switch clock source */
|
||||||
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL);
|
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL);
|
||||||
rtc_clk_apb_freq_update(cpu_freq * MHZ);
|
rtc_clk_apb_freq_update(cpu_freq * MHZ);
|
||||||
/* lower the voltage */
|
|
||||||
int dbias = (cpu_freq <= 2) ? DIG_DBIAS_2M : DIG_DBIAS_XTAL;
|
/* lower the voltage
|
||||||
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, dbias);
|
* cpu_frequency < 240M: dbias = DIG_DBIAS_XTAL_80M_160M;
|
||||||
|
* cpu_frequency = 240M: dbias = DIG_DBIAS_240M;
|
||||||
|
*/
|
||||||
|
if (cur_config.freq_mhz == 240) {
|
||||||
|
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_XTAL_80M_160M);
|
||||||
|
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DBIAS_WAK, RTC_DBIAS_XTAL_80M_160M);
|
||||||
|
esp_rom_delay_us(40);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtc_clk_cpu_freq_to_8m(void)
|
static void rtc_clk_cpu_freq_to_8m(void)
|
||||||
{
|
{
|
||||||
|
assert(0 && "LDO dbias need to modified");
|
||||||
esp_rom_set_cpu_ticks_per_us(8);
|
esp_rom_set_cpu_ticks_per_us(8);
|
||||||
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_XTAL);
|
REG_SET_FIELD(RTC_CNTL_REG, RTC_CNTL_DIG_DBIAS_WAK, DIG_DBIAS_XTAL);
|
||||||
|
esp_rom_delay_us(40);
|
||||||
clk_ll_cpu_set_divider(1);
|
clk_ll_cpu_set_divider(1);
|
||||||
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST);
|
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST);
|
||||||
rtc_clk_apb_freq_update(SOC_CLK_RC_FAST_FREQ_APPROX);
|
rtc_clk_apb_freq_update(SOC_CLK_RC_FAST_FREQ_APPROX);
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
@@ -185,18 +185,6 @@ static void rtc_clk_bbpll_configure(rtc_xtal_freq_t xtal_freq, int pll_freq)
|
|||||||
*/
|
*/
|
||||||
static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
|
static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
|
||||||
{
|
{
|
||||||
/* cpu_frequency < 240M: dbias = pvt-dig + 2;
|
|
||||||
cpu_frequency = 240M: dbias = pvt-dig + 3;
|
|
||||||
*/
|
|
||||||
if (cpu_freq_mhz != 240) {
|
|
||||||
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG, g_rtc_dbias_pvt_non_240m);
|
|
||||||
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, g_dig_dbias_pvt_non_240m);
|
|
||||||
} else {
|
|
||||||
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG, g_rtc_dbias_pvt_240m);
|
|
||||||
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, g_dig_dbias_pvt_240m);
|
|
||||||
}
|
|
||||||
esp_rom_delay_us(40);
|
|
||||||
|
|
||||||
/* There are totally 6 LDO slaves(all on by default). At the moment of swithing LDO slave, LDO voltage will also change instantaneously.
|
/* There are totally 6 LDO slaves(all on by default). At the moment of swithing LDO slave, LDO voltage will also change instantaneously.
|
||||||
* LDO slave can reduce the voltage change caused by switching frequency.
|
* LDO slave can reduce the voltage change caused by switching frequency.
|
||||||
* CPU frequency <= 40M : just open 3 LDO slaves; CPU frequency = 80M : open 4 LDO slaves; CPU frequency = 160M : open 5 LDO slaves; CPU frequency = 240M : open 6 LDO slaves;
|
* CPU frequency <= 40M : just open 3 LDO slaves; CPU frequency = 80M : open 4 LDO slaves; CPU frequency = 160M : open 5 LDO slaves; CPU frequency = 240M : open 6 LDO slaves;
|
||||||
@@ -207,21 +195,32 @@ static void rtc_clk_cpu_freq_to_pll_mhz(int cpu_freq_mhz)
|
|||||||
int pd_slave = cpu_freq_mhz / 80;
|
int pd_slave = cpu_freq_mhz / 80;
|
||||||
rtc_cpu_freq_config_t cur_config;
|
rtc_cpu_freq_config_t cur_config;
|
||||||
rtc_clk_cpu_freq_get_config(&cur_config);
|
rtc_clk_cpu_freq_get_config(&cur_config);
|
||||||
|
/* cpu_frequency < 240M: dbias = pvt-dig + 2;
|
||||||
|
* cpu_frequency = 240M: dbias = pvt-dig + 3;
|
||||||
|
*/
|
||||||
if (cpu_freq_mhz > cur_config.freq_mhz) {
|
if (cpu_freq_mhz > cur_config.freq_mhz) {
|
||||||
|
if (cpu_freq_mhz == 240) {
|
||||||
|
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG, g_rtc_dbias_pvt_240m);
|
||||||
|
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, g_dig_dbias_pvt_240m);
|
||||||
|
esp_rom_delay_us(40);
|
||||||
|
}
|
||||||
REG_SET_FIELD(RTC_CNTL_DATE_REG, RTC_CNTL_SLAVE_PD, DEFAULT_LDO_SLAVE >> pd_slave);
|
REG_SET_FIELD(RTC_CNTL_DATE_REG, RTC_CNTL_SLAVE_PD, DEFAULT_LDO_SLAVE >> pd_slave);
|
||||||
|
}
|
||||||
|
|
||||||
clk_ll_cpu_set_freq_mhz_from_pll(cpu_freq_mhz);
|
clk_ll_cpu_set_freq_mhz_from_pll(cpu_freq_mhz);
|
||||||
clk_ll_cpu_set_divider(1);
|
clk_ll_cpu_set_divider(1);
|
||||||
/* switch clock source */
|
/* switch clock source */
|
||||||
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL);
|
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL);
|
||||||
rtc_clk_apb_freq_update(80 * MHZ);
|
rtc_clk_apb_freq_update(80 * MHZ);
|
||||||
esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz);
|
esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz);
|
||||||
} else {
|
|
||||||
clk_ll_cpu_set_freq_mhz_from_pll(cpu_freq_mhz);
|
if (cpu_freq_mhz < cur_config.freq_mhz) {
|
||||||
clk_ll_cpu_set_divider(1);
|
if (cur_config.freq_mhz == 240) {
|
||||||
/* switch clock source */
|
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG, g_rtc_dbias_pvt_non_240m);
|
||||||
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL);
|
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, g_dig_dbias_pvt_non_240m);
|
||||||
rtc_clk_apb_freq_update(80 * MHZ);
|
esp_rom_delay_us(40);
|
||||||
esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz);
|
}
|
||||||
|
|
||||||
REG_SET_FIELD(RTC_CNTL_DATE_REG, RTC_CNTL_SLAVE_PD, DEFAULT_LDO_SLAVE >> pd_slave);
|
REG_SET_FIELD(RTC_CNTL_DATE_REG, RTC_CNTL_SLAVE_PD, DEFAULT_LDO_SLAVE >> pd_slave);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -376,9 +375,9 @@ void rtc_clk_cpu_set_to_default_config(void)
|
|||||||
*/
|
*/
|
||||||
void rtc_clk_cpu_freq_to_xtal(int cpu_freq, int div)
|
void rtc_clk_cpu_freq_to_xtal(int cpu_freq, int div)
|
||||||
{
|
{
|
||||||
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG, g_rtc_dbias_pvt_non_240m);
|
rtc_cpu_freq_config_t cur_config;
|
||||||
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, g_dig_dbias_pvt_non_240m);
|
rtc_clk_cpu_freq_get_config(&cur_config);
|
||||||
esp_rom_delay_us(40);
|
|
||||||
esp_rom_set_cpu_ticks_per_us(cpu_freq);
|
esp_rom_set_cpu_ticks_per_us(cpu_freq);
|
||||||
/* Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) first. */
|
/* Set divider from XTAL to APB clock. Need to set divider to 1 (reg. value 0) first. */
|
||||||
clk_ll_cpu_set_divider(1);
|
clk_ll_cpu_set_divider(1);
|
||||||
@@ -386,18 +385,25 @@ void rtc_clk_cpu_freq_to_xtal(int cpu_freq, int div)
|
|||||||
/* switch clock source */
|
/* switch clock source */
|
||||||
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL);
|
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_XTAL);
|
||||||
rtc_clk_apb_freq_update(cpu_freq * MHZ);
|
rtc_clk_apb_freq_update(cpu_freq * MHZ);
|
||||||
|
|
||||||
|
if (cur_config.freq_mhz == 240) {
|
||||||
|
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG, g_rtc_dbias_pvt_non_240m);
|
||||||
|
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, g_dig_dbias_pvt_non_240m);
|
||||||
|
esp_rom_delay_us(40);
|
||||||
|
}
|
||||||
|
|
||||||
REG_SET_FIELD(RTC_CNTL_DATE_REG, RTC_CNTL_SLAVE_PD, DEFAULT_LDO_SLAVE);
|
REG_SET_FIELD(RTC_CNTL_DATE_REG, RTC_CNTL_SLAVE_PD, DEFAULT_LDO_SLAVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtc_clk_cpu_freq_to_8m(void)
|
static void rtc_clk_cpu_freq_to_8m(void)
|
||||||
{
|
{
|
||||||
|
assert(0 && "LDO dbias need to modified");
|
||||||
esp_rom_set_cpu_ticks_per_us(20);
|
esp_rom_set_cpu_ticks_per_us(20);
|
||||||
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG, g_rtc_dbias_pvt_non_240m);
|
|
||||||
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, g_dig_dbias_pvt_non_240m);
|
|
||||||
esp_rom_delay_us(40);
|
|
||||||
clk_ll_cpu_set_divider(1);
|
clk_ll_cpu_set_divider(1);
|
||||||
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST);
|
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST);
|
||||||
rtc_clk_apb_freq_update(SOC_CLK_RC_FAST_FREQ_APPROX);
|
rtc_clk_apb_freq_update(SOC_CLK_RC_FAST_FREQ_APPROX);
|
||||||
|
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_RTC_DREG, g_rtc_dbias_pvt_non_240m);
|
||||||
|
REGI2C_WRITE_MASK(I2C_DIG_REG, I2C_DIG_REG_EXT_DIG_DREG, g_dig_dbias_pvt_non_240m);
|
||||||
REG_SET_FIELD(RTC_CNTL_DATE_REG, RTC_CNTL_SLAVE_PD, DEFAULT_LDO_SLAVE);
|
REG_SET_FIELD(RTC_CNTL_DATE_REG, RTC_CNTL_SLAVE_PD, DEFAULT_LDO_SLAVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -84,7 +84,10 @@ extern "C" {
|
|||||||
#define DIG_DBIAS_80M_160M RTC_CNTL_DBIAS_1V10
|
#define DIG_DBIAS_80M_160M RTC_CNTL_DBIAS_1V10
|
||||||
#endif
|
#endif
|
||||||
#define DIG_DBIAS_240M RTC_CNTL_DBIAS_1V25
|
#define DIG_DBIAS_240M RTC_CNTL_DBIAS_1V25
|
||||||
|
#define RTC_DBIAS_240M RTC_CNTL_DBIAS_1V25
|
||||||
#define DIG_DBIAS_XTAL RTC_CNTL_DBIAS_1V10
|
#define DIG_DBIAS_XTAL RTC_CNTL_DBIAS_1V10
|
||||||
|
#define DIG_DBIAS_XTAL_80M_160M RTC_CNTL_DBIAS_1V10
|
||||||
|
#define RTC_DBIAS_XTAL_80M_160M RTC_CNTL_DBIAS_1V10
|
||||||
#define DIG_DBIAS_2M RTC_CNTL_DBIAS_1V00
|
#define DIG_DBIAS_2M RTC_CNTL_DBIAS_1V00
|
||||||
|
|
||||||
#define RTC_CNTL_PLL_BUF_WAIT_DEFAULT 20
|
#define RTC_CNTL_PLL_BUF_WAIT_DEFAULT 20
|
||||||
|
Reference in New Issue
Block a user