From da79bf739660f1fe4df658239f124be35027f618 Mon Sep 17 00:00:00 2001 From: Quy Tran Date: Wed, 24 Sep 2025 02:56:59 +0000 Subject: [PATCH 1/5] manifest: hal_renesas: Update revision of hal_renesas to latest Update commit ID to latest for hal_renesas Signed-off-by: Quy Tran --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 9861263cd7106..f28c9fe54e15b 100644 --- a/west.yml +++ b/west.yml @@ -226,7 +226,7 @@ manifest: - hal - name: hal_renesas path: modules/hal/renesas - revision: a279c14e196cb0904593035888a334dcd2c720bd + revision: pull/142/head groups: - hal - name: hal_rpi_pico From c73ae591b987f3fb94f4696095cf58ac1a94f4a9 Mon Sep 17 00:00:00 2001 From: Tatsuya Ogawa Date: Thu, 3 Apr 2025 14:18:08 +0900 Subject: [PATCH 2/5] drivers: interrupt-controller: Add support Group interrupt driver on RX Add support Group interrupt driver on RX Signed-off-by: Tatsuya Ogawa --- drivers/interrupt_controller/CMakeLists.txt | 1 + .../interrupt_controller/Kconfig.renesas_rx | 7 + .../intc_renesas_rx_grp_int.c | 149 +++++++++ .../renesas,rx-grp-intc.yaml | 22 ++ dts/rx/renesas/rx26t-common.dtsi | 299 +++++++++++------- .../intc_renesas_rx_grp_int.h | 51 +++ 6 files changed, 416 insertions(+), 113 deletions(-) create mode 100644 drivers/interrupt_controller/intc_renesas_rx_grp_int.c create mode 100644 dts/bindings/interrupt-controller/renesas,rx-grp-intc.yaml create mode 100644 include/zephyr/drivers/interrupt_controller/intc_renesas_rx_grp_int.h diff --git a/drivers/interrupt_controller/CMakeLists.txt b/drivers/interrupt_controller/CMakeLists.txt index 2446120963041..2beee3c6d7786 100644 --- a/drivers/interrupt_controller/CMakeLists.txt +++ b/drivers/interrupt_controller/CMakeLists.txt @@ -58,6 +58,7 @@ zephyr_library_sources_ifdef(CONFIG_NXP_PINT intc_nxp_pint.c) zephyr_library_sources_ifdef(CONFIG_NXP_S32_WKPU intc_wkpu_nxp_s32.c) zephyr_library_sources_ifdef(CONFIG_NXP_SIUL2_EIRQ intc_nxp_siul2_eirq.c) zephyr_library_sources_ifdef(CONFIG_PLIC intc_plic.c) +zephyr_library_sources_ifdef(CONFIG_RENESAS_RX_GRP_INTC intc_renesas_rx_grp_int.c) zephyr_library_sources_ifdef(CONFIG_RENESAS_RX_ICU intc_renesas_rx_icu.c) zephyr_library_sources_ifdef(CONFIG_RENESAS_RZ_EXT_IRQ intc_renesas_rz_ext_irq.c) zephyr_library_sources_ifdef(CONFIG_RV32M1_INTMUX intc_rv32m1_intmux.c) diff --git a/drivers/interrupt_controller/Kconfig.renesas_rx b/drivers/interrupt_controller/Kconfig.renesas_rx index cd7921f5f2461..63ded1782c597 100644 --- a/drivers/interrupt_controller/Kconfig.renesas_rx +++ b/drivers/interrupt_controller/Kconfig.renesas_rx @@ -7,3 +7,10 @@ config RENESAS_RX_ICU depends on DT_HAS_RENESAS_RX_ICU_ENABLED help Renesas RX series interrupt controller unit + +config RENESAS_RX_GRP_INTC + bool "Renesas RX series group interrupt" + default y + depends on DT_HAS_RENESAS_RX_GRP_INTC_ENABLED + help + Renesas RX series group interrupt feature diff --git a/drivers/interrupt_controller/intc_renesas_rx_grp_int.c b/drivers/interrupt_controller/intc_renesas_rx_grp_int.c new file mode 100644 index 0000000000000..edf819c642516 --- /dev/null +++ b/drivers/interrupt_controller/intc_renesas_rx_grp_int.c @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_rx_grp_intc + +#include +#include +#include +#include +#include +#include + +extern void group_bl0_handler_isr(void); +extern void group_bl1_handler_isr(void); +extern void group_bl2_handler_isr(void); +extern void group_al0_handler_isr(void); +extern void group_al1_handler_isr(void); + +#define VECT_GROUP_BL0 DT_IRQN(DT_NODELABEL(group_irq_bl0)) +#define VECT_GROUP_BL1 DT_IRQN(DT_NODELABEL(group_irq_bl1)) +#define VECT_GROUP_BL2 DT_IRQN(DT_NODELABEL(group_irq_bl2)) +#define VECT_GROUP_AL0 DT_IRQN(DT_NODELABEL(group_irq_al0)) +#define VECT_GROUP_AL1 DT_IRQN(DT_NODELABEL(group_irq_al1)) + +struct rx_grp_int_cfg { + /* address of the Group Interrupt Request Enable Register (GENxxx) */ + volatile uint32_t *gen; + /* vector number of the interrupt */ + const uint8_t vect; + /* priority of the interrupt */ + const uint8_t prio; +}; + +struct rx_grp_int_data { + struct k_spinlock lock; +}; + +int rx_grp_intc_set_callback(const struct device *dev, bsp_int_src_t vector, bsp_int_cb_t callback, + void *context) +{ + ARG_UNUSED(dev); + bsp_int_err_t err; + + err = R_BSP_InterruptWrite_EX(vector, callback, context); + if (err != BSP_INT_SUCCESS) { + return -EINVAL; + } + + return 0; +} + +int rx_grp_intc_set_grp_int(const struct device *dev, bsp_int_src_t vector, bool set) +{ + const struct rx_grp_int_cfg *cfg = dev->config; + struct rx_grp_int_data *data = dev->data; + volatile bsp_int_ctrl_t group_priority; + bsp_int_err_t err; + + group_priority.ipl = cfg->prio; + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + if (set) { + err = R_BSP_InterruptControl(vector, BSP_INT_CMD_GROUP_INTERRUPT_ENABLE, + (void *)&group_priority); + } else { + err = R_BSP_InterruptControl(vector, BSP_INT_CMD_GROUP_INTERRUPT_DISABLE, NULL); + } + + if (err != BSP_INT_SUCCESS) { + k_spin_unlock(&data->lock, key); + return -EINVAL; + } + + k_spin_unlock(&data->lock, key); + + return 0; +} + +int rx_grp_intc_set_gen(const struct device *dev, uint8_t vector_num, bool set) +{ + const struct rx_grp_int_cfg *cfg = dev->config; + struct rx_grp_int_data *data = dev->data; + + if (vector_num > 31) { + return -EINVAL; + } + + k_spinlock_key_t key = k_spin_lock(&data->lock); + + if (set) { + *cfg->gen |= (1U << vector_num); + } else { + *cfg->gen &= ~(1U << vector_num); + } + + k_spin_unlock(&data->lock, key); + + return 0; +} + +static int rx_grp_intc_init(const struct device *dev) +{ + const struct rx_grp_int_cfg *cfg = dev->config; + + switch (cfg->vect) { + case VECT_GROUP_BL0: + IRQ_CONNECT(VECT_GROUP_BL0, cfg->prio, group_bl0_handler_isr, NULL, 0); + break; + case VECT_GROUP_BL1: + IRQ_CONNECT(VECT_GROUP_BL1, cfg->prio, group_bl1_handler_isr, NULL, 0); + break; + case VECT_GROUP_BL2: + IRQ_CONNECT(VECT_GROUP_BL2, cfg->prio, group_bl2_handler_isr, NULL, 0); + break; + case VECT_GROUP_AL0: + IRQ_CONNECT(VECT_GROUP_AL0, cfg->prio, group_al0_handler_isr, NULL, 0); + break; + case VECT_GROUP_AL1: + IRQ_CONNECT(VECT_GROUP_AL1, cfg->prio, group_al1_handler_isr, NULL, 0); + break; + default: + /* ERROR */ + return -EINVAL; + } + + irq_enable(cfg->vect); + + return 0; +} + +#define GRP_INT_RX_INIT(index) \ + static struct rx_grp_int_cfg rx_grp_int_##index##_cfg = { \ + .gen = (volatile uint32_t *)DT_INST_REG_ADDR_BY_NAME(index, GEN), \ + .vect = DT_INST_IRQN(index), \ + .prio = DT_INST_IRQ(index, priority), \ + }; \ + static struct rx_grp_int_data rx_grp_int_##index##_data; \ + static int rx_grp_int_##index##_init(const struct device *dev) \ + { \ + return rx_grp_intc_init(dev); \ + } \ + DEVICE_DT_INST_DEFINE(index, rx_grp_int_##index##_init, NULL, &rx_grp_int_##index##_data, \ + &rx_grp_int_##index##_cfg, PRE_KERNEL_1, \ + CONFIG_KERNEL_INIT_PRIORITY_DEVICE, NULL); + +DT_INST_FOREACH_STATUS_OKAY(GRP_INT_RX_INIT); diff --git a/dts/bindings/interrupt-controller/renesas,rx-grp-intc.yaml b/dts/bindings/interrupt-controller/renesas,rx-grp-intc.yaml new file mode 100644 index 0000000000000..0c264200e8083 --- /dev/null +++ b/dts/bindings/interrupt-controller/renesas,rx-grp-intc.yaml @@ -0,0 +1,22 @@ +# Copyright (c) 2021 KT-Elektronik Klaucke und Partner GmbH +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas group interrupt +compatible: "renesas,rx-grp-intc" + +include: [interrupt-controller.yaml, base.yaml] + +properties: + reg: + required: true + + reg-names: + required: true + + "#interrupt-cells": + const: 2 + +interrupt-cells: + - irq + - priority diff --git a/dts/rx/renesas/rx26t-common.dtsi b/dts/rx/renesas/rx26t-common.dtsi index 3be576623b882..cfddc9c8595f2 100644 --- a/dts/rx/renesas/rx26t-common.dtsi +++ b/dts/rx/renesas/rx26t-common.dtsi @@ -15,6 +15,7 @@ / { #address-cells = <1>; #size-cells = <1>; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -180,12 +181,12 @@ ngpios = <2>; port = <0>; reg = <0x0008C000 0x01>, - <0x0008C020 0x01>, - <0x0008C040 0x01>, - <0x0008C060 0x01>, - <0x0008C080 0x01>, - <0x0008C0C0 0x01>, - <0x0008C0E0 0x01>; + <0x0008C020 0x01>, + <0x0008C040 0x01>, + <0x0008C060 0x01>, + <0x0008C080 0x01>, + <0x0008C0C0 0x01>, + <0x0008C0E0 0x01>; reg-names = "PDR", "PODR", "PIDR", "PMR", "ODR0", "PCR", "DSCR"; pinmux = <&pinmux0>; status = "disabled"; @@ -198,12 +199,12 @@ ngpios = <2>; port = <1>; reg = <0x0008C001 0x01>, - <0x0008C021 0x01>, - <0x0008C041 0x01>, - <0x0008C061 0x01>, - <0x0008C082 0x01>, - <0x0008C0C1 0x01>, - <0x0008C0E1 0x01>; + <0x0008C021 0x01>, + <0x0008C041 0x01>, + <0x0008C061 0x01>, + <0x0008C082 0x01>, + <0x0008C0C1 0x01>, + <0x0008C0E1 0x01>; reg-names = "PDR", "PODR", "PIDR", "PMR", "ODR0", "PCR", "DSCR"; pinmux = <&pinmux1>; status = "disabled"; @@ -216,13 +217,13 @@ ngpios = <6>; port = <2>; reg = <0x0008C002 0x01>, - <0x0008C022 0x01>, - <0x0008C042 0x01>, - <0x0008C062 0x01>, - <0x0008C084 0x01>, - <0x0008C085 0x01>, - <0x0008C0C2 0x01>, - <0x0008C0E2 0x01>; + <0x0008C022 0x01>, + <0x0008C042 0x01>, + <0x0008C062 0x01>, + <0x0008C084 0x01>, + <0x0008C085 0x01>, + <0x0008C0C2 0x01>, + <0x0008C0E2 0x01>; reg-names = "PDR", "PODR", "PIDR", "PMR", "ODR0", "ODR1", "PCR", "DSCR"; pinmux = <&pinmux2>; status = "disabled"; @@ -235,13 +236,13 @@ ngpios = <6>; port = <3>; reg = <0x0008C003 0x01>, - <0x0008C023 0x01>, - <0x0008C043 0x01>, - <0x0008C063 0x01>, - <0x0008C086 0x01>, - <0x0008C087 0x01>, - <0x0008C0C3 0x01>, - <0x0008C0E3 0x01>; + <0x0008C023 0x01>, + <0x0008C043 0x01>, + <0x0008C063 0x01>, + <0x0008C086 0x01>, + <0x0008C087 0x01>, + <0x0008C0C3 0x01>, + <0x0008C0E3 0x01>; reg-names = "PDR", "PODR", "PIDR", "PMR", "ODR0", "ODR1", "PCR", "DSCR"; pinmux = <&pinmux3>; status = "disabled"; @@ -254,12 +255,12 @@ ngpios = <8>; port = <4>; reg = <0x0008C004 0x01>, - <0x0008C024 0x01>, - <0x0008C044 0x01>, - <0x0008C064 0x01>, - <0x0008C088 0x01>, - <0x0008C089 0x01>, - <0x0008C0C4 0x01>; + <0x0008C024 0x01>, + <0x0008C044 0x01>, + <0x0008C064 0x01>, + <0x0008C088 0x01>, + <0x0008C089 0x01>, + <0x0008C0C4 0x01>; reg-names = "PDR", "PODR", "PIDR", "PMR", "ODR0", "ODR1", "PCR"; pinmux = <&pinmux4>; status = "disabled"; @@ -272,12 +273,12 @@ ngpios = <6>; port = <5>; reg = <0x0008C005 0x01>, - <0x0008C025 0x01>, - <0x0008C045 0x01>, - <0x0008C065 0x01>, - <0x0008C08A 0x01>, - <0x0008C08B 0x01>, - <0x0008C0C5 0x01>; + <0x0008C025 0x01>, + <0x0008C045 0x01>, + <0x0008C065 0x01>, + <0x0008C08A 0x01>, + <0x0008C08B 0x01>, + <0x0008C0C5 0x01>; reg-names = "PDR", "PODR", "PIDR", "PMR", "ODR0", "ODR1", "PCR"; pinmux = <&pinmux5>; status = "disabled"; @@ -290,12 +291,12 @@ ngpios = <6>; port = <6>; reg = <0x0008C006 0x01>, - <0x0008C026 0x01>, - <0x0008C046 0x01>, - <0x0008C066 0x01>, - <0x0008C08C 0x01>, - <0x0008C08D 0x01>, - <0x0008C0C6 0x01>; + <0x0008C026 0x01>, + <0x0008C046 0x01>, + <0x0008C066 0x01>, + <0x0008C08C 0x01>, + <0x0008C08D 0x01>, + <0x0008C0C6 0x01>; reg-names = "PDR", "PODR", "PIDR", "PMR", "ODR0", "ODR1", "PCR"; pinmux = <&pinmux5>; status = "disabled"; @@ -308,16 +309,16 @@ ngpios = <7>; port = <7>; reg = <0x0008C007 0x01>, - <0x0008C027 0x01>, - <0x0008C047 0x01>, - <0x0008C067 0x01>, - <0x0008C08E 0x01>, - <0x0008C08F 0x01>, - <0x0008C0C7 0x01>, - <0x0008C0E7 0x01>, - <0x0008C12F 0x01>; + <0x0008C027 0x01>, + <0x0008C047 0x01>, + <0x0008C067 0x01>, + <0x0008C08E 0x01>, + <0x0008C08F 0x01>, + <0x0008C0C7 0x01>, + <0x0008C0E7 0x01>, + <0x0008C12F 0x01>; reg-names = "PDR", "PODR", "PIDR", "PMR", "ODR0", "ODR1", "PCR", - "DSCR", "DSCR2"; + "DSCR", "DSCR2"; pinmux = <&pinmux7>; status = "disabled"; }; @@ -329,15 +330,15 @@ ngpios = <3>; port = <8>; reg = <0x0008C008 0x01>, - <0x0008C028 0x01>, - <0x0008C048 0x01>, - <0x0008C068 0x01>, - <0x0008C090 0x01>, - <0x0008C0C8 0x01>, - <0x0008C0E8 0x01>, - <0x0008C130 0x01>; + <0x0008C028 0x01>, + <0x0008C048 0x01>, + <0x0008C068 0x01>, + <0x0008C090 0x01>, + <0x0008C0C8 0x01>, + <0x0008C0E8 0x01>, + <0x0008C130 0x01>; reg-names = "PDR", "PODR", "PIDR", "PMR", "ODR0", "PCR", "DSCR", - "DSCR2"; + "DSCR2"; pinmux = <&pinmux8>; status = "disabled"; }; @@ -349,16 +350,16 @@ ngpios = <7>; port = <9>; reg = <0x0008C009 0x01>, - <0x0008C029 0x01>, - <0x0008C049 0x01>, - <0x0008C069 0x01>, - <0x0008C092 0x01>, - <0x0008C093 0x01>, - <0x0008C0C9 0x01>, - <0x0008C0E9 0x01>, - <0x0008C131 0x01>; + <0x0008C029 0x01>, + <0x0008C049 0x01>, + <0x0008C069 0x01>, + <0x0008C092 0x01>, + <0x0008C093 0x01>, + <0x0008C0C9 0x01>, + <0x0008C0E9 0x01>, + <0x0008C131 0x01>; reg-names = "PDR", "PODR", "PIDR", "PMR", "ODR0", "ODR1", "PCR", - "DSCR", "DSCR2"; + "DSCR", "DSCR2"; pinmux = <&pinmux9>; status = "disabled"; }; @@ -370,15 +371,15 @@ ngpios = <6>; port = <10>; reg = <0x0008C00A 0x01>, - <0x0008C02A 0x01>, - <0x0008C04A 0x01>, - <0x0008C06A 0x01>, - <0x0008C094 0x01>, - <0x0008C095 0x01>, - <0x0008C0CA 0x01>, - <0x0008C0EA 0x01>; + <0x0008C02A 0x01>, + <0x0008C04A 0x01>, + <0x0008C06A 0x01>, + <0x0008C094 0x01>, + <0x0008C095 0x01>, + <0x0008C0CA 0x01>, + <0x0008C0EA 0x01>; reg-names = "PDR", "PODR", "PIDR", "PMR", "ODR0", "ODR1", - "PCR", "DSCR"; + "PCR", "DSCR"; pinmux = <&pinmuxa>; status = "disabled"; }; @@ -390,16 +391,16 @@ ngpios = <8>; port = <11>; reg = <0x0008C00B 0x01>, - <0x0008C02B 0x01>, - <0x0008C04B 0x01>, - <0x0008C06B 0x01>, - <0x0008C096 0x01>, - <0x0008C097 0x01>, - <0x0008C0CB 0x01>, - <0x0008C0EB 0x01>, - <0x0008C133 0x01>; + <0x0008C02B 0x01>, + <0x0008C04B 0x01>, + <0x0008C06B 0x01>, + <0x0008C096 0x01>, + <0x0008C097 0x01>, + <0x0008C0CB 0x01>, + <0x0008C0EB 0x01>, + <0x0008C133 0x01>; reg-names = "PDR", "PODR", "PIDR", "PMR", "ODR0", "ODR1", "PCR", - "DSCR", "DSCR2"; + "DSCR", "DSCR2"; pinmux = <&pinmuxb>; status = "disabled"; }; @@ -411,16 +412,16 @@ ngpios = <8>; port = <13>; reg = <0x0008C00D 0x01>, - <0x0008C02D 0x01>, - <0x0008C04D 0x01>, - <0x0008C06D 0x01>, - <0x0008C09A 0x01>, - <0x0008C09B 0x01>, - <0x0008C0CD 0x01>, - <0x0008C0ED 0x01>, - <0x0008C135 0x01>; + <0x0008C02D 0x01>, + <0x0008C04D 0x01>, + <0x0008C06D 0x01>, + <0x0008C09A 0x01>, + <0x0008C09B 0x01>, + <0x0008C0CD 0x01>, + <0x0008C0ED 0x01>, + <0x0008C135 0x01>; reg-names = "PDR", "PODR", "PIDR", "PMR", "ODR0", "ODR1", "PCR", - "DSCR", "DSCR2"; + "DSCR", "DSCR2"; pinmux = <&pinmuxd>; status = "disabled"; }; @@ -432,13 +433,13 @@ ngpios = <6>; port = <14>; reg = <0x0008C00E 0x01>, - <0x0008C02E 0x01>, - <0x0008C04E 0x01>, - <0x0008C06E 0x01>, - <0x0008C09C 0x01>, - <0x0008C09D 0x01>, - <0x0008C0CE 0x01>, - <0x0008C0EE 0x01>; + <0x0008C02E 0x01>, + <0x0008C04E 0x01>, + <0x0008C06E 0x01>, + <0x0008C09C 0x01>, + <0x0008C09D 0x01>, + <0x0008C0CE 0x01>, + <0x0008C0EE 0x01>; reg-names = "PDR", "PODR", "PIDR", "PMR", "ODR0", "ODR1", "PCR", "DSCR"; pinmux = <&pinmuxe>; status = "disabled"; @@ -451,12 +452,12 @@ ngpios = <2>; port = <23>; reg = <0x0008C016 0x01>, - <0x0008C036 0x01>, - <0x0008C056 0x01>, - <0x0008C076 0x01>, - <0x0008C0D6 0x01>, - <0x0008C0F6 0x01>, - <0x0008C0AD 0x01>; + <0x0008C036 0x01>, + <0x0008C056 0x01>, + <0x0008C076 0x01>, + <0x0008C0D6 0x01>, + <0x0008C0F6 0x01>, + <0x0008C0AD 0x01>; reg-names = "PDR", "PODR", "PIDR", "PMR", "PCR", "DSCR", "ODR1"; pinmux = <&pinmuxn>; status = "disabled"; @@ -536,8 +537,8 @@ #address-cells = <1>; #size-cells = <1>; reg = <0x00088002 0x02>, - <0x00088004 0x02>, - <0x00088006 0x02>; + <0x00088004 0x02>, + <0x00088006 0x02>; reg-names = "CMCR", "CMCNT", "CMCOR"; interrupts = <28 1>; interrupt-names = "cmi"; @@ -547,8 +548,8 @@ cmt1: timer@88008 { compatible = "renesas,rx-timer-cmt"; reg = <0x00088008 0x02>, - <0x0008800A 0x02>, - <0x0008800C 0x02>; + <0x0008800A 0x02>, + <0x0008800C 0x02>; reg-names = "CMCR", "CMCNT", "CMCOR"; interrupts = <29 1>; interrupt-names = "cmi"; @@ -562,5 +563,77 @@ zephyr,memory-region = "OFSM"; status = "okay"; }; + + group_irq_be0: grp_intc@87600 { + compatible = "renesas,rx-grp-intc"; + interrupt-controller; + label = "be0"; + reg = <0x00087600 0x04>, + <0x00087640 0x04>; + reg-names = "GRP", "GEN"; + interrupts = <106 4>; + status = "disabled"; + #interrupt-cells = <2>; + }; + + group_irq_bl0: grp_intc@87630 { + compatible = "renesas,rx-grp-intc"; + interrupt-controller; + label = "bl0"; + reg = <0x00087630 0x04>, + <0x00087670 0x04>; + reg-names = "GRP", "GEN"; + interrupts = <110 4>; + status = "okay"; + #interrupt-cells = <2>; + }; + + group_irq_bl1: grp_intc@87634 { + compatible = "renesas,rx-grp-intc"; + interrupt-controller; + label = "bl1"; + reg = <0x00087634 0x04>, + <0x00087674 0x04>; + reg-names = "GRP", "GEN"; + interrupts = <111 4>; + status = "disabled"; + #interrupt-cells = <2>; + }; + + group_irq_bl2: grp_intc@87638 { + compatible = "renesas,rx-grp-intc"; + interrupt-controller; + label = "bl2"; + reg = <0x00087638 0x04>, + <0x00087678 0x04>; + reg-names = "GRP", "GEN"; + interrupts = <107 4>; + status = "disabled"; + #interrupt-cells = <2>; + }; + + group_irq_al0: grp_intc@87830 { + compatible = "renesas,rx-grp-intc"; + interrupt-controller; + label = "al0"; + reg = <0x00087830 0x04>, + <0x00087870 0x04>; + reg-names = "GRP", "GEN"; + interrupts = <112 4>; + status = "disabled"; + #interrupt-cells = <2>; + }; + + group_irq_al1: grp_intc@87834 { + compatible = "renesas,rx-grp-intc"; + interrupt-controller; + label = "al1"; + reg = <0x00087834 0x04>, + <0x00087874 0x04>; + reg-names = "GRP", "GEN"; + interrupts = <113 4>; + status = "disabled"; + #interrupt-cells = <2>; + }; }; }; diff --git a/include/zephyr/drivers/interrupt_controller/intc_renesas_rx_grp_int.h b/include/zephyr/drivers/interrupt_controller/intc_renesas_rx_grp_int.h new file mode 100644 index 0000000000000..cd5b1fa134745 --- /dev/null +++ b/include/zephyr/drivers/interrupt_controller/intc_renesas_rx_grp_int.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_RENESAS_RX_GRP_INT_H_ +#define ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_RENESAS_RX_GRP_INT_H_ + +#include "platform.h" + +/** + * @brief Enables or disables a group interrupt for a given interrupt vector. + * + * @param dev RX group interrupt device. + * @param vector The interrupt vector (bsp_int_src_t) to be controlled. + * @param set A boolean indicating enable or disable. + * + * @retval 0 If successful. + * @retval -EINVAL if the interrupt control operation fails. + */ +int rx_grp_intc_set_grp_int(const struct device *dev, bsp_int_src_t vector, bool set); + +/** + * @brief Enables or disables a specific group interrupt source by setting or clearing the + * corresponding bit (vector_num) in the group interrupt register. + * + * @param dev RX group interrupt device. + * @param vector_num Index of the interrupt source (0–31) within the group. + * @param set A boolean indicating enable or disable. + * + * @retval 0 If successful. + * @retval -EINVAL if the interrupt control operation fails. + */ +int rx_grp_intc_set_gen(const struct device *dev, uint8_t vector_num, bool set); + +/** + * @brief Registers a callback function for a specific group interrupt source (vector). When the + * interrupt is triggered, the provided callback is executed with the associated context. + * + * @param dev RX group interrupt device. + * @param vector Interrupt source to attach the callback to. + * @param callback Function to be called when the interrupt occurs. + * @param context Pointer to user-defined data passed to the callback. + * + * @retval 0 if successful. + * @retval -EINVAL if the callback registration fails. + */ +int rx_grp_intc_set_callback(const struct device *dev, bsp_int_src_t vector, bsp_int_cb_t callback, + void *context); + +#endif /* ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_RENESAS_RX_GRP_INT_H_ */ From 2e7018c9b7816a1b7f179d5db03065983fcae439 Mon Sep 17 00:00:00 2001 From: Quy Tran Date: Tue, 23 Sep 2025 13:45:23 +0700 Subject: [PATCH 3/5] drivers: serial: Add support for group interrupt in the serial driver Apply the grp irq support in serial driver for MCB-RX26T Signed-off-by: Quy Tran --- boards/renesas/mcb_rx26t/mcb_rx26t_defconfig | 2 +- drivers/serial/uart_renesas_rx_sci.c | 369 ++++++++++++++++--- dts/rx/renesas/rx26t-common.dtsi | 28 +- 3 files changed, 328 insertions(+), 71 deletions(-) diff --git a/boards/renesas/mcb_rx26t/mcb_rx26t_defconfig b/boards/renesas/mcb_rx26t/mcb_rx26t_defconfig index 47ef28e9e96dd..c23cdd58f2a0c 100644 --- a/boards/renesas/mcb_rx26t/mcb_rx26t_defconfig +++ b/boards/renesas/mcb_rx26t/mcb_rx26t_defconfig @@ -6,7 +6,7 @@ CONFIG_GPIO=y # Enable UART driver CONFIG_SERIAL=y -CONFIG_UART_INTERRUPT_DRIVEN=n +CONFIG_UART_INTERRUPT_DRIVEN=y # Enable console CONFIG_CONSOLE=y diff --git a/drivers/serial/uart_renesas_rx_sci.c b/drivers/serial/uart_renesas_rx_sci.c index afbc0d003c447..fed13d0f71ddd 100644 --- a/drivers/serial/uart_renesas_rx_sci.c +++ b/drivers/serial/uart_renesas_rx_sci.c @@ -17,6 +17,10 @@ #include #include +#ifdef CONFIG_RENESAS_RX_GRP_INTC +#include +#endif + #include "r_sci_rx_if.h" #include "iodefine_sci.h" @@ -30,7 +34,7 @@ #error Unknown SOC, not (yet) supported. #endif -#if defined(CONFIG_UART_ASYNC_API) +#ifdef CONFIG_UART_ASYNC_API #include #endif @@ -41,7 +45,14 @@ LOG_MODULE_REGISTER(rx_uart_sci, CONFIG_UART_LOG_LEVEL); #define DEV_CFG(dev) ((const struct uart_rx_sci_config *const)(dev)->config) #define DEV_BASE(dev) (DEV_CFG(dev)->regs) -#if defined(CONFIG_UART_INTERRUPT_DRIVEN) +#ifdef CONFIG_RENESAS_RX_GRP_INTC +#define _SCI_INT_TEI_SRC(chan) BSP_INT_SRC_BL0_SCI##chan##_TEI##chan +#define SCI_INT_TEI_SRC(chan) _SCI_INT_TEI_SRC(chan) +#define _SCI_INT_ERI_SRC(chan) BSP_INT_SRC_BL0_SCI##chan##_ERI##chan +#define SCI_INT_ERI_SRC(chan) _SCI_INT_ERI_SRC(chan) +#endif + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN static void uart_rx_sci_txi_isr(const struct device *dev); #endif @@ -72,15 +83,28 @@ struct uart_rx_sci_data { sci_hdl_t hdl; struct uart_config uart_config; sci_cfg_t sci_config; -#if defined(CONFIG_UART_INTERRUPT_DRIVEN) +#ifdef CONFIG_UART_INTERRUPT_DRIVEN uint8_t rxi_irq; uint8_t txi_irq; +#ifdef CONFIG_RENESAS_RX_GRP_INTC + bsp_int_src_t tei_src; + bsp_int_src_t eri_src; + /* Group interrupt controller for the transmit end interrupt (TEI) */ + const struct device *tei_ctrl; + /* Group interrupt number for the transmit end interrupt (TEI) */ + uint8_t tei_num; + /* Group interrupt controller for the error interrupt (ERI) */ + const struct device *eri_ctrl; + /* Group interrupt number for the error interrupt (ERI) */ + uint8_t eri_num; +#else /* CONFIG_RENESAS_RX_GRP_INTC */ uint8_t tei_irq; uint8_t eri_irq; +#endif /* CONFIG_RENESAS_RX_GRP_INTC */ uart_irq_callback_user_data_t user_cb; void *user_cb_data; -#endif -#if defined(CONFIG_UART_ASYNC_API) +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +#ifdef CONFIG_UART_ASYNC_API uart_callback_t async_user_cb; void *async_user_cb_data; @@ -102,9 +126,146 @@ struct uart_rx_sci_data { transfer_info_t rx_transfer_info; transfer_info_t tx_transfer_info; -#endif +#endif /* CONFIG_UART_ASYNC_API */ }; +#if defined(CONFIG_UART_ASYNC_API) +static inline void async_user_callback(const struct device *dev, struct uart_event *event) +{ + struct uart_rx_sci_data *data = dev->data; + + if (data->async_user_cb) { + data->async_user_cb(dev, event, data->async_user_cb_data); + } +} +#endif + +#if defined(CONFIG_UART_INTERRUPT_DRIVEN) || defined(CONFIG_UART_ASYNC_API) +#ifdef CONFIG_RENESAS_RX_GRP_INTC +void uart_rx_sci_tei_isr(bsp_int_cb_args_t *p_args) +{ + struct device *sci_dev = (struct device *)(p_args->p_context); + volatile struct st_sci *sci = (struct st_sci *)DEV_BASE(sci_dev); + struct uart_rx_sci_data *data = sci_dev->data; + + /* Disable SCI.SCR.TEIE */ + sci->SCR.BIT.TEIE = 0; + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + if (data->user_cb != NULL) { + data->user_cb(sci_dev, data->user_cb_data); + } +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +#ifdef CONFIG_UART_ASYNC_API + /* TODO */ + k_work_cancel_delayable(&data->tx_timeout); + struct uart_event event = { + .type = UART_TX_DONE, + .data.tx.buf = (uint8_t *)data->tx_transfer_info.p_src, + .data.tx.len = data->tx_buf_cap, + }; + async_user_callback(sci_dev, &event); +#endif /* CONFIG_UART_ASYNC_API */ +} + +void uart_rx_sci_eri_isr(bsp_int_cb_args_t *p_args) +{ + struct device *sci_dev = (struct device *)(p_args->p_context); + struct uart_rx_sci_data *data = sci_dev->data; + +#ifdef CONFIG_UART_INTERRUPT_DRIVEN + if (data->user_cb != NULL) { + data->user_cb(sci_dev, data->user_cb_data); + } +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +#ifdef CONFIG_UART_ASYNC_API + /* TODO */ + volatile struct st_sci *sci = (struct st_sci *)DEV_BASE(sci_dev); + + uint8_t reason; + + if (sci->SSR.BIT.ORER) { + reason = UART_ERROR_OVERRUN; + } else if (sci->SSR.BIT.PER) { + reason = UART_ERROR_PARITY; + } else if (sci->SSR.BIT.FER) { + reason = UART_ERROR_FRAMING; + } else { + reason = UART_ERROR_OVERRUN; + } + + /* Clear error flags */ + sci->SSR.BYTE &= + ~(BIT(R_SCI_SSR_ORER_Pos) | BIT(R_SCI_SSR_PER_Pos) | BIT(R_SCI_SSR_FER_Pos)); + + k_work_cancel_delayable(&data->rx_timeout_work); + struct uart_event event = { + .type = UART_RX_STOPPED, + .data.rx_stop.reason = reason, + .data.rx_stop.data.buf = (uint8_t *)data->rx_buffer, + .data.rx_stop.data.offset = 0, + .data.rx_stop.data.len = data->rx_buf_cap - data->rx_buf_len - data->rx_buf_offset, + }; + async_user_callback(sci_dev, &event); +#endif /* CONFIG_UART_ASYNC_API */ +} + +static inline int uart_rx_sci_tei_grp_enable(const struct device *dev) +{ + struct uart_rx_sci_data *data = dev->data; + int err; + + err = rx_grp_intc_set_callback(data->tei_ctrl, (bsp_int_src_t)data->tei_src, + (bsp_int_cb_t)uart_rx_sci_tei_isr, (void *)dev); + if (err != 0) { + LOG_ERR("Failed to set callback for group interrupt TEI: %d", err); + return err; + } + + err = rx_grp_intc_set_gen(data->tei_ctrl, data->tei_num, true); + if (err != 0) { + LOG_ERR("Failed to allow interrupt request for TEI: %d", err); + return err; + } + + err = rx_grp_intc_set_grp_int(data->tei_ctrl, (bsp_int_src_t)data->tei_src, true); + if (err != 0) { + LOG_ERR("Failed to enable group interrupt for TEI: %d", err); + return err; + } + + return 0; +} + +static inline int uart_rx_sci_eri_grp_enable(const struct device *dev) +{ + struct uart_rx_sci_data *data = dev->data; + int err; + + err = rx_grp_intc_set_callback(data->eri_ctrl, (bsp_int_src_t)data->eri_src, + (bsp_int_cb_t)uart_rx_sci_eri_isr, (void *)dev); + if (err != 0) { + LOG_ERR("Failed to set callback for group interrupt ERI: %d", err); + return err; + } + + err = rx_grp_intc_set_gen(data->eri_ctrl, data->eri_num, true); + if (err != 0) { + LOG_ERR("Failed to allow interrupt request for ERI: %d", err); + return err; + } + + err = rx_grp_intc_set_grp_int(data->eri_ctrl, (bsp_int_src_t)data->eri_src, true); + if (err != 0) { + LOG_ERR("Failed to enable group interrupt for ERI: %d", err); + return err; + } + + return 0; +} +#endif /* CONFIG_RENESAS_RX_GRP_INTC */ +#endif /* CONFIG_UART_INTERRUPT_DRIVEN || CONFIG_UART_ASYNC_API */ + static int uart_rx_sci_poll_in(const struct device *dev, unsigned char *c) { volatile struct st_sci *sci = (struct st_sci *)DEV_BASE(dev); @@ -129,8 +290,19 @@ static void uart_rx_sci_poll_out(const struct device *dev, unsigned char c) while (sci->SSR.BIT.TEND == 0U) { } +#ifdef CONFIG_RENESAS_RX_GRP_INTC + struct uart_rx_sci_data *data = dev->data; + /* Disable ICU.GEN and SCI.SCR.TEIE */ + rx_grp_intc_set_gen(data->tei_ctrl, data->tei_num, false); + sci->SCR.BIT.TEIE = 0; +#endif /* CONFIG_RENESAS_RX_GRP_INTC */ sci->TDR = c; +#ifdef CONFIG_RENESAS_RX_GRP_INTC + /* Enable ICU.GEN and SCI.SCR.TEIE */ + sci->SCR.BIT.TEIE = 1; + rx_grp_intc_set_gen(data->tei_ctrl, data->tei_num, true); +#endif /* CONFIG_RENESAS_RX_GRP_INTC */ } static int uart_rx_err_check(const struct device *dev) @@ -222,7 +394,6 @@ static int uart_rx_sci_apply_config(const struct uart_config *config, sci_cfg_t } #ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE - static int uart_rx_configure(const struct device *dev, const struct uart_config *cfg) { int err; @@ -259,21 +430,31 @@ static int uart_rx_config_get(const struct device *dev, struct uart_config *cfg) return 0; } - #endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */ #ifdef CONFIG_UART_INTERRUPT_DRIVEN - static int uart_rx_fifo_fill(const struct device *dev, const uint8_t *tx_data, int size) { volatile struct st_sci *sci = (struct st_sci *)DEV_BASE(dev); uint8_t num_tx = 0U; +#ifdef CONFIG_RENESAS_RX_GRP_INTC + struct uart_rx_sci_data *data = dev->data; + /* Disable ICU.GEN and SCI.SCR.TEIE*/ + rx_grp_intc_set_gen(data->tei_ctrl, data->tei_num, false); + sci->SCR.BIT.TEIE = 0; +#endif if (size > 0 && sci->SSR.BIT.TDRE) { /* Send a character (8bit , parity none) */ sci->TDR = tx_data[num_tx++]; } +#ifdef CONFIG_RENESAS_RX_GRP_INTC + /* Enable ICU.GEN and SCI.SCR.TEIE*/ + sci->SCR.BIT.TEIE = 1; + rx_grp_intc_set_gen(data->tei_ctrl, data->tei_num, true); +#endif + return num_tx; } @@ -292,26 +473,48 @@ static int uart_rx_fifo_read(const struct device *dev, uint8_t *rx_data, const i static void uart_rx_irq_tx_enable(const struct device *dev) { - struct uart_rx_sci_data *data = dev->data; volatile struct st_sci *sci = (struct st_sci *)DEV_BASE(dev); - sci->SCR.BYTE |= (BIT(R_SCI_SCR_TIE_Pos) | BIT(R_SCI_SCR_TEIE_Pos)); + +#ifdef CONFIG_RENESAS_RX_GRP_INTC + /* Allows the interrupt request for the tei interrupt */ + int err = uart_rx_sci_tei_grp_enable(dev); + + if (err != 0) { + LOG_ERR("Failed to enable group interrupt TEI: %d", err); + return; + } +#else + struct uart_rx_sci_data *data = dev->data; irq_enable(data->tei_irq); #ifdef CONFIG_PM_DEVICE pm_device_busy_set(dev); #endif +#endif /* CONFIG_RENESAS_RX_GRP_INTC */ } static void uart_rx_irq_tx_disable(const struct device *dev) { - struct uart_rx_sci_data *data = dev->data; volatile struct st_sci *sci = (struct st_sci *)DEV_BASE(dev); sci->SCR.BYTE &= ~(BIT(R_SCI_SCR_TIE_Pos) | BIT(R_SCI_SCR_TEIE_Pos)); +#ifdef CONFIG_RENESAS_RX_GRP_INTC + struct uart_rx_sci_data *data = dev->data; + int err = 0; + + /* Disable the interrupt request for the tei interrupt */ + err = rx_grp_intc_set_gen(data->tei_ctrl, data->tei_num, false); + if (err != 0) { + LOG_ERR("Failed to disable group interrupt TEI: %d", err); + return; + } +#else + struct uart_rx_sci_data *data = dev->data; irq_disable(data->tei_irq); #ifdef CONFIG_PM_DEVICE pm_device_busy_clear(dev); #endif +#endif /* CONFIG_RENESAS_RX_GRP_INTC */ } static int uart_rx_irq_tx_ready(const struct device *dev) @@ -337,6 +540,16 @@ static void uart_rx_irq_rx_enable(const struct device *dev) #ifdef CONFIG_PM_DEVICE pm_device_busy_set(dev); #endif + +#ifdef CONFIG_RENESAS_RX_GRP_INTC + /* Allows the interrupt request for the tei interrupt */ + int err = uart_rx_sci_eri_grp_enable(dev); + + if (err != 0) { + LOG_ERR("Failed to enable group interrupt ERI: %d", err); + return; + } +#endif /* CONFIG_RENESAS_RX_GRP_INTC */ } static void uart_rx_irq_rx_disable(const struct device *dev) @@ -358,16 +571,37 @@ static int uart_rx_irq_rx_ready(const struct device *dev) static void uart_rx_irq_err_enable(const struct device *dev) { +#ifndef CONFIG_RENESAS_RX_GRP_INTC struct uart_rx_sci_data *data = dev->data; - irq_enable(data->eri_irq); +#else + /* Allows the interrupt request for the eri interrupt */ + int err = uart_rx_sci_eri_grp_enable(dev); + + if (err != 0) { + LOG_ERR("Failed to enable group interrupt ERI: %d", err); + return; + } +#endif /* CONFIG_RENESAS_RX_GRP_INTC */ } static void uart_rx_irq_err_disable(const struct device *dev) { - struct uart_rx_sci_data *data = dev->data; +#ifndef CONFIG_RENESAS_RX_GRP_INTC + struct uart_rx_sci_data *data = dev->data; irq_disable(data->eri_irq); +#else + /* Disable the interrupt request for the eri interrupt */ + struct uart_rx_sci_data *data = dev->data; + int err = 0; + + err = rx_grp_intc_set_gen(data->eri_ctrl, data->eri_num, false); + if (err != 0) { + LOG_ERR("Failed to disable interrupt request for ERI: %d", err); + return; + } +#endif /* CONFIG_RENESAS_RX_GRP_INTC */ } static int uart_rx_irq_is_pending(const struct device *dev) @@ -398,7 +632,6 @@ static void uart_rx_irq_callback_set(const struct device *dev, uart_irq_callback data->user_cb = cb; data->user_cb_data = cb_data; } - #endif /* CONFIG_UART_INTERRUPT_DRIVEN */ #ifdef CONFIG_UART_ASYNC_API @@ -421,12 +654,22 @@ static inline void disable_tx(const struct device *dev) static inline void enable_tx(const struct device *dev) { - struct uart_rx_sci_data *data = dev->data; volatile struct st_sci *sci = (struct st_sci *)DEV_BASE(dev); sci->SCR.BIT.TIE = 1; sci->SCR.BIT.TE = 1; +#ifdef CONFIG_RENESAS_RX_GRP_INTC + /* Allows the interrupt request for the tei interrupt */ + int err = uart_rx_sci_tei_grp_enable(dev); + + if (err != 0) { + LOG_ERR("Failed to enable group interrupt TEI: %d", err); + return; + } +#else + struct uart_rx_sci_data *data = dev->data; irq_enable(data->tei_irq); +#endif /* CONFIG_RENESAS_RX_GRP_INTC */ } static int uart_rx_sci_async_callback_set(const struct device *dev, uart_callback_t cb, @@ -438,7 +681,7 @@ static int uart_rx_sci_async_callback_set(const struct device *dev, uart_callbac data->async_user_cb = cb; data->async_user_cb_data = cb_data; -#if defined(CONFIG_UART_EXCLUSIVE_API_CALLBACKS) +#ifdef CONFIG_UART_EXCLUSIVE_API_CALLBACKS data->user_cb = NULL; data->user_cb_data = NULL; #endif @@ -523,7 +766,6 @@ static int configure_rx_transfer(const struct device *dev, uint8_t *buf, size_t p_info->p_src = (void *)&sci->RDR; err = dtc_renesas_rx_configuration(data->dtc, data->rxi_irq, p_info); - if (err != 0) { return err; } @@ -565,15 +807,6 @@ static int uart_rx_sci_async_tx(const struct device *dev, const uint8_t *buf, si return err; } -static inline void async_user_callback(const struct device *dev, struct uart_event *event) -{ - struct uart_rx_sci_data *data = dev->data; - - if (data->async_user_cb) { - data->async_user_cb(dev, event, data->async_user_cb_data); - } -} - static inline void async_rx_release_buf(const struct device *dev) { struct uart_rx_sci_data *data = dev->data; @@ -798,7 +1031,6 @@ static void uart_rx_sci_tx_timeout_handler(struct k_work *work) uart_rx_sci_async_tx_abort(data->dev); } - #endif /* CONFIG_UART_ASYNC_API */ static int uart_rx_init(const struct device *dev) @@ -819,7 +1051,7 @@ static int uart_rx_init(const struct device *dev) return ret; } -#if defined(CONFIG_UART_ASYNC_API) +#ifdef CONFIG_UART_ASYNC_API k_work_init_delayable(&data->rx_timeout_work, uart_rx_sci_rx_timeout_handler); k_work_init_delayable(&data->tx_timeout, uart_rx_sci_tx_timeout_handler); #endif @@ -903,17 +1135,17 @@ static DEVICE_API(uart, uart_rx_driver_api) = { #endif /* CONFIG_UART_ASYNC_API */ }; -#if CONFIG_UART_INTERRUPT_DRIVEN || CONFIG_UART_ASYNC_API +#if defined(CONFIG_UART_INTERRUPT_DRIVEN) || defined(CONFIG_UART_ASYNC_API) static void uart_rx_sci_rxi_isr(const struct device *dev) { -#if defined(CONFIG_UART_INTERRUPT_DRIVEN) +#ifdef CONFIG_UART_INTERRUPT_DRIVEN struct uart_rx_sci_data *data = dev->data; if (data->user_cb != NULL) { data->user_cb(dev, data->user_cb_data); } -#endif -#if defined(CONFIG_UART_ASYNC_API) +#endif /* CONFIG_UART_INTERRUPT_DRIVEN*/ +#ifdef CONFIG_UART_ASYNC_API if (data->rx_timeout != SYS_FOREVER_US && data->rx_timeout != 0) { k_work_reschedule(&data->rx_timeout_work, Z_TIMEOUT_US(data->rx_timeout)); } @@ -933,36 +1165,37 @@ static void uart_rx_sci_rxi_isr(const struct device *dev) async_rx_disable(dev); } } -#endif +#endif /* CONFIG_UART_ASYNC_API */ } static void uart_rx_sci_txi_isr(const struct device *dev) { -#if defined(CONFIG_UART_INTERRUPT_DRIVEN) +#ifdef CONFIG_UART_INTERRUPT_DRIVEN struct uart_rx_sci_data *data = dev->data; if (data->user_cb != NULL) { data->user_cb(dev, data->user_cb_data); } -#endif -#if defined(CONFIG_UART_ASYNC_API) +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +#ifdef CONFIG_UART_ASYNC_API struct st_sci *sci = (struct st_sci *)DEV_BASE(dev); sci->SCR.BIT.TEIE = 1; sci->SCR.BIT.TIE = 0; -#endif +#endif /* CONFIG_UART_ASYNC_API */ } +#ifndef CONFIG_RENESAS_RX_GRP_INTC static void uart_rx_sci_tei_isr(const struct device *dev) { -#if defined(CONFIG_UART_INTERRUPT_DRIVEN) +#ifdef CONFIG_UART_INTERRUPT_DRIVEN struct uart_rx_sci_data *data = dev->data; if (data->user_cb != NULL) { data->user_cb(dev, data->user_cb_data); } -#endif -#if defined(CONFIG_UART_ASYNC_API) +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +#ifdef CONFIG_UART_ASYNC_API /* TODO */ struct st_sci *sci = (struct st_sci *)DEV_BASE(dev); @@ -978,19 +1211,19 @@ static void uart_rx_sci_tei_isr(const struct device *dev) pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); pm_policy_state_lock_put(PM_STATE_STANDBY, PM_ALL_SUBSTATES); #endif -#endif +#endif /* CONFIG_UART_ASYNC_API */ } static void uart_rx_sci_eri_isr(const struct device *dev) { -#if defined(CONFIG_UART_INTERRUPT_DRIVEN) +#ifdef CONFIG_UART_INTERRUPT_DRIVEN struct uart_rx_sci_data *data = dev->data; if (data->user_cb != NULL) { data->user_cb(dev, data->user_cb_data); } -#endif -#if defined(CONFIG_UART_ASYNC_API) +#endif /* CONFIG_UART_INTERRUPT_DRIVEN */ +#ifdef CONFIG_UART_ASYNC_API /* TODO */ struct st_sci *sci = (struct st_sci *)DEV_BASE(dev); uint8_t reason; @@ -1020,20 +1253,11 @@ static void uart_rx_sci_eri_isr(const struct device *dev) async_user_callback(dev, &event); #endif } -#endif - -#if defined(CONFIG_SOC_SERIES_RX26T) -#define UART_RX_SCI_CONFIG_INIT(index) -#else -#define UART_RX_SCI_CONFIG_INIT(index) \ - .rxi_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq), \ - .txi_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq), \ - .tei_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), tei, irq), \ - .eri_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), eri, irq), -#endif +#endif /* CONFIG_RENESAS_RX_GRP_INTC */ +#endif /* CONFIG_UART_INTERRUPT_DRIVEN || CONFIG_UART_ASYNC_API */ #if CONFIG_UART_INTERRUPT_DRIVEN || CONFIG_UART_ASYNC_API -#ifndef CONFIG_SOC_SERIES_RX26T +#ifndef CONFIG_RENESAS_RX_GRP_INTC #define UART_RX_SCI_IRQ_INIT(index) \ do { \ IRQ_CONNECT(DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq), \ @@ -1052,9 +1276,38 @@ static void uart_rx_sci_eri_isr(const struct device *dev) irq_enable(DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq)); \ irq_enable(DT_IRQ_BY_NAME(DT_INST_PARENT(index), tei, irq)); \ } while (0) + +#define UART_RX_SCI_CONFIG_INIT(index) \ + .rxi_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq), \ + .txi_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq), \ + .tei_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), tei, irq), \ + .eri_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), eri, irq), +#else +#define UART_RX_SCI_IRQ_INIT(index) \ + do { \ + IRQ_CONNECT(DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq), \ + DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, priority), \ + uart_rx_sci_rxi_isr, DEVICE_DT_INST_GET(index), 0); \ + IRQ_CONNECT(DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq), \ + DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, priority), \ + uart_rx_sci_txi_isr, DEVICE_DT_INST_GET(index), 0); \ + irq_enable(DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq)); \ + irq_enable(DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq)); \ + } while (0) + +#define UART_RX_SCI_CONFIG_INIT(index) \ + .rxi_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq), \ + .txi_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq), \ + .tei_src = SCI_INT_TEI_SRC(DT_PROP(DT_INST_PARENT(index), channel)), \ + .eri_src = SCI_INT_ERI_SRC(DT_PROP(DT_INST_PARENT(index), channel)), \ + .tei_ctrl = DEVICE_DT_GET(DT_IRQ_INTC_BY_NAME(DT_INST_PARENT(index), tei)), \ + .tei_num = DT_IRQ_BY_NAME(DT_INST_PARENT(index), tei, irq), \ + .eri_ctrl = DEVICE_DT_GET(DT_IRQ_INTC_BY_NAME(DT_INST_PARENT(index), eri)), \ + .eri_num = DT_IRQ_BY_NAME(DT_INST_PARENT(index), eri, irq), #endif #else #define UART_RX_SCI_IRQ_INIT(index) +#define UART_RX_SCI_CONFIG_INIT(index) #endif #if defined(CONFIG_UART_ASYNC_API) @@ -1089,7 +1342,7 @@ static void uart_rx_sci_eri_isr(const struct device *dev) }, #else #define UART_RX_SCI_ASYNC_INIT(index) -#endif +#endif /* CONFIG_UART_ASYNC_API */ #define UART_RX_INIT(index) \ PINCTRL_DT_DEFINE(DT_INST_PARENT(index)); \ diff --git a/dts/rx/renesas/rx26t-common.dtsi b/dts/rx/renesas/rx26t-common.dtsi index cfddc9c8595f2..0a25b36455cdc 100644 --- a/dts/rx/renesas/rx26t-common.dtsi +++ b/dts/rx/renesas/rx26t-common.dtsi @@ -465,12 +465,13 @@ sci1: sci1@8a020 { compatible = "renesas,rx-sci"; - interrupts = <60 1>, <61 1>; - interrupt-names = "rxi", "txi"; + interrupts-extended = <&icu 60 1>, <&icu 61 1>, + <&group_irq_bl0 2 1>, <&group_irq_bl0 3 1>; + interrupt-names = "rxi", "txi", "tei", "eri"; reg = <0x8A020 0x20>; clocks = <&pclkb MSTPB 30>; - status = "disabled"; channel = <1>; + status = "disabled"; uart { compatible = "renesas,rx-uart-sci"; @@ -480,12 +481,13 @@ sci5: sci5@8a0a0 { compatible = "renesas,rx-sci"; - interrupts = <84 1>, <85 1>; - interrupt-names = "rxi", "txi"; reg = <0x8A0A0 0x20>; clocks = <&pclkb MSTPB 26>; - status = "disabled"; + interrupts-extended = <&icu 84 1>, <&icu 85 1>, + <&group_irq_bl0 10 1>, <&group_irq_bl0 11 1>; + interrupt-names = "rxi", "txi", "tei", "eri"; channel = <5>; + status = "disabled"; uart { compatible = "renesas,rx-uart-sci"; @@ -495,12 +497,13 @@ sci6: sci6@8a0c0 { compatible = "renesas,rx-sci"; - interrupts = <86 1>, <87 1>; - interrupt-names = "rxi", "txi"; + interrupts-extended = <&icu 86 1>, <&icu 87 1>, + <&group_irq_bl0 12 1>, <&group_irq_bl0 13 1>; + interrupt-names = "rxi", "txi", "tei", "eri"; reg = <0x8A0C0 0x20>; clocks = <&pclkb MSTPB 25>; - status = "disabled"; channel = <6>; + status = "disabled"; uart { compatible = "renesas,rx-uart-sci"; @@ -510,12 +513,13 @@ sci12: sci12@8b300 { compatible = "renesas,rx-sci"; - interrupts = <116 1>, <117 1>; - interrupt-names = "rxi", "txi"; + interrupts-extended = <&icu 116 1>, <&icu 117 1>, + <&group_irq_bl0 16 1>, <&group_irq_bl0 17 1>; + interrupt-names = "rxi", "txi", "tei", "eri"; reg = <0x8B300 0x20>; clocks = <&pclkb MSTPB 4>; - status = "disabled"; channel = <12>; + status = "disabled"; uart { compatible = "renesas,rx-uart-sci"; From 33bac2e09e0cf022923a1f389155eb0d897c125f Mon Sep 17 00:00:00 2001 From: Quy Tran Date: Wed, 15 Oct 2025 07:16:07 +0000 Subject: [PATCH 4/5] dts: renesas: rx: Add dtc node support on RX26T Add dtc property node on RX26T dts, and ram section for dtc_vector_table on RX26T SoC for dtc support Signed-off-by: Quy Tran --- dts/rx/renesas/rx26t-common.dtsi | 11 +++++++++++ soc/renesas/rx/rx26t/CMakeLists.txt | 1 + soc/renesas/rx/rx26t/ram_sections.ld | 14 ++++++++++++++ 3 files changed, 26 insertions(+) create mode 100644 soc/renesas/rx/rx26t/ram_sections.ld diff --git a/dts/rx/renesas/rx26t-common.dtsi b/dts/rx/renesas/rx26t-common.dtsi index 0a25b36455cdc..807c4120e6f10 100644 --- a/dts/rx/renesas/rx26t-common.dtsi +++ b/dts/rx/renesas/rx26t-common.dtsi @@ -56,6 +56,13 @@ }; }; + dtc: rx-dtc@82400 { + compatible = "renesas,rx-dtc"; + reg = <0x00082400 0x1c>; + clocks = <&iclk MSTPA 28>; + status = "okay"; + }; + soc { #address-cells = <1>; #size-cells = <1>; @@ -471,6 +478,7 @@ reg = <0x8A020 0x20>; clocks = <&pclkb MSTPB 30>; channel = <1>; + dtc = <&dtc>; status = "disabled"; uart { @@ -487,6 +495,7 @@ <&group_irq_bl0 10 1>, <&group_irq_bl0 11 1>; interrupt-names = "rxi", "txi", "tei", "eri"; channel = <5>; + dtc = <&dtc>; status = "disabled"; uart { @@ -503,6 +512,7 @@ reg = <0x8A0C0 0x20>; clocks = <&pclkb MSTPB 25>; channel = <6>; + dtc = <&dtc>; status = "disabled"; uart { @@ -519,6 +529,7 @@ reg = <0x8B300 0x20>; clocks = <&pclkb MSTPB 4>; channel = <12>; + dtc = <&dtc>; status = "disabled"; uart { diff --git a/soc/renesas/rx/rx26t/CMakeLists.txt b/soc/renesas/rx/rx26t/CMakeLists.txt index 278090303888b..0d6d15cea1986 100644 --- a/soc/renesas/rx/rx26t/CMakeLists.txt +++ b/soc/renesas/rx/rx26t/CMakeLists.txt @@ -8,5 +8,6 @@ zephyr_sources( ) zephyr_linker_sources(SECTIONS ofsm.ld) +zephyr_linker_sources(RAM_SECTIONS ram_sections.ld) set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/rx/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/rx/rx26t/ram_sections.ld b/soc/renesas/rx/rx26t/ram_sections.ld new file mode 100644 index 0000000000000..e71b43349a8b7 --- /dev/null +++ b/soc/renesas/rx/rx26t/ram_sections.ld @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifdef CONFIG_RENESAS_RX_DTC +SECTION_DATA_PROLOGUE(.dtc_vector_table,(NOLOAD),) +{ + /* If DTC is used, put the DTC vector table at the start of SRAM. + This avoids memory holes due to 1K alignment required by it. */ + *(.dtc_vector_table) +} GROUP_DATA_LINK_IN(RAMABLE_REGION, RAMABLE_REGION) +#endif From f519da2d39d2fd5924fac8281ebb826afe321894 Mon Sep 17 00:00:00 2001 From: Quy Tran Date: Wed, 15 Oct 2025 07:16:48 +0000 Subject: [PATCH 5/5] tests: drivers: uart: Add overlay for mcb_rx26t async test Add overlay for mcb_rx26t uart async test Signed-off-by: Quy Tran --- .../uart_async_api/boards/mcb_rx26t.overlay | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 tests/drivers/uart/uart_async_api/boards/mcb_rx26t.overlay diff --git a/tests/drivers/uart/uart_async_api/boards/mcb_rx26t.overlay b/tests/drivers/uart/uart_async_api/boards/mcb_rx26t.overlay new file mode 100644 index 0000000000000..7d9f2b2da5883 --- /dev/null +++ b/tests/drivers/uart/uart_async_api/boards/mcb_rx26t.overlay @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + sci5_default: sci5_default { + group1 { + psels = , + ; + }; + }; +}; + +&sci5 { + pinctrl-0 = <&sci5_default>; + pinctrl-names = "default"; + status = "okay"; + + dut: uart { + current-speed = <115200>; + status = "okay"; + }; +};