Skip to content

Commit c2cf3d7

Browse files
committed
Merge branch 'fix/stall_other_core_in_cpu_freq_switching_v5.3' into 'release/v5.3'
fix(esp_hw_support): stall another core during cpu/mem/apb freq switching (v5.3) See merge request espressif/esp-idf!32163
2 parents 02e19c4 + 4c2b86f commit c2cf3d7

File tree

2 files changed

+31
-5
lines changed

2 files changed

+31
-5
lines changed

components/esp_hw_support/port/esp32p4/rtc_clk.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "soc/rtc.h"
1515
#include "esp_private/rtc_clk.h"
1616
#include "esp_attr.h"
17+
#include "esp_cpu.h"
1718
#include "esp_hw_log.h"
1819
#include "esp_rom_sys.h"
1920
#include "hal/clk_tree_ll.h"
@@ -182,7 +183,13 @@ static void rtc_clk_cpu_freq_to_xtal(int cpu_freq, int div, bool to_default)
182183
clk_ll_mem_set_divider(mem_divider);
183184
clk_ll_sys_set_divider(sys_divider);
184185
clk_ll_apb_set_divider(apb_divider);
186+
#if (!defined(BOOTLOADER_BUILD) && (CONFIG_FREERTOS_NUMBER_OF_CORES == 2))
187+
esp_cpu_stall(1 - esp_cpu_get_core_id());
188+
#endif
185189
clk_ll_bus_update();
190+
#if (!defined(BOOTLOADER_BUILD) && (CONFIG_FREERTOS_NUMBER_OF_CORES == 2))
191+
esp_cpu_unstall(1 - esp_cpu_get_core_id());
192+
#endif
186193
esp_rom_set_cpu_ticks_per_us(cpu_freq);
187194
}
188195

@@ -194,7 +201,13 @@ static void rtc_clk_cpu_freq_to_8m(void)
194201
clk_ll_sys_set_divider(1);
195202
clk_ll_apb_set_divider(1);
196203
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_RC_FAST);
204+
#if (!defined(BOOTLOADER_BUILD) && (CONFIG_FREERTOS_NUMBER_OF_CORES == 2))
205+
esp_cpu_stall(1 - esp_cpu_get_core_id());
206+
#endif
197207
clk_ll_bus_update();
208+
#if (!defined(BOOTLOADER_BUILD) && (CONFIG_FREERTOS_NUMBER_OF_CORES == 2))
209+
esp_cpu_unstall(1 - esp_cpu_get_core_id());
210+
#endif
198211
esp_rom_set_cpu_ticks_per_us(20);
199212
}
200213

@@ -240,14 +253,22 @@ static void rtc_clk_cpu_freq_to_cpll_mhz(int cpu_freq_mhz, hal_utils_clk_div_t *
240253
// Update bit does not control CPU clock sel mux. Therefore, there may be a middle state during the switch (CPU rises)
241254
// Since this is upscaling, we need to configure the frequency division coefficient before switching the clock source.
242255
// Otherwise, an intermediate state will occur, in the intermediate state, the frequency of APB/MEM does not meet the
243-
// timing requirements. If there are periperals/CPU access that depend on these two clocks at this moment, some exception
256+
// timing requirements. If there are periperals access that depend on these two clocks at this moment, some exception
244257
// might occur.
245258
clk_ll_cpu_set_divider(div->integer, div->numerator, div->denominator);
246259
clk_ll_mem_set_divider(mem_divider);
247260
clk_ll_sys_set_divider(sys_divider);
248261
clk_ll_apb_set_divider(apb_divider);
262+
#if (!defined(BOOTLOADER_BUILD) && (CONFIG_FREERTOS_NUMBER_OF_CORES == 2))
263+
// During frequency switching, non-frequency switching cores may have ongoing memory accesses, which may cause access
264+
// failures, stalling non-frequency switching cores here can avoid such failures.
265+
esp_cpu_stall(1 - esp_cpu_get_core_id());
266+
#endif
249267
clk_ll_bus_update();
250268
clk_ll_cpu_set_src(SOC_CPU_CLK_SRC_PLL);
269+
#if (!defined(BOOTLOADER_BUILD) && (CONFIG_FREERTOS_NUMBER_OF_CORES == 2))
270+
esp_cpu_unstall(1 - esp_cpu_get_core_id());
271+
#endif
251272
esp_rom_set_cpu_ticks_per_us(cpu_freq_mhz);
252273
}
253274

components/hal/esp32p4/include/hal/cpu_utility_ll.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "soc/pmu_struct.h"
1212
#include "soc/hp_system_reg.h"
1313
#include "esp_attr.h"
14+
#include "hal/misc.h"
1415

1516
#ifdef __cplusplus
1617
extern "C" {
@@ -29,18 +30,22 @@ FORCE_INLINE_ATTR void cpu_utility_ll_reset_cpu(uint32_t cpu_no)
2930
FORCE_INLINE_ATTR void cpu_utility_ll_stall_cpu(uint32_t cpu_no)
3031
{
3132
if (cpu_no == 0) {
32-
PMU.cpu_sw_stall.hpcore0_stall_code = 0x86;
33+
HAL_FORCE_MODIFY_U32_REG_FIELD(PMU.cpu_sw_stall, hpcore0_stall_code, 0x86);
34+
while(!REG_GET_BIT(HP_SYSTEM_CPU_CORESTALLED_ST_REG, HP_SYSTEM_REG_CORE0_CORESTALLED_ST));
3335
} else {
34-
PMU.cpu_sw_stall.hpcore1_stall_code = 0x86;
36+
HAL_FORCE_MODIFY_U32_REG_FIELD(PMU.cpu_sw_stall, hpcore1_stall_code, 0x86);
37+
while(!REG_GET_BIT(HP_SYSTEM_CPU_CORESTALLED_ST_REG, HP_SYSTEM_REG_CORE1_CORESTALLED_ST));
3538
}
3639
}
3740

3841
FORCE_INLINE_ATTR void cpu_utility_ll_unstall_cpu(uint32_t cpu_no)
3942
{
4043
if (cpu_no == 0) {
41-
PMU.cpu_sw_stall.hpcore0_stall_code = 0xFF;
44+
HAL_FORCE_MODIFY_U32_REG_FIELD(PMU.cpu_sw_stall, hpcore0_stall_code, 0xFF);
45+
while(REG_GET_BIT(HP_SYSTEM_CPU_CORESTALLED_ST_REG, HP_SYSTEM_REG_CORE0_CORESTALLED_ST));
4246
} else {
43-
PMU.cpu_sw_stall.hpcore1_stall_code = 0xFF;
47+
HAL_FORCE_MODIFY_U32_REG_FIELD(PMU.cpu_sw_stall, hpcore1_stall_code, 0xFF);
48+
while(REG_GET_BIT(HP_SYSTEM_CPU_CORESTALLED_ST_REG, HP_SYSTEM_REG_CORE1_CORESTALLED_ST));
4449
}
4550
}
4651
#endif // SOC_CPU_CORES_NUM > 1

0 commit comments

Comments
 (0)