1
1
/*
2
2
* Copyright (c) 2024 Felipe Neves.
3
+ * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd.
3
4
*
4
5
* SPDX-License-Identifier: Apache-2.0
5
6
*/
6
7
7
8
#define DT_DRV_COMPAT espressif_mbox_esp32
9
+ #if !defined(CONFIG_SOC_SERIES_ESP32C6 )
8
10
#include "soc/dport_reg.h"
11
+ #else
12
+ #include <ulp_lp_core.h>
13
+ #include <soc/pmu_reg.h>
14
+ #include <ulp_lp_core_utils.h>
15
+ #include <ulp_lp_core_interrupts.h>
16
+ #endif
17
+
9
18
#include "soc/gpio_periph.h"
10
19
11
20
#include <stdint.h>
@@ -64,12 +73,16 @@ IRAM_ATTR static void esp32_mbox_isr(const struct device *dev)
64
73
DPORT_WRITE_PERI_REG (DPORT_CPU_INTR_FROM_CPU_0_REG , 0 );
65
74
#elif defined(CONFIG_SOC_SERIES_ESP32S3 )
66
75
WRITE_PERI_REG (SYSTEM_CPU_INTR_FROM_CPU_0_REG , 0 );
76
+ #elif defined(CONFIG_SOC_ESP32C6_HPCORE )
77
+ SET_PERI_REG_MASK (PMU_HP_INT_CLR_REG , PMU_SW_INT_CLR );
67
78
#endif
68
79
} else {
69
80
#if defined(CONFIG_SOC_SERIES_ESP32 )
70
81
DPORT_WRITE_PERI_REG (DPORT_CPU_INTR_FROM_CPU_1_REG , 0 );
71
82
#elif defined(CONFIG_SOC_SERIES_ESP32S3 )
72
83
WRITE_PERI_REG (SYSTEM_CPU_INTR_FROM_CPU_1_REG , 0 );
84
+ #elif defined(CONFIG_SOC_ESP32C6_LPCORE )
85
+ ulp_lp_core_sw_intr_clear ();
73
86
#endif
74
87
}
75
88
@@ -116,23 +129,26 @@ static int esp32_mbox_send(const struct device *dev, mbox_channel_id_t channel,
116
129
/* Only the lower 16bits of id are used */
117
130
dev_data -> control -> dest_cpu_msg_id [dev_data -> other_core_id ] = (uint16_t )(channel & 0xFFFF );
118
131
132
+ atomic_set (& dev_data -> control -> lock , ESP32_MBOX_LOCK_FREE_VAL );
133
+
119
134
/* Generate interrupt in the remote core */
120
135
if (dev_data -> this_core_id == 0 ) {
121
- atomic_set (& dev_data -> control -> lock , ESP32_MBOX_LOCK_FREE_VAL );
122
136
LOG_DBG ("Generating interrupt on remote CPU 1 from CPU 0" );
123
137
#if defined(CONFIG_SOC_SERIES_ESP32 )
124
138
DPORT_WRITE_PERI_REG (DPORT_CPU_INTR_FROM_CPU_1_REG , DPORT_CPU_INTR_FROM_CPU_1 );
125
139
#elif defined(CONFIG_SOC_SERIES_ESP32S3 )
126
140
WRITE_PERI_REG (SYSTEM_CPU_INTR_FROM_CPU_1_REG , SYSTEM_CPU_INTR_FROM_CPU_1 );
141
+ #elif defined(CONFIG_SOC_ESP32C6_HPCORE )
142
+ ulp_lp_core_sw_intr_trigger ();
127
143
#endif
128
-
129
144
} else {
130
- atomic_set (& dev_data -> control -> lock , ESP32_MBOX_LOCK_FREE_VAL );
131
145
LOG_DBG ("Generating interrupt on remote CPU 0 from CPU 1" );
132
146
#if defined(CONFIG_SOC_SERIES_ESP32 )
133
147
DPORT_WRITE_PERI_REG (DPORT_CPU_INTR_FROM_CPU_0_REG , DPORT_CPU_INTR_FROM_CPU_0 );
134
148
#elif defined(CONFIG_SOC_SERIES_ESP32S3 )
135
149
WRITE_PERI_REG (SYSTEM_CPU_INTR_FROM_CPU_0_REG , SYSTEM_CPU_INTR_FROM_CPU_0 );
150
+ #elif defined(CONFIG_SOC_ESP32C6_LPCORE )
151
+ ulp_lp_core_wakeup_main_processor ();
136
152
#endif
137
153
}
138
154
@@ -197,6 +213,9 @@ static int esp32_mbox_init(const struct device *dev)
197
213
int ret ;
198
214
199
215
data -> this_core_id = esp_core_id ();
216
+ #if defined(CONFIG_SOC_ESP32C6_LPCORE )
217
+ data -> this_core_id = 1 ;
218
+ #endif
200
219
data -> other_core_id = (data -> this_core_id == 0 ) ? 1 : 0 ;
201
220
202
221
LOG_DBG ("Size of MBOX shared memory: %d" , data -> shm_size );
@@ -206,29 +225,40 @@ static int esp32_mbox_init(const struct device *dev)
206
225
207
226
/* pro_cpu is responsible to initialize the lock of shared memory */
208
227
if (data -> this_core_id == 0 ) {
228
+ #if !defined(CONFIG_SOC_ESP32C6_LPCORE )
209
229
ret = esp_intr_alloc (cfg -> irq_source_pro_cpu ,
210
230
ESP_PRIO_TO_FLAGS (cfg -> irq_priority_pro_cpu ) |
211
231
ESP_INT_FLAGS_CHECK (cfg -> irq_flags_pro_cpu ) |
212
232
ESP_INTR_FLAG_IRAM ,
213
233
(intr_handler_t )esp32_mbox_isr , (void * )dev , NULL );
234
+ #endif
235
+ #if defined(CONFIG_SOC_ESP32C6_HPCORE )
236
+ SET_PERI_REG_MASK (PMU_HP_INT_ENA_REG , PMU_SW_INT_ENA );
237
+ #endif
214
238
atomic_set (& data -> control -> lock , ESP32_MBOX_LOCK_FREE_VAL );
215
239
} else {
216
240
/* app_cpu wait for initialization from pro_cpu, then takes it,
217
241
* after that releases
218
242
*/
243
+ #if defined(CONFIG_SOC_ESP32C6_LPCORE )
244
+ ret = 0 ;
245
+ ulp_lp_core_intr_set_handler (cfg -> irq_source_app_cpu ,
246
+ (void (* )(void * ))esp32_mbox_isr , (void * )dev );
247
+ ulp_lp_core_intr_enable ();
248
+ ulp_lp_core_sw_intr_enable (true);
249
+ #else
219
250
ret = esp_intr_alloc (cfg -> irq_source_app_cpu ,
220
251
ESP_PRIO_TO_FLAGS (cfg -> irq_priority_app_cpu ) |
221
252
ESP_INT_FLAGS_CHECK (cfg -> irq_flags_app_cpu ) |
222
253
ESP_INTR_FLAG_IRAM ,
223
254
(intr_handler_t )esp32_mbox_isr , (void * )dev , NULL );
224
-
255
+ #endif
225
256
LOG_DBG ("Waiting CPU0 to sync" );
226
257
while (!atomic_cas (& data -> control -> lock , ESP32_MBOX_LOCK_FREE_VAL ,
227
258
data -> this_core_id )) {
228
259
}
229
260
230
261
atomic_set (& data -> control -> lock , ESP32_MBOX_LOCK_FREE_VAL );
231
-
232
262
LOG_DBG ("Synchronization done" );
233
263
}
234
264
0 commit comments