Skip to contentSkip to conversation

drm/tiny: Add RAiO RA8875 display controller driver support

PATCH In review Adam Azuddin 3 participants 5 messages Nov 10 – Nov 11

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

v6 cover drm/tiny: Add RAiO RA8875 display controller driver support

This series adds a new drm/tiny driver and matching dt-binding for the RAiO RA8875 SPI display controller. An fbtft driver for this chip currently exists at drivers/staging/fbtft/fb_ra8875.c, but fbtft is a legacy fbdev-based staging driver, and nothing in mainline DRM currently supports this controller.

This driver does not use drm_mipi_dbi. The RA8875 SPI protocol is structurally incompatible with both Type C options drm_mipi_dbi supports. Type C1 encodes command/data as a 9th bit within a 9-bit SPI word. The RA8875 uses a full prefix byte (0x80 = command write, 0x00 = data write, 0x40 = data read, 0xC0 = status read) sent as a separate 8-bit transaction. These are not the same thing and cannot be mapped to each other. Type C3 models two transfer types via a D/CX GPIO. The RA8875 has four transfer cycle types and no D/CX pin.

My ER-TFTM050-3 board has RST tied NC, and VDD is a fixed supply set via an on-board solder jumper rather than software-controllable, so I couldn't test reset-gpios/vdd-supply myself, but added them as optional/required properties respectively per review feedback for boards that do need them.

Tested on a Raspberry Pi 3B connected over SPI to an East Rising ER-TFTM050-3, a 5" 800x480 panel driven by the RA8875 in Linux 7.3.0-rc4.

Link to v1: https://lore.kernel.org/all/[email protected]/
Link to v2: https://lore.kernel.org/all/[email protected]/
Link to v3: https://lore.kernel.org/all/[email protected]/
Link to v4: https://lore.kernel.org/all/[email protected]/
Link to v5: https://lore.kernel.org/all/[email protected]/
---
Changes in v6:

Documentation/devicetree/bindings/display/panel/raio,ra8875.yaml:
- Drop Assisted-by tag.
- Remove sentence referencing driver polling from interrupt description.

drivers/gpu/drm/tiny/ra8875.c:
- use drm_atomic_helper_connector_create_state instead of drm_atomic_helper_connector_reset.

Changes in v5:

Documentation/devicetree/bindings/display/panel/raio,ra8875.yaml:
- Drop the "Add YAML binding schema..." paragraph from the commit message (Krzysztof)
- Add interrupts property for the INT# pin

drivers/gpu/drm/tiny/ra8875.c:
- Move bindings table to above ra8875_spi_driver definition

Changes in v4:

Documentation/devicetree/bindings/display/panel/raio,ra8875.yaml:
- Drop the sentence in the description saying the binding covers only the SPI-connected device (Conor).
- Drop unused panel label

drivers/gpu/drm/tiny/ra8875.c:
- Catch error value from ra8875_write_pixels
- Use consistent include header format.
- Return if fb is null in atomic_update
- Drop unnecessary extra byte in pixel data spi write.

drivers/gpu/drm/tiny/Kconfig:
- Add depends on OF, which is caught by intel 0-day[3]

Changes in v3:

Documentation/devicetree/bindings/display/panel/raio,ra8875.yaml:
- Add gpio.h include in example to pass dt_binding_check
- Remove spi-max-frequency as there is no reference in datasheet

drivers/gpu/drm/tiny/ra8875.c:
- Remove debug-only ra8875_read_reg function
- Chunk large SPI transfers to 16 rows per chunk
- Remove unnecessary includes and spi cs setups in probe
- Create ra8875_write_pixels function for clear_screen and fb_dirty
- Use 2 spi writes instead of 1 write with 2 transfers and cs_change in write_reg

Changes in v2:

Documentation/devicetree/bindings/display/panel/raio,ra8875.yaml (review by Krzysztof Kozlowski):
- Add hardware description to the binding
- Drop the display-timings property, and instead require it in the required block
- Add a required vdd-supply and an optional reset gpio property
- Rename the example node to a more generic "panel: display@0"

drivers/gpu/drm/tiny/Makefile and Kconfig:
- Remove TINYDRM prefix from the config name (Thomas Zimmermann [1])

drivers/gpu/drm/tiny/ra8875.c:
- Reformat device_id table to match current convention (Krzysztof Kozlowski)
- Drop unneeded linux/mod_devicetable.h include (Uwe Kleine-König)
- Use drm_dev_unplug() instead of drm_dev_unregister() in remove callback
- Move stack-allocated cmd/data buffers into ra8875_device struct
- Add mode_valid() callback to validate height/width against panel maximum
- Add optional reset gpio
- Use dev_err_probe() in probe function
- Remove connector detect callback
- Remove unnecessary |= on register write return value in hw_init
- Migrate from simple display pipe to manually-handled plane/crtc/encoder, following the simple-KMS-helper removal effort [2]
- Use defined constants instead of magic values where possible
- Use drm_atomic_helper_damage_merged() and drm_fb_swab() in plane update

[1] https://lore.kernel.org/all/[email protected]/
[2] https://lore.kernel.org/all/20260705-drm-simple-kms-removal-v1-0-b4e1ca053623@oss.qualcomm.com/
[3] https://lore.kernel.org/all/[email protected]/

Adam Azuddin (2):
dt-bindings: display: panel: Add RAiO RA8875 display controller drm/tiny: Add RAiO RA8875 display controller driver

 .../bindings/display/panel/raio,ra8875.yaml   |  86 +++
 .../devicetree/bindings/vendor-prefixes.yaml  |   2 +
 MAINTAINERS                                   |   6 +
 drivers/gpu/drm/tiny/Kconfig                  |  13 +
 drivers/gpu/drm/tiny/Makefile                 |   1 +
 drivers/gpu/drm/tiny/ra8875.c                 | 719 ++++++++++++++++++
 6 files changed, 827 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/panel/raio,ra8875.yaml
 create mode 100644 drivers/gpu/drm/tiny/ra8875.c
Signature · 1 line
2.55.0
#1 lore raw

PATCH v6 1/2 dt-bindings: display: panel: Add RAiO RA8875 display controller

The RA8875 is an SPI-connected TFT display controller by RAiO Technology Inc. It supports display resolutions of up to 800x480.

---
 .../bindings/display/panel/raio,ra8875.yaml   | 86 +++++++++++++++++++
 .../devicetree/bindings/vendor-prefixes.yaml  |  2 +
 2 files changed, 88 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/panel/raio,ra8875.yaml
Documentation/devicetree/bindings/display/panel/raio,ra8875.yaml new file +86 -0
new file mode 100644
index 000000000000..4c72130f0dbe
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/display/panel/raio,ra8875.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: RAiO RA8875 Display Controller
+
+maintainers:
+  - Adam Azuddin <[email protected]>
+
+description:
+  The RA8875 is a TFT LCD controller for panels up to 800x480 pixels.
+  It can be connected to the host via 8080/6800 parallel interface,
+  SPI or I2C.
+
+allOf:
+  - $ref: panel-common.yaml#
+  - $ref: /schemas/spi/spi-peripheral-props.yaml#
+
+properties:
+  compatible:
+    const: raio,ra8875
+
+  reg:
+    maxItems: 1
+
+  vdd-supply:
+    description:
+      3.3 V supply for the IO pins, the oscillator IO pins, the ADC pins
+      and the internal LDO. The 1.8 V core rail is generated internally.
+
+  reset-gpios:
+    description:
+      GPIO connected to the active-low RST# pin. Optional, since the board
+      may instead use an RC reset circuit.
+    maxItems: 1
+
+  interrupts:
+    description:
+      INT# pin, active low. Signals RA8875 interrupt events such as touch
+      panel, key scan, DMA, BTE and font access completion.
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - display-timings
+  - vdd-supply
+
+unevaluatedProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    #include <dt-bindings/interrupt-controller/irq.h>
+
+    spi {
+        #address-cells = <1>;
+        #size-cells = <0>;
+
+        display@0 {
+            compatible = "raio,ra8875";
+            reg = <0>;
+            spi-max-frequency = <16000000>;
+            vdd-supply = <&vcc_3v3>;
+            reset-gpios = <&gpio 25 GPIO_ACTIVE_LOW>;
+            interrupt-parent = <&gpio>;
+            interrupts = <5 IRQ_TYPE_LEVEL_LOW>;
+
+            display-timings {
+                native-mode = <&timing0>;
+                timing0: timing0 {
+                    clock-frequency = <25000000>;
+                    hactive = <800>;
+                    vactive = <480>;
+                    hfront-porch = <40>;
+                    hsync-len = <40>;
+                    hback-porch = <40>;
+                    vfront-porch = <10>;
+                    vsync-len = <10>;
+                    vback-porch = <20>;
+                };
+            };
+        };
+    };
Documentation/devicetree/bindings/vendor-prefixes.yaml +2 -0
index 7602034374d7..c834ad2eb582 100644
@@ -1411,6 +1411,8 @@ patternProperties:
     description: Radxa
   "^raidsonic,.*":
     description: RaidSonic Technology GmbH
+  "^raio,.*":
+    description: RAiO Technology Inc.
   "^ralink,.*":
     description: Mediatek/Ralink Technology Corp.
   "^ramtron,.*":
Signature · 1 line
2.55.0
Reviewed-by on v6 1/2
#2 lore raw

Re: [PATCH v6 1/2] dt-bindings: display: panel: Add RAiO RA8875 display controller

Quoted 9 lines · Adam Azuddin

The RA8875 is an SPI-connected TFT display controller by RAiO Technology Inc. It supports display resolutions of up to 800x480.

---
 .../bindings/display/panel/raio,ra8875.yaml   | 86 +++++++++++++++++++
 .../devicetree/bindings/vendor-prefixes.yaml  |  2 +
 2 files changed, 88 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/display/panel/raio,ra8875.yaml

Best regards,
Krzysztof

#3 lore raw

PATCH v6 2/2 drm/tiny: Add RAiO RA8875 display controller driver

In reply to Adam Azuddin

Add a DRM tiny driver for the RAiO RA8875 SPI-connected TFT display controller. The driver supports display resolutions up to 800x480 and uses the GEM shmem helper for buffer management.

---
 MAINTAINERS                   |   6 +
 drivers/gpu/drm/tiny/Kconfig  |  13 +
 drivers/gpu/drm/tiny/Makefile |   1 +
 drivers/gpu/drm/tiny/ra8875.c | 719 ++++++++++++++++++++++++++++++++++
 4 files changed, 739 insertions(+)
 create mode 100644 drivers/gpu/drm/tiny/ra8875.c
MAINTAINERS +6 -0
index 2e6bca640901..70d194ad0f37 100644
@@ -8648,6 +8648,12 @@ T:	git https://gitlab.freedesktop.org/drm/misc/kernel.git
 F:	drivers/gpu/drm/qxl/
 F:	include/uapi/drm/qxl_drm.h
 
+DRM DRIVER FOR RAIO RA8875 PANELS
+M:	Adam Azuddin <[email protected]>
+S:	Maintained
+F:	Documentation/devicetree/bindings/display/panel/raio,ra8875.yaml
+F:	drivers/gpu/drm/tiny/ra8875.c
+
 DRM DRIVER FOR RAYDIUM RM67191 PANELS
 M:	Robert Chiras <[email protected]>
 S:	Maintained
drivers/gpu/drm/tiny/Kconfig +13 -0
index f0e72d4b6a47..2f1c49e31dd6 100644
@@ -98,6 +98,19 @@ config DRM_PIXPAPER
 
 	  If M is selected, the module will be built as pixpaper.ko.
 
+config DRM_RA8875
+	tristate "DRM support for RA8875 display panels"
+	depends on DRM && SPI && OF
+	select DRM_CLIENT_SELECTION
+	select DRM_KMS_HELPER
+	select DRM_GEM_SHMEM_HELPER
+	select VIDEOMODE_HELPERS
+	help
+	  DRM driver for the following RAiO RA8875 based LCD panels:
+	  * East Rising 5.00" TFT LCD (ER-TFTM050-3)
+
+	  If M is selected the module will be called ra8875.
+
 config TINYDRM_HX8357D
 	tristate "DRM support for HX8357D display panels"
 	depends on DRM && SPI
drivers/gpu/drm/tiny/Makefile +1 -0
index 48d30bf6152f..ed4602097fbb 100644
@@ -14,4 +14,5 @@ obj-$(CONFIG_TINYDRM_ILI9341)		+= ili9341.o
 obj-$(CONFIG_TINYDRM_ILI9486)		+= ili9486.o
 obj-$(CONFIG_TINYDRM_MI0283QT)		+= mi0283qt.o
 obj-$(CONFIG_TINYDRM_REPAPER)		+= repaper.o
+obj-$(CONFIG_DRM_RA8875)		+= ra8875.o
 obj-$(CONFIG_TINYDRM_SHARP_MEMORY)	+= sharp-memory.o
drivers/gpu/drm/tiny/ra8875.c new file +719 -0

719 lines not on this page · raw message

Signature · 1 line
2.55.0
#4 lore raw

Re: [PATCH v6 2/2] drm/tiny: Add RAiO RA8875 display controller driver

Thank you for your contribution! Sashiko AI review found 8 potential issues to consider: - [Critical] drm/tiny: ra8875: heap overflow in ra8875_clear_screen() via mode width - [High] drm/tiny…

Thank you for your contribution! Sashiko AI review found 8 potential issues to consider:
- [Critical] drm/tiny: ra8875: heap overflow in ra8875_clear_screen() via mode width
- [High] drm/tiny: ra8875: plane updates run before CRTC enable and screen clear
- [High] drm/tiny: ra8875: miscalculation of HNDR and VNDR in ra8875_hw_init()
- [High] drm/tiny: ra8875: missing drm_dev_enter() in ra8875_crtc_atomic_enable()
- [Medium] drm/tiny: ra8875: missing vdd-supply regulator enable in ra8875_probe()
- [Medium] drm/tiny: ra8875: missing drm_gem_fb_begin_cpu_access() in ra8875_fb_dirty()
- [Medium] drm/tiny: ra8875: unaligned u16 destination in ra8875_fb_dirty()
- [Low] drm/tiny: ra8875: missing MMU dependency in Kconfig for DRM_RA8875
--

commit c87472ee809dcef3cdfa786e0f03db0247928c50
Author: Adam Azuddin <[email protected]>

drm/tiny: Add RAiO RA8875 display controller driver

This commit adds a DRM tiny driver for the SPI-connected RAiO RA8875 TFT display controller using the GEM shmem helper.

Quoted 5 lines
drivers/gpu/drm/tiny/Kconfig +0 -0
index f0e72d4b6a470..2f1c49e31dd60 100644

drivers/gpu/drm/tiny/Kconfig config DRM_PIXPAPER · line 107

Quoted 10 lines
drivers/gpu/drm/tiny/Kconfig +7 -0
@@ -98,6 +98,19 @@ config DRM_PIXPAPER
 
 	  If M is selected, the module will be built as pixpaper.ko.
 
+config DRM_RA8875
+	tristate "DRM support for RA8875 display panels"
+	depends on DRM && SPI && OF
+	select DRM_CLIENT_SELECTION
+	select DRM_KMS_HELPER
+	select DRM_GEM_SHMEM_HELPER
+	select VIDEOMODE_HELPERS

[Severity: Low]
Should DRM_RA8875 depend on MMU? DRM_GEM_SHMEM_HELPER depends on MMU, so selecting it on a !CONFIG_MMU build triggers an unmet direct dependency warning and fails to link against MMU-only symbols such as vmf_insert_pfn().

[ ... ]

Quoted 5 lines
drivers/gpu/drm/tiny/ra8875.c new file +0 -0
new file mode 100644
index 0000000000000..bf1584c6aa79d

[ ... ]

Quoted 17 lines
drivers/gpu/drm/tiny/ra8875.c new file +17 -0
+	/* Horizontal timing */
+	hdwr = (mode->hdisplay / 8) - 1;
+	hndr = ((mode->htotal - mode->hdisplay) / 8) - 1;
+	hstr = ((mode->hsync_start - mode->hdisplay) / 8) - 1;
+	hpwr = ((mode->hsync_end - mode->hsync_start) / 8) - 1;
+
+	ret = ra8875_write_reg(ra8875, RA8875_HDWR, hdwr);
+	if (ret)
+		return ret;
+	ret = ra8875_write_reg(ra8875, RA8875_HNDFTR, RA8875_HNDFTR_HNDFT(0));
+	if (ret)
+		return ret;
+	ret = ra8875_write_reg(ra8875, RA8875_HNDR, hndr);
+	if (ret)
+		return ret;
+	ret = ra8875_write_reg(ra8875, RA8875_HSTR, hstr);
+	if (ret)

drivers/gpu/drm/tiny/ra8875.c line 260

Quoted 10 lines
drivers/gpu/drm/tiny/ra8875.c new file +10 -0
+		return ret;
+	ret = ra8875_write_reg(ra8875, RA8875_HPWR, hpwr);
+	if (ret)
+		return ret;
+
+	/* Vertical timing */
+	vdhr = mode->vdisplay - 1;
+	vndr = mode->vtotal - mode->vdisplay - 1;
+	vstr = mode->vsync_start - mode->vdisplay - 1;
+	vpwr = mode->vsync_end - mode->vsync_start - 1;

[Severity: High]
Are hndr and vndr calculated from the total blanking interval instead of the back porch?

In drm_display_mode_from_videomode(), htotal - hdisplay is the sum of the front porch, sync pulse, and back porch. Because HSTR/VSTR and HPWR/VPWR already program the front porch and sync pulse width, RA8875_HNDR and RA8875_VNDR0/1 expect only the back porch (mode->htotal - mode->hsync_end and mode->vtotal - mode->vsync_end), so this double-counts the front porch and sync pulse into the scanout timings. Also, neither ra8875_probe() nor ra8875_mode_valid() checks that each porch and sync pulse is non-zero before subtracting 1, which can underflow these registers.

[ ... ]

drivers/gpu/drm/tiny/ra8875.c line 375

Quoted 12 lines
drivers/gpu/drm/tiny/ra8875.c new file +12 -0
+	memset(txbuf, 0, 1 + rows_per_chunk * width * 2);
+	txbuf[0] = RA8875_DATAWRITE;
+
+	for (y = 0; y < height; y += rows) {
+		rows = min(rows_per_chunk, height - y);
+		ret = ra8875_write_pixels(ra8875, 1 + rows * width * 2);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}

[Severity: Critical]
Can userspace overflow ra8875->txbuf in ra8875_clear_screen()?

ra8875_probe() allocates ra8875->txbuf for a fixed width of RA8875_MAX_WIDTH (800), or 25,601 bytes. However, ra8875_mode_valid() only checks that horizontal timings are multiples of 8 and does not reject modes larger than RA8875_MAX_WIDTH or call drm_crtc_helper_mode_valid_fixed(). If DRM master commits a custom mode with mode->hdisplay > 800 and the primary plane disabled, ra8875_clear_screen() writes 1 + 16 * width * 2 bytes into txbuf, overflowing the heap buffer.

Quoted 12 lines
drivers/gpu/drm/tiny/ra8875.c new file +12 -0
+
+static void ra8875_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_commit *state)
+{
+	struct ra8875_device *ra8875 =
+		container_of(crtc->dev, struct ra8875_device, drm);
+	struct drm_crtc_state *crtc_state =
+		drm_atomic_get_new_crtc_state(state, crtc);
+	struct drm_display_mode *mode = &crtc_state->mode;
+	int ret;
+
+	ret = ra8875_hw_init(ra8875, mode);
+	if (ret) {

drivers/gpu/drm/tiny/ra8875.c line 397

Quoted 10 lines
drivers/gpu/drm/tiny/ra8875.c new file +10 -0
+		drm_err(&ra8875->drm, "Failed to initialize hardware\n");
+		return;
+	}
+
+	ret = ra8875_clear_screen(ra8875, mode);
+	if (ret) {
+		drm_err(&ra8875->drm, "Failed to clear screen\n");
+		return;
+	}
+}

[Severity: High]
Does ra8875_crtc_atomic_enable() wipe out the initial plane update on every modeset?

Because drm->mode_config.helper_private is not set to use drm_atomic_helper_commit_tail_rpm(), the default drm_atomic_helper_commit_tail() runs drm_atomic_helper_commit_planes() before drm_atomic_helper_commit_modeset_enables(). On initial modeset, ra8875_plane_atomic_update() writes the framebuffer while the controller is still held in reset, and then ra8875_crtc_atomic_enable() resets the chip and zeroes display RAM in ra8875_clear_screen(), leaving the panel blank.

In addition, ra8875_plane_atomic_check() passes can_update_disabled = true and plane commits do not pass DRM_PLANE_COMMIT_ACTIVE_ONLY, so plane updates while the CRTC is disabled will also write to the powered-down controller.

drivers/gpu/drm/tiny/ra8875.c line 408

Quoted 11 lines
drivers/gpu/drm/tiny/ra8875.c new file +11 -0
+
+static void ra8875_crtc_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_commit *state)
+{
+	struct ra8875_device *ra8875 =
+		container_of(crtc->dev, struct ra8875_device, drm);
+
+	ra8875_write_reg(ra8875, RA8875_P1CR, RA8875_P1CR_DISABLE);
+	ra8875_write_reg(ra8875, RA8875_P1DCR, RA8875_P1DCR_MIN);
+
+	ra8875_write_reg(ra8875, RA8875_PWRR, RA8875_PWRR_DISPOFF);
+}

[Severity: High]
Can ra8875_crtc_atomic_enable() and ra8875_crtc_atomic_disable() race with ra8875_remove() and cause a use-after-free?

CPU0 CPU1
ra8875_crtc_atomic_enable()
ra8875_hw_init()

    msleep(RA8875_RESET_WAIT_MS)
                                  ra8875_remove()
                                    drm_dev_unplug(drm)
                                    ...
                                  devres_release_all(&spi->dev)
                                    /* frees txbuf and rst_gpio */
  ra8875_clear_screen()
    memset(txbuf, 0, ...)         <-- use-after-free

Unlike ra8875_plane_atomic_update(), neither CRTC callback guards its hardware and buffer accesses with drm_dev_enter() and drm_dev_exit(). Because ra8875->txbuf and ra8875->rst_gpio are managed by devres on &spi->dev while struct ra8875_device lives until the last drm_device reference drops, drm_dev_unplug() does not wait for in-flight CRTC enable or disable callbacks before devres frees txbuf and rst_gpio.

[ ... ]

drivers/gpu/drm/tiny/ra8875.c line 455

Quoted 12 lines
drivers/gpu/drm/tiny/ra8875.c new file +12 -0
+	for (int y = rect->y1; y < rect->y2; y += rows) {
+		struct drm_rect chunk;
+
+		rows = min(RA8875_TXBUF_ROWS, rect->y2 - y);
+		chunk = DRM_RECT_INIT(rect->x1, y, width, rows);
+
+		iosys_map_set_vaddr(&dst, ra8875->txbuf + 1);
+		drm_fb_swab(&dst, NULL, src, fb, &chunk, false, &fmtcnv_state);
+
+		if (ra8875_write_pixels(ra8875, 1 + rows * width * 2))
+			goto err;
+	}

[Severity: Medium]
Does passing ra8875->txbuf + 1 to drm_fb_swab() perform unaligned 16-bit writes on every pixel?

ra8875->txbuf is kmalloc-aligned to an even address, so ra8875->txbuf + 1 is at an odd byte address. For DRM_FORMAT_RGB565 in system memory, drm_fb_swab() calls drm_fb_swab16_line(), which casts the destination pointer directly to u16 * and dereferences it without put_unaligned(), triggering alignment faults on strict-alignment architectures and UBSAN warnings.

[ ... ]

Quoted 16 lines
drivers/gpu/drm/tiny/ra8875.c new file +16 -0
+static void ra8875_plane_atomic_update(struct drm_plane *plane, struct drm_atomic_commit *state)
+{
+	struct ra8875_device *ra8875 = container_of(plane->dev, struct ra8875_device, drm);
+	struct drm_plane_state *old_plane_state = drm_atomic_get_old_plane_state(state, plane);
+	struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
+	struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
+	struct drm_framebuffer *fb = plane_state->fb;
+	struct drm_rect rect;
+	struct iosys_map *map = &shadow_plane_state->data[0];
+	int idx;
+
+	if (!fb)
+		return;
+
+	if (!drm_dev_enter(&ra8875->drm, &idx))
+		return;

drivers/gpu/drm/tiny/ra8875.c line 489

Quoted 10 lines
drivers/gpu/drm/tiny/ra8875.c new file +10 -0
+
+	if (iosys_map_is_null(map)) {
+		drm_err(&ra8875->drm, "Shadow map is null\n");
+		goto exit;
+	}
+	if (drm_atomic_helper_damage_merged(old_plane_state, plane_state, &rect))
+		ra8875_fb_dirty(ra8875, map, fb, &rect);
+exit:
+	drm_dev_exit(idx);
+}

[Severity: Medium]
Should the framebuffer CPU read here be bracketed with drm_gem_fb_begin_cpu_access() and drm_gem_fb_end_cpu_access()?

drm_gem_begin_shadow_fb_access() only vmaps the buffer and does not synchronize caches for imported DMA-BUFs, so reading src in drm_fb_swab() can observe stale data on non-coherent platforms. Also, ra8875_fb_dirty() could pass &shadow_plane_state->fmtcnv_state instead of allocating and freeing a local drm_format_conv_state on every update.

[ ... ]

drivers/gpu/drm/tiny/ra8875.c line 593

Quoted 7 lines
drivers/gpu/drm/tiny/ra8875.c new file +7 -0
+	drm = &ra8875->drm;
+	connector = &ra8875->connector;
+
+	ra8875->rst_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH);
+	if (IS_ERR(ra8875->rst_gpio))
+		return dev_err_probe(dev, PTR_ERR(ra8875->rst_gpio),
+			     "failed to get reset GPIO\n");

[Severity: Medium]
Does ra8875_probe() need to enable the vdd-supply regulator?

The raio,ra8875 DT binding requires vdd-supply, but the driver never requests or enables it (for example with devm_regulator_get_enable(dev, "vdd")), leaving the controller unpowered on boards where vdd-supply is a switchable regulator.

Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=2