diff --git a/boards/renesas/rza3m_ek/Kconfig.rza3m_ek b/boards/renesas/rza3m_ek/Kconfig.rza3m_ek new file mode 100644 index 0000000000000..8675734db1ca5 --- /dev/null +++ b/boards/renesas/rza3m_ek/Kconfig.rza3m_ek @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_RZA3M_EK + select SOC_R9A07G066M04GBG diff --git a/boards/renesas/rza3m_ek/board.cmake b/boards/renesas/rza3m_ek/board.cmake new file mode 100644 index 0000000000000..b6c4df3be4062 --- /dev/null +++ b/boards/renesas/rza3m_ek/board.cmake @@ -0,0 +1,9 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "--device=R9A07G066M04") +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) + +if(CONFIG_BUILD_WITH_TFA) + set(TFA_PLAT "a3m_ek_nor") +endif() diff --git a/boards/renesas/rza3m_ek/board.yml b/boards/renesas/rza3m_ek/board.yml new file mode 100644 index 0000000000000..1329537f95b5e --- /dev/null +++ b/boards/renesas/rza3m_ek/board.yml @@ -0,0 +1,6 @@ +board: + name: rza3m_ek + full_name: RZ/A3M Evaluation Kit + vendor: renesas + socs: + - name: r9a07g066m04gbg diff --git a/boards/renesas/rza3m_ek/doc/index.rst b/boards/renesas/rza3m_ek/doc/index.rst new file mode 100644 index 0000000000000..a94593d6f42c7 --- /dev/null +++ b/boards/renesas/rza3m_ek/doc/index.rst @@ -0,0 +1,162 @@ +.. zephyr:board:: rza3m_ek + +Overview +******** + +The EK-RZ/A3M evaluation kit enables users to easily evaluate the features of the RZ/A3M MPU. +This kit includes an EK-RZ/A3M board, 5-inch 720x1280 pixel LCD MIPI graphics expansion board, and +USB cables, allowing the seamless evaluation of high-definition human machine interface (HMI), camera +input through USB, and more features. Equipped with an on-board J-Link debugger, users can +conveniently start debugging without additional debuggers. +Additionally, it also has several expansion connectors such as SDIO, PMOD,and Arduino to connect +sensors, Wi-Fi, and Bluetooth® Low Energy (LE), allowing users to add more features without +expanding the board space. + +* Special Feature Access + + * MIPI DSI 4 lanes & parallel graphics expansion ports + * 5-inch MIPI LCD panel (720x1280 pixels) + * USB High-Speed Host & Device + * 32MB External QSPI NOR Flash + * 128MB External QSPI NAND Flash + * External sound codec + * External RTC + +* MPU Native Pin Access + + * R9A07G066M04GBG MPU + * 1GHz, Arm Cortex®-A55 core w/NEON extension + * Built-in 128MB DDR3L DRAM + * 128KB SRAM w/ECC + * 244 pins, BGA package + * Native pin access + * MPU & USB current measurement + +* Ecosystem & System Control Access + + * USB High-Speed Host & Device + * 5V input through USB (Debug, HS, USB-PD) or external power supply + * Debug on-board (Segger J-Link®) + * Debug external (SWD & JTAG) + * SCIF download (SWD) + * 3 user LEDs & 2 user buttons + * 2 SeeedGrove® system (I2C & analog) + * 2 Digilent Pmod™ (I2C, SPI or UART selectable) + * Arduino™ (Uno R3) + * MikroElektronika™ mikroBUS + * SparkFun® Qwiic® (I2C) + * MPU boot configuration switch + * Audio In/Out 4-pole + * MicroSD card slot + +* Kit Contents + + * EK-RZ/A3M board + * MIPI graphics expansion board + * USB cable (USB C to USB C) + * USB cable (USB A female to USB C) + * USB cable (USB A male to USB C) + * Screw and spacer for fixing the sub board + +Hardware +******** +The Renesas RZ/A3M MPU documentation can be found at `RZ/A3M Group Website`_ + +.. figure:: rza3m_block_diagram.webp + :width: 600px + :align: center + :alt: RZ/A3M group feature + + RZ/A3M block diagram (Credit: Renesas Electronics Corporation) + +Detailed hardware features for the board can be found at `EK-RZ/A3M Website`_ + +Supported Features +================== + +.. zephyr:board-supported-hw:: + +Programming and Debugging +************************* + +EK-RZ/A3M uses Initial Program Loader (IPL) to perform initial settings and copy the Zephyr image from flash to DDR SRAM for execution. +It only needs to be written to flash at lease once before running Zephyr. + +1. For the board setup and connections, follow "3.2 Board Setup" of `Getting Started with RZ/A Flexible Software Package`_. + +2. Enable the IPL build with ``-DCONFIG_BUILD_WITH_TFA=y``. + The IPL image ``rza3m_ek_nor_ipl.bin`` is generated under zephyr/build/tfa/rza3m_ek_nor/release + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: rza3m_ek + :goals: build + :gen-args: -DCONFIG_BUILD_WITH_TFA=y + +.. note:: + Currently, the IPL source code can built on Linux environment only. + For Windows, please follow `Initial Program Loader Application Note`_ + +3. Flash it onto the board at address 0x20000000 by Jlink command `Segger JLink Renesas R9A07G066`_ + +.. code-block:: console + + $ JLinkExe + J-Link> connect + Device> R9A07G066M04 + TIF> s + Speed> [Enter] + J-Link> h + J-Link> loadfile 0x20000000 + +Where ```` is the path to the ``rza3m_ek_nor_ipl.bin`` in the output directory. + +Applications for the ``rza3m_ek`` board can be built in the usual way as +documented in :ref:`build_an_application`. + +Console +======= +The UART port is accessed by USB Debug connector (J10). + +Debugging +========= + +It is possible to load and execute a Zephyr application binary on this board on the Cortex-A55 System Core +from the DDR SDRAM, using ``JLink`` debugger (:ref:`jlink-debug-host-tools`). + +Here is an example for building and debugging with the :zephyr:code-sample:`hello_world` application. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: rza3m_ek + :goals: build debug + +Flashing +======== + +Zephyr application can be flashed to Quad-SPI storage and then loaded by Initial Program Loader. + +.. zephyr-app-commands:: + :zephyr-app: samples/hello_world + :board: rza3m_ek + :goals: build flash + +References +********** + +.. target-notes:: + +.. _RZ/A3M Group Website: + https://www.renesas.com/en/products/microcontrollers-microprocessors/rz-mpus/rza3m-powerful-1ghz-mpus-built-ddr3l-sdram-high-definition-hmi + +.. _EK-RZ/A3M Website: + https://www.renesas.com/en/products/microcontrollers-microprocessors/rz-mpus/ek-rza3m-evaluation-kit-rza3m-mpu + +.. _Initial Program Loader Application Note: + https://github.com/renesas/rza-initial-program-loader/tree/main/application_note + +.. _Getting Started with RZ/A Flexible Software Package: + https://www.renesas.com/en/document/apn/rza-getting-started-flexible-software-package + +.. _Segger JLink Renesas R9A07G066: + https://kb.segger.com/Renesas_R9A07G066 diff --git a/boards/renesas/rza3m_ek/doc/rza3m_block_diagram.webp b/boards/renesas/rza3m_ek/doc/rza3m_block_diagram.webp new file mode 100644 index 0000000000000..b3ca900ac02e6 Binary files /dev/null and b/boards/renesas/rza3m_ek/doc/rza3m_block_diagram.webp differ diff --git a/boards/renesas/rza3m_ek/doc/rza3m_ek.webp b/boards/renesas/rza3m_ek/doc/rza3m_ek.webp new file mode 100644 index 0000000000000..2fb1c7b51a6d4 Binary files /dev/null and b/boards/renesas/rza3m_ek/doc/rza3m_ek.webp differ diff --git a/boards/renesas/rza3m_ek/rza3m_ek-pinctrl.dtsi b/boards/renesas/rza3m_ek/rza3m_ek-pinctrl.dtsi new file mode 100644 index 0000000000000..bc9da2414defb --- /dev/null +++ b/boards/renesas/rza3m_ek/rza3m_ek-pinctrl.dtsi @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +&pinctrl { + /omit-if-no-ref/ scif0_pins: scif0 { + scif0-pinmux { + pinmux = , /* RXD */ + ; /* TXD */ + drive-strength = <1>; + slew-rate = "fast"; + }; + }; + + /omit-if-no-ref/ lcdc_default: lcdc { + lcdc-pinmux { + pinmux = , /* DISP_CLK */ + , /* DISP_DATA0 */ + , /* DISP_DATA1 */ + , /* DISP_DATA2 */ + , /* DISP_DATA3 */ + , /* DISP_DATA4 */ + , /* DISP_DATA5 */ + , /* DISP_DATA6 */ + , /* DISP_DATA7 */ + , /* DISP_DATA8 */ + , /* DISP_DATA9 */ + , /* DISP_DATA10 */ + , /* DISP_DATA11 */ + , /* DISP_DATA12 */ + , /* DISP_DATA13 */ + , /* DISP_DATA14 */ + , /* DISP_DATA15 */ + , /* DISP_DATA16 */ + , /* DISP_DATA17 */ + , /* DISP_DATA18 */ + , /* DISP_DATA19 */ + , /* DISP_DATA20 */ + , /* DISP_DATA21 */ + , /* DISP_DATA22 */ + , /* DISP_DATA23 */ + , /* DISP_DE */ + , /* DISP_HSYNC */ + ; /* DISP_VSYNC */ + }; + }; +}; diff --git a/boards/renesas/rza3m_ek/rza3m_ek.dts b/boards/renesas/rza3m_ek/rza3m_ek.dts new file mode 100644 index 0000000000000..39af979b066c5 --- /dev/null +++ b/boards/renesas/rza3m_ek/rza3m_ek.dts @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; + +#include +#include +#include +#include +#include +#include "rza3m_ek-pinctrl.dtsi" +#include + +/ { + model = "Renesas RZ/A3M EK"; + compatible = "renesas,rza3m-ek"; + + chosen { + zephyr,sram = &ddr; + zephyr,flash = &spi_flash; + zephyr,console = &scif0; + zephyr,shell-uart = &scif0; + zephyr,code-partition= &slot0_partition; + zephyr,display = &zephyr_lcdif; + }; + + ddr: memory@40200000 { + compatible ="zephyr,memory-region", "mmio-sram"; + reg = <0x40200000 (DT_SIZE_M(128) - 0x200000)>; + zephyr,memory-region = "DDR"; + }; + + sram: memory@1e000 { + compatible ="zephyr,memory-region", "mmio-sram"; + reg = <0x1e000 DT_SIZE_K(72)>; + zephyr,memory-region = "SRAM"; + }; + + spi_flash: memory@20020000 { + compatible = "mmio-sram"; + reg = <0x20020000 (DT_SIZE_M(16) - 0x20000)>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + header: partition@0 { + label = "header"; + reg = <0x00000000 0x200>; + read-only; + }; + + slot0_partition: partition@200 { + label = "image-0"; + reg = <0x00000200 (DT_SIZE_M(16) - 0x20200)>; + read-only; + }; + }; + }; + + aliases { + led0 = &led1; + sw0 = &sw1; + mipi-dsi = &mipi_dsi; + }; + + leds { + compatible = "gpio-leds"; + + led1: led1 { + gpios = <&gpio10 1 GPIO_ACTIVE_HIGH>; + label = "led1"; + }; + + led2: led2 { + gpios = <&gpio20 3 GPIO_ACTIVE_HIGH>; + label = "led2"; + }; + + led3: led3 { + gpios = <&gpio20 4 GPIO_ACTIVE_HIGH>; + label = "led3"; + }; + }; + + gpio_keys { + compatible = "gpio-keys"; + + sw1: sw1 { + label = "sw1"; + gpios = <&gpio10 3 GPIO_ACTIVE_HIGH>; + zephyr,code = ; + }; + + sw2: sw2 { + label = "sw2"; + gpios = <&gpio11 1 GPIO_ACTIVE_HIGH>; + zephyr,code = ; + }; + }; + + renesas_mipi_connector: mipi-connector { + compatible = "renesas,rz-gpio-mipi-header"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <20 0 &gpio8 2 0>, /* I2C_SDA */ + <21 0 &gpio10 2 0>, /* DIMMER */ + <22 0 &gpio8 3 0>, /* I2C_SCL */ + <23 0 &gpio8 1 0>; /* TP_INT */ + }; +}; + +&scif0 { + current-speed = <115200>; + pinctrl-0 = <&scif0_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&gpio { + status = "okay"; +}; + +&gpio8 { + status = "okay"; +}; + +&gpio10 { + status = "okay"; +}; + +&gpio11 { + status = "okay"; +}; + +&gpio20 { + status = "okay"; +}; + +zephyr_lcdif: &lcdif {}; + +zephyr_mipi_dsi: &mipi_dsi {}; + +renesas_mipi_i2c: &i2c1 {}; + +&i2c0 { + pinctrl-0 = <&i2c0_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&i2c1 { + pinctrl-0 = <&i2c1_pins>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/boards/renesas/rza3m_ek/rza3m_ek.yaml b/boards/renesas/rza3m_ek/rza3m_ek.yaml new file mode 100644 index 0000000000000..af31f179fcfd4 --- /dev/null +++ b/boards/renesas/rza3m_ek/rza3m_ek.yaml @@ -0,0 +1,15 @@ +identifier: rza3m_ek +name: Renesas RZ/A3M Evaluation Kit +type: mcu +arch: arm64 +toolchain: + - zephyr + - cross-compile +supported: + - uart + - gpio + - display + - mipi_dsi +testing: + ignore_tags: + - bluetooth diff --git a/boards/renesas/rza3m_ek/rza3m_ek_defconfig b/boards/renesas/rza3m_ek/rza3m_ek_defconfig new file mode 100644 index 0000000000000..dd2f33248dd5a --- /dev/null +++ b/boards/renesas/rza3m_ek/rza3m_ek_defconfig @@ -0,0 +1,19 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_XIP=n + +# MMU Options +CONFIG_MAX_XLAT_TABLES=24 + +# Cache Options +CONFIG_CACHE_MANAGEMENT=y +CONFIG_DCACHE_LINE_SIZE_DETECT=y +CONFIG_ICACHE_LINE_SIZE_DETECT=y + +# Enable UART driver +CONFIG_SERIAL=y + +# Enable console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y diff --git a/boards/shields/rtkapplcdms02001be/Kconfig.defconfig b/boards/shields/rtkapplcdms02001be/Kconfig.defconfig new file mode 100644 index 0000000000000..e30df2b32238d --- /dev/null +++ b/boards/shields/rtkapplcdms02001be/Kconfig.defconfig @@ -0,0 +1,47 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +if SHIELD_RTKAPPLCDMS02001BE +if DISPLAY + +# Enable MIPI DSI, as this display controller requires it. + +config MIPI_DSI + default y + +endif # DISPLAY + +if LVGL + +# Configure LVGL to use touchscreen with input API + +config INPUT + default y + +# LVGL should allocate buffers equal to size of display +config LV_Z_VDB_SIZE + default 100 + +# Enable double buffering +config LV_Z_DOUBLE_VDB + default y + +# Force full refresh. This prevents memory copy associated with partial +# display refreshes, which is not necessary for the LCDC driver +config LV_Z_FULL_REFRESH + default y + +config LV_Z_BITS_PER_PIXEL + default 32 + +# Use offloaded render thread +config LV_Z_FLUSH_THREAD + default y + +choice LV_COLOR_DEPTH + default LV_COLOR_DEPTH_32 +endchoice + +endif # LVGL + +endif # SHIELD_RTKAPPLCDMS02001BE diff --git a/boards/shields/rtkapplcdms02001be/Kconfig.shield b/boards/shields/rtkapplcdms02001be/Kconfig.shield new file mode 100644 index 0000000000000..cd317e47d16c4 --- /dev/null +++ b/boards/shields/rtkapplcdms02001be/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_RTKAPPLCDMS02001BE + def_bool $(shields_list_contains,rtkapplcdms02001be) diff --git a/boards/shields/rtkapplcdms02001be/boards/rza3m_ek.conf b/boards/shields/rtkapplcdms02001be/boards/rza3m_ek.conf new file mode 100644 index 0000000000000..0ac7b7ace6abc --- /dev/null +++ b/boards/shields/rtkapplcdms02001be/boards/rza3m_ek.conf @@ -0,0 +1,6 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_LV_Z_FLUSH_THREAD=n +CONFIG_LV_Z_BITS_PER_PIXEL=16 +CONFIG_LV_COLOR_DEPTH_16=y diff --git a/boards/shields/rtkapplcdms02001be/boards/rza3m_ek.overlay b/boards/shields/rtkapplcdms02001be/boards/rza3m_ek.overlay new file mode 100644 index 0000000000000..e838cef38c008 --- /dev/null +++ b/boards/shields/rtkapplcdms02001be/boards/rza3m_ek.overlay @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&i2c1 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = ; + pinctrl-0 = <&i2c1_pins>; + pinctrl-names = "default"; +}; + +&zephyr_lcdif { + input-pixel-format = ; +}; + +&mipi_dsi { + status = "okay"; + ulps-wakeup-period = <130>; + video-mode-delay = <216>; + timing = <162 53 45 52>; + + phys-timing { + t-init = <79801>; + t-clk-prep = <8>; + t-hs-prep = <9>; + t-clk-zero = <33>; + t-clk-pre = <4>; + t-clk-post = <35>; + t-clk-trail = <7>; + t-hs-zero = <16>; + t-hs-trail = <9>; + t-hs-exit = <13>; + t-lp-exit = <6>; + }; +}; diff --git a/boards/shields/rtkapplcdms02001be/doc/index.rst b/boards/shields/rtkapplcdms02001be/doc/index.rst new file mode 100644 index 0000000000000..e56c10f8f5d73 --- /dev/null +++ b/boards/shields/rtkapplcdms02001be/doc/index.rst @@ -0,0 +1,48 @@ +.. _rtkapplcdms02001be: + +RTKAPPLCDMS02001BE MIPI Display +############################### + +Overview +******** + +The Focus LCDs RTKAPPLCDMS02001BE MIPI Display is a 5 inch TFT 1280x720 pixels +capacitive touch panel. + +This display uses a 40 pin connector header. + +Pins Assignment of the Renesas RTKAPPLCDMS02001BE MIPI Display +============================================================== + ++----------------------+-------------------------+ +| Connector Pin | Function | ++======================+=========================+ +| 20 | Touch ctrl I2C SDA | ++----------------------+-------------------------+ +| 21 | Display backlight enable| ++----------------------+-------------------------+ +| 22 | Touch ctrl I2C SCL | ++----------------------+-------------------------+ +| 23 | External interrupt | ++----------------------+-------------------------+ +| 24 | Display reset | ++----------------------+-------------------------+ + +Hardware Requirements: +********************** + +Supported Renesas RZ boards: EK-RZ/A3M +- 1 x RZ Board +- 1 x USB-C cable + +Programming +*********** + +Set ``--shield=rtkapplcdms02001be`` when you invoke ``west build``. For +example: + +.. zephyr-app-commands:: + :zephyr-app: tests/drivers/display/display_read_write + :board: rza3m_ek + :shield: rtkapplcdms02001be + :goals: build diff --git a/boards/shields/rtkapplcdms02001be/rtkapplcdms02001be.overlay b/boards/shields/rtkapplcdms02001be/rtkapplcdms02001be.overlay new file mode 100644 index 0000000000000..15c2ee7c42cf1 --- /dev/null +++ b/boards/shields/rtkapplcdms02001be/rtkapplcdms02001be.overlay @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +/{ + chosen { + zephyr,display = &zephyr_lcdif; + }; + + lvgl_pointer { + compatible = "zephyr,lvgl-pointer-input"; + input = <>911_rtkapplcdms02001be>; + }; +}; + +&renesas_mipi_i2c { + status = "okay"; + + gt911_rtkapplcdms02001be: gt911-rtkapplcdms02001be@14 { + compatible = "goodix,gt911"; + reg = <0x14>; + irq-gpios = <&renesas_mipi_connector 23 GPIO_ACTIVE_HIGH>; + }; +}; + +&zephyr_mipi_dsi { + status = "okay"; + + ili9881c: ili9881c@0 { + status = "okay"; + compatible = "ilitek,ili9881c-dsi"; + reg = <0x0>; + height = <1280>; + width = <720>; + data-lanes = <4>; + pixel-format = ; + }; +}; + +&zephyr_lcdif { + status = "okay"; + width = <720>; + height = <1280>; + input-pixel-format = ; + output-pixel-format = ; + + display-timings { + compatible = "zephyr,panel-timing"; + hsync-len = <33>; + hback-porch = <100>; + vsync-len = <2>; + vback-porch = <30>; + hsync-active = <1>; + vsync-active = <1>; + de-active = <1>; + pixelclk-active = <0>; + hfront-porch = <133>; + vfront-porch = <22>; + }; + backlight-gpios = <&renesas_mipi_connector 21 GPIO_ACTIVE_HIGH>; +}; diff --git a/boards/shields/rtkapplcdms02001be/shield.yml b/boards/shields/rtkapplcdms02001be/shield.yml new file mode 100644 index 0000000000000..0c6b93583ddfd --- /dev/null +++ b/boards/shields/rtkapplcdms02001be/shield.yml @@ -0,0 +1,7 @@ +shield: + name: rtkapplcdms02001be + full_name: RTKAPPLCDMS02001BE MIPI Display + vendor: renesas + supported_features: + - input + - display diff --git a/drivers/display/CMakeLists.txt b/drivers/display/CMakeLists.txt index f0bb444ab4ad6..b4fb3905b2691 100644 --- a/drivers/display/CMakeLists.txt +++ b/drivers/display/CMakeLists.txt @@ -44,7 +44,9 @@ zephyr_library_sources_ifdef(CONFIG_LED_STRIP_MATRIX display_led_strip_matrix.c) zephyr_library_sources_ifdef(CONFIG_DISPLAY_RENESAS_LCDC display_renesas_lcdc.c) zephyr_library_sources_ifdef(CONFIG_NT35510 display_nt35510.c) zephyr_library_sources_ifdef(CONFIG_RENESAS_RA_GLCDC display_renesas_ra.c) +zephyr_library_sources_ifdef(CONFIG_RENESAS_RZ_LCDC display_renesas_rz.c) zephyr_library_sources_ifdef(CONFIG_ILI9806E_DSI display_ili9806e_dsi.c) +zephyr_library_sources_ifdef(CONFIG_ILI9881C_DSI display_ili9881c_dsi.c) zephyr_library_sources_ifdef(CONFIG_ST7701 display_st7701.c) zephyr_library_sources_ifdef(CONFIG_LPM013M126 display_lpm013m126.c) zephyr_library_sources_ifdef(CONFIG_CO5300 display_co5300.c) diff --git a/drivers/display/Kconfig b/drivers/display/Kconfig index 7273d16f48f47..d3d57d994c5c8 100644 --- a/drivers/display/Kconfig +++ b/drivers/display/Kconfig @@ -60,7 +60,9 @@ source "drivers/display/Kconfig.led_strip_matrix" source "drivers/display/Kconfig.renesas_lcdc" source "drivers/display/Kconfig.nt35510" source "drivers/display/Kconfig.renesas_ra" +source "drivers/display/Kconfig.renesas_rz" source "drivers/display/Kconfig.ili9806e_dsi" +source "drivers/display/Kconfig.ili9881c_dsi" source "drivers/display/Kconfig.st7701" source "drivers/display/Kconfig.waveshare_dsi_lcd" source "drivers/display/Kconfig.lpm013m126" diff --git a/drivers/display/Kconfig.ili9881c_dsi b/drivers/display/Kconfig.ili9881c_dsi new file mode 100644 index 0000000000000..29b36ee49c1d3 --- /dev/null +++ b/drivers/display/Kconfig.ili9881c_dsi @@ -0,0 +1,20 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config ILI9881C_DSI + bool "ILI9881C_DSI display driver" + default y + depends on DT_HAS_ILITEK_ILI9881C_DSI_ENABLED + select MIPI_DSI + help + Enable driver for ILI9881C_DSI display driver. + +if ILI9881C_DSI + +config DISPLAY_ILI9881C_DSI_INIT_PRIORITY + int "Initialization priority" + default 90 + help + ILI9881C_DSI display driver initialization priority. + +endif diff --git a/drivers/display/Kconfig.renesas_rz b/drivers/display/Kconfig.renesas_rz new file mode 100644 index 0000000000000..ebad28106ca4d --- /dev/null +++ b/drivers/display/Kconfig.renesas_rz @@ -0,0 +1,35 @@ +# Renesas RZ Family + +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config RENESAS_RZ_LCDC + bool "Renesas display controller driver" + default y + depends on DT_HAS_RENESAS_RZ_LCDC_ENABLED + select USE_RZ_FSP_DISPLAY + select NOCACHE_MEMORY + help + Enable Renesas display controller. + +if RENESAS_RZ_LCDC + +config RENESAS_RZ_LCDC_FB_NUM + int "Frame buffer number" + default 2 + range 0 2 + help + RENESAS RZ LCDC frame buffer number config: + - 0 frame buffer maintained by application, must write with full screen pixels. + - 1 single frame buffer in RENESAS RZ LCDC driver. + - 2 double frame buffer in RENESAS RZ LCDC driver. + +if LVGL + +# Force display buffers to be aligned to cache line size (64 bytes) +config LV_Z_VDB_ALIGN + default 64 + +endif # LVGL + +endif # RENESAS_RZ_LCDC diff --git a/drivers/display/display_ili9881c_dsi.c b/drivers/display/display_ili9881c_dsi.c new file mode 100644 index 0000000000000..3d1c1ca16eb97 --- /dev/null +++ b/drivers/display/display_ili9881c_dsi.c @@ -0,0 +1,487 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ilitek_ili9881c_dsi + +#include +#include +#include +#include +#include +#include +#include "display_ili9881c_dsi.h" +LOG_MODULE_REGISTER(display_ili9881c_dsi, CONFIG_DISPLAY_LOG_LEVEL); + +#define ILITEK_ILI9881C_COLMOD_RGB565 0x50 +#define ILITEK_ILI9881C_COLMOD_RGB888 0x70 +struct ili9881c_config { + const struct device *mipi_dsi; + const struct gpio_dt_spec reset; + const struct gpio_dt_spec backlight; + enum display_pixel_format pixel_format; + uint8_t data_lanes; + uint16_t width; + uint16_t height; + uint8_t channel; +}; + +struct ili9881c_init_cmd { + uint8_t reg; + uint8_t cmd_len; + uint8_t cmd[3]; +} __packed; + +static const struct ili9881c_init_cmd init_cmds[] = { + /* Change to Page 3 CMD */ + {.reg = 0xff, .cmd_len = 3, .cmd = {0x98, 0x81, 0x03}}, + /* GIP_1 */ + {.reg = 0x01, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x02, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x03, .cmd_len = 1, .cmd = {0x72}}, + {.reg = 0x04, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x05, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x06, .cmd_len = 1, .cmd = {0x09}}, + {.reg = 0x07, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x08, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x09, .cmd_len = 1, .cmd = {0x01}}, + {.reg = 0x0a, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x0b, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x0c, .cmd_len = 1, .cmd = {0x01}}, + {.reg = 0x0d, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x0e, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x0f, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x10, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x11, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x12, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x13, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x14, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x15, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x16, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x17, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x18, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x19, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x1a, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x1b, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x1c, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x1d, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x1e, .cmd_len = 1, .cmd = {0x40}}, + {.reg = 0x1f, .cmd_len = 1, .cmd = {0x80}}, + {.reg = 0x20, .cmd_len = 1, .cmd = {0x05}}, + {.reg = 0x21, .cmd_len = 1, .cmd = {0x02}}, + {.reg = 0x22, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x23, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x24, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x25, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x26, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x27, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x28, .cmd_len = 1, .cmd = {0x33}}, + {.reg = 0x29, .cmd_len = 1, .cmd = {0x02}}, + {.reg = 0x2a, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x2b, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x2c, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x2d, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x2e, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x2f, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x30, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x31, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x32, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x32, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x33, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x34, .cmd_len = 1, .cmd = {0x04}}, + {.reg = 0x35, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x36, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x37, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x38, .cmd_len = 1, .cmd = {0x3C}}, + {.reg = 0x39, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x3a, .cmd_len = 1, .cmd = {0x40}}, + {.reg = 0x3b, .cmd_len = 1, .cmd = {0x40}}, + {.reg = 0x3c, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x3d, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x3e, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x3f, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x40, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x41, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x42, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x43, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x44, .cmd_len = 1, .cmd = {0x00}}, + /* GIP_2 */ + {.reg = 0x50, .cmd_len = 1, .cmd = {0x01}}, + {.reg = 0x51, .cmd_len = 1, .cmd = {0x23}}, + {.reg = 0x52, .cmd_len = 1, .cmd = {0x45}}, + {.reg = 0x53, .cmd_len = 1, .cmd = {0x67}}, + {.reg = 0x54, .cmd_len = 1, .cmd = {0x89}}, + {.reg = 0x55, .cmd_len = 1, .cmd = {0xab}}, + {.reg = 0x56, .cmd_len = 1, .cmd = {0x01}}, + {.reg = 0x57, .cmd_len = 1, .cmd = {0x23}}, + {.reg = 0x58, .cmd_len = 1, .cmd = {0x45}}, + {.reg = 0x59, .cmd_len = 1, .cmd = {0x67}}, + {.reg = 0x5a, .cmd_len = 1, .cmd = {0x89}}, + {.reg = 0x5b, .cmd_len = 1, .cmd = {0xab}}, + {.reg = 0x5c, .cmd_len = 1, .cmd = {0xcd}}, + {.reg = 0x5d, .cmd_len = 1, .cmd = {0xef}}, + /* GIP_3 */ + {.reg = 0x5e, .cmd_len = 1, .cmd = {0x11}}, + {.reg = 0x5f, .cmd_len = 1, .cmd = {0x01}}, + {.reg = 0x60, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x61, .cmd_len = 1, .cmd = {0x15}}, + {.reg = 0x62, .cmd_len = 1, .cmd = {0x14}}, + {.reg = 0x63, .cmd_len = 1, .cmd = {0x0E}}, + {.reg = 0x64, .cmd_len = 1, .cmd = {0x0F}}, + {.reg = 0x65, .cmd_len = 1, .cmd = {0x0C}}, + {.reg = 0x66, .cmd_len = 1, .cmd = {0x0D}}, + {.reg = 0x67, .cmd_len = 1, .cmd = {0x06}}, + {.reg = 0x68, .cmd_len = 1, .cmd = {0x02}}, + {.reg = 0x69, .cmd_len = 1, .cmd = {0x07}}, + {.reg = 0x6a, .cmd_len = 1, .cmd = {0x02}}, + {.reg = 0x6b, .cmd_len = 1, .cmd = {0x02}}, + {.reg = 0x6c, .cmd_len = 1, .cmd = {0x02}}, + {.reg = 0x6d, .cmd_len = 1, .cmd = {0x02}}, + {.reg = 0x6e, .cmd_len = 1, .cmd = {0x02}}, + {.reg = 0x6f, .cmd_len = 1, .cmd = {0x02}}, + {.reg = 0x70, .cmd_len = 1, .cmd = {0x02}}, + {.reg = 0x71, .cmd_len = 1, .cmd = {0x02}}, + {.reg = 0x72, .cmd_len = 1, .cmd = {0x02}}, + {.reg = 0x73, .cmd_len = 1, .cmd = {0x02}}, + {.reg = 0x74, .cmd_len = 1, .cmd = {0x02}}, + {.reg = 0x75, .cmd_len = 1, .cmd = {0x01}}, + {.reg = 0x76, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x77, .cmd_len = 1, .cmd = {0x14}}, + {.reg = 0x78, .cmd_len = 1, .cmd = {0x15}}, + {.reg = 0x79, .cmd_len = 1, .cmd = {0x0E}}, + {.reg = 0x7a, .cmd_len = 1, .cmd = {0x0F}}, + {.reg = 0x7b, .cmd_len = 1, .cmd = {0x0C}}, + {.reg = 0x7c, .cmd_len = 1, .cmd = {0x0D}}, + {.reg = 0x7d, .cmd_len = 1, .cmd = {0x06}}, + {.reg = 0x7e, .cmd_len = 1, .cmd = {0x02}}, + {.reg = 0x7f, .cmd_len = 1, .cmd = {0x07}}, + {.reg = 0x80, .cmd_len = 1, .cmd = {0x02}}, + {.reg = 0x81, .cmd_len = 1, .cmd = {0x02}}, + {.reg = 0x83, .cmd_len = 1, .cmd = {0x02}}, + {.reg = 0x84, .cmd_len = 1, .cmd = {0x02}}, + {.reg = 0x85, .cmd_len = 1, .cmd = {0x02}}, + {.reg = 0x86, .cmd_len = 1, .cmd = {0x02}}, + {.reg = 0x87, .cmd_len = 1, .cmd = {0x02}}, + {.reg = 0x88, .cmd_len = 1, .cmd = {0x02}}, + {.reg = 0x89, .cmd_len = 1, .cmd = {0x02}}, + {.reg = 0x8A, .cmd_len = 1, .cmd = {0x02}}, + /* Change to Page 4 CMD */ + {.reg = 0xff, .cmd_len = 3, .cmd = {0x98, 0x81, 0x04}}, + {.reg = 0x6C, .cmd_len = 1, .cmd = {0x15}}, + {.reg = 0x6E, .cmd_len = 1, .cmd = {0x2A}}, + {.reg = 0x6F, .cmd_len = 1, .cmd = {0x33}}, + {.reg = 0x3A, .cmd_len = 1, .cmd = {0x94}}, + {.reg = 0x8D, .cmd_len = 1, .cmd = {0x15}}, + {.reg = 0x87, .cmd_len = 1, .cmd = {0xBA}}, + {.reg = 0x26, .cmd_len = 1, .cmd = {0x76}}, + {.reg = 0xB2, .cmd_len = 1, .cmd = {0xD1}}, + {.reg = 0xB5, .cmd_len = 1, .cmd = {0x06}}, + /* Change to Page 1 CMD */ + {.reg = 0xff, .cmd_len = 3, .cmd = {0x98, 0x81, 0x01}}, + {.reg = 0x22, .cmd_len = 1, .cmd = {0x0A}}, + {.reg = 0x31, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x53, .cmd_len = 1, .cmd = {0xA5}}, + {.reg = 0x55, .cmd_len = 1, .cmd = {0xA2}}, + {.reg = 0x50, .cmd_len = 1, .cmd = {0xB7}}, + {.reg = 0x51, .cmd_len = 1, .cmd = {0xB7}}, + {.reg = 0x60, .cmd_len = 1, .cmd = {0x22}}, + {.reg = 0x61, .cmd_len = 1, .cmd = {0x00}}, + {.reg = 0x62, .cmd_len = 1, .cmd = {0x19}}, + {.reg = 0x63, .cmd_len = 1, .cmd = {0x10}}, + /* Gamma Start */ + {.reg = 0xA0, .cmd_len = 1, .cmd = {0x08}}, + {.reg = 0xA1, .cmd_len = 1, .cmd = {0x17}}, + {.reg = 0xA2, .cmd_len = 1, .cmd = {0x1E}}, + {.reg = 0xA3, .cmd_len = 1, .cmd = {0x0E}}, + {.reg = 0xA4, .cmd_len = 1, .cmd = {0x13}}, + {.reg = 0xA5, .cmd_len = 1, .cmd = {0x24}}, + {.reg = 0xA6, .cmd_len = 1, .cmd = {0x1B}}, + {.reg = 0xA7, .cmd_len = 1, .cmd = {0x1B}}, + {.reg = 0xA8, .cmd_len = 1, .cmd = {0x53}}, + {.reg = 0xA9, .cmd_len = 1, .cmd = {0x1B}}, + {.reg = 0xAA, .cmd_len = 1, .cmd = {0x28}}, + {.reg = 0xAB, .cmd_len = 1, .cmd = {0x45}}, + {.reg = 0xAC, .cmd_len = 1, .cmd = {0x1A}}, + {.reg = 0xAD, .cmd_len = 1, .cmd = {0x1A}}, + {.reg = 0xAE, .cmd_len = 1, .cmd = {0x50}}, + {.reg = 0xAF, .cmd_len = 1, .cmd = {0x21}}, + {.reg = 0xB0, .cmd_len = 1, .cmd = {0x2C}}, + {.reg = 0xB1, .cmd_len = 1, .cmd = {0x3B}}, + {.reg = 0xB2, .cmd_len = 1, .cmd = {0x63}}, + {.reg = 0xB3, .cmd_len = 1, .cmd = {0x39}}, + /* Neg Register */ + {.reg = 0xC0, .cmd_len = 1, .cmd = {0x08}}, + {.reg = 0xC1, .cmd_len = 1, .cmd = {0x0C}}, + {.reg = 0xC2, .cmd_len = 1, .cmd = {0x17}}, + {.reg = 0xC3, .cmd_len = 1, .cmd = {0x0F}}, + {.reg = 0xC4, .cmd_len = 1, .cmd = {0x0B}}, + {.reg = 0xC5, .cmd_len = 1, .cmd = {0x1C}}, + {.reg = 0xC6, .cmd_len = 1, .cmd = {0x10}}, + {.reg = 0xC7, .cmd_len = 1, .cmd = {0x16}}, + {.reg = 0xC8, .cmd_len = 1, .cmd = {0x5B}}, + {.reg = 0xC9, .cmd_len = 1, .cmd = {0x1A}}, + {.reg = 0xCA, .cmd_len = 1, .cmd = {0x26}}, + {.reg = 0xCB, .cmd_len = 1, .cmd = {0x55}}, + {.reg = 0xCC, .cmd_len = 1, .cmd = {0x1D}}, + {.reg = 0xCD, .cmd_len = 1, .cmd = {0x1E}}, + {.reg = 0xCE, .cmd_len = 1, .cmd = {0x52}}, + {.reg = 0xCF, .cmd_len = 1, .cmd = {0x26}}, + {.reg = 0xD0, .cmd_len = 1, .cmd = {0x29}}, + {.reg = 0xD1, .cmd_len = 1, .cmd = {0x45}}, + {.reg = 0xD2, .cmd_len = 1, .cmd = {0x63}}, + {.reg = 0xD3, .cmd_len = 1, .cmd = {0x39}}, + /* Change to Page 0 CMD */ + {.reg = 0xff, .cmd_len = 3, .cmd = {0x98, 0x81, 0x00}}}; + +static int ili9881c_write_reg(const struct device *dev, uint8_t reg, const uint8_t *buf, size_t len) +{ + int ret; + const struct ili9881c_config *cfg = dev->config; + + struct mipi_dsi_msg msg = { + .cmd = reg, + .tx_buf = buf, + .tx_len = len, + .flags = MIPI_DSI_MSG_USE_LPM, + }; + + switch (len) { + case 0U: + msg.type = MIPI_DSI_DCS_SHORT_WRITE; + break; + + case 1U: + msg.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM; + break; + + default: + msg.type = MIPI_DSI_DCS_LONG_WRITE; + break; + } + + ret = mipi_dsi_transfer(cfg->mipi_dsi, cfg->channel, &msg); + if (ret < 0) { + LOG_ERR("Failed writing reg: 0x%x result: (%d)", reg, ret); + return ret; + } + + return 0; +} + +static int ili9881c_write_reg_val(const struct device *dev, uint8_t reg, uint8_t value) +{ + return ili9881c_write_reg(dev, reg, &value, 1); +} + +static int ili9881c_write_sequence(const struct device *dev, const struct ili9881c_init_cmd *cmd, + uint8_t nr_cmds) +{ + int ret = 0; + + /* Loop through all commands as long as writes are successful */ + for (int i = 0; i < nr_cmds && ret == 0; i++) { + ret = ili9881c_write_reg(dev, cmd->reg, cmd->cmd, cmd->cmd_len); + if (ret < 0) { + LOG_ERR("Failed writing sequence: 0x%x result: (%d)", cmd->reg, ret); + return ret; + } + cmd++; + } + + return ret; +} + +static int ili9881c_regs_init(const struct device *dev) +{ + const struct ili9881c_config *cfg = dev->config; + int ret; + + ret = ili9881c_write_sequence(dev, init_cmds, ARRAY_SIZE(init_cmds)); + if (ret < 0) { + return ret; + } + /* Add a delay, otherwise MADCTL not taken */ + k_msleep(120); + + /* Exit sleep mode */ + ret = ili9881c_write_reg(dev, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0); + if (ret < 0) { + return ret; + } + + /* Wait for sleep out exit */ + k_msleep(5); + + /* Set color mode */ + ret = ili9881c_write_reg_val(dev, MIPI_DCS_SET_PIXEL_FORMAT, + cfg->pixel_format == PIXEL_FORMAT_RGB_565 + ? ILITEK_ILI9881C_COLMOD_RGB565 + : ILITEK_ILI9881C_COLMOD_RGB888); + if (ret < 0) { + return ret; + } + + /* Turn on display */ + ret = ili9881c_write_reg(dev, MIPI_DCS_SET_DISPLAY_ON, NULL, 0); + + /* Set Tearing Effect Line On */ + ret = ili9881c_write_reg_val(dev, MIPI_DCS_SET_TEAR_ON, 0); + + return ret; +} + +static int ili9881c_blanking_on(const struct device *dev) +{ + const struct ili9881c_config *cfg = dev->config; + int ret; + + if (cfg->backlight.port != NULL) { + ret = gpio_pin_set_dt(&cfg->backlight, 0); + if (ret) { + LOG_ERR("Disable backlight failed! (%d)", ret); + return ret; + } + } + + return ili9881c_write_reg(dev, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0); +} + +static int ili9881c_blanking_off(const struct device *dev) +{ + const struct ili9881c_config *cfg = dev->config; + int ret; + + if (cfg->backlight.port != NULL) { + ret = gpio_pin_set_dt(&cfg->backlight, 1); + if (ret) { + LOG_ERR("Enable backlight failed! (%d)", ret); + return ret; + } + } + + return ili9881c_write_reg(dev, MIPI_DCS_SET_DISPLAY_ON, NULL, 0); +} + +static void ili9881c_get_capabilities(const struct device *dev, + struct display_capabilities *capabilities) +{ + const struct ili9881c_config *cfg = dev->config; + + memset(capabilities, 0, sizeof(struct display_capabilities)); + capabilities->x_resolution = cfg->width; + capabilities->y_resolution = cfg->height; + capabilities->supported_pixel_formats = cfg->pixel_format; + capabilities->current_pixel_format = cfg->pixel_format; +} + +static int ili9881c_pixel_format(const struct device *dev, + const enum display_pixel_format pixel_format) +{ + const struct ili9881c_config *config = dev->config; + + LOG_WRN("Pixel format change not implemented"); + if (pixel_format == config->pixel_format) { + return 0; + } + + return -ENOTSUP; +} + +static DEVICE_API(display, ili9881c_api) = { + .blanking_on = ili9881c_blanking_on, + .blanking_off = ili9881c_blanking_off, + .set_pixel_format = ili9881c_pixel_format, + .get_capabilities = ili9881c_get_capabilities, +}; + +static int ili9881c_init(const struct device *dev) +{ + const struct ili9881c_config *cfg = dev->config; + struct mipi_dsi_device mdev; + int ret; + + if (cfg->reset.port) { + if (!gpio_is_ready_dt(&cfg->reset)) { + LOG_ERR("Reset GPIO device is not ready!"); + return -ENODEV; + } + k_sleep(K_MSEC(1)); + + ret = gpio_pin_configure_dt(&cfg->reset, GPIO_OUTPUT_INACTIVE); + if (ret < 0) { + LOG_ERR("Reset display failed! (%d)", ret); + return ret; + } + + ret = gpio_pin_set_dt(&cfg->reset, 0); + if (ret < 0) { + LOG_ERR("Reset display failed! (%d)", ret); + return ret; + } + k_sleep(K_MSEC(1)); + + ret = gpio_pin_set_dt(&cfg->reset, 1); + if (ret < 0) { + LOG_ERR("Enable display failed! (%d)", ret); + return ret; + } + k_sleep(K_MSEC(50)); + } + + /* Attach to MIPI-DSI host */ + if (cfg->pixel_format == PIXEL_FORMAT_RGB_565) { + mdev.pixfmt = MIPI_DSI_PIXFMT_RGB565; + } else { + mdev.pixfmt = MIPI_DSI_PIXFMT_RGB888; + } + mdev.data_lanes = cfg->data_lanes; + mdev.mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_LPM; + mdev.timings.hactive = cfg->width; + mdev.timings.hbp = ILITEK_ILI9881C_HBP; + mdev.timings.hfp = ILITEK_ILI9881C_HFP; + mdev.timings.hsync = ILITEK_ILI9881C_HSYNC; + mdev.timings.vactive = cfg->height; + mdev.timings.vbp = ILITEK_ILI9881C_VBP; + mdev.timings.vfp = ILITEK_ILI9881C_VFP; + mdev.timings.vsync = ILITEK_ILI9881C_VSYNC; + + ret = mipi_dsi_attach(cfg->mipi_dsi, cfg->channel, &mdev); + if (ret < 0) { + LOG_ERR("Could not attach to MIPI-DSI host"); + return ret; + } + + if (cfg->backlight.port != NULL) { + ret = gpio_pin_configure_dt(&cfg->backlight, GPIO_OUTPUT_ACTIVE); + if (ret < 0) { + LOG_ERR("Could not configure backlight GPIO (%d)", ret); + return ret; + } + } + + ret = ili9881c_regs_init(dev); + if (ret) { + LOG_ERR("DSI init sequence failed! (%d)", ret); + return ret; + } + + return 0; +} + +#define ILITEK_ILI9881C_DEFINE(n) \ + static const struct ili9881c_config ili9881c_config_##n = { \ + .mipi_dsi = DEVICE_DT_GET(DT_INST_BUS(n)), \ + .reset = GPIO_DT_SPEC_INST_GET_OR(n, reset_gpios, {0}), \ + .backlight = GPIO_DT_SPEC_INST_GET_OR(n, bl_gpios, {0}), \ + .data_lanes = DT_INST_PROP_BY_IDX(n, data_lanes, 0), \ + .width = DT_INST_PROP(n, width), \ + .height = DT_INST_PROP(n, height), \ + .channel = DT_INST_REG_ADDR(n), \ + .pixel_format = DT_INST_PROP(n, pixel_format), \ + }; \ + DEVICE_DT_INST_DEFINE(n, &ili9881c_init, NULL, NULL, &ili9881c_config_##n, POST_KERNEL, \ + CONFIG_DISPLAY_ILI9881C_DSI_INIT_PRIORITY, &ili9881c_api); + +DT_INST_FOREACH_STATUS_OKAY(ILITEK_ILI9881C_DEFINE) diff --git a/drivers/display/display_ili9881c_dsi.h b/drivers/display/display_ili9881c_dsi.h new file mode 100644 index 0000000000000..0cadbf4122999 --- /dev/null +++ b/drivers/display/display_ili9881c_dsi.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_DISPLAY_ILITEK_ILI9881C_H_ +#define ZEPHYR_DRIVERS_DISPLAY_ILITEK_ILI9881C_H_ + +#define LCD_TIMINGS_NODE DT_CHILD(DT_NODELABEL(zephyr_lcdif), display_timings) + +#define LCD_HTIMMING_SYNC DT_PROP(LCD_TIMINGS_NODE, hsync_len) +#define LCD_HTIMMING_BACK_PORCH DT_PROP(LCD_TIMINGS_NODE, hback_porch) +#define LCD_HTIMMING_FRONT_PORCH DT_PROP(LCD_TIMINGS_NODE, hfront_porch) + +#define LCD_VTIMMING_SYNC DT_PROP(LCD_TIMINGS_NODE, vsync_len) +#define LCD_VTIMMING_BACK_PORCH DT_PROP(LCD_TIMINGS_NODE, vback_porch) +#define LCD_VTIMMING_FRONT_PORCH DT_PROP(LCD_TIMINGS_NODE, vfront_porch) + +#define ILITEK_ILI9881C_HSYNC LCD_HTIMMING_SYNC +#define ILITEK_ILI9881C_HBP LCD_HTIMMING_BACK_PORCH - LCD_HTIMMING_SYNC +#define ILITEK_ILI9881C_HFP LCD_HTIMMING_FRONT_PORCH + +#define ILITEK_ILI9881C_VSYNC LCD_VTIMMING_SYNC +#define ILITEK_ILI9881C_VBP LCD_VTIMMING_BACK_PORCH - LCD_VTIMMING_SYNC +#define ILITEK_ILI9881C_VFP LCD_VTIMMING_FRONT_PORCH + +#endif /* ZEPHYR_DRIVERS_DISPLAY_ILITEK_ILI9881C_H_ */ diff --git a/drivers/display/display_renesas_rz.c b/drivers/display/display_renesas_rz.c new file mode 100644 index 0000000000000..7210a7de8f5b5 --- /dev/null +++ b/drivers/display/display_renesas_rz.c @@ -0,0 +1,404 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_rz_lcdc + +#include "display_renesas_rz.h" +#include "r_lcdc.h" +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(display_renesas_rz, CONFIG_DISPLAY_LOG_LEVEL); + +struct display_rz_config { + const display_api_t *fsp_api; + const struct pinctrl_dev_config *pincfg; + const struct gpio_dt_spec backlight_gpio; + uint16_t height; + uint16_t width; + void (*irq_configure)(void); +}; + +struct display_rz_data { + lcdc_instance_ctrl_t display_ctrl; + display_cfg_t display_fsp_cfg; + const uint8_t *pend_buf; + const uint8_t *front_buf; + uint8_t pixel_size; + enum display_pixel_format current_pixel_format; + uint8_t *frame_buffer; + uint32_t frame_buffer_len; + struct k_sem frame_buf_sem; +}; + +extern void lcdc_vspd_int(void *irq); + +static void renesas_rz_lcdc_isr(const struct device *dev) +{ + struct display_rz_data *data = dev->data; + const lcdc_extended_cfg_t *ext_cfg = data->display_fsp_cfg.p_extend; + + lcdc_vspd_int((void *)ext_cfg->frame_end_irq); +} + +static void renesas_rz_callback_adapter(display_callback_args_t *p_args) +{ + const struct device *dev = p_args->p_context; + struct display_rz_data *data = dev->data; + + if (p_args->event == DISPLAY_EVENT_FRAME_END) { + if (data->front_buf != data->pend_buf) { + data->front_buf = data->pend_buf; + } + + k_sem_give(&data->frame_buf_sem); + } +} + +static int rz_display_write(const struct device *dev, const uint16_t x, const uint16_t y, + const struct display_buffer_descriptor *desc, const void *buf) +{ + struct display_rz_data *data = dev->data; + const struct display_rz_config *config = dev->config; + const uint8_t *l_pend_buf = NULL; + fsp_err_t err; + + if (desc->pitch < desc->width) { + LOG_ERR("Pitch is smaller than width"); + return -EINVAL; + } + + if ((desc->pitch * data->pixel_size * desc->height) > desc->buf_size) { + LOG_ERR("Input buffer too small"); + return -EINVAL; + } + + if (x == 0 && y == 0 && desc->height == config->height && desc->width == config->width) { + l_pend_buf = buf; + } else { +#if CONFIG_RENESAS_RZ_LCDC_FB_NUM == 0 + LOG_ERR("Partial write requires internal frame buffer"); + return -ENOTSUP; +#else + const uint8_t *src = buf; + uint8_t *dst = NULL; + uint16_t row; + + dst = data->frame_buffer; + + if (CONFIG_RENESAS_RZ_LCDC_FB_NUM == 2) { + if (data->front_buf == data->frame_buffer) { + dst = data->frame_buffer + data->frame_buffer_len; + } + + memcpy(dst, data->front_buf, data->frame_buffer_len); + } + + l_pend_buf = dst; + + /* dst = pointer to upper left pixel of the rectangle + * to be updated in frame buffer. + */ + dst += (x * data->pixel_size); + dst += (y * config->width * data->pixel_size); + + for (row = 0; row < desc->height; row++) { + (void)memcpy(dst, src, desc->width * data->pixel_size); + sys_cache_data_flush_range(dst, desc->width * data->pixel_size); + dst += (config->width * data->pixel_size); + src += (desc->pitch * data->pixel_size); + } +#endif /* CONFIG_RENESAS_RZ_LCDC_FB_NUM == 0 */ + } + + if (data->front_buf != l_pend_buf) { + k_sem_reset(&data->frame_buf_sem); + data->pend_buf = l_pend_buf; + sys_cache_data_flush_range((void *)data->pend_buf, data->frame_buffer_len); + err = config->fsp_api->bufferChange(&data->display_ctrl, (uint8_t *)data->pend_buf, + DISPLAY_FRAME_LAYER_1); + if (err != FSP_SUCCESS) { + LOG_ERR("LCDC buffer change failed"); + return -EIO; + } + k_sem_take(&data->frame_buf_sem, K_FOREVER); + } + + return 0; +} + +static int rz_display_read(const struct device *dev, const uint16_t x, const uint16_t y, + const struct display_buffer_descriptor *desc, void *buf) +{ + struct display_rz_data *data = dev->data; + const struct display_rz_config *config = dev->config; + uint8_t *dst = buf; + const uint8_t *src = data->front_buf; + uint16_t row; + + /* src = pointer to upper left pixel of the rectangle to be read from frame buffer */ + src += (x * data->pixel_size); + src += (y * config->width * data->pixel_size); + + for (row = 0; row < desc->height; row++) { + (void)memcpy(dst, src, desc->width * data->pixel_size); + src += (config->width * data->pixel_size); + dst += (desc->pitch * data->pixel_size); + } + + return 0; +} + +static int rz_display_blanking_on(const struct device *dev) +{ + const struct display_rz_config *config = dev->config; + int ret = 0; + + if (config->backlight_gpio.port != NULL) { + ret = gpio_pin_set_dt(&config->backlight_gpio, 0); + } else { + ret = -ENOTSUP; + } + + return ret; +} + +static int rz_display_blanking_off(const struct device *dev) +{ + const struct display_rz_config *config = dev->config; + int ret = 0; + + if (config->backlight_gpio.port != NULL) { + ret = gpio_pin_set_dt(&config->backlight_gpio, 1); + } else { + ret = -ENOTSUP; + } + + return ret; +} + +static void rz_display_get_capabilities(const struct device *dev, + struct display_capabilities *capabilities) +{ + const struct display_rz_config *config = dev->config; + struct display_rz_data *data = dev->data; + + capabilities->x_resolution = config->width; + capabilities->y_resolution = config->height; + capabilities->current_orientation = DISPLAY_ORIENTATION_NORMAL; + capabilities->supported_pixel_formats = + PIXEL_FORMAT_RGB_888 | PIXEL_FORMAT_ARGB_8888 | PIXEL_FORMAT_RGB_565; + capabilities->current_pixel_format = data->current_pixel_format; + capabilities->screen_info = 0U; +} + +static int rz_display_set_pixel_format(const struct device *dev, + const enum display_pixel_format pixel_format) +{ + const struct display_rz_config *config = dev->config; + struct display_rz_data *data = dev->data; + display_runtime_cfg_t layer_cfg; + enum display_pixel_format set_pixel_format; + display_in_format_t hardware_pixel_format; + uint32_t buf_len; + fsp_err_t err; + + if (pixel_format == data->current_pixel_format) { + return 0; + } + + if (data->display_ctrl.state == DISPLAY_STATE_DISPLAYING) { + LOG_ERR("Cannot change the display format while displaying"); + return -EWOULDBLOCK; + } + + switch (pixel_format) { + case PIXEL_FORMAT_RGB_888: + set_pixel_format = PIXEL_FORMAT_ARGB_8888; + hardware_pixel_format = DISPLAY_IN_FORMAT_32BITS_RGB888; + break; + + case PIXEL_FORMAT_ARGB_8888: + set_pixel_format = PIXEL_FORMAT_ARGB_8888; + hardware_pixel_format = DISPLAY_IN_FORMAT_32BITS_ARGB8888; + break; + + case PIXEL_FORMAT_RGB_565: + set_pixel_format = PIXEL_FORMAT_RGB_565; + hardware_pixel_format = DISPLAY_IN_FORMAT_16BITS_RGB565; + break; + + default: + return -ENOTSUP; + } + + buf_len = (config->height * config->width * DISPLAY_BITS_PER_PIXEL(set_pixel_format)) >> 3; + + if (buf_len > data->frame_buffer_len) { + LOG_ERR("Frame buffer is smaller than new pixel format require"); + return -ENOTSUP; + } + + memcpy(&layer_cfg.input, &data->display_fsp_cfg.input[0], sizeof(display_input_cfg_t)); + memcpy(&layer_cfg.layer, &data->display_fsp_cfg.layer[0], sizeof(display_layer_t)); + layer_cfg.input.format = hardware_pixel_format; + layer_cfg.input.hstride = + ROUND_UP(layer_cfg.input.hsize * DISPLAY_BITS_PER_PIXEL(set_pixel_format), + NUM_BITS(uint64_t)) / + DISPLAY_BITS_PER_PIXEL(set_pixel_format); + + err = config->fsp_api->layerChange(&data->display_ctrl, &layer_cfg, DISPLAY_FRAME_LAYER_1); + if (err != FSP_SUCCESS) { + LOG_ERR("Failed to change the pixel format"); + return -EIO; + } + + data->current_pixel_format = pixel_format; + data->pixel_size = DISPLAY_BITS_PER_PIXEL(set_pixel_format) >> 3; + + return 0; +} + +static void *rz_display_get_framebuffer(const struct device *dev) +{ + struct display_rz_data *data = dev->data; + + return (void *)data->front_buf; +} + +static DEVICE_API(display, display_api) = { + .blanking_on = rz_display_blanking_on, + .blanking_off = rz_display_blanking_off, + .get_capabilities = rz_display_get_capabilities, + .set_pixel_format = rz_display_set_pixel_format, + .write = rz_display_write, + .read = rz_display_read, + .get_framebuffer = rz_display_get_framebuffer, +}; + +static int display_init(const struct device *dev) +{ + const struct display_rz_config *config = dev->config; + struct display_rz_data *data = dev->data; + int err; + + if (config->pincfg != NULL) { + err = pinctrl_apply_state(config->pincfg, PINCTRL_STATE_DEFAULT); + if (err) { + LOG_ERR("Pin function initial failed"); + return err; + } + } + + k_sem_init(&data->frame_buf_sem, 0, 1); + + err = config->fsp_api->open(&data->display_ctrl, &data->display_fsp_cfg); + if (err) { + LOG_ERR("LCDC open failed"); + return -EIO; + } + + err = gpio_pin_configure_dt(&config->backlight_gpio, GPIO_OUTPUT_ACTIVE); + if (err) { + LOG_ERR("Backlight GPIO configuration failed"); + return err; + } + + config->irq_configure(); + + err = config->fsp_api->start(&data->display_ctrl); + if (err) { + LOG_ERR("LCDC start failed"); + return -EIO; + } + + return 0; +} + +#define IRQ_CONFIGURE_FUNC(id) \ + static void lcdc_renesas_rz_configure_func_##id(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(id, vspd_int, irq), \ + DT_INST_IRQ_BY_NAME(id, vspd_int, priority), renesas_rz_lcdc_isr, \ + DEVICE_DT_INST_GET(id), DT_INST_IRQ_BY_NAME(id, vspd_int, flags)); \ + irq_enable(DT_INST_IRQ_BY_NAME(id, vspd_int, irq)); \ + } + +#define IRQ_CONFIGURE_DEFINE(id) .irq_configure = lcdc_renesas_rz_configure_func_##id + +#define RENESAS_RZ_FRAME_BUFFER_LEN(id) \ + (RENESAS_RZ_LCDC_PIXEL_BYTE_SIZE(id) * DT_INST_PROP(id, height) * DT_INST_PROP(id, width)) + +#define RENESAS_RZ_LCDC_DEVICE_PINCTRL_INIT(n) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(n, pinctrl_0), (PINCTRL_DT_INST_DEFINE(n)), ()) + +#define RENESAS_RZ_LCDC_DEVICE_PINCTRL_GET(n) \ + COND_CODE_1(DT_INST_NODE_HAS_PROP(n, pinctrl_0), (PINCTRL_DT_INST_DEV_CONFIG_GET(n)), \ + (NULL)) + +#define RENESAS_RZ_DEVICE_INIT(id) \ + RENESAS_RZ_LCDC_DEVICE_PINCTRL_INIT(id); \ + \ + IRQ_CONFIGURE_FUNC(id) \ + \ + static uint8_t __aligned(64) \ + fb_background##id[CONFIG_RENESAS_RZ_LCDC_FB_NUM * RENESAS_RZ_FRAME_BUFFER_LEN(id)]; \ + \ + static const lcdc_extended_cfg_t display_extend_cfg##id = { \ + .frame_end_ipl = DT_INST_IRQ_BY_NAME(id, vspd_int, priority), \ + .underrun_ipl = DT_INST_IRQ_BY_NAME(id, vspd_int, priority), \ + .frame_end_irq = DT_INST_IRQ_BY_NAME(id, vspd_int, irq), \ + .underrun_irq = DT_INST_IRQ_BY_NAME(id, vspd_int, irq)}; \ + \ + static struct display_rz_data rz_data##id = { \ + .frame_buffer = fb_background##id, \ + .frame_buffer_len = RENESAS_RZ_FRAME_BUFFER_LEN(id), \ + .front_buf = fb_background##id, \ + .pend_buf = fb_background##id, \ + .pixel_size = RENESAS_RZ_LCDC_PIXEL_BYTE_SIZE(id), \ + .current_pixel_format = RENESAS_RZ_DISPLAY_GET_PIXEL_FORMAT(id), \ + .display_fsp_cfg = { \ + .input[0] = \ + { \ + .p_base = (uint32_t *)fb_background##id, \ + .hsize = DISPLAY_HSIZE(id), \ + .vsize = DISPLAY_VSIZE(id), \ + .coordinate_x = 0, \ + .coordinate_y = 0, \ + .hstride = RENESAS_RZ_DISPLAY_BUFFER_HSTRIDE_BYTE(id), \ + .format = RENESAS_RZ_LCDC_IN_PIXEL_FORMAT(id), \ + .data_swap = DISPLAY_DATA_SWAP_64BIT | \ + DISPLAY_DATA_SWAP_32BIT | \ + DISPLAY_DATA_SWAP_16BIT, \ + }, \ + .input[1] = {.p_base = NULL}, \ + .output = {.htiming = RENESAS_RZ_LCDC_HTIMING(id), \ + .vtiming = RENESAS_RZ_LCDC_VTIMING(id), \ + .format = RENESAS_RZ_LCDC_OUT_PIXEL_FORMAT(id), \ + .data_enable_polarity = RENESAS_RZ_LCDC_OUTPUT_DE_POLARITY(id), \ + .sync_edge = RENESAS_RZ_LCDC_OUTPUT_SYNC_EDGE(id), \ + .bg_color = RENESAS_RZ_LCDC_BG_COLOR(id), \ + .dithering_on = false}, \ + .p_callback = renesas_rz_callback_adapter, \ + .p_context = DEVICE_DT_INST_GET(id), \ + .p_extend = (void *)(&display_extend_cfg##id)}}; \ + \ + static struct display_rz_config rz_config##id = { \ + .fsp_api = &g_display_on_lcdc, \ + IRQ_CONFIGURE_DEFINE(id), \ + .pincfg = RENESAS_RZ_LCDC_DEVICE_PINCTRL_GET(id), \ + .backlight_gpio = GPIO_DT_SPEC_INST_GET_OR(id, backlight_gpios, NULL), \ + .height = DT_INST_PROP(id, height), \ + .width = DT_INST_PROP(id, width)}; \ + \ + DEVICE_DT_INST_DEFINE(id, &display_init, NULL, &rz_data##id, &rz_config##id, POST_KERNEL, \ + CONFIG_DISPLAY_INIT_PRIORITY, &display_api); + +DT_INST_FOREACH_STATUS_OKAY(RENESAS_RZ_DEVICE_INIT) diff --git a/drivers/display/display_renesas_rz.h b/drivers/display/display_renesas_rz.h new file mode 100644 index 0000000000000..4dddb3d5c7bf4 --- /dev/null +++ b/drivers/display/display_renesas_rz.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_DRIVERS_DISPLAY_RENESAS_RZ_H_ +#define ZEPHYR_DRIVERS_DISPLAY_RENESAS_RZ_H_ + +#include + +#define ROUND_UP_64BYTES(x) ROUND_UP(x, NUM_BITS(uint64_t)) +#define INPUT_FORMAT_PIXEL(n) DT_INST_PROP(n, input_pixel_format) +#define OUTPUT_FORMAT_PIXEL(n) DT_INST_PROP(n, output_pixel_format) + +#define RENESAS_RZ_LCDC_IN_PIXEL_FORMAT_1 (DISPLAY_IN_FORMAT_32BITS_RGB888) +#define RENESAS_RZ_LCDC_IN_PIXEL_FORMAT_8 (DISPLAY_IN_FORMAT_32BITS_ARGB8888) +#define RENESAS_RZ_LCDC_IN_PIXEL_FORMAT_16 (DISPLAY_IN_FORMAT_16BITS_RGB565) + +#define RENESAS_RZ_LCDC_OUT_PIXEL_FORMAT_1 (DISPLAY_OUT_FORMAT_24BITS_RGB888) +#define RENESAS_RZ_LCDC_OUT_PIXEL_FORMAT_16 (DISPLAY_OUT_FORMAT_16BITS_RGB565) + +#define RENESAS_RZ_DISPLAY_GET_PIXEL_FORMAT(n) \ + (DT_INST_PROP(n, input_pixel_format) == PANEL_PIXEL_FORMAT_RGB_888 \ + ? PANEL_PIXEL_FORMAT_ARGB_8888 \ + : DT_INST_PROP(n, input_pixel_format)) + +#define DISPLAY_HSIZE(n) (DT_INST_PROP(n, width)) +#define DISPLAY_VSIZE(n) (DT_INST_PROP(n, height)) + +#define RENESAS_RZ_LCDC_IN_PIXEL_FORMAT(n) \ + UTIL_CAT(RENESAS_RZ_LCDC_IN_PIXEL_FORMAT_, INPUT_FORMAT_PIXEL(n)) + +#define RENESAS_RZ_LCDC_OUT_PIXEL_FORMAT(n) \ + UTIL_CAT(RENESAS_RZ_LCDC_OUT_PIXEL_FORMAT_, OUTPUT_FORMAT_PIXEL(n)) + +#define RENESAS_RZ_LCDC_PIXEL_BYTE_SIZE(n) \ + (DISPLAY_BITS_PER_PIXEL(RENESAS_RZ_DISPLAY_GET_PIXEL_FORMAT(n)) >> 3) + +#define RENESAS_RZ_DISPLAY_BUFFER_HSTRIDE_BYTE(n) \ + (DISPLAY_HSIZE(n) * DISPLAY_BITS_PER_PIXEL(INPUT_FORMAT_PIXEL(n)) >> 3) + +#define RENESAS_RZ_LCDC_HTIMING(n) \ + {.total_cyc = DT_INST_PROP(n, width) + \ + DT_PROP(DT_INST_CHILD(n, display_timings), hback_porch) + \ + DT_PROP(DT_INST_CHILD(n, display_timings), hfront_porch), \ + .display_cyc = DT_INST_PROP(n, width), \ + .back_porch = DT_PROP(DT_INST_CHILD(n, display_timings), hback_porch), \ + .sync_width = DT_PROP(DT_INST_CHILD(n, display_timings), hsync_len), \ + .sync_polarity = DT_PROP(DT_INST_CHILD(n, display_timings), hsync_active)} + +#define RENESAS_RZ_LCDC_VTIMING(n) \ + {.total_cyc = DT_INST_PROP(n, height) + \ + DT_PROP(DT_INST_CHILD(n, display_timings), vback_porch) + \ + DT_PROP(DT_INST_CHILD(n, display_timings), vfront_porch), \ + .display_cyc = DT_INST_PROP(n, height), \ + .back_porch = DT_PROP(DT_INST_CHILD(n, display_timings), vback_porch), \ + .sync_width = DT_PROP(DT_INST_CHILD(n, display_timings), vsync_len), \ + .sync_polarity = DT_PROP(DT_INST_CHILD(n, display_timings), vsync_active)} + +#define RENESAS_RZ_LCDC_OUTPUT_DE_POLARITY(n) DT_INST_ENUM_IDX(n, output_data_signal_polarity) + +#define RENESAS_RZ_LCDC_OUTPUT_SYNC_EDGE(n) DT_INST_ENUM_IDX(n, output_signal_sync_edge) + +#define RENESAS_RZ_LCDC_BG_COLOR(n) \ + { \ + .byte = { \ + .a = DT_INST_PROP(n, background_color_alpha), \ + .r = DT_INST_PROP(n, background_color_red), \ + .g = DT_INST_PROP(n, background_color_green), \ + .b = DT_INST_PROP(n, background_color_blue) \ + } \ + } + +#endif /* ZEPHYR_DRIVERS_DISPLAY_RENESAS_RZ_H_ */ diff --git a/drivers/gpio/gpio_renesas_rz.h b/drivers/gpio/gpio_renesas_rz.h index 3258ca8bd06b9..04ef2c062c9f1 100644 --- a/drivers/gpio/gpio_renesas_rz.h +++ b/drivers/gpio/gpio_renesas_rz.h @@ -15,7 +15,7 @@ #if defined(CONFIG_SOC_SERIES_RZG3S) || defined(CONFIG_SOC_SERIES_RZA3UL) || \ defined(CONFIG_SOC_SERIES_RZV2L) || defined(CONFIG_SOC_SERIES_RZG2L) || \ defined(CONFIG_SOC_SERIES_RZV2H) || defined(CONFIG_SOC_SERIES_RZG2UL) || \ - defined(CONFIG_SOC_SERIES_RZV2N) + defined(CONFIG_SOC_SERIES_RZV2N) || defined(CONFIG_SOC_SERIES_RZA3M) #include #if defined(CONFIG_SOC_SERIES_RZG3S) @@ -40,6 +40,18 @@ static const uint8_t gpio_rz_int[GPIO_RZ_MAX_PORT_NUM] = {0, 4, 9, 13, 17, 23 static const uint8_t gpio_rz_int[GPIO_RZ_MAX_PORT_NUM] = {0, 4, 9, 13, 17, 23, 28, 33, 38, 43, 47, 52, 56, 58, 63, 66, 70, 72, 76}; +#elif defined(CONFIG_SOC_SERIES_RZA3M) +#define GPIO_RZ_P_REG_BASE_GET (&R_GPIO->P01) +#define GPIO_RZ_PM_REG_BASE_GET (&R_GPIO->PM01) +#define GPIO_RZ_PFC_REG_BASE_GET (&R_GPIO->PFC01) +#define GPIO_RZ_MAX_PORT_NUM 24 +#define GPIO_RZ_TINT_IRQ_OFFSET 476 +#define R_INTC R_INTC_IA55 +#define GPIO_RZ_TINT_STATUS_REG_CLEAR(tint_num) (R_INTC_IA55->TSCR &= ~BIT(tint_num)) +static const uint8_t gpio_rz_int[GPIO_RZ_MAX_PORT_NUM] = {0, 4, 9, 13, 17, 23, 28, 33, 38, 42, + 47, 52, 56, 0, 0, 0, 0, 0, 0, 0, + 58, 64, 67, 72}; + #elif defined(CONFIG_SOC_SERIES_RZV2H) || defined(CONFIG_SOC_SERIES_RZV2N) #define GPIO_RZ_P_REG_BASE_GET (&R_GPIO->P20) #define GPIO_RZ_PM_REG_BASE_GET (&R_GPIO->PM20) diff --git a/drivers/mipi_dsi/CMakeLists.txt b/drivers/mipi_dsi/CMakeLists.txt index 614e86020d57f..c7c6bce1bc04a 100644 --- a/drivers/mipi_dsi/CMakeLists.txt +++ b/drivers/mipi_dsi/CMakeLists.txt @@ -5,3 +5,4 @@ zephyr_sources_ifdef(CONFIG_MIPI_DSI_NXP_DWC dsi_nxp_dwc.c) zephyr_sources_ifdef(CONFIG_MIPI_DSI_STM32 dsi_stm32.c) zephyr_sources_ifdef(CONFIG_MIPI_DSI_TEST dsi_test.c) zephyr_sources_ifdef(CONFIG_MIPI_DSI_RENESAS_RA dsi_renesas_ra.c) +zephyr_sources_ifdef(CONFIG_MIPI_DSI_RENESAS_RZ dsi_renesas_rz.c) diff --git a/drivers/mipi_dsi/Kconfig b/drivers/mipi_dsi/Kconfig index 508579001f2ad..b5584e07b5e4e 100644 --- a/drivers/mipi_dsi/Kconfig +++ b/drivers/mipi_dsi/Kconfig @@ -25,5 +25,6 @@ source "drivers/mipi_dsi/Kconfig.mcux" source "drivers/mipi_dsi/Kconfig.stm32" source "drivers/mipi_dsi/Kconfig.test" source "drivers/mipi_dsi/Kconfig.renesas_ra" +source "drivers/mipi_dsi/Kconfig.renesas_rz" endif diff --git a/drivers/mipi_dsi/Kconfig.renesas_rz b/drivers/mipi_dsi/Kconfig.renesas_rz new file mode 100644 index 0000000000000..b4489a97a98c1 --- /dev/null +++ b/drivers/mipi_dsi/Kconfig.renesas_rz @@ -0,0 +1,12 @@ +# Renesas RZ Family + +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config MIPI_DSI_RENESAS_RZ + bool "Renesas RZ MIPI-DSI Host Controller" + default y + depends on DT_HAS_RENESAS_RZ_MIPI_DSI_ENABLED + select USE_RZ_FSP_MIPI_DSI + help + Renesas RZ MIPI DSI controller driver diff --git a/drivers/mipi_dsi/dsi_renesas_rz.c b/drivers/mipi_dsi/dsi_renesas_rz.c new file mode 100644 index 0000000000000..1248440c76206 --- /dev/null +++ b/drivers/mipi_dsi/dsi_renesas_rz.c @@ -0,0 +1,364 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_rz_mipi_dsi + +#include +#include +#include +#include +#include "r_mipi_dsi_b.h" +#include "r_display_api.h" + +LOG_MODULE_REGISTER(dsi_renesas_rz, CONFIG_MIPI_DSI_LOG_LEVEL); + +struct mipi_dsi_renesas_rz_config { + void (*irq_configure)(void); + const mipi_dsi_api_t *fsp_api; +}; + +struct mipi_dsi_renesas_rz_data { + mipi_dsi_ctrl_t *fsp_ctrl; + mipi_dsi_cfg_t *fsp_cfg; + struct k_sem in_transmission; + atomic_t status; +}; + +extern void mipi_dsi_seq0(void *irq); + +static void renesas_rz_mipi_dsi_isr(const struct device *dev) +{ + struct mipi_dsi_renesas_rz_data *data = dev->data; + const mipi_dsi_b_extended_cfg_t *ext_cfg = data->fsp_cfg->p_extend; + + mipi_dsi_seq0((void *)ext_cfg->dsi_seq0.irq); +} + +void mipi_dsi_callback(mipi_dsi_callback_args_t *p_args) +{ + const struct device *dev = (struct device *)p_args->p_context; + struct mipi_dsi_renesas_rz_data *data = dev->data; + + if (p_args->event == MIPI_DSI_EVENT_SEQUENCE_0) { + atomic_set(&data->status, p_args->tx_status); + k_sem_give(&data->in_transmission); + } +} + +static int mipi_dsi_renesas_rz_attach(const struct device *dev, uint8_t channel, + const struct mipi_dsi_device *mdev) +{ + struct mipi_dsi_renesas_rz_data *data = dev->data; + const struct mipi_dsi_renesas_rz_config *config = dev->config; + mipi_dsi_cfg_t *cfg = data->fsp_cfg; + fsp_err_t err; + + if (!(mdev->mode_flags & MIPI_DSI_MODE_VIDEO)) { + LOG_ERR("DSI host supports video mode only!"); + return -ENOTSUP; + } + + if (channel == 0 && (mdev->mode_flags & MIPI_DSI_MODE_LPM) == 0) { + LOG_ERR("This channel support LP mode transfer only"); + return -ENOTSUP; + } + + cfg->virtual_channel_id = channel; + cfg->num_lanes = mdev->data_lanes; + + if (mdev->pixfmt == MIPI_DSI_PIXFMT_RGB888) { + cfg->data_type = MIPI_DSI_VIDEO_DATA_24RGB_PIXEL_STREAM; + } else if (mdev->pixfmt == MIPI_DSI_PIXFMT_RGB565) { + cfg->data_type = MIPI_DSI_VIDEO_DATA_16RGB_PIXEL_STREAM; + } else { + return -ENOTSUP; + } + + cfg->horizontal_active_lines = mdev->timings.hactive; + cfg->horizontal_front_porch = mdev->timings.hfp; + cfg->horizontal_back_porch = mdev->timings.hbp; + cfg->horizontal_sync_lines = mdev->timings.hsync; + + cfg->vertical_active_lines = mdev->timings.vactive; + cfg->vertical_front_porch = mdev->timings.vfp; + cfg->vertical_back_porch = mdev->timings.vbp; + cfg->vertical_sync_lines = mdev->timings.vsync; + + err = config->fsp_api->open(data->fsp_ctrl, cfg); + if (err != FSP_SUCCESS) { + LOG_ERR("Open DSI failed (%d)", err); + return -EIO; + } + + err = config->fsp_api->start(data->fsp_ctrl); + if (err != FSP_SUCCESS) { + LOG_ERR("Start DSI host failed! (%d)", err); + return -EIO; + } + + return 0; +} + +#define MIPI_DSI_SEQUENCE_STATUS_ERROR \ + (MIPI_DSI_SEQUENCE_STATUS_DESCRIPTOR_ABORT | MIPI_DSI_SEQUENCE_STATUS_SIZE_ERROR | \ + MIPI_DSI_SEQUENCE_STATUS_TX_INTERNAL_BUS_ERROR | \ + MIPI_DSI_SEQUENCE_STATUS_RX_FATAL_ERROR | MIPI_DSI_SEQUENCE_STATUS_RX_FAIL | \ + MIPI_DSI_SEQUENCE_STATUS_RX_PACKET_DATA_FAIL | \ + MIPI_DSI_SEQUENCE_STATUS_RX_CORRECTABLE_ERROR | \ + MIPI_DSI_SEQUENCE_STATUS_RX_ACK_AND_ERROR) + +static ssize_t mipi_dsi_renesas_rz_dcs_write(const struct device *dev, uint8_t channel, + struct mipi_dsi_msg *msg) +{ + struct mipi_dsi_renesas_rz_data *data = dev->data; + const struct mipi_dsi_renesas_rz_config *config = dev->config; + uint8_t payload[msg->tx_len + 1]; + mipi_dsi_cmd_t fsp_msg = {.channel = channel, + .cmd_id = msg->type, + .p_tx_buffer = payload, + .tx_len = msg->tx_len + 1, + .flags = (msg->flags & MIPI_DSI_MSG_USE_LPM) != 0 + ? MIPI_DSI_CMD_FLAG_LOW_POWER + : 0}; + + payload[0] = msg->cmd; + memcpy(&payload[1], msg->tx_buf, msg->tx_len); + + atomic_clear(&data->status); + k_sem_reset(&data->in_transmission); + + if (config->fsp_api->command(data->fsp_ctrl, &fsp_msg) != FSP_SUCCESS) { + LOG_ERR("DSI write fail"); + return -EIO; + } + + k_sem_take(&data->in_transmission, K_FOREVER); + + if ((data->status & MIPI_DSI_SEQUENCE_STATUS_ERROR) != MIPI_DSI_SEQUENCE_STATUS_NONE) { + return -EIO; + } + + return (ssize_t)msg->tx_len; +} + +static ssize_t mipi_dsi_renesas_rz_generic_write(const struct device *dev, uint8_t channel, + struct mipi_dsi_msg *msg) +{ + struct mipi_dsi_renesas_rz_data *data = dev->data; + const struct mipi_dsi_renesas_rz_config *config = dev->config; + mipi_dsi_cmd_t fsp_msg = {.channel = channel, + .cmd_id = msg->type, + .p_tx_buffer = msg->tx_buf, + .tx_len = msg->tx_len, + .flags = (msg->flags & MIPI_DSI_MSG_USE_LPM) != 0 + ? MIPI_DSI_CMD_FLAG_LOW_POWER + : 0}; + + atomic_clear(&data->status); + k_sem_reset(&data->in_transmission); + + if (config->fsp_api->command(data->fsp_ctrl, &fsp_msg) != FSP_SUCCESS) { + LOG_ERR("DSI write fail"); + return -EIO; + } + + k_sem_take(&data->in_transmission, K_FOREVER); + + if ((data->status & MIPI_DSI_SEQUENCE_STATUS_ERROR) != MIPI_DSI_SEQUENCE_STATUS_NONE) { + return -EIO; + } + + return (ssize_t)msg->tx_len; +} + +static ssize_t mipi_dsi_renesas_rz_transfer(const struct device *dev, uint8_t channel, + struct mipi_dsi_msg *msg) +{ + if (channel == 0 && (msg->flags & MIPI_DSI_MSG_USE_LPM) == 0) { + LOG_ERR("This channel support LP mode transfer only"); + return -ENOTSUP; + } + + switch (msg->type) { + case MIPI_DSI_DCS_SHORT_WRITE: + __fallthrough; + case MIPI_DSI_DCS_SHORT_WRITE_PARAM: + __fallthrough; + case MIPI_DSI_DCS_LONG_WRITE: + return mipi_dsi_renesas_rz_dcs_write(dev, channel, msg); + case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM: + __fallthrough; + case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM: + __fallthrough; + case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM: + __fallthrough; + case MIPI_DSI_GENERIC_LONG_WRITE: + return mipi_dsi_renesas_rz_generic_write(dev, channel, msg); + default: + return -ENOTSUP; + } + + return 0; +} + +static DEVICE_API(mipi_dsi, mipi_dsi_api) = { + .attach = mipi_dsi_renesas_rz_attach, + .transfer = mipi_dsi_renesas_rz_transfer, +}; + +static int mipi_dsi_renesas_rz_init(const struct device *dev) +{ + const struct mipi_dsi_renesas_rz_config *config = dev->config; + struct mipi_dsi_renesas_rz_data *data = dev->data; + + k_sem_init(&data->in_transmission, 0, 1); + + config->irq_configure(); + + return 0; +} + +#define RENESAS_RZ_MIPI_PHYS_SETTING_DEFINE(n) \ + static const mipi_phy_b_timing_t mipi_phy##n##_timing = { \ + .t_init = DT_PROP(DT_INST_CHILD(n, phys_timing), t_init), \ + .t_clk_prep = DT_PROP(DT_INST_CHILD(n, phys_timing), t_clk_prep), \ + .t_hs_prep = DT_PROP(DT_INST_CHILD(n, phys_timing), t_hs_prep), \ + .t_clk_zero = DT_PROP(DT_INST_CHILD(n, phys_timing), t_clk_zero), \ + .t_clk_pre = DT_PROP(DT_INST_CHILD(n, phys_timing), t_clk_pre), \ + .t_clk_post = DT_PROP(DT_INST_CHILD(n, phys_timing), t_clk_post), \ + .t_clk_trail = DT_PROP(DT_INST_CHILD(n, phys_timing), t_clk_trail), \ + .t_hs_zero = DT_PROP(DT_INST_CHILD(n, phys_timing), t_hs_zero), \ + .t_hs_trail = DT_PROP(DT_INST_CHILD(n, phys_timing), t_hs_trail), \ + .t_hs_exit = DT_PROP(DT_INST_CHILD(n, phys_timing), t_hs_exit), \ + .t_lp_exit = DT_PROP(DT_INST_CHILD(n, phys_timing), t_lp_exit), \ + }; \ + \ + static const mipi_phy_b_cfg_t mipi_phy##n##_cfg = { \ + .p_timing = &mipi_phy##n##_timing, \ + }; \ + \ + mipi_phy_b_ctrl_t mipi_phy##n##_ctrl; \ + \ + static const mipi_phy_instance_t mipi_phy##n = { \ + .p_ctrl = &mipi_phy##n##_ctrl, \ + .p_cfg = &mipi_phy##n##_cfg, \ + .p_api = &g_mipi_phy, \ + }; + +#define RENESAS_RZ_MIPI_DSI_PHYS_GET(n) &mipi_phy##n + +#define RENESAS_RZ_MIPI_DSI_TIMING_DEFINE(n) \ + static const mipi_dsi_timing_t mipi_dsi_##n##_timing = { \ + .clock_stop_time = DT_INST_PROP_BY_IDX(n, timing, 0), \ + .clock_beforehand_time = DT_INST_PROP_BY_IDX(n, timing, 1), \ + .clock_keep_time = DT_INST_PROP_BY_IDX(n, timing, 2), \ + .go_lp_and_back = DT_INST_PROP_BY_IDX(n, timing, 3), \ + }; + +#define RENESAS_RZ_MIPI_DSI_TIMING_GET(n) &mipi_dsi_##n##_timing + +#define RENESAS_MIPI_DSI_DEVICE(id) \ + static void mipi_dsi_rz_configure_func_##id(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQ_BY_NAME(id, sq0, irq), \ + DT_INST_IRQ_BY_NAME(id, sq0, priority), renesas_rz_mipi_dsi_isr, \ + DEVICE_DT_INST_GET(id), DT_INST_IRQ_BY_NAME(id, sq0, flags)); \ + irq_enable(DT_INST_IRQ_BY_NAME(id, sq0, irq)); \ + } \ + \ + RENESAS_RZ_MIPI_DSI_TIMING_DEFINE(id) \ + RENESAS_RZ_MIPI_PHYS_SETTING_DEFINE(id) \ + \ + static const mipi_dsi_b_extended_cfg_t mipi_dsi_##id##_extended_cfg = { \ + .dsi_seq0.ipl = DT_INST_IRQ_BY_NAME(id, sq0, priority), \ + .dsi_seq0.irq = DT_INST_IRQ_BY_NAME(id, sq0, irq), \ + .dsi_seq1.ipl = DT_INST_IRQ_BY_NAME(id, sq1, priority), \ + .dsi_seq1.irq = DT_INST_IRQ_BY_NAME(id, sq1, irq), \ + .dsi_ferr.ipl = DT_INST_IRQ_BY_NAME(id, ferr, priority), \ + .dsi_ferr.irq = DT_INST_IRQ_BY_NAME(id, ferr, irq), \ + .dsi_ppi.ipl = DT_INST_IRQ_BY_NAME(id, ppi, priority), \ + .dsi_ppi.irq = DT_INST_IRQ_BY_NAME(id, ppi, irq), \ + .dsi_rcv.ipl = DT_INST_IRQ_BY_NAME(id, rcv, priority), \ + .dsi_rcv.irq = DT_INST_IRQ_BY_NAME(id, rcv, irq), \ + .dsi_vin1.ipl = DT_INST_IRQ_BY_NAME(id, vin1, priority), \ + .dsi_vin1.irq = DT_INST_IRQ_BY_NAME(id, vin1, irq), \ + .dsi_rxie = R_MIPI_DSI_RXIER_BTAREQEND_Msk | R_MIPI_DSI_RXIER_LRXHTO_Msk | \ + R_MIPI_DSI_RXIER_TATO_Msk | R_MIPI_DSI_RXIER_RXRESP_Msk | \ + R_MIPI_DSI_RXIER_RXEOTP_Msk | R_MIPI_DSI_RXIER_RXACK_Msk | \ + R_MIPI_DSI_RXIER_MLFERR_Msk | R_MIPI_DSI_RXIER_ECCERR_Msk | \ + R_MIPI_DSI_RXIER_UEXPKTERR_Msk | R_MIPI_DSI_RXIER_WCERR_Msk | \ + R_MIPI_DSI_RXIER_CRCERR_Msk | R_MIPI_DSI_RXIER_IBERR_Msk | \ + R_MIPI_DSI_RXIER_RXOVFERR_Msk | R_MIPI_DSI_RXIER_PRESPTOERR_Msk | \ + R_MIPI_DSI_RXIER_NORETERR_Msk | R_MIPI_DSI_RXIER_MAXRPSZERR_Msk | \ + R_MIPI_DSI_RXIER_ECCERR1B_Msk | R_MIPI_DSI_RXIER_RXAKE_Msk, \ + .dsi_ferrie = R_MIPI_DSI_FERRIER_HTXTO_Msk | R_MIPI_DSI_FERRIER_LRXHTO_Msk | \ + R_MIPI_DSI_FERRIER_TATO_Msk | R_MIPI_DSI_FERRIER_ERRESC_Msk | \ + R_MIPI_DSI_FERRIER_ERRSYNESC_Msk | R_MIPI_DSI_FERRIER_ERRCTRL_Msk | \ + R_MIPI_DSI_FERRIER_ERRCLP0_Msk | R_MIPI_DSI_FERRIER_ERRCLP1_Msk, \ + .dsi_plie = 0x0, \ + .dsi_vmie = R_MIPI_DSI_VICH1IER_VBUFUDF_Msk | R_MIPI_DSI_VICH1IER_VBUFOVF_Msk, \ + .dsi_sqch0ie = \ + R_MIPI_DSI_SQCH0IER_AACTFIN_Msk | R_MIPI_DSI_SQCH0IER_ADESFIN_Msk | \ + R_MIPI_DSI_SQCH0IER_TXIBERR_Msk | R_MIPI_DSI_SQCH0IER_RXFATALERR_Msk | \ + R_MIPI_DSI_SQCH0IER_RXFAIL_Msk | R_MIPI_DSI_SQCH0IER_RXPKTDFAIL_Msk | \ + R_MIPI_DSI_SQCH0IER_RXCORERR_Msk | R_MIPI_DSI_SQCH0IER_RXAKE_Msk, \ + .dsi_sqch1ie = \ + R_MIPI_DSI_SQCH1IER_AACTFIN_Msk | R_MIPI_DSI_SQCH1IER_ADESFIN_Msk | \ + R_MIPI_DSI_SQCH1IER_PKTBIGERR_Msk | R_MIPI_DSI_SQCH1IER_TXIBERR_Msk | \ + R_MIPI_DSI_SQCH1IER_RXFATALERR_Msk | R_MIPI_DSI_SQCH1IER_RXFAIL_Msk | \ + R_MIPI_DSI_SQCH1IER_RXPKTDFAIL_Msk | R_MIPI_DSI_SQCH1IER_RXCORERR_Msk | \ + R_MIPI_DSI_SQCH1IER_RXAKE_Msk, \ + }; \ + \ + static struct mipi_dsi_renesas_rz_config rz_config_##id = { \ + .irq_configure = mipi_dsi_rz_configure_func_##id, \ + .fsp_api = &g_mipi_dsi, \ + }; \ + \ + static mipi_dsi_b_instance_ctrl_t g_mipi_dsi##id##_ctrl; \ + \ + static mipi_dsi_cfg_t g_mipi_dsi##id##_cfg = { \ + .p_mipi_phy_instance = RENESAS_RZ_MIPI_DSI_PHYS_GET(id), \ + .p_timing = RENESAS_RZ_MIPI_DSI_TIMING_GET(id), \ + .hsa_no_lp = 0, \ + .hbp_no_lp = 0, \ + .hfp_no_lp = 0, \ + .ulps_wakeup_period = DT_INST_PROP(id, ulps_wakeup_period), \ + .continuous_clock = 1, \ + .hs_tx_timeout = 0, \ + .lp_rx_timeout = 0, \ + .turnaround_timeout = 0, \ + .bta_timeout = 0, \ + .lprw_timeout = 0, \ + .hsrw_timeout = 0, \ + .max_return_packet_size = 1, \ + .ecc_enable = 1, \ + .crc_check_mask = (mipi_dsi_vc_t)0x0, \ + .scramble_enable = 0, \ + .tearing_detect = 0, \ + .eotp_enable = 1, \ + .sync_pulse = 0, \ + .vertical_sync_polarity = \ + DT_PROP(DT_CHILD(DT_NODELABEL(zephyr_lcdif), display_timings), \ + vsync_active) != DISPLAY_SIGNAL_POLARITY_HIACTIVE, \ + .horizontal_sync_polarity = \ + DT_PROP(DT_CHILD(DT_NODELABEL(zephyr_lcdif), display_timings), \ + hsync_active) != DISPLAY_SIGNAL_POLARITY_HIACTIVE, \ + .video_mode_delay = DT_INST_PROP(id, video_mode_delay), \ + .p_extend = &mipi_dsi_##id##_extended_cfg, \ + .p_callback = mipi_dsi_callback, \ + .p_context = DEVICE_DT_INST_GET(id), \ + }; \ + \ + static struct mipi_dsi_renesas_rz_data rz_data_##id = { \ + .fsp_ctrl = (mipi_dsi_ctrl_t *)&g_mipi_dsi##id##_ctrl, \ + .fsp_cfg = &g_mipi_dsi##id##_cfg, \ + }; \ + \ + DEVICE_DT_INST_DEFINE(id, &mipi_dsi_renesas_rz_init, NULL, &rz_data_##id, &rz_config_##id, \ + POST_KERNEL, CONFIG_MIPI_DSI_INIT_PRIORITY, &mipi_dsi_api); + +DT_INST_FOREACH_STATUS_OKAY(RENESAS_MIPI_DSI_DEVICE) diff --git a/dts/arm64/renesas/rz/rza/r9a07g066.dtsi b/dts/arm64/renesas/rz/rza/r9a07g066.dtsi new file mode 100644 index 0000000000000..84d8741e6e48e --- /dev/null +++ b/dts/arm64/renesas/rz/rza/r9a07g066.dtsi @@ -0,0 +1,410 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +/ { + compatible = "renesas,r9a07g066"; + #address-cells = <1>; + #size-cells = <1>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a55"; + clock-frequency = ; + reg = <0>; + }; + }; + + arch_timer: timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + interrupt-parent = <&gic>; + }; + + osc: osc { + compatible = "fixed-clock"; + clock-frequency = ; + #clock-cells = <0>; + }; + + soc { + interrupt-parent = <&gic>; + + gic: interrupt-controller@11900000 { + compatible = "arm,gic-v3", "arm,gic"; + reg = <0x11900000 0x10000>, /* GICD */ + <0x11940000 0x20000>; /* GICR */ + interrupt-controller; + #interrupt-cells = <4>; + status = "okay"; + }; + + pinctrl: pin-controller@11030000 { + compatible = "renesas,rza-pinctrl"; + reg = <0x11030000 DT_SIZE_K(64)>; + reg-names = "pinctrl"; + + gpio: gpio-common { + compatible = "renesas,rz-gpio-int"; + interrupts = + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + , + ; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + gpio0: gpio@f00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0xf00>; + status = "disabled"; + }; + + gpio1: gpio@1000 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0x1000>; + status = "disabled"; + }; + + gpio2: gpio@1100 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x1100>; + status = "disabled"; + }; + + gpio3: gpio@1200 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x1200>; + status = "disabled"; + }; + + gpio4: gpio@1300 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <6>; + reg = <0x1300>; + status = "disabled"; + }; + + gpio5: gpio@1400 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0x1400>; + status = "disabled"; + }; + + gpio6: gpio@1500 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0x1500>; + status = "disabled"; + }; + + gpio7: gpio@1600 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1600>; + status = "disabled"; + }; + + gpio8: gpio@1700 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x1700>; + status = "disabled"; + }; + + gpio9: gpio@1800 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0x1800>; + status = "disabled"; + }; + + gpio10: gpio@1900 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x1900>; + status = "disabled"; + }; + + gpio11: gpio@1a00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <4>; + reg = <0x1a00>; + status = "disabled"; + }; + + gpio12: gpio@1b00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x1b00>; + status = "disabled"; + }; + + gpio13: gpio@1c00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <0>; + reg = <0x1c00>; + status = "disabled"; + }; + + gpio14: gpio@1d00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <0>; + reg = <0x1d00>; + status = "disabled"; + }; + + gpio15: gpio@1e00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <0>; + reg = <0x1e00>; + status = "disabled"; + }; + + gpio16: gpio@1f00 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <0>; + reg = <0x1f00>; + status = "disabled"; + }; + + gpio17: gpio@2000 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <0>; + reg = <0x2000>; + status = "disabled"; + }; + + gpio18: gpio@2100 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <0>; + reg = <0x2100>; + status = "disabled"; + }; + + gpio19: gpio@2200 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <0>; + reg = <0x2200>; + status = "disabled"; + }; + + gpio20: gpio@0 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <6>; + reg = <0x0>; + status = "disabled"; + }; + + gpio21: gpio@100 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <3>; + reg = <0x100>; + status = "disabled"; + }; + + gpio22: gpio@300 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <5>; + reg = <0x300>; + status = "disabled"; + }; + + gpio23: gpio@400 { + compatible = "renesas,rz-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <2>; + reg = <0x400>; + status = "disabled"; + }; + }; + }; + + scif0: serial@1004b800 { + compatible = "renesas,rz-scif-uart"; + channel = <0>; + reg = <0x1004b800 0x400>; + interrupts = , + , + , + , + ; + interrupt-names = "eri", "bri", "rxi", "txi", "tei"; + status = "disabled"; + }; + + scif1: serial@1004bc00 { + compatible = "renesas,rz-scif-uart"; + channel = <1>; + reg = <0x1004bc00 0x400>; + interrupts = , + , + , + , + ; + interrupt-names = "eri", "bri", "rxi", "txi", "tei"; + status = "disabled"; + }; + + scif2: serial@1004c000 { + compatible = "renesas,rz-scif-uart"; + channel = <2>; + reg = <0x1004c000 0x400>; + interrupts = , + , + , + , + ; + interrupt-names = "eri", "bri", "rxi", "txi", "tei"; + status = "disabled"; + }; + + scif3: serial@1004c400 { + compatible = "renesas,rz-scif-uart"; + channel = <3>; + reg = <0x1004c400 0x400>; + interrupts = , + , + , + , + ; + interrupt-names = "eri", "bri", "rxi", "txi", "tei"; + status = "disabled"; + }; + + scif4: serial@1004c800 { + compatible = "renesas,rz-scif-uart"; + channel = <4>; + reg = <0x1004c800 0x400>; + interrupts = , + , + , + , + ; + interrupt-names = "eri", "bri", "rxi", "txi", "tei"; + status = "disabled"; + }; + + lcdif: display-controller@10870000 { + compatible = "renesas,rz-lcdc"; + reg = <0x10870000 0x10000>, <0x10880000 0x10000>, <0x10890000 0x10000>; + reg-names = "vcpd", "fcpvd", "du"; + interrupts = , + ; + interrupt-names = "vspd_int", "du_int"; + status = "disabled"; + }; + + mipi_dsi: dsihost@10860000 { + compatible = "renesas,rz-mipi-dsi"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x10860000 DT_SIZE_K(64)>; + interrupts = , + , + , + , + , + ; + interrupt-names = "sq0", "sq1", "vin1", "rcv", "ferr", "ppi"; + status = "disabled"; + }; + }; +}; diff --git a/dts/bindings/display/ilitek,ili9881c.yaml b/dts/bindings/display/ilitek,ili9881c.yaml new file mode 100644 index 0000000000000..45430a1096ae0 --- /dev/null +++ b/dts/bindings/display/ilitek,ili9881c.yaml @@ -0,0 +1,21 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: ILITEK ILI9881C display controller + +compatible: "ilitek,ili9881c-dsi" + +include: [mipi-dsi-device.yaml, display-controller.yaml] + +properties: + reset-gpios: + type: phandle-array + description: | + The RESETn pin is asserted to disable the sensor causing a hard + reset. The sensor receives this as an active-low signal. + + bl-gpios: + type: phandle-array + description: | + The BLn pin is asserted to control the backlight of the panel. + The sensor receives this as an active-high signal. diff --git a/dts/bindings/display/renesas,rz-lcdc.yaml b/dts/bindings/display/renesas,rz-lcdc.yaml new file mode 100644 index 0000000000000..fd4b68eba4346 --- /dev/null +++ b/dts/bindings/display/renesas,rz-lcdc.yaml @@ -0,0 +1,79 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas LCD controller + +compatible: "renesas,rz-lcdc" + +include: [display-controller.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + pinctrl-0: + description: | + Provide a pin configuration for using parallel pixel output. In combination with DSI HOST + the pin configuration is not necessary due to dedicated (MIPI D-PHY) pins. + + interrupts: + required: true + + interrupt-names: + type: string-array + required: true + description: name of each interrupt + + backlight-gpios: + type: phandle-array + description: | + The BLn pin is asserted to control the backlight of the panel. + The sensor receives this as an active-high signal. + + output-data-signal-polarity: + type: string + enum: + - "LOACTIVE" + - "HIACTIVE" + default: "HIACTIVE" + description: Select the output data enable signal polarity. Default is high active. + + output-signal-sync-edge: + type: string + enum: + - "RISING" + - "FALLING" + default: "FALLING" + description: Select the output signal synchronization edge. Default is falling edge. + + input-pixel-format: + type: int + required: true + description: | + Initial input Pixel format for LCD controller. + + output-pixel-format: + type: int + required: true + description: | + Initial output Pixel format for LCD controller. + + background-color-alpha: + type: int + default: 0 + description: Alpha component of the background color. + + background-color-red: + type: int + default: 0 + description: Red component of the background color. + + background-color-green: + type: int + default: 0 + description: Green component of the background color. + + background-color-blue: + type: int + default: 0 + description: Blue component of the background color. diff --git a/dts/bindings/gpio/renesas,rz-mipi-header.yaml b/dts/bindings/gpio/renesas,rz-mipi-header.yaml new file mode 100644 index 0000000000000..6627ed240b5fe --- /dev/null +++ b/dts/bindings/gpio/renesas,rz-mipi-header.yaml @@ -0,0 +1,34 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: | + GPIO pins exposed on Renesas MIPI lcd display headers. + + The Renesas MIPI lcd display layout provides 2 columns of 20 pins headers + + This binding provides a mapping for the default 40 pins as depicted below: + + 1 GND DIMMER 21 + 2 GND I2C SCL 22 + 3 DATA0_P TP_INT 23 + 4 DATA1_P TP_RESET 24 + 5 DATA0_N GND 25 + 6 DATA1_N GND 26 + 7 GND NC 27 + 8 GND NC 28 + 9 DATA2_P NC 29 + 10 DATA3_P NC 30 + 11 DATA2_N NC 31 + 12 DATA3_N NC 32 + 13 GND GND 33 + 14 GND GND 34 + 15 CLK_P 1.8V 35 + 16 NC 1.8V 36 + 17 CLK_N 3.3V 37 + 18 GND 3.3V 38 + 19 GND 5V 39 + 20 I2C SDA 5V 40 + +compatible: "renesas,rz-gpio-mipi-header" + +include: [gpio-nexus.yaml, base.yaml] diff --git a/dts/bindings/mipi-dsi/renesas,rz-mipi-dsi.yaml b/dts/bindings/mipi-dsi/renesas,rz-mipi-dsi.yaml new file mode 100644 index 0000000000000..0b1dff4a7022f --- /dev/null +++ b/dts/bindings/mipi-dsi/renesas,rz-mipi-dsi.yaml @@ -0,0 +1,102 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RZ MIPI DSI host + +compatible: "renesas,rz-mipi-dsi" + +include: [mipi-dsi-host.yaml] + +properties: + interrupts: + required: true + + interrupt-names: + type: string-array + required: true + description: name of each interrupt + + ulps-wakeup-period: + type: int + description: ULPS wakeup period. + + video-mode-delay: + type: int + description: | + Set the delay value inside DSI Host until the transfer begins. + + timing: + type: array + description: | + MIPI DSI timing parameter: + +child-binding: + description: | + MIPI PHY timing configuration. The child node must be named "phys-timing". + + properties: + t-init: + type: int + required: true + description: | + Minimum duration of the TINIT state (Units: PCLKA cycles). + + t-clk-prep: + type: int + required: true + description: | + Duration of the clock lane LP-00 state (immediately before entry to the HS-0 state). + + t-hs-prep: + type: int + required: true + description: | + Duration of the data lane LP-00 state (immediately before entry to the HS-0 state. + + t-clk-zero: + type: int + required: true + description: | + TCLKZERO setting. + + t-clk-pre: + type: int + required: true + description: | + TCLKPRE setting. + + t-clk-post: + type: int + required: true + description: | + TCLKPOST setting. + + t-clk-trail: + type: int + required: true + description: | + TCLKTRAIL setting. + + t-hs-zero: + type: int + required: true + description: | + THSZERO setting. + + t-hs-trail: + type: int + required: true + description: | + THSTRAIL setting. + + t-hs-exit: + type: int + required: true + description: | + THSEXIT setting. + + t-lp-exit: + type: int + required: true + description: | + Low-power transition time to High-Speed mode. diff --git a/include/zephyr/dt-bindings/pinctrl/renesas/pinctrl-rza3m.h b/include/zephyr/dt-bindings/pinctrl/renesas/pinctrl-rza3m.h new file mode 100644 index 0000000000000..cc7dee10c7416 --- /dev/null +++ b/include/zephyr/dt-bindings/pinctrl/renesas/pinctrl-rza3m.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RENESAS_PINCTRL_RZA3M_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RENESAS_PINCTRL_RZA3M_H_ + +/* Superset list of all possible IO ports. */ +#define PORT_00 0x0F00 /* IO port 0 */ +#define PORT_01 0x1000 /* IO port 1 */ +#define PORT_02 0x1100 /* IO port 2 */ +#define PORT_03 0x1200 /* IO port 3 */ +#define PORT_04 0x1300 /* IO port 4 */ +#define PORT_05 0x1400 /* IO port 5 */ +#define PORT_06 0x1500 /* IO port 6 */ +#define PORT_07 0x1600 /* IO port 7 */ +#define PORT_08 0x1700 /* IO port 8 */ +#define PORT_09 0x1800 /* IO port 9 */ +#define PORT_10 0x1900 /* IO port 10 */ +#define PORT_11 0x1A00 /* IO port 11 */ +#define PORT_12 0x1B00 /* IO port 12 */ +#define PORT_20 0x0000 /* IO port 20 */ +#define PORT_21 0x0100 /* IO port 21 */ +#define PORT_22 0x0300 /* IO port 22 */ +#define PORT_23 0x0400 /* IO port 23 */ + +/* + * Create the value contain port/pin/function information + * + * port: port number BSP_IO_PORT_00..BSP_IO_PORT_18 + * pin: pin number + * func: pin function + */ +#define RZA_PINMUX(port, pin, func) (port | pin | (func << 4)) + +/* Special purpose port */ +#define BSP_IO_NMI 0xFFFF0001 /* NMI */ + +#define BSP_IO_TMS_SWDIO 0xFFFF0200 /* TMS_SWDIO */ + +#define BSP_IO_SD0_CLK 0xFFFF0400 /* SD0_CLK */ + +#define BSP_IO_QSPI0_SPCLK 0xFFFF0500 /* QSPI0_SPCLK */ +#define BSP_IO_QSPI0_IO0 0xFFFF0501 /* QSPI0_IO0 */ +#define BSP_IO_QSPI0_IO1 0xFFFF0502 /* QSPI0_IO1 */ +#define BSP_IO_QSPI0_SSL 0xFFFF0505 /* QSPI0_SSL */ + +#define BSP_IO_WDTOVF_PERROUT 0xFFFF0600 /* WDTOVF_PERROUT */ + +#define BSP_IO_RIIC0_SDA 0xFFFF0700 /* RIIC0_SDA */ +#define BSP_IO_RIIC0_SCL 0xFFFF0701 /* RIIC0_SCL */ + +/* FILNUM */ +#define RZA_FILNUM_4_STAGE 0 +#define RZA_FILNUM_8_STAGE 1 +#define RZA_FILNUM_12_STAGE 2 +#define RZA_FILNUM_16_STAGE 3 + +/* FILCLKSEL */ +#define RZA_FILCLKSEL_NOT_DIV 0 +#define RZA_FILCLKSEL_DIV_9000 1 +#define RZA_FILCLKSEL_DIV_18000 2 +#define RZA_FILCLKSEL_DIV_36000 3 + +#define RZA_FILTER_SET(filnum, filclksel) (((filnum) & 0x3) << 0x2) | (filclksel & 0x3) + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_PINCTRL_RENESAS_PINCTRL_RZA3M_H_ */ diff --git a/modules/Kconfig.renesas b/modules/Kconfig.renesas index b6f4fdf600ea1..e348596e7db1a 100644 --- a/modules/Kconfig.renesas +++ b/modules/Kconfig.renesas @@ -397,6 +397,16 @@ config USE_RZ_FSP_QSPI_SPIBSC help Enable RZ FSP QSPI SPIBSC driver +config USE_RZ_FSP_DISPLAY + bool + help + Enable RZ FSP Display driver + +config USE_RZ_FSP_MIPI_DSI + bool + help + Enable RZ FSP MIPI-DSI driver + endif config HAS_RENESAS_RX_RDP diff --git a/samples/drivers/display/boards/rza3m_ek.conf b/samples/drivers/display/boards/rza3m_ek.conf new file mode 100644 index 0000000000000..a9c84a35bfdfa --- /dev/null +++ b/samples/drivers/display/boards/rza3m_ek.conf @@ -0,0 +1,5 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_GPIO=y +CONFIG_HEAP_MEM_POOL_SIZE=90440 diff --git a/samples/modules/lvgl/demos/boards/rza3m_ek.conf b/samples/modules/lvgl/demos/boards/rza3m_ek.conf new file mode 100644 index 0000000000000..77ab52115d709 --- /dev/null +++ b/samples/modules/lvgl/demos/boards/rza3m_ek.conf @@ -0,0 +1,6 @@ +CONFIG_MAIN_STACK_SIZE=16384 +CONFIG_LV_Z_MEM_POOL_SIZE=98304 +CONFIG_INPUT_GPIO_KEYS=n +CONFIG_GPIO=y +CONFIG_SPEED_OPTIMIZATIONS=y +CONFIG_CPU_LOAD=y diff --git a/soc/renesas/rz/common/pinctrl_rza.h b/soc/renesas/rz/common/pinctrl_rza.h index 5471a358699fd..1d7d76bd23777 100644 --- a/soc/renesas/rz/common/pinctrl_rza.h +++ b/soc/renesas/rz/common/pinctrl_rza.h @@ -62,6 +62,14 @@ typedef struct pinctrl_soc_pin_t { #define RZA_FILTER_ON_OFF(node_id) COND_CODE_0(DT_PROP(node_id, renesas_filter), (0), (1)) +#if defined(CONFIG_SOC_SERIES_RZA3M) +#define RZA_GET_PFC(node_id, state_prop, idx) \ + (RZA_GET_FUNC(DT_PROP_BY_IDX(node_id, state_prop, idx)) - 1) +#else +#define RZA_GET_PFC(node_id, state_prop, idx) \ + (RZA_GET_FUNC(DT_PROP_BY_IDX(node_id, state_prop, idx))) +#endif + /* Process pinmux cfg */ #define Z_PINCTRL_PINMUX_INIT(node_id, state_prop, idx) \ { \ @@ -77,7 +85,7 @@ typedef struct pinctrl_soc_pin_t { .filonoff_reg = RZA_FILTER_ON_OFF(node_id), \ .filnum_reg = RZA_GET_FILNUM(node_id), \ .filclksel_reg = RZA_GET_FILCLKSEL(node_id), \ - .pfc_reg = RZA_GET_FUNC(DT_PROP_BY_IDX(node_id, state_prop, idx)), \ + .pfc_reg = RZA_GET_PFC(node_id, state_prop, idx), \ }, \ }, diff --git a/soc/renesas/rz/rza3m/CMakeLists.txt b/soc/renesas/rz/rza3m/CMakeLists.txt new file mode 100644 index 0000000000000..b7bb7ee2f2a6e --- /dev/null +++ b/soc/renesas/rz/rza3m/CMakeLists.txt @@ -0,0 +1,11 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +zephyr_sources(soc.c) +zephyr_library_sources_ifdef(CONFIG_ARM_MMU mmu_regions.c) + +zephyr_include_directories(.) + +zephyr_linker_sources(SECTIONS sections.ld) + +set(SOC_LINKER_SCRIPT ${ZEPHYR_BASE}/include/zephyr/arch/arm64/scripts/linker.ld CACHE INTERNAL "") diff --git a/soc/renesas/rz/rza3m/Kconfig b/soc/renesas/rz/rza3m/Kconfig new file mode 100644 index 0000000000000..8f2f4472080c7 --- /dev/null +++ b/soc/renesas/rz/rza3m/Kconfig @@ -0,0 +1,9 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_RZA3M + select ARM64 + select CPU_CORTEX_A55 + select ARM_ARCH_TIMER + select HAS_RENESAS_RZ_FSP + select SOC_EARLY_INIT_HOOK diff --git a/soc/renesas/rz/rza3m/Kconfig.defconfig b/soc/renesas/rz/rza3m/Kconfig.defconfig new file mode 100644 index 0000000000000..2db397ea309ec --- /dev/null +++ b/soc/renesas/rz/rza3m/Kconfig.defconfig @@ -0,0 +1,31 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +if SOC_SERIES_RZA3M + +config SYS_CLOCK_EXISTS + default y + +config NUM_IRQS + default 512 + +config SYS_CLOCK_HW_CYCLES_PER_SEC + default $(dt_node_int_prop_int,/osc,clock-frequency) + +config FLASH_SIZE + default $(dt_chosen_reg_size_int,$(DT_CHOSEN_Z_FLASH),0,K) + +config FLASH_BASE_ADDRESS + default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_FLASH)) + +DT_CHOSEN_IMAGE_ZEPHYR = zephyr,code-partition +DT_CHOSEN_SRAM_ZEPHYR = zephyr,sram + +config BUILD_OUTPUT_ADJUST_LMA + default "$(dt_chosen_partition_addr_hex,$(DT_CHOSEN_IMAGE_ZEPHYR)) - \ + $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_SRAM_ZEPHYR))" + +config BUILD_OUTPUT_ADJUST_LMA_SECTIONS + default "*;!.header" + +endif # SOC_SERIES_RZA3M diff --git a/soc/renesas/rz/rza3m/Kconfig.soc b/soc/renesas/rz/rza3m/Kconfig.soc new file mode 100644 index 0000000000000..b199157a0f953 --- /dev/null +++ b/soc/renesas/rz/rza3m/Kconfig.soc @@ -0,0 +1,20 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +config SOC_SERIES_RZA3M + bool + select SOC_FAMILY_RENESAS_RZ + help + Renesas RZ/A3M series + +config SOC_SERIES + default "rza3m" if SOC_SERIES_RZA3M + +config SOC_R9A07G066M04GBG + bool + select SOC_SERIES_RZA3M + help + R9A07G066M04GBG + +config SOC + default "r9a07g066m04gbg" if SOC_R9A07G066M04GBG diff --git a/soc/renesas/rz/rza3m/mmu_regions.c b/soc/renesas/rz/rza3m/mmu_regions.c new file mode 100644 index 0000000000000..3f07572e5804a --- /dev/null +++ b/soc/renesas/rz/rza3m/mmu_regions.c @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +static const struct arm_mmu_region mmu_regions[] = { + MMU_REGION_FLAT_ENTRY("IO_REG", 0x10000000, 0x10000000, + MT_DEVICE_nGnRnE | MT_RW | MT_DEFAULT_SECURE_STATE), +}; + +const struct arm_mmu_config mmu_config = { + .num_regions = ARRAY_SIZE(mmu_regions), + .mmu_regions = mmu_regions, +}; diff --git a/soc/renesas/rz/rza3m/pinctrl_soc.h b/soc/renesas/rz/rza3m/pinctrl_soc.h new file mode 100644 index 0000000000000..d3bfddf310738 --- /dev/null +++ b/soc/renesas/rz/rza3m/pinctrl_soc.h @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_RENESAS_RZ_RZA3M_PINCTRL_SOC_H_ +#define ZEPHYR_SOC_RENESAS_RZ_RZA3M_PINCTRL_SOC_H_ + +#include + +#endif /* ZEPHYR_SOC_RENESAS_RZ_RZA3M_PINCTRL_SOC_H_ */ diff --git a/soc/renesas/rz/rza3m/sections.ld b/soc/renesas/rz/rza3m/sections.ld new file mode 100644 index 0000000000000..bdc29c67e39d2 --- /dev/null +++ b/soc/renesas/rz/rza3m/sections.ld @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +SECTION_PROLOGUE(.header, CONFIG_FLASH_BASE_ADDRESS,) +{ + QUAD(__start) + QUAD(0xFFFFFFFFFFFFFFFF-__start) + QUAD(CONFIG_SRAM_BASE_ADDRESS) + QUAD(0xFFFFFFFFFFFFFFFF-CONFIG_SRAM_BASE_ADDRESS) + QUAD(z_mapped_size) + QUAD(0xFFFFFFFFFFFFFFFF-z_mapped_size) + FILL(0x00) + . += 0x1B0; + QUAD(0x4120505346205a52) + QUAD(0x69746163696c7070) + QUAD(0x0000000000006e6f) + QUAD(0x0000000000000000) +} > FLASH + +z_mapped_size = z_mapped_end - z_mapped_start; diff --git a/soc/renesas/rz/rza3m/soc.c b/soc/renesas/rz/rza3m/soc.c new file mode 100644 index 0000000000000..b989a4c429579 --- /dev/null +++ b/soc/renesas/rz/rza3m/soc.c @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief System/hardware module for Renesas RZ/A3UL Group + */ + +#include +#include "soc.h" + +uint32_t SystemCoreClock; + +void soc_early_init_hook(void) +{ + /* Configure system clocks. */ + bsp_clock_init(); + + /* Initialize SystemCoreClock variable. */ + SystemCoreClockUpdate(); +} diff --git a/soc/renesas/rz/rza3m/soc.h b/soc/renesas/rz/rza3m/soc.h new file mode 100644 index 0000000000000..3769172507ede --- /dev/null +++ b/soc/renesas/rz/rza3m/soc.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SOC_RENESAS_RZA3M_SOC_H_ +#define ZEPHYR_SOC_RENESAS_RZA3M_SOC_H_ + +#include + +#endif /* ZEPHYR_SOC_RENESAS_RZA3M_SOC_H_ */ diff --git a/soc/renesas/rz/soc.yml b/soc/renesas/rz/soc.yml index 929a3140b758b..58cf254383485 100644 --- a/soc/renesas/rz/soc.yml +++ b/soc/renesas/rz/soc.yml @@ -4,6 +4,9 @@ family: - name: rza2m socs: - name: r7s921053vcbg + - name: rza3m + socs: + - name: r9a07g066m04gbg - name: rza3ul socs: - name: r9a07g063u02gbg diff --git a/tests/arch/arm64/arm64_high_addresses/testcase.yaml b/tests/arch/arm64/arm64_high_addresses/testcase.yaml index 9b09f9745a61c..238ff45ee29d7 100644 --- a/tests/arch/arm64/arm64_high_addresses/testcase.yaml +++ b/tests/arch/arm64/arm64_high_addresses/testcase.yaml @@ -2,6 +2,7 @@ common: arch_allow: arm64 platform_exclude: - rza3ul_smarc + - rza3m_ek tags: - arm - userspace diff --git a/tests/drivers/display/display_read_write/boards/rza3m_ek.conf b/tests/drivers/display/display_read_write/boards/rza3m_ek.conf new file mode 100644 index 0000000000000..f0f3a4b6090df --- /dev/null +++ b/tests/drivers/display/display_read_write/boards/rza3m_ek.conf @@ -0,0 +1,4 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_GPIO=y diff --git a/tests/drivers/display/display_read_write/src/main.c b/tests/drivers/display/display_read_write/src/main.c index 16e1ba1688ac4..a789f509c6c08 100644 --- a/tests/drivers/display/display_read_write/src/main.c +++ b/tests/drivers/display/display_read_write/src/main.c @@ -86,10 +86,10 @@ static void verify_background_color(int x, int y, size_t width, size_t height, u for (size_t i = 0; i < width * height; i++) { switch (bpp) { case 4: - zassert_equal(buf32[i], color, "@%d", i); + zassert_equal(buf32[i], color, "@%zu", i); break; case 2: - zassert_equal(buf16[i], (uint16_t)color, "@%d", i); + zassert_equal(buf16[i], (uint16_t)color, "@%zu", i); break; case 1: if (is_vtiled) { @@ -100,13 +100,13 @@ static void verify_background_color(int x, int y, size_t width, size_t height, u uint8_t *tptr = disp_buffer + (tile * width + x); - zassert_equal(!!(*tptr & BIT(y)), !!(color), "@%d", i); + zassert_equal(!!(*tptr & BIT(y)), !!(color), "@%zu", i); } else if (is_htiled) { uint8_t *tptr = disp_buffer + i / 8; - zassert_equal(!!(*tptr & BIT(i % 8)), !!(color), "@%d", i); + zassert_equal(!!(*tptr & BIT(i % 8)), !!(color), "@%zu", i); } else { - zassert_equal(buf8[i], (uint8_t)color, "@%d", i); + zassert_equal(buf8[i], (uint8_t)color, "@%zu", i); } break; } diff --git a/tests/drivers/gpio/gpio_basic_api/boards/rza3m_ek.conf b/tests/drivers/gpio/gpio_basic_api/boards/rza3m_ek.conf new file mode 100644 index 0000000000000..b9d02cf11d5d4 --- /dev/null +++ b/tests/drivers/gpio/gpio_basic_api/boards/rza3m_ek.conf @@ -0,0 +1 @@ +CONFIG_SKIP_PULL_TEST=y diff --git a/tests/drivers/gpio/gpio_basic_api/boards/rza3m_ek.overlay b/tests/drivers/gpio/gpio_basic_api/boards/rza3m_ek.overlay new file mode 100644 index 0000000000000..bde8907a1fc10 --- /dev/null +++ b/tests/drivers/gpio/gpio_basic_api/boards/rza3m_ek.overlay @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + resources { + compatible = "test-gpio-basic-api"; + out-gpios = <&gpio5 3 GPIO_ACTIVE_HIGH>; + in-gpios = <&gpio8 0 GPIO_ACTIVE_HIGH>; + }; +}; + +&gpio5 { + status = "okay"; +}; + +&gpio8 { + status = "okay"; +}; diff --git a/west.yml b/west.yml index d6544812a2c89..47e84db9735c4 100644 --- a/west.yml +++ b/west.yml @@ -226,7 +226,7 @@ manifest: - hal - name: hal_renesas path: modules/hal/renesas - revision: 62136a8ff8a2e644b72f0dc902d33b397991cace + revision: pull/169/head groups: - hal - name: hal_rpi_pico