drm/tiny: add support for PIXPAPER 4.26 monochrome e-ink panel
LiangCheng Wang
maintainerv2 cover drm/tiny: add support for PIXPAPER 4.26 monochrome e-ink panel
This patch series adds support for the Mayqueen Pixpaper 4.26 monochrome e-ink display panel, controlled via SPI.
The series includes:
- Device tree binding updates for the Pixpaper 4.26 panel
- A DRM tiny driver implementation for the Pixpaper 4.26 panel
- A MAINTAINERS update for the Pixpaper DRM drivers and binding
The panel supports 800x480 resolution with XRGB8888 framebuffer input and uses SPI, along with GPIO lines for reset, busy, and data/command control.
Tested on:
- Raspberry Pi 5 with Linux kernel 7.1.0-rc1
Feedback is welcome.
---
Changes in v2:
- Explain why pixpaper-426m requires a distinct compatible string despite sharing the same SPI and GPIO properties with the existing Pixpaper panel.
- Drop the duplicated pixpaper-426m DT binding example.
- Update the binding description for multiple Pixpaper panels.
- Select DRM_GEM_SHMEM_HELPER instead of DRM_GEM_DMA_HELPER for the pixpaper-426m driver.
- Link to v1: https://lore.kernel.org/r/[email protected]
---
LiangCheng Wang (2):
dt-bindings: display: mayqueen,pixpaper: add pixpaper-426m drm/tiny: add support for PIXPAPER 4.26 monochrome e-ink panel
.../bindings/display/mayqueen,pixpaper.yaml | 13 +- MAINTAINERS | 3 +- drivers/gpu/drm/tiny/Kconfig | 16 + drivers/gpu/drm/tiny/Makefile | 1 + drivers/gpu/drm/tiny/pixpaper-426m.c | 828 +++++++++++++++++++++ 5 files changed, 855 insertions(+), 6 deletions(-)
---
base-commit: a293ec25d59dd96309058c70df5a4dd0f889a1e4
change-id: 20260505-bar-523f2c3f6939
Best regards,
Signature · 1 line
LiangCheng Wang <[email protected]>
LiangCheng Wang
maintainerPATCH v2 1/2 dt-bindings: display: mayqueen,pixpaper: add pixpaper-426m
Add the compatible string for the PIXPAPER 4.26 monochrome e-ink panel to the Mayqueen Pixpaper binding.
The new panel uses the same SPI and GPIO properties as the existing Pixpaper panel, but it is not software-compatible with it. The 4.26-inch panel requires different panel-specific initialization and update command sequences, so use a distinct compatible string.
Document the new compatible string and update the binding description accordingly.
--- .../devicetree/bindings/display/mayqueen,pixpaper.yaml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
Documentation/devicetree/bindings/display/mayqueen,pixpaper.yaml +8 -5
@@ -4,22 +4,25 @@ $id: http://devicetree.org/schemas/display/mayqueen,pixpaper.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Mayqueen Pixpaper e-ink display panel +title: Mayqueen Pixpaper e-ink display panels maintainers: - LiangCheng Wang <[email protected]> description: - The Pixpaper is an e-ink display panel controlled via an SPI interface. - The panel has a resolution of 122x250 pixels and requires GPIO pins for - reset, busy, and data/command control. + Mayqueen Pixpaper e-ink display panels are controlled via an SPI interface + and require GPIO pins for reset, busy, and data/command control. Different + panel models use model-specific command sequences selected via their + compatible strings. allOf: - $ref: /schemas/spi/spi-peripheral-props.yaml# properties: compatible: - const: mayqueen,pixpaper + enum: + - mayqueen,pixpaper + - mayqueen,pixpaper-426m reg: maxItems: 1
Signature · 1 line
2.34.1
Re: [PATCH v2 1/2] dt-bindings: display: mayqueen,pixpaper: add pixpaper-426m
pw-bot: not-applicable
LiangCheng Wang
maintainerPATCH v2 2/2 drm/tiny: add support for PIXPAPER 4.26 monochrome e-ink panel
In reply to LiangCheng WangIntroduce a DRM driver for the Mayqueen Pixpaper 4.26 monochrome e-ink display panel, which is controlled via SPI. The driver supports an 800x480 display with XRGB8888 framebuffer input.
Also, add Kconfig and Makefile entries for the driver and update MAINTAINERS for the Pixpaper DRM drivers and binding.
--- MAINTAINERS | 3 +- drivers/gpu/drm/tiny/Kconfig | 16 + drivers/gpu/drm/tiny/Makefile | 1 + drivers/gpu/drm/tiny/pixpaper-426m.c | 828 +++++++++++++++++++++++++++++++++++ 4 files changed, 847 insertions(+), 1 deletion(-)
MAINTAINERS +2 -1
@@ -8234,11 +8234,12 @@ T: git https://gitlab.freedesktop.org/drm/misc/kernel.git F: Documentation/devicetree/bindings/display/repaper.txt F: drivers/gpu/drm/tiny/repaper.c -DRM DRIVER FOR PIXPAPER E-INK PANEL +DRM DRIVER FOR PIXPAPER E-INK PANELS M: LiangCheng Wang <[email protected]> L: [email protected] S: Maintained F: Documentation/devicetree/bindings/display/mayqueen,pixpaper.yaml +F: drivers/gpu/drm/tiny/pixpaper-426m.c F: drivers/gpu/drm/tiny/pixpaper.c DRM DRIVER FOR QEMU'S CIRRUS DEVICE
drivers/gpu/drm/tiny/Kconfig +16 -0
@@ -98,6 +98,22 @@ config DRM_PIXPAPER If M is selected, the module will be built as pixpaper.ko. +config DRM_PIXPAPER_426M + tristate "DRM support for PIXPAPER 4.26 monochrome display panel" + depends on DRM && SPI + depends on MMU + select DRM_CLIENT_SELECTION + select DRM_GEM_SHMEM_HELPER + select DRM_KMS_HELPER + help + DRM driver for the Mayqueen Pixpaper 4.26 monochrome e-ink + display panel. + + This driver supports SPI-connected 800x480 monochrome panels + with an XRGB8888 framebuffer input format. + + If M is selected, the module will be built as pixpaper-426m.ko. + config TINYDRM_HX8357D tristate "DRM support for HX8357D display panels" depends on DRM && SPI
drivers/gpu/drm/tiny/Makefile +1 -0
@@ -7,6 +7,7 @@ obj-$(CONFIG_DRM_CIRRUS_QEMU) += cirrus-qemu.o obj-$(CONFIG_DRM_GM12U320) += gm12u320.o obj-$(CONFIG_DRM_PANEL_MIPI_DBI) += panel-mipi-dbi.o obj-$(CONFIG_DRM_PIXPAPER) += pixpaper.o +obj-$(CONFIG_DRM_PIXPAPER_426M) += pixpaper-426m.o obj-$(CONFIG_TINYDRM_HX8357D) += hx8357d.o obj-$(CONFIG_TINYDRM_ILI9163) += ili9163.o obj-$(CONFIG_TINYDRM_ILI9225) += ili9225.o
drivers/gpu/drm/tiny/pixpaper-426m.c new file +828 -0
828 lines not on this page · raw message
Signature · 1 line
2.34.1
[email protected]
AI reviewThank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider: - [High] The plane's atomic_update callback calls multiple sleeping functions and allocates memory with…
Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:
- [High] The plane's atomic_update callback calls multiple sleeping functions and allocates memory with GFP_KERNEL, violating DRM subsystem constraints.
- [High] The driver passes stack-allocated variables and read-only data (.rodata) directly to spi_write(), which violates Linux DMA API requirements.
- [High] Incorrect pixel format extraction on big-endian architectures due to native 32-bit reads of a little-endian byte array.
- [Medium] Hardware timeouts in pixpaper_wait_busy() are logged but not propagated to the caller, causing the driver to issue subsequent commands to an unready panel.
- [Medium] The format conversion function pixpaper_xrgb8888_to_bw() unintentionally flips the image horizontally.
--
commit 9e268f738b87e01832dbe79fc73ab5d8adefe3cb
Author: LiangCheng Wang <[email protected]>
drm/tiny: add support for PIXPAPER 4.26 monochrome e-ink panel
Introduce a DRM driver for the Mayqueen Pixpaper 4.26 monochrome e-ink display panel, which is controlled via SPI. The driver supports an 800x480 display with XRGB8888 framebuffer input.
Quoted 5 lines
drivers/gpu/drm/tiny/pixpaper-426m.c new file +0
-0
[ ... ]
drivers/gpu/drm/tiny/pixpaper-426m.c line 250
Quoted 12 lines
drivers/gpu/drm/tiny/pixpaper-426m.c new file +12
-0+static void pixpaper_wait_busy (struct pixpaper_panel *panel) +{ +unsigned int timeout_ms =PIXPAPER_BUSY_TIMEOUT_MS ; +unsigned long timeout_jiffies = jiffies +msecs_to_jiffies (timeout_ms); + +usleep_range (PIXPAPER_BUSY_POLL_INITIAL_US_MIN , +PIXPAPER_BUSY_POLL_INITIAL_US_MAX ); +while (gpiod_get_value_cansleep (panel->busy) !=0 ) { +if (time_after (jiffies, timeout_jiffies)) { +drm_warn (&panel->drm,"Busy wait timed out\n" ); +return ; + }
[Severity: Medium]
Should this function update the error context when it times out?
Currently, on timeout it logs a warning but returns without setting err->errno_code to -ETIMEDOUT or another error code. Because the error context is not updated, callers like pixpaper_trigger_update() remain unaware of the failure and continue sending SPI commands to an unready panel, which may cause hardware state corruption.
Quoted 4 lines
drivers/gpu/drm/tiny/pixpaper-426m.c new file +4
-0+usleep_range (PIXPAPER_BUSY_POLL_US_MIN , +PIXPAPER_BUSY_POLL_US_MAX ); + } +}
[ ... ]
drivers/gpu/drm/tiny/pixpaper-426m.c line 283
Quoted 11 lines
drivers/gpu/drm/tiny/pixpaper-426m.c new file +11
-0+static void pixpaper_send_cmd (struct pixpaper_panel *panel,u8 cmd, +struct pixpaper_error_ctx *err) +{ +pixpaper_spi_write (panel,0 , &cmd,sizeof (cmd), err); +} + +static void pixpaper_send_data (struct pixpaper_panel *panel,u8 data, +struct pixpaper_error_ctx *err) +{ +pixpaper_spi_write (panel,1 , &data,sizeof (data), err); +}
[Severity: High]
Does this code violate the DMA API by mapping stack memory?
The spi_write() function maps the provided buffer using the DMA API. In pixpaper_send_cmd() and pixpaper_send_data(), pointers to local stack variables (cmd and data) are passed.
The Linux DMA API forbids mapping stack memory because cacheline operations by the DMA controller can silently corrupt adjacent stack frames or cause kernel panics.
[ ... ]
drivers/gpu/drm/tiny/pixpaper-426m.c line 322
Quoted 10 lines
drivers/gpu/drm/tiny/pixpaper-426m.c new file +10
-0+static void pixpaper_send_init_seq (struct pixpaper_panel *panel, +const struct pixpaper_init_seq *seq, +struct pixpaper_error_ctx *err) +{ +if (err->errno_code || !seq->data || !seq->len) +return ; + +pixpaper_send_cmd (panel, seq->cmd, err); +pixpaper_spi_write (panel,1 , seq->data, seq->len, err); +}
[Severity: High]
Can passing read-only data to spi_write() cause DMA issues here?
The caller passes pointers to global const arrays residing in .rodata (e.g., pixpaper_init_temp_sensor). The DMA API also explicitly forbids mapping read-only data.
[ ... ]
drivers/gpu/drm/tiny/pixpaper-426m.c line 347
Quoted 12 lines
drivers/gpu/drm/tiny/pixpaper-426m.c new file +12
-0+static void *pixpaper_prepare_buffer (const void *vaddr, +const struct drm_framebuffer *fb, +u32 *dst_pitch, +struct pixpaper_error_ctx *err) +{ +void *dst; + +if (err->errno_code) +return NULL ; + + *dst_pitch =DIV_ROUND_UP (fb->width,8 ); + dst =kzalloc (*dst_pitch * fb->height,GFP_KERNEL );
[Severity: High]
Is it safe to allocate memory with GFP_KERNEL here?
This function is called from pixpaper_plane_atomic_update(), which executes in an atomic context where sleeping is forbidden. This allocation can cause kernel warnings (e.g., scheduling while atomic) and potential deadlocks.
Quoted 4 lines
drivers/gpu/drm/tiny/pixpaper-426m.c new file +4
-0+if (!dst) { + err->errno_code = -ENOMEM ; +return NULL ; + }
[ ... ]
Quoted 6 lines
drivers/gpu/drm/tiny/pixpaper-426m.c new file +6
-0+static void pixpaper_xrgb8888_to_bw (const void *src,void *dst,u32 height, +u32 width,u32 src_pitch,u32 dst_pitch) +{ +const uint8_t *src_base = src; +uint8_t *dst_pixels = dst; +
drivers/gpu/drm/tiny/pixpaper-426m.c line 410
Quoted 10 lines
drivers/gpu/drm/tiny/pixpaper-426m.c new file +10
-0+if (dst ==NULL || src ==NULL ) +return ; + +for (u32 y =0 ; y < height; y++) { +uint8_t *dst_row = dst_pixels + y * dst_pitch; +const uint8_t *src_row = src_base + y * src_pitch; +const uint32_t *src_pixels = (const uint32_t *)src_row; + +for (u32 x =0 ; x < width; x++) { +u32 src_x = width -1 - x;
[Severity: Medium]
Does this coordinate mapping intentionally flip the image horizontally?
The source pixel index is calculated as width - 1 - x, while the destination bit is derived directly from x. This maps the rightmost pixel of the source to the leftmost pixel of the output.
drivers/gpu/drm/tiny/pixpaper-426m.c line 421
Quoted 11 lines
drivers/gpu/drm/tiny/pixpaper-426m.c new file +11
-0+uint8_t r, g, b; +u8 bit; +u32 bit_pos = x %8 ; +u32 byte_pos = x /8 ; +uint32_t gray_val; +uint32_t pixel; + + pixel = src_pixels[src_x]; + r = (pixel >>16 ) &0xFF ; + g = (pixel >>8 ) &0xFF ; + b = pixel &0xFF ;
[Severity: High]
Can this pixel format extraction fail on big-endian architectures?
The DRM_FORMAT_XRGB8888 pixel format specifies bytes in little-endian order in memory (B, G, R, X). The native 32-bit read casts the source buffer and performs a 32-bit load. On big-endian architectures, this will interpret the byte sequence incorrectly, placing the color bytes in the wrong positions and extracting the wrong channels.
[ ... ]
drivers/gpu/drm/tiny/pixpaper-426m.c line 499
Quoted 3 lines
drivers/gpu/drm/tiny/pixpaper-426m.c new file +3
-0+static void pixpaper_plane_atomic_update (struct drm_plane *plane, +struct drm_atomic_state *state) +{
[Severity: High]
Are you aware that plane atomic_update callbacks execute in an atomic context where sleeping is forbidden?
This function calls pixpaper_prepare_buffer(), which allocates memory with GFP_KERNEL, and it invokes blocking SPI operations via pixpaper_write_image() and pixpaper_trigger_update() which sleep. Calling sleeping functions from atomic context violates DRM subsystem constraints.
Quoted 4 lines
drivers/gpu/drm/tiny/pixpaper-426m.c new file +4
-0+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);
Signature · 1 line
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=2