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
@@ -196,7 +212,11 @@ static int esp32_mbox_init(const struct device *dev)
196
212
struct esp32_mbox_config * cfg = (struct esp32_mbox_config * )dev -> config ;
197
213
int ret ;
198
214
215
+ #if defined(CONFIG_SOC_ESP32C6_LPCORE )
216
+ data -> this_core_id = 1 ;
217
+ #else
199
218
data -> this_core_id = esp_core_id ();
219
+ #endif
200
220
data -> other_core_id = (data -> this_core_id == 0 ) ? 1 : 0 ;
201
221
202
222
LOG_DBG ("Size of MBOX shared memory: %d" , data -> shm_size );
@@ -206,29 +226,40 @@ static int esp32_mbox_init(const struct device *dev)
206
226
207
227
/* pro_cpu is responsible to initialize the lock of shared memory */
208
228
if (data -> this_core_id == 0 ) {
229
+ #if !defined(CONFIG_SOC_ESP32C6_LPCORE )
209
230
ret = esp_intr_alloc (cfg -> irq_source_pro_cpu ,
210
231
ESP_PRIO_TO_FLAGS (cfg -> irq_priority_pro_cpu ) |
211
232
ESP_INT_FLAGS_CHECK (cfg -> irq_flags_pro_cpu ) |
212
233
ESP_INTR_FLAG_IRAM ,
213
234
(intr_handler_t )esp32_mbox_isr , (void * )dev , NULL );
235
+ #endif
236
+ #if defined(CONFIG_SOC_ESP32C6_HPCORE )
237
+ SET_PERI_REG_MASK (PMU_HP_INT_ENA_REG , PMU_SW_INT_ENA );
238
+ #endif
214
239
atomic_set (& data -> control -> lock , ESP32_MBOX_LOCK_FREE_VAL );
215
240
} else {
216
241
/* app_cpu wait for initialization from pro_cpu, then takes it,
217
242
* after that releases
218
243
*/
244
+ #if defined(CONFIG_SOC_ESP32C6_LPCORE )
245
+ ret = 0 ;
246
+ ulp_lp_core_intr_set_handler (cfg -> irq_source_app_cpu ,
247
+ (void (* )(void * ))esp32_mbox_isr , (void * )dev );
248
+ ulp_lp_core_intr_enable ();
249
+ ulp_lp_core_sw_intr_enable (true);
250
+ #else
219
251
ret = esp_intr_alloc (cfg -> irq_source_app_cpu ,
220
252
ESP_PRIO_TO_FLAGS (cfg -> irq_priority_app_cpu ) |
221
253
ESP_INT_FLAGS_CHECK (cfg -> irq_flags_app_cpu ) |
222
254
ESP_INTR_FLAG_IRAM ,
223
255
(intr_handler_t )esp32_mbox_isr , (void * )dev , NULL );
224
-
256
+ #endif
225
257
LOG_DBG ("Waiting CPU0 to sync" );
226
258
while (!atomic_cas (& data -> control -> lock , ESP32_MBOX_LOCK_FREE_VAL ,
227
259
data -> this_core_id )) {
228
260
}
229
261
230
262
atomic_set (& data -> control -> lock , ESP32_MBOX_LOCK_FREE_VAL );
231
-
232
263
LOG_DBG ("Synchronization done" );
233
264
}
234
265
0 commit comments