diff --git a/drivers/misc/CMakeLists.txt b/drivers/misc/CMakeLists.txt index 54ed29d9349..107b6d218e2 100644 --- a/drivers/misc/CMakeLists.txt +++ b/drivers/misc/CMakeLists.txt @@ -14,3 +14,4 @@ add_subdirectory_ifdef(CONFIG_RENESAS_RA_EXTERNAL_INTERRUPT renesas_ra_external_ add_subdirectory_ifdef(CONFIG_NXP_RTXXX_DSP_CTRL nxp_rtxxx_dsp_ctrl) add_subdirectory(coresight) +add_subdirectory(interconn) diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 5668434c43e..09d814f8024 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -15,6 +15,7 @@ source "drivers/misc/devmux/Kconfig" source "drivers/misc/nordic_vpr_launcher/Kconfig" source "drivers/misc/mcux_flexio/Kconfig" source "drivers/misc/coresight/Kconfig" +source "drivers/misc/interconn/Kconfig" source "drivers/misc/renesas_ra_external_interrupt/Kconfig" source "drivers/misc/nxp_rtxxx_dsp_ctrl/Kconfig" diff --git a/drivers/misc/interconn/CMakeLists.txt b/drivers/misc/interconn/CMakeLists.txt new file mode 100644 index 00000000000..50acd4d1900 --- /dev/null +++ b/drivers/misc/interconn/CMakeLists.txt @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: Apache-2.0 + +add_subdirectory_ifdef(CONFIG_RENESAS_ELC renesas_elc) diff --git a/drivers/misc/interconn/Kconfig b/drivers/misc/interconn/Kconfig new file mode 100644 index 00000000000..ac73bb1d9fb --- /dev/null +++ b/drivers/misc/interconn/Kconfig @@ -0,0 +1,10 @@ +# Interconn drivers not exposing Zephyr Device Driver API + +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +menu "Interconn Drivers" + +source "drivers/misc/interconn/renesas_elc/Kconfig" + +endmenu diff --git a/drivers/misc/interconn/renesas_elc/CMakeLists.txt b/drivers/misc/interconn/renesas_elc/CMakeLists.txt new file mode 100644 index 00000000000..fa84d7eaf85 --- /dev/null +++ b/drivers/misc/interconn/renesas_elc/CMakeLists.txt @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/drivers/misc/interconn/renesas_elc/renesas_elc.h) + +zephyr_library() + +zephyr_library_sources_ifdef(CONFIG_USERSPACE renesas_elc_handlers.c) + +zephyr_library_sources_ifdef(CONFIG_RENESAS_RA_ELC renesas_ra_elc.c) diff --git a/drivers/misc/interconn/renesas_elc/Kconfig b/drivers/misc/interconn/renesas_elc/Kconfig new file mode 100644 index 00000000000..96ef6ea62ec --- /dev/null +++ b/drivers/misc/interconn/renesas_elc/Kconfig @@ -0,0 +1,22 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +# Renesas Event Link Controller config options + +menuconfig RENESAS_ELC + bool "Renesas Event Link Controller Driver" + depends on SOC_FAMILY_RENESAS_RA + help + Enable config options for Renesas Event Link Controller + +if RENESAS_ELC + +config RENESAS_ELC_INIT_PRIORITY + int "Renesas Event Link Controller initialization priority" + default KERNEL_INIT_PRIORITY_DEVICE + help + System initialization priority for Renesas Event Link Controller drivers. + +source "drivers/misc/interconn/renesas_elc/Kconfig.renesas_ra_elc" + +endif # RENESAS_ELC diff --git a/drivers/misc/interconn/renesas_elc/Kconfig.renesas_ra_elc b/drivers/misc/interconn/renesas_elc/Kconfig.renesas_ra_elc new file mode 100644 index 00000000000..5bd54f815fa --- /dev/null +++ b/drivers/misc/interconn/renesas_elc/Kconfig.renesas_ra_elc @@ -0,0 +1,12 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +# Renesas RA Event Link Controller Option + +config RENESAS_RA_ELC + bool "Renesas RA Event Link Controller Driver" + depends on DT_HAS_RENESAS_RA_ELC_ENABLED + select USE_RA_FSP_ELC + default y + help + Enable config options for Renesas RA Event Link Controller diff --git a/drivers/misc/interconn/renesas_elc/renesas_elc_handlers.c b/drivers/misc/interconn/renesas_elc/renesas_elc_handlers.c new file mode 100644 index 00000000000..ccd3c28d691 --- /dev/null +++ b/drivers/misc/interconn/renesas_elc/renesas_elc_handlers.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +int z_vrfy_renesas_elc_software_event_generate(const struct device *dev, + elc_software_event_t sw_event) +{ + K_OOPS(K_SYSCALL_DRIVER_RENESAS_ELC(dev, software_event_generate)); + return z_impl_renesas_elc_software_event_generate(dev, sw_event); +} +#include + +int z_vrfy_renesas_elc_link_set(const struct device *dev, elc_peripheral_t peripheral, + elc_event_t event) +{ + K_OOPS(K_SYSCALL_DRIVER_RENESAS_ELC(dev, link_set)); + return z_impl_renesas_elc_link_set(dev, peripheral, event); +} +#include + +int z_vrfy_renesas_elc_link_break(const struct device *dev, elc_peripheral_t peripheral) +{ + K_OOPS(K_SYSCALL_DRIVER_RENESAS_ELC(dev, link_break)); + return z_impl_renesas_elc_link_break(dev, peripheral); +} +#include + +int z_vrfy_renesas_elc_enable(const struct device *dev) +{ + K_OOPS(K_SYSCALL_DRIVER_RENESAS_ELC(dev, enable)); + return z_impl_renesas_elc_enable(dev); +} +#include + +int z_vrfy_renesas_elc_disable(const struct device *dev) +{ + K_OOPS(K_SYSCALL_DRIVER_RENESAS_ELC(dev, disable)); + return z_impl_renesas_elc_disable(dev); +} +#include diff --git a/drivers/misc/interconn/renesas_elc/renesas_ra_elc.c b/drivers/misc/interconn/renesas_elc/renesas_ra_elc.c new file mode 100644 index 00000000000..5f6bb83f2c7 --- /dev/null +++ b/drivers/misc/interconn/renesas_elc/renesas_ra_elc.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_ra_elc + +#include +#include +#include +#include +#include +#include +#include + +struct renesas_ra_elc_config { + const elc_cfg_t fsp_cfg; + const struct device *clock_dev; + const struct clock_control_ra_subsys_cfg clock_subsys; +}; + +struct renesas_ra_elc_data { + elc_instance_ctrl_t fsp_ctrl; +}; + +static int renesas_ra_elc_software_event_generate(const struct device *dev, uint32_t event) +{ + struct renesas_ra_elc_data *data = (struct renesas_ra_elc_data *const)(dev)->data; + fsp_err_t err; + + err = R_ELC_SoftwareEventGenerate(&data->fsp_ctrl, event); + if (err != FSP_SUCCESS) { + return -EIO; + } + + return 0; +} + +static int renesas_ra_elc_link_set(const struct device *dev, uint32_t peripheral, uint32_t event) +{ + struct renesas_ra_elc_data *data = (struct renesas_ra_elc_data *const)(dev)->data; + fsp_err_t err; + + if (BIT(peripheral) & BSP_ELC_PERIPHERAL_MASK) { + err = R_ELC_LinkSet(&data->fsp_ctrl, peripheral, event); + if (err != FSP_SUCCESS) { + return -EIO; + } + } else { + return -EINVAL; + } + + return 0; +} + +static int renesas_ra_elc_link_break(const struct device *dev, uint32_t peripheral) +{ + struct renesas_ra_elc_data *data = (struct renesas_ra_elc_data *const)(dev)->data; + fsp_err_t err; + + if (BIT(peripheral) & BSP_ELC_PERIPHERAL_MASK) { + err = R_ELC_LinkBreak(&data->fsp_ctrl, peripheral); + if (err != FSP_SUCCESS) { + return -EIO; + } + } else { + return -EINVAL; + } + + return 0; +} + +static int renesas_ra_elc_enable(const struct device *dev) +{ + struct renesas_ra_elc_data *data = (struct renesas_ra_elc_data *const)(dev)->data; + fsp_err_t err; + + err = R_ELC_Enable(&data->fsp_ctrl); + if (err != FSP_SUCCESS) { + return -EIO; + } + + return 0; +} + +static int renesas_ra_elc_disable(const struct device *dev) +{ + struct renesas_ra_elc_data *data = (struct renesas_ra_elc_data *const)(dev)->data; + fsp_err_t err; + + err = R_ELC_Disable(&data->fsp_ctrl); + if (err != FSP_SUCCESS) { + return -EIO; + } + + return 0; +} + +static int renesas_ra_elc_init(const struct device *dev) +{ + struct renesas_ra_elc_data *data = (struct renesas_ra_elc_data *const)(dev)->data; + struct renesas_ra_elc_config *cfg = (struct renesas_ra_elc_config *const)(dev)->config; + fsp_err_t err; + int ret; + + if (!device_is_ready(cfg->clock_dev)) { + return -ENODEV; + } + + ret = clock_control_on(cfg->clock_dev, (clock_control_subsys_t)&cfg->clock_subsys); + if (ret < 0) { + return ret; + } + + err = R_ELC_Open(&data->fsp_ctrl, &cfg->fsp_cfg); + if (err != FSP_SUCCESS) { + return -EIO; + } + + return 0; +} + +static DEVICE_API(renesas_elc, renesas_ra_elc_driver_api) = { + .software_event_generate = renesas_ra_elc_software_event_generate, + .link_set = renesas_ra_elc_link_set, + .link_break = renesas_ra_elc_link_break, + .enable = renesas_ra_elc_enable, + .disable = renesas_ra_elc_disable, +}; + +#define RA_ELC_INIT(inst) \ + static const struct renesas_ra_elc_config renesas_ra_elc_config_##inst = { \ + .fsp_cfg = \ + { \ + .link = {0}, \ + .p_extend = NULL, \ + }, \ + .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(inst)), \ + .clock_subsys = \ + { \ + .mstp = (uint32_t)DT_INST_CLOCKS_CELL_BY_IDX(inst, 0, mstp), \ + .stop_bit = DT_INST_CLOCKS_CELL_BY_IDX(inst, 0, stop_bit), \ + }, \ + }; \ + static struct renesas_ra_elc_data renesas_ra_elc_data_##inst; \ + DEVICE_DT_INST_DEFINE(inst, renesas_ra_elc_init, NULL, &renesas_ra_elc_data_##inst, \ + &renesas_ra_elc_config_##inst, PRE_KERNEL_1, \ + CONFIG_RENESAS_ELC_INIT_PRIORITY, &renesas_ra_elc_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(RA_ELC_INIT) diff --git a/dts/bindings/misc/renesas,ra-elc.yaml b/dts/bindings/misc/renesas,ra-elc.yaml new file mode 100644 index 00000000000..638fea133a2 --- /dev/null +++ b/dts/bindings/misc/renesas,ra-elc.yaml @@ -0,0 +1,23 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA Event Link Controller + +compatible: "renesas,ra-elc" + +include: [base.yaml] + +properties: + reg: + required: true + + clocks: + required: true + + "#renesas-elc-cells": + type: int + const: 2 + +renesas-elc-cells: + - peripheral + - event diff --git a/modules/Kconfig.renesas b/modules/Kconfig.renesas index 1f62e38720f..f512021a609 100644 --- a/modules/Kconfig.renesas +++ b/modules/Kconfig.renesas @@ -186,6 +186,11 @@ config USE_RA_FSP_OSPI_B_NOR_FLASH help Enable RA FSP Octal-SPI driver +config USE_RA_FSP_ELC + bool + help + Enable RA FSP ELC driver + endif # HAS_RENESAS_RA_FSP if HAS_RENESAS_RZ_FSP