Skip to content

Commit 51205a8

Browse files
committed
fix(esp_hw_support): fix esp32s2/esp32s3 RTC IOMUX clock management
1 parent 7e93f4b commit 51205a8

File tree

18 files changed

+245
-27
lines changed

18 files changed

+245
-27
lines changed

components/esp_driver_gpio/src/rtc_io.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ esp_err_t rtc_gpio_deinit(gpio_num_t gpio_num)
6262
rtcio_hal_function_select(rtc_io_number_get(gpio_num), RTCIO_LL_FUNC_DIGITAL);
6363

6464
#if SOC_LP_IO_CLOCK_IS_INDEPENDENT
65-
io_mux_enable_lp_io_clock(gpio_num, false);
65+
io_mux_force_disable_lp_io_clock(gpio_num);
6666
#endif
6767
RTCIO_EXIT_CRITICAL();
6868

components/esp_hw_support/include/esp_private/io_mux.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -43,6 +43,12 @@ typedef struct {
4343
* @param enable true to enable the clock / false to disable the clock
4444
*/
4545
void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable);
46+
47+
/**
48+
* Force disable one LP_IO to clock dependency
49+
* @param gpio_num GPIO number
50+
*/
51+
void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num);
4652
#endif
4753

4854
#ifdef __cplusplus

components/esp_hw_support/port/esp32c5/io_mux.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -68,3 +68,16 @@ void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
6868
}
6969
portEXIT_CRITICAL(&s_io_mux_spinlock);
7070
}
71+
72+
void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
73+
{
74+
portENTER_CRITICAL(&s_io_mux_spinlock);
75+
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] = 0;
76+
s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num);
77+
if (s_rtc_io_status.rtc_io_using_mask == 0) {
78+
RTCIO_RCC_ATOMIC() {
79+
rtcio_ll_enable_io_clock(false);
80+
}
81+
}
82+
portEXIT_CRITICAL(&s_io_mux_spinlock);
83+
}

components/esp_hw_support/port/esp32c6/io_mux.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -69,3 +69,16 @@ void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
6969
}
7070
portEXIT_CRITICAL(&s_io_mux_spinlock);
7171
}
72+
73+
void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
74+
{
75+
portENTER_CRITICAL(&s_io_mux_spinlock);
76+
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] = 0;
77+
s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num);
78+
if (s_rtc_io_status.rtc_io_using_mask == 0) {
79+
RTCIO_RCC_ATOMIC() {
80+
rtcio_ll_enable_io_clock(false);
81+
}
82+
}
83+
portEXIT_CRITICAL(&s_io_mux_spinlock);
84+
}

components/esp_hw_support/port/esp32c61/io_mux.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -67,3 +67,16 @@ void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
6767
}
6868
portEXIT_CRITICAL(&s_io_mux_spinlock);
6969
}
70+
71+
void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
72+
{
73+
portENTER_CRITICAL(&s_io_mux_spinlock);
74+
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] = 0;
75+
s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num);
76+
if (s_rtc_io_status.rtc_io_using_mask == 0) {
77+
RTCIO_RCC_ATOMIC() {
78+
rtcio_ll_enable_io_clock(false);
79+
}
80+
}
81+
portEXIT_CRITICAL(&s_io_mux_spinlock);
82+
}

components/esp_hw_support/port/esp32h2/io_mux.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -61,3 +61,16 @@ void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
6161
}
6262
portEXIT_CRITICAL(&s_io_mux_spinlock);
6363
}
64+
65+
void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
66+
{
67+
portENTER_CRITICAL(&s_io_mux_spinlock);
68+
s_rtc_io_enabled_cnt[gpio_num] = 0;
69+
s_rtc_io_using_mask &= ~(1ULL << gpio_num);
70+
if (s_rtc_io_using_mask == 0) {
71+
RTCIO_RCC_ATOMIC() {
72+
rtcio_ll_enable_io_clock(false);
73+
}
74+
}
75+
portEXIT_CRITICAL(&s_io_mux_spinlock);
76+
}

components/esp_hw_support/port/esp32p4/io_mux.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -78,3 +78,20 @@ void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
7878
}
7979
portEXIT_CRITICAL(&s_io_mux_spinlock);
8080
}
81+
82+
void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
83+
{
84+
if (gpio_num > MAX_RTC_GPIO_NUM) {
85+
assert(false && "RTCIO number error");
86+
return;
87+
}
88+
portENTER_CRITICAL(&s_io_mux_spinlock);
89+
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] = 0;
90+
s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num);
91+
if (s_rtc_io_status.rtc_io_using_mask == 0) {
92+
RTCIO_RCC_ATOMIC() {
93+
rtcio_ll_enable_io_clock(false);
94+
}
95+
}
96+
portEXIT_CRITICAL(&s_io_mux_spinlock);
97+
}
Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,67 @@
11
/*
2-
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7+
#include "sdkconfig.h"
8+
#include "esp_attr.h"
9+
#include "freertos/FreeRTOS.h"
710
#include "esp_private/io_mux.h"
11+
#include "hal/rtc_io_ll.h"
12+
13+
#define RTCIO_RCC_ATOMIC() \
14+
for (int _rc_cnt = 1; \
15+
_rc_cnt ? (portENTER_CRITICAL(&rtc_spinlock), 1) : 0; \
16+
portEXIT_CRITICAL(&rtc_spinlock), _rc_cnt--)
817

918
esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
1019
{
1120
// IO MUX clock source is not selectable
1221
return ESP_OK;
1322
}
23+
24+
extern portMUX_TYPE rtc_spinlock;
25+
static portMUX_TYPE s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED;
26+
27+
static rtc_io_status_t s_rtc_io_status = {
28+
.rtc_io_enabled_cnt = { 0 },
29+
.rtc_io_using_mask = 0
30+
};
31+
32+
void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
33+
{
34+
portENTER_CRITICAL(&s_io_mux_spinlock);
35+
if (enable) {
36+
if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) {
37+
s_rtc_io_status.rtc_io_using_mask |= (1ULL << gpio_num);
38+
}
39+
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num]++;
40+
} else if (!enable && (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] > 0)) {
41+
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num]--;
42+
if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) {
43+
s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num);
44+
}
45+
}
46+
RTCIO_RCC_ATOMIC() {
47+
if (s_rtc_io_status.rtc_io_using_mask == 0) {
48+
rtcio_ll_enable_io_clock(false);
49+
} else {
50+
rtcio_ll_enable_io_clock(true);
51+
}
52+
}
53+
portEXIT_CRITICAL(&s_io_mux_spinlock);
54+
}
55+
56+
void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
57+
{
58+
portENTER_CRITICAL(&s_io_mux_spinlock);
59+
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] = 0;
60+
s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num);
61+
if (s_rtc_io_status.rtc_io_using_mask == 0) {
62+
RTCIO_RCC_ATOMIC() {
63+
rtcio_ll_enable_io_clock(false);
64+
}
65+
}
66+
portEXIT_CRITICAL(&s_io_mux_spinlock);
67+
}
Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,67 @@
11
/*
2-
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
2+
* SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7+
#include "sdkconfig.h"
8+
#include "esp_attr.h"
9+
#include "freertos/FreeRTOS.h"
710
#include "esp_private/io_mux.h"
11+
#include "hal/rtc_io_ll.h"
12+
13+
#define RTCIO_RCC_ATOMIC() \
14+
for (int _rc_cnt = 1; \
15+
_rc_cnt ? (portENTER_CRITICAL(&rtc_spinlock), 1) : 0; \
16+
portEXIT_CRITICAL(&rtc_spinlock), _rc_cnt--)
817

918
esp_err_t io_mux_set_clock_source(soc_module_clk_t clk_src)
1019
{
1120
// IO MUX clock source is not selectable
1221
return ESP_OK;
1322
}
23+
24+
extern portMUX_TYPE rtc_spinlock;
25+
static portMUX_TYPE s_io_mux_spinlock = portMUX_INITIALIZER_UNLOCKED;
26+
27+
static rtc_io_status_t s_rtc_io_status = {
28+
.rtc_io_enabled_cnt = { 0 },
29+
.rtc_io_using_mask = 0
30+
};
31+
32+
void io_mux_enable_lp_io_clock(gpio_num_t gpio_num, bool enable)
33+
{
34+
portENTER_CRITICAL(&s_io_mux_spinlock);
35+
if (enable) {
36+
if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) {
37+
s_rtc_io_status.rtc_io_using_mask |= (1ULL << gpio_num);
38+
}
39+
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num]++;
40+
} else if (!enable && (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] > 0)) {
41+
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num]--;
42+
if (s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] == 0) {
43+
s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num);
44+
}
45+
}
46+
RTCIO_RCC_ATOMIC() {
47+
if (s_rtc_io_status.rtc_io_using_mask == 0) {
48+
rtcio_ll_enable_io_clock(false);
49+
} else {
50+
rtcio_ll_enable_io_clock(true);
51+
}
52+
}
53+
portEXIT_CRITICAL(&s_io_mux_spinlock);
54+
}
55+
56+
void io_mux_force_disable_lp_io_clock(gpio_num_t gpio_num)
57+
{
58+
portENTER_CRITICAL(&s_io_mux_spinlock);
59+
s_rtc_io_status.rtc_io_enabled_cnt[gpio_num] = 0;
60+
s_rtc_io_status.rtc_io_using_mask &= ~(1ULL << gpio_num);
61+
if (s_rtc_io_status.rtc_io_using_mask == 0) {
62+
RTCIO_RCC_ATOMIC() {
63+
rtcio_ll_enable_io_clock(false);
64+
}
65+
}
66+
portEXIT_CRITICAL(&s_io_mux_spinlock);
67+
}

components/esp_hw_support/port/esp32s3/rtc_clk.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "esp_hw_log.h"
2121
#include "hal/clk_tree_ll.h"
2222
#include "hal/regi2c_ctrl_ll.h"
23+
#include "hal/rtc_io_ll.h"
2324
#include "esp_private/regi2c_ctrl.h"
2425
#include "soc/regi2c_dig_reg.h"
2526
#include "soc/sens_reg.h"
@@ -66,7 +67,7 @@ void rtc_clk_32k_enable(bool enable)
6667
void rtc_clk_32k_enable_external(void)
6768
{
6869
PIN_INPUT_ENABLE(IO_MUX_GPIO15_REG);
69-
SET_PERI_REG_MASK(SENS_SAR_PERI_CLK_GATE_CONF_REG, SENS_IOMUX_CLK_EN);
70+
rtcio_ll_enable_io_clock(true);
7071
SET_PERI_REG_MASK(RTC_CNTL_PAD_HOLD_REG, RTC_CNTL_X32P_HOLD);
7172
clk_ll_xtal32k_enable(CLK_LL_XTAL32K_ENABLE_MODE_EXTERNAL);
7273
}

0 commit comments

Comments
 (0)