From 7e0d006851d043e9a416f5c6ba9c06ac28f19764 Mon Sep 17 00:00:00 2001 From: Duy Nguyen Date: Wed, 26 Feb 2025 10:04:49 +0700 Subject: [PATCH] driver: serial: Add support for uart interface for qemu_rx Support uart driver for qemu_rx environment base on the SCI0 HW on RX MCU Signed-off-by: Duy Nguyen --- drivers/serial/CMakeLists.txt | 1 + drivers/serial/Kconfig | 1 + drivers/serial/Kconfig.renesas_rx_qemu | 10 ++ drivers/serial/uart_renesas_rx_sci.c | 2 +- drivers/serial/uart_renesas_rx_sci_qemu.c | 126 ++++++++++++++++++ .../serial/renesas,rx-uart-sci-qemu.yaml | 8 ++ 6 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 drivers/serial/Kconfig.renesas_rx_qemu create mode 100644 drivers/serial/uart_renesas_rx_sci_qemu.c create mode 100644 dts/bindings/serial/renesas,rx-uart-sci-qemu.yaml diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt index 64effb49e20..c7b31eab7e1 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -65,6 +65,7 @@ zephyr_library_sources_ifdef(CONFIG_UART_QUICKLOGIC_USBSERIALPORT_S3B uart_ql_us zephyr_library_sources_ifdef(CONFIG_UART_RA8_SCI_B uart_renesas_ra8_sci_b.c) zephyr_library_sources_ifdef(CONFIG_UART_RCAR uart_rcar.c) zephyr_library_sources_ifdef(CONFIG_UART_RENESAS_RX uart_renesas_rx_sci.c) +zephyr_library_sources_ifdef(CONFIG_UART_RENESAS_RX_QEMU uart_renesas_rx_sci_qemu.c) zephyr_library_sources_ifdef(CONFIG_UART_RENESAS_RZA2M_SCIF uart_renesas_rza2m_scif.c) zephyr_library_sources_ifdef(CONFIG_UART_RENESAS_RZ_SCI uart_renesas_rz_sci.c) zephyr_library_sources_ifdef(CONFIG_UART_RENESAS_RZ_SCIF uart_renesas_rz_scif.c) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 2ef74a701b8..c7ae544ea22 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -211,6 +211,7 @@ rsource "Kconfig.realtek_rts5912" rsource "Kconfig.renesas_ra" rsource "Kconfig.renesas_ra8" rsource "Kconfig.renesas_rx" +rsource "Kconfig.renesas_rx_qemu" rsource "Kconfig.renesas_rz" rsource "Kconfig.rpi_pico" rsource "Kconfig.rtt" diff --git a/drivers/serial/Kconfig.renesas_rx_qemu b/drivers/serial/Kconfig.renesas_rx_qemu new file mode 100644 index 00000000000..6e0aecf524e --- /dev/null +++ b/drivers/serial/Kconfig.renesas_rx_qemu @@ -0,0 +1,10 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config UART_RENESAS_RX_QEMU + bool "Renesas RX Series UART Driver" + default y + depends on DT_HAS_RENESAS_RX_UART_SCI_QEMU_ENABLED + select SERIAL_HAS_DRIVER + help + Enable Renesas RX series UART driver. diff --git a/drivers/serial/uart_renesas_rx_sci.c b/drivers/serial/uart_renesas_rx_sci.c index f788ae6727d..d8ac3b926ee 100644 --- a/drivers/serial/uart_renesas_rx_sci.c +++ b/drivers/serial/uart_renesas_rx_sci.c @@ -395,7 +395,7 @@ static int uart_rx_init(const struct device *dev) return 0; } -static const struct uart_driver_api uart_rx_driver_api = { +static DEVICE_API(uart, uart_rx_driver_api) = { .poll_in = uart_rx_sci_poll_in, .poll_out = uart_rx_sci_poll_out, .err_check = uart_rx_err_check, diff --git a/drivers/serial/uart_renesas_rx_sci_qemu.c b/drivers/serial/uart_renesas_rx_sci_qemu.c new file mode 100644 index 00000000000..46e088ea28b --- /dev/null +++ b/drivers/serial/uart_renesas_rx_sci_qemu.c @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2024 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_rx_uart_sci_qemu + +#include +#include + +#include + +LOG_MODULE_REGISTER(renesas_rx_uart_sci_qemu, CONFIG_UART_LOG_LEVEL); + +#define REG_MASK(reg) (BIT_MASK(_CONCAT(reg, _LEN)) << _CONCAT(reg, _POS)) + +/* Registers */ +#define SMR 0x00 /*!< Serial Mode Register */ +#define BRR 0x01 /*!< Bit Rate Register */ +#define SCR 0x02 /*!< Serial Control Register */ +#define TDR 0x03 /*!< Transmit Data Register */ +#define SSR 0x04 /*!< Serial Status Register */ +#define RDR 0x05 /*!< Receive Data Register */ + +/** + * SSR (Serial Status Register) + * + * - MPBT[0..1]: Multi-Processor Bit Transfer + * - MPB[1..2]: Multi-Processor + * - TEND[2..3]: Transmit End Flag + * - PER[3..4]: Parity Error Flag + * - FER[4..5]: Framing Error Flag + * - ORER[5..6]: Overrun Error Flag + * - RDRF[6..7]: Receive Data Full Flag + * - TDRE[7..8]: Transmit Data Empty Flag + */ +#define SSR_MPBT_POS (0) +#define SSR_MPBT_LEN (1) +#define SSR_MPB_POS (1) +#define SSR_MPB_LEN (1) +#define SSR_TEND_POS (2) +#define SSR_TEND_LEN (1) +#define SSR_PER_POS (3) +#define SSR_PER_LEN (1) +#define SSR_FER_POS (4) +#define SSR_FER_LEN (1) +#define SSR_ORER_POS (5) +#define SSR_ORER_LEN (1) +#define SSR_RDRF_POS (6) +#define SSR_RDRF_LEN (1) +#define SSR_TDRE_POS (7) +#define SSR_TDRE_LEN (1) + +struct uart_renesas_rx_sci_qemu_cfg { + mem_addr_t regs; +}; + +struct uart_renesas_rx_sci_qemu_data { + const struct device *dev; + struct uart_config uart_config; +}; + +static uint8_t uart_renesas_rx_qemu_read_8(const struct device *dev, uint32_t offs) +{ + const struct uart_renesas_rx_sci_qemu_cfg *config = dev->config; + + return sys_read8(config->regs + offs); +} + +static void uart_renesas_rx_qemu_write_8(const struct device *dev, uint32_t offs, uint8_t value) +{ + const struct uart_renesas_rx_sci_qemu_cfg *config = dev->config; + + sys_write8(value, config->regs + offs); +} + +static int uart_renesas_rx_sci_qemu_poll_in(const struct device *dev, unsigned char *c) +{ + if ((uart_renesas_rx_qemu_read_8(dev, SSR) & REG_MASK(SSR_RDRF)) == 0) { + /* There are no characters available to read. */ + return -1; + } + + *c = uart_renesas_rx_qemu_read_8(dev, RDR); + + return 0; +} + +static void uart_renesas_rx_sci_qemu_poll_out(const struct device *dev, unsigned char c) +{ + while (!(uart_renesas_rx_qemu_read_8(dev, SSR) & REG_MASK(SSR_TEND))) { + } + + uart_renesas_rx_qemu_write_8(dev, TDR, c); +} + +static const struct uart_driver_api uart_rx_driver_api = { + .poll_in = uart_renesas_rx_sci_qemu_poll_in, + .poll_out = uart_renesas_rx_sci_qemu_poll_out, +}; + +/* Device Instantiation */ +#define UART_RENESAS_RX_SCI_QEMU_CFG_INIT(n) \ + static const struct uart_renesas_rx_sci_qemu_cfg uart_rx_sci_cfg_##n = { \ + .regs = DT_REG_ADDR(DT_INST_PARENT(n)), \ + } + +#define UART_RENESAS_RX_SCI_QEMU_INIT(n) \ + UART_RENESAS_RX_SCI_QEMU_CFG_INIT(n); \ + \ + static struct uart_renesas_rx_sci_qemu_data uart_rx_sci_data_##n = { \ + .uart_config = \ + { \ + .baudrate = DT_INST_PROP(n, current_speed), \ + .parity = UART_CFG_PARITY_NONE, \ + .stop_bits = UART_CFG_STOP_BITS_1, \ + .data_bits = UART_CFG_DATA_BITS_8, \ + .flow_ctrl = UART_CFG_FLOW_CTRL_NONE, \ + }, \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, NULL, NULL, &uart_rx_sci_data_##n, &uart_rx_sci_cfg_##n, \ + PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, &uart_rx_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(UART_RENESAS_RX_SCI_QEMU_INIT) diff --git a/dts/bindings/serial/renesas,rx-uart-sci-qemu.yaml b/dts/bindings/serial/renesas,rx-uart-sci-qemu.yaml new file mode 100644 index 00000000000..62c7a74ed36 --- /dev/null +++ b/dts/bindings/serial/renesas,rx-uart-sci-qemu.yaml @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RX SCI QEMU controller + +compatible: "renesas,rx-uart-sci-qemu" + +include: [pinctrl-device.yaml, uart-controller.yaml]