Skip to content

drivers: mbox: espressif: add esp32c6 support #93202

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion drivers/interrupt_controller/Kconfig.esp32
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

config INTC_ESP32
bool "Interrupt allocator for Espressif SoCs"
default y
default y if !SOC_ESP32C6_LPCORE
depends on SOC_FAMILY_ESPRESSIF_ESP32
help
Enable custom interrupt allocator for Espressif SoCs based on Xtensa
Expand Down
41 changes: 36 additions & 5 deletions drivers/mbox/mbox_esp32.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
/*
* Copyright (c) 2024 Felipe Neves.
* Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/

#define DT_DRV_COMPAT espressif_mbox_esp32
#if !defined(CONFIG_SOC_SERIES_ESP32C6)
#include "soc/dport_reg.h"
#else
#include <ulp_lp_core.h>
#include <soc/pmu_reg.h>
#include <ulp_lp_core_utils.h>
#include <ulp_lp_core_interrupts.h>
#endif

#include "soc/gpio_periph.h"

#include <stdint.h>
Expand Down Expand Up @@ -64,12 +73,16 @@ IRAM_ATTR static void esp32_mbox_isr(const struct device *dev)
DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, 0);
#elif defined(CONFIG_SOC_SERIES_ESP32S3)
WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_0_REG, 0);
#elif defined(CONFIG_SOC_ESP32C6_HPCORE)
SET_PERI_REG_MASK(PMU_HP_INT_CLR_REG, PMU_SW_INT_CLR);
#endif
} else {
#if defined(CONFIG_SOC_SERIES_ESP32)
DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_1_REG, 0);
#elif defined(CONFIG_SOC_SERIES_ESP32S3)
WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_1_REG, 0);
#elif defined(CONFIG_SOC_ESP32C6_LPCORE)
ulp_lp_core_sw_intr_clear();
#endif
}

Expand Down Expand Up @@ -116,23 +129,26 @@ static int esp32_mbox_send(const struct device *dev, mbox_channel_id_t channel,
/* Only the lower 16bits of id are used */
dev_data->control->dest_cpu_msg_id[dev_data->other_core_id] = (uint16_t)(channel & 0xFFFF);

atomic_set(&dev_data->control->lock, ESP32_MBOX_LOCK_FREE_VAL);

/* Generate interrupt in the remote core */
if (dev_data->this_core_id == 0) {
atomic_set(&dev_data->control->lock, ESP32_MBOX_LOCK_FREE_VAL);
LOG_DBG("Generating interrupt on remote CPU 1 from CPU 0");
#if defined(CONFIG_SOC_SERIES_ESP32)
DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_1_REG, DPORT_CPU_INTR_FROM_CPU_1);
#elif defined(CONFIG_SOC_SERIES_ESP32S3)
WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_1_REG, SYSTEM_CPU_INTR_FROM_CPU_1);
#elif defined(CONFIG_SOC_ESP32C6_HPCORE)
ulp_lp_core_sw_intr_trigger();
#endif

} else {
atomic_set(&dev_data->control->lock, ESP32_MBOX_LOCK_FREE_VAL);
LOG_DBG("Generating interrupt on remote CPU 0 from CPU 1");
#if defined(CONFIG_SOC_SERIES_ESP32)
DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, DPORT_CPU_INTR_FROM_CPU_0);
#elif defined(CONFIG_SOC_SERIES_ESP32S3)
WRITE_PERI_REG(SYSTEM_CPU_INTR_FROM_CPU_0_REG, SYSTEM_CPU_INTR_FROM_CPU_0);
#elif defined(CONFIG_SOC_ESP32C6_LPCORE)
ulp_lp_core_wakeup_main_processor();
#endif
}

Expand Down Expand Up @@ -196,7 +212,11 @@ static int esp32_mbox_init(const struct device *dev)
struct esp32_mbox_config *cfg = (struct esp32_mbox_config *)dev->config;
int ret;

#if defined(CONFIG_SOC_ESP32C6_LPCORE)
data->this_core_id = 1;
#else
data->this_core_id = esp_core_id();
#endif
data->other_core_id = (data->this_core_id == 0) ? 1 : 0;

LOG_DBG("Size of MBOX shared memory: %d", data->shm_size);
Expand All @@ -206,29 +226,40 @@ static int esp32_mbox_init(const struct device *dev)

/* pro_cpu is responsible to initialize the lock of shared memory */
if (data->this_core_id == 0) {
#if !defined(CONFIG_SOC_ESP32C6_LPCORE)
ret = esp_intr_alloc(cfg->irq_source_pro_cpu,
ESP_PRIO_TO_FLAGS(cfg->irq_priority_pro_cpu) |
ESP_INT_FLAGS_CHECK(cfg->irq_flags_pro_cpu) |
ESP_INTR_FLAG_IRAM,
(intr_handler_t)esp32_mbox_isr, (void *)dev, NULL);
#endif
#if defined(CONFIG_SOC_ESP32C6_HPCORE)
SET_PERI_REG_MASK(PMU_HP_INT_ENA_REG, PMU_SW_INT_ENA);
#endif
atomic_set(&data->control->lock, ESP32_MBOX_LOCK_FREE_VAL);
} else {
/* app_cpu wait for initialization from pro_cpu, then takes it,
* after that releases
*/
#if defined(CONFIG_SOC_ESP32C6_LPCORE)
ret = 0;
ulp_lp_core_intr_set_handler(cfg->irq_source_app_cpu,
(void (*)(void *))esp32_mbox_isr, (void *)dev);
ulp_lp_core_intr_enable();
ulp_lp_core_sw_intr_enable(true);
#else
ret = esp_intr_alloc(cfg->irq_source_app_cpu,
ESP_PRIO_TO_FLAGS(cfg->irq_priority_app_cpu) |
ESP_INT_FLAGS_CHECK(cfg->irq_flags_app_cpu) |
ESP_INTR_FLAG_IRAM,
(intr_handler_t)esp32_mbox_isr, (void *)dev, NULL);

#endif
LOG_DBG("Waiting CPU0 to sync");
while (!atomic_cas(&data->control->lock, ESP32_MBOX_LOCK_FREE_VAL,
data->this_core_id)) {
}

atomic_set(&data->control->lock, ESP32_MBOX_LOCK_FREE_VAL);

LOG_DBG("Synchronization done");
}

Expand Down
17 changes: 15 additions & 2 deletions dts/riscv/espressif/esp32c6/esp32c6_common.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,24 @@
reg = <0x50000000 DT_SIZE_K(16)>;
zephyr,memory-region = "SRAMLP ";

shmlp: memory@0 {
reg = <0x0 0x10>;
shmlp: memory@50003fe0 {
reg = <0x50003fe0 0x10>;
};
};

mbox0: mbox@50003ff0 {
compatible = "espressif,mbox-esp32";
reg = <0x50003ff0 0x8>;
status = "disabled";
shared-memory = <&shmlp>;
shared-memory-size = <0x10>;
interrupts =
<PMU_INTR_SOURCE IRQ_DEFAULT_PRIORITY 0>,
<LP_CORE_PMU_INTR_SOURCE IRQ_DEFAULT_PRIORITY 0>;
interrupt-parent = <&intc>;
#mbox-cells = <1>;
};

intc: interrupt-controller@60010000 {
compatible = "espressif,esp32-intc";
#address-cells = <0>;
Expand Down
26 changes: 24 additions & 2 deletions dts/riscv/espressif/esp32c6/esp32c6_lpcore.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,33 @@
compatible = "mmio-sram";
reg = <0x50000000 DT_SIZE_K(16)>;

shmlp: memory@0 {
reg = <0x0 0x10>;
shmlp: memory@50003fb0{
reg = <0x50003fb0 0x50>;
};
};

mbox0: mbox@50003ff0 {
compatible = "espressif,mbox-esp32";
reg = <0x50003ff0 0x8>;
status = "disabled";
shared-memory = <&shmlp>;
shared-memory-size = <0x40>;
interrupts =
<PMU_INTR_SOURCE IRQ_DEFAULT_PRIORITY 0>,
<LP_CORE_PMU_INTR_SOURCE IRQ_DEFAULT_PRIORITY 0>;
interrupt-parent = <&intc>;
#mbox-cells = <1>;
};

intc: interrupt-controller@50000008 {
compatible = "espressif,esp32-intc";
#address-cells = <0>;
#interrupt-cells = <3>;
interrupt-controller;
reg = <0x50000008 DT_SIZE_K(4)>;
status = "okay";
};

flash: flash-controller@60002000 {
compatible = "espressif,esp32-flash-controller";
reg = <0x60002000 0x1000>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,11 @@

#define ESP_INTR_FLAG_SHARED (1<<8) /* Interrupt can be shared between ISRs */

/* LP Core intmux */
#define LP_CORE_IO_INTR_SOURCE 0
#define LP_CORE_I2C_INTR_SOURCE 1
#define LP_CORE_UART_INTR_SOURCE 2
#define LP_CORE_TIMER_INTR_SOURCE 3
#define LP_CORE_PMU_INTR_SOURCE 5

#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_INTERRUPT_CONTROLLER_ESP32C6_INTMUX_H_ */
1 change: 1 addition & 0 deletions samples/drivers/mbox/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ if(CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPP OR
CONFIG_BOARD_MCX_N9XX_EVK_MCXN947_CPU0 OR
CONFIG_BOARD_ESP32_DEVKITC_ESP32_PROCPU OR
CONFIG_BOARD_ESP32S3_DEVKITM_ESP32S3_PROCPU OR
CONFIG_BOARD_ESP32C6_DEVKITC_ESP32C6_HPCORE OR
CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUAPP OR
CONFIG_BOARD_NRF54H20DK_NRF54H20_CPURAD OR
CONFIG_BOARD_NRF54L09PDK_NRF54L09_CPUAPP OR
Expand Down
1 change: 1 addition & 0 deletions samples/drivers/mbox/Kconfig.sysbuild
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,6 @@ config REMOTE_BOARD
default "stm32h747i_disco/stm32h747xx/m4" if $(BOARD) = "stm32h747i_disco"
default "esp32_devkitc/esp32/appcpu" if "$(BOARD)${BOARD_QUALIFIERS}" = "esp32_devkitc/esp32/procpu"
default "esp32s3_devkitm/esp32s3/appcpu" if "$(BOARD)${BOARD_QUALIFIERS}" = "esp32s3_devkitm/esp32s3/procpu"
default "esp32c6_devkitc/esp32c6/lpcore" if "$(BOARD)${BOARD_QUALIFIERS}" = "esp32c6_devkitc/esp32c6/hpcore"
default "bl54l15_dvk/nrf54l15/cpuflpr" if "$(BOARD)${BOARD_QUALIFIERS}" = "bl54l15_dvk/nrf54l15/cpuapp"
default "bl54l15u_dvk/nrf54l15/cpuflpr" if $(BOARD) = "bl54l15u_dvk"
2 changes: 2 additions & 0 deletions samples/drivers/mbox/boards/esp32c6_devkitc_hpcore.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
CONFIG_ULP_COPROC_ENABLED=y
CONFIG_DEBUG_OPTIMIZATIONS=y
26 changes: 26 additions & 0 deletions samples/drivers/mbox/boards/esp32c6_devkitc_hpcore.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/

/ {
chosen {
zephyr,ipc_shm = &shmlp;
zephyr,ipc = &mbox0;
};

mbox-consumer {
compatible = "vnd,mbox-consumer";
mboxes = <&mbox0 0>, <&mbox0 1>;
mbox-names = "tx", "rx";
};
};

&mbox0 {
status = "okay";
};

&lp_uart {
status = "okay";
};
1 change: 1 addition & 0 deletions samples/drivers/mbox/remote/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ if(CONFIG_BOARD_NRF5340DK_NRF5340_CPUNET OR
CONFIG_BOARD_MCX_N9XX_EVK_MCXN947_CPU1 OR
CONFIG_BOARD_ESP32_DEVKITC_ESP32_APPCPU OR
CONFIG_BOARD_ESP32S3_DEVKITM_ESP32S3_APPCPU OR
CONFIG_BOARD_ESP32C6_DEVKITC_ESP32C6_LPCORE OR
CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUPPR OR
CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUFLPR OR
CONFIG_BOARD_NRF54H20DK_NRF54H20_CPUAPP OR
Expand Down
26 changes: 26 additions & 0 deletions samples/drivers/mbox/remote/boards/esp32c6_devkitc_lpcore.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright (c) 2024 Felipe Neves.
*
* SPDX-License-Identifier: Apache-2.0
*/

/ {
chosen {
zephyr,ipc_shm = &shmlp;
zephyr,ipc = &mbox0;
};

mbox-consumer {
compatible = "vnd,mbox-consumer";
mboxes = <&mbox0 1>, <&mbox0 0>;
mbox-names = "tx", "rx";
};
};

&mbox0 {
status = "okay";
};

&lp_uart {
status = "okay";
};
6 changes: 3 additions & 3 deletions soc/espressif/esp32c6/default_lpcore.ld
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ _aligned_coproc_mem = ALIGNED_COPROC_MEM;
_vector_table_org = LPSRAM_IRAM_START;
_vector_table_len = 0x80;
_ram_org = _vector_table_org + _vector_table_len;
_ram_len = _aligned_coproc_mem - _vector_table_len - ULP_SHARED_MEM;
_shared_mem_org = _ram_org + _ram_len;
_shared_mem_len = ULP_SHARED_MEM;
_ram_len = _aligned_coproc_mem - _vector_table_len - ULP_SHARED_MEM_SIZE;
_shared_mem_org = ULP_SHARED_MEM_ADDR;
_shared_mem_len = ULP_SHARED_MEM_SIZE;

ENTRY(reset_vector)

Expand Down
4 changes: 3 additions & 1 deletion soc/espressif/esp32c6/hpcore_init_ulp.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@
#include "ulp_lp_core.h"
#include "lp_core_uart.h"
#include <zephyr/logging/log.h>
#include <zephyr/devicetree.h>

LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL);

void IRAM_ATTR lp_core_image_init(void)
{
const uint32_t lpcore_img_off = FIXED_PARTITION_OFFSET(slot0_lpcore_partition);
const uint32_t lpcore_img_size = 0x4000;
const uint32_t lpcore_img_size =
DT_REG_SIZE(DT_NODELABEL(sramlp)) - DT_REG_SIZE(DT_NODELABEL(shmlp));
int ret = 0;

LOG_INF("Getting LPU image at %p, size %d", (void *)lpcore_img_off, lpcore_img_size);
Expand Down
3 changes: 2 additions & 1 deletion soc/espressif/esp32c6/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
/* LP-SRAM (16kB) memory */
#define LPSRAM_IRAM_START DT_REG_ADDR(DT_NODELABEL(sramlp))
#define LPSRAM_SIZE DT_REG_SIZE(DT_NODELABEL(sramlp))
#define ULP_SHARED_MEM DT_REG_SIZE(DT_NODELABEL(shmlp))
#define ULP_SHARED_MEM_SIZE DT_REG_SIZE(DT_NODELABEL(shmlp))
#define ULP_SHARED_MEM_ADDR DT_REG_ADDR(DT_NODELABEL(shmlp))
#define ULP_COPROC_RESERVE_MEM (0x4000)

/* HP-SRAM (512kB) memory */
Expand Down
2 changes: 1 addition & 1 deletion west.yml
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ manifest:
groups:
- hal
- name: hal_espressif
revision: f3453bdeced28642424692aae32cce4eec3f2d7f
revision: pull/464/head
path: modules/hal/espressif
west-commands: west/west-commands.yml
groups:
Expand Down
Loading