Skip to content

drm/tiny: Add support for Mayqueen Pixpaper e-ink panel #6931

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 661 commits into
base: rpi-6.16.y
Choose a base branch
from

Conversation

lc-wang
Copy link

@lc-wang lc-wang commented Jul 2, 2025

This series adds support for the Mayqueen Pixpaper e-ink display panel, controlled via SPI.

The series includes:

  • A vendor-prefix entry for "mayqueen"
  • Device tree binding documentation for the Pixpaper panel
  • A new DRM tiny driver using the simple KMS helper framework

Panel specs:

  • Resolution: 122x250
  • Format: XRGB8888
  • Interface: SPI

The driver has been tested on:

  • Raspberry Pi 2 Model B
  • Linux kernel 6.16

All patches are signed off and follow the existing DRM/tiny structure. The goal is to provide a lightweight, open-source reference driver for integrating small e-paper displays in embedded systems using the DRM subsystem.


Tested-by: LiangCheng Wang [email protected]
Signed-off-by: LiangCheng Wang [email protected]
Co-developed-by: Wig Cheng [email protected]

pelwell and others added 30 commits June 30, 2025 11:22
In the absence of a value in Device Tree, set the SDA hold time to half
the SCL low time.

Signed-off-by: Phil Elwell <[email protected]>
The legacy stack had an option to have a GPIO track frame start and
end events to give basic synchronisation to the incoming image stream.
https://forums.raspberrypi.com/viewtopic.php?t=190314

Replicate this in the kernel Unicam driver.

Signed-off-by: Dave Stevenson <[email protected]>
This code:
for_each_sg(sgl, sg, sg_len, i)
  num_sgs += DIV_ROUND_UP(sg_dma_len(sg), axi_block_len);

determines how many hw_desc are allocated.
If sg_dma_len(sg)=0 we don't allocate for this sgl.

However in the next loop, we will increment loop
for this case, and loop gets higher than num_sgs
and we trample memory.

Signed-off-by: Dom Cobley <[email protected]>
"rotation" is listed as a standard property of panels in panel-common.yaml,
therefore it would be logical to process that from within the core
code should a panel driver not implement the get_orientation hook.

Call of_drm_get_panel_orientation from
drm_connector_set_orientation_from_panel to get that information.

This removes the need for any boiler-plate in panel drivers for calling
drm_connector_set_orientation_from_panel or
drm_connector_set_panel_orientation.

Signed-off-by: Dave Stevenson <[email protected]>
The autodetection of resolution/timing by the TC358762 can lead
to the display being shifted by a pixel or two.

Program the TC358762 with the requested mode timing so that
it can reproduce it accurately.

Signed-off-by: Dave Stevenson <[email protected]>
Reverts 8a4b2fc ("drm/bridge: tc358762: Split register programming from pre-enable to enable")
as we want the config commands sent before video starts.

Signed-off-by: Dave Stevenson <[email protected]>
Having accepted the upstream change to add the persist_gpio_outputs
parameter, make it true by default.

See: raspberrypi#6117

Signed-off-by: Phil Elwell <[email protected]>
Even when configured to use only gpiod CS lines, the DW SPI controller
still expects a bit to be set in the SER register, otherwise transfers
stall. For the csgpiod case, nominate bit 0 for the job.

See: raspberrypi#6159

Signed-off-by: Phil Elwell <[email protected]>
The naming of backlight devices is not terribly useful for
associating a backlight controller with a display (assuming
it is attached to one).

Add a sysfs node that will return a display name that can be set
by other subsystems.

Signed-off-by: Dave Stevenson <[email protected]>
Pass the DRM connector name to any configured backlight
device so that userspace can associate the two items.

Ideally this should be in drm_panel, but it is bridge/panel
that creates the drm_connector and therefore knows the name.

Signed-off-by: Dave Stevenson <[email protected]>

drm/bridge: panel: Ensure backlight is reachable

Ensure that the various options of modules vs builtin results
in being able to call into the backlight code.

raspberrypi#6198

Fixes: 573f8fd ("drm/bridge: panel: Name an associated backlight device")
Signed-off-by: Dave Stevenson <[email protected]>
Add version 4.17.1 of the Hailo PCIe device drivers.
Sourced from https://github.com/hailo-ai/hailort-drivers/

Signed-off-by: Naushir Patuck <[email protected]>

drivers: media: pcie: hailo: Fix include paths

An attempt to fix the include paths - they look reasonable, but the
GitHub auto-builds fail.

Signed-off-by: Phil Elwell <[email protected]>

drivers: media: pci: Update Hailo accelerator device driver to v4.18.0

Sourced from https://github.com/hailo-ai/hailort-drivers/

Signed-off-by: Naushir Patuck <[email protected]>

drivers: media: pci: Add wrapper after removal of follow_pfn

drivers: media: pci: Fix Hailo compile warnings

Signed-off-by: Phil Elwell <[email protected]>

drivers: media: pci: Update Hailo accelerator device driver to v4.19

Sourced from https://github.com/hailo-ai/hailort-drivers/

Signed-off-by: Naushir Patuck <[email protected]>

drivers: media: pci: Update Hailo accelerator device driver to v4.20

Sourced from https://github.com/hailo-ai/hailort-drivers

Signed-off-by: Naushir Patuck <[email protected]>
Add helpers to set and get vchiq driver data. vchiq_set_drvdata() and
vchiq_get_drvdata() wraps dev_set_drvdata() and dev_get_drvdata()
respectively.

Signed-off-by: Umang Jain <[email protected]>
Signed-off-by: Kieran Bingham <[email protected]>
The vchiq_connected.h header was removed in f875976 ("staging:
vc04_services: Drop vchiq_connected.[ch] files") to simplify the
implementation.

Update the vc_sm driver accordingly which can still use the same
functions through the vchiq_arm.h header declarations.

Fixes: b1ab7a0 ("staging: vc04_services: Add new vc-sm-cma driver")
Signed-off-by: Kieran Bingham <[email protected]>
Drop the include directive. They can break the build, when one only
wants to build a subdirectory. Replace with "../" for the includes in
the vc_sm files instead.

The fix is equivalent to the four patches between 29d49a7
("staging: vc04_services: bcm2835-audio: Drop include Makefile
directive")...2529ca2 ("staging: vc04_services: interface: Drop
include Makefile directive")

Fixes: b1ab7a0 ("staging: vc04_services: Add new vc-sm-cma driver")
Suggested-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Kieran Bingham <[email protected]>
Register the vcsm rive with the vchiq_bus_type instead of useing the
platform driver/device.

Signed-off-by: Kieran Bingham <[email protected]>
Now that V4L2_PIX_FMT_Y12P is defined, allow passing raw 12bit
mono packed data through the peripheral.

Signed-off-by: Dave Stevenson <[email protected]>
Now that V4L2_PIX_FMT_Y14 and V4L2_PIX_FMT_Y14P are defined,
allow passing 14bit mono data through the peripheral.

Signed-off-by: Dave Stevenson <[email protected]>
Now that the 14bit non-packed Bayer formats are defined, add them
into the supported formats lookup table.

Signed-off-by: Dave Stevenson <[email protected]>
Add two new DT properties:
* microchip,eee-enabled  - a boolean to enable EEE
* microchip,tx-lpi-timer - time in microseconds to wait before entering
                           low power state

Signed-off-by: Phil Elwell <[email protected]>
Disabling tx_lpi or eee should not cause the value of tx_lpi_timer to
be lost, even though it is not useful until they are re-enabled.

Signed-off-by: Phil Elwell <[email protected]>
The platform model originally handled the DMA mask. Now that
we are on the vchiq_bus we need to explicitly set this.

Signed-off-by: Kieran Bingham <[email protected]>
Re-introduce multi-context support that was dropped from the
mainline driver version.

Signed-off-by: Jacopo Mondi <[email protected]>
Offset the backend dev-nodes starting at /dev/video20
onwards to maintain backward compatibility with the
pre-upstreamed kernel driver.

Signed-off-by: Naushir Patuck <[email protected]>
Add YAML device tree bindings for the Raspberry Pi RP2040 GPIO Bridge.

Signed-off-by: Richard Oliver <[email protected]>
The Raspberry Pi RP2040 GPIO bridge is an I2C-attached device exposing
both a Tx-only SPI controller, and a GPIO controller.

Due to the relative difference in transfer rates between standard-mode
I2C and SPI, the GPIO bridge makes use of 12 MiB of non-volatile storage
to cache repeated transfers. This cache is arranged in ~8 KiB blocks and
is addressed by the MD5 digest of the data contained therein.

Optionally, this driver is able to take advantage of Raspberry Pi RP1
GPIOs to achieve faster than I2C data transfer rates.

Signed-off-by: Richard Oliver <[email protected]>

spi: rp2040-gpio-bridge: Add debugfs progress indicator

Useful for tracking upload progress via userspace.

Signed-off-by: Naushir Patuck <[email protected]>

spi: rp2040-gpio-bridge: add missing MD5 dependency

rp2040-gpio-bridge relies on the md5 crypto driver. This dependency
cannot be determined automatically as rp2040-gpio-bridge does not
use any of md5's symbols directly.

Declare a soft 'pre' dependency on md5 to ensure that it is included and
loaded before rp2040-gpio-bridge.

Signed-off-by: Richard Oliver <[email protected]>

spi: rp2040-gpio-bridge: fix gpiod error handling

In some circumstances, devm_gpiod_get_array_optional() can return
PTR_ERR rather than NULL to indicate failure. Handle these cases.

Signed-off-by: Richard Oliver <[email protected]>

spi: rp2040-gpio-bridge: probe: Cfg fast_xfer clk

Fast transfer mode requires that the first bit of data is clocked with a
rising edge. This can cause extra bits of data to be clocked on hardware
where the clock signal uses a pull-up. This change ensures that clk is
driven low before fast data transfer mode is entered.

Signed-off-by: Richard Oliver <[email protected]>
The snps,block-size DT property declares the maximum block size for each
channel of the dw-axi-dmac. However, the driver ignores these when
setting max_seg_size and uses MAX_BLOCK_SIZE (4096) instead.

To take advantage of the efficiencies of larger blocks, calculate the
minimum block size across all channels and use that instead.

See: raspberrypi#6256

Signed-off-by: Phil Elwell <[email protected]>
The firmware advertises its features as a string of words separated by
spaces. Ensure that feature names are only matched in their entirety.

Signed-off-by: Phil Elwell <[email protected]>
The Cypress firmwares use "extsae" to indicate wpa_supplicant-hosted
SAE/WPA3.

Signed-off-by: Phil Elwell <[email protected]>
support sae executed in wpa_supplicant and offload 4-way handshake offload.

Signed-off-by: Chien-Chia Chen <[email protected]>

JIRA: SWWLAN-142424
Whilst the Unicam driver has now been upstreamed it only supports
configuration via Media Controller (not driven from the /dev/videoN
node), which makes life significantly harder for simple devices such
as mono sensors, and HDMI or analogue video to CSI2 bridge chips
(eg TC358743 and ADV7282M).

Fix up the downstream driver so that it builds, reinstate the links
from Kconfig and Makefile to it, and give it a new Kconfig name
(VIDEO_BCM2835_UNICAM_LEGACY).

Signed-off-by: Dave Stevenson <[email protected]>
njhollinghurst and others added 27 commits June 30, 2025 11:22
After analyzing more Raspberry Pi V3 cameras, adjust the
default PDAF shield-pixel gain tables (they can still be
overridden by camera OTP where programmed).

Signed-off-by: Nick Hollinghurst <[email protected]>
drm_helper_probe_add_cmdline_mode was looking for a match for
the width, height, and refresh rate within the EDID modes, but
didn't check the interlacing flag. That meant that with
video=1920x1080@50i would match any 1920x1080@50 mode that was
found.
The converse would be possible too if an interlaced mode with
matching resolution & refresh rate was found first.

Check the interlacing flag as well.

Signed-off-by: Dave Stevenson <[email protected]>
The cadence mac on rp1 doesn't support EEE, but unfortunately the phy
advertises otherwise. This leads to high package loss or even unusable
network interfaces in EEE capable setups.

Fix this and mark EEE as broken on phy.

Signed-off-by: Nicolai Buchwitz <[email protected]>
Add support for the 'gpio-gate-clock-releasing' compatible string. The
behaviour is identical to that of 'gpio-gate-clock' but the gpio is
acquired on 'enable' and released on 'disable'.

Signed-off-by: Richard Oliver <[email protected]>
Document the gpio-gate-clock-releasing compatible string that enables
acquire/release GPIO semantics on gpio-gated clocks.

Signed-off-by: Richard Oliver <[email protected]>
The clock using by IMX500 in 'AI Camera' is gpio-gated. The GPIO used is
provided by an I2C-controlled rpi-rp2040-gpio-bridge on 'AI Camera'.
Both the IMX500 and gpio-bridge share a common regulator for their power
supply. Using 'gpio-gate-clock', the 'AI Camera' will never be
powered-down as the GPIO provided by the gpio-bridge is always claimed
by the clock driver. Switching to 'gpio-gate-clock-releasing' causes the
GPIO to be released by the clock driver when the clock is not needed.
This allows 'AI Camera' to be powered-down.

Signed-off-by: Richard Oliver <[email protected]>
This change amends various error-paths in imx500_start_streaming() to
ensure that pm_runtime refcounts do not remain erroneously incremented
on failure.

Signed-off-by: Richard Oliver <[email protected]>
When the imx500 driver is used as part of the 'AI Camera', the poweroff
state is never reached as the camera and gpio driver share a regulator.
By releasing the GPIOs when they are not in use, 'AI Camera' is able to
achieve a powered-down state.

Signed-off-by: Richard Oliver <[email protected]>
Add support for the M41T80 RTC to the i2c-rtc and i2c-rtc-gpio overlays.
The driver is already enabled, thanks to the existing M41T62 support.

Signed-off-by: Phil Elwell <[email protected]>
Shift it in the wrapper function, or scheduling periodic transfers breaks.

Signed-off-by: Jonathan Bell <[email protected]>
This reverts commit 781f2e0.

dwc2 is sufficiently different to dwc_otg that the same override can't be
cleanly applied - it ends up spamming the endpoint with start-splits and
rarely schedules complete-splits.

Signed-off-by: Jonathan Bell <[email protected]>
The driver uses pci_msi methods, only defined when CONFIG_PCI_MSI symbol
is set, and cannot be compiled without. Therefore, it depends on this
symbol.

Signed-off-by: Jorge Marques <[email protected]>
A comment in the pisp_be driver references the
pispbe_schedule_internal() function which doesn't exist.

Drop it.

Reviewed-by: Laurent Pinchart <[email protected]>
Reviewed-by: Naushir Patuck <[email protected]>
Signed-off-by: Jacopo Mondi <[email protected]>
The config parameters buffer is already validated in
pisp_be_validate_config() at .buf_prepare() time.

However some of the same validations are also performed at
pispbe_schedule() time. In particular the function checks that:

1) config.num_tiles is valid
2) At least one of the BAYER or RGB input is enabled

The input config validation is already performed in
pisp_be_validate_config() and while job.hw_enables is modified by
pispbe_xlate_addrs(), the function only resets the input masks if

- there is no input buffer available, but pispbe_prepare_job() fails
  before calling pispbe_xlate_addrs() in this case
- bayer_enable is 0, but in this case rgb_enable is valid as guaranteed
  by pisp_be_validate_config()
- only outputs are reset in rgb_enable

For this reasons there is no need to repeat the check at
pispbe_schedule() time.

The num_tiles validation can be moved to pisp_be_validate_config() as
well. As num_tiles is a u32 it can'be be < 0, so change the sanity
check accordingly.

Reviewed-by: Laurent Pinchart <[email protected]>
Reviewed-by: Naushir Patuck <[email protected]>
Signed-off-by: Jacopo Mondi <[email protected]>
Currently the 'pispbe_schedule()' function does two things:

1) Tries to assemble a job by inspecting all the video node queues
   to make sure all the required buffers are available
2) Submit the job to the hardware

The pispbe_schedule() function is called at:

- video device start_streaming() time
- video device qbuf() time
- irq handler

As assembling a job requires inspecting all queues, it is a rather
time consuming operation which is better not run in IRQ context.

To avoid executing the time consuming job creation in interrupt
context split the job creation and job scheduling in two distinct
operations. When a well-formed job is created, append it to the
newly introduced 'pispbe->job_queue' where it will be dequeued from
by the scheduling routine.

As the per-node 'ready_queue' buffer list is only accessed in vb2 ops
callbacks, protected by the node->queue_lock mutex, it is not necessary
to guard it with a dedicated spinlock so drop it. Also use the
spin_lock_irq() variant in all functions not called from an IRQ context
where the spin_lock_irqsave() version was used.

Reviewed-by: Laurent Pinchart <[email protected]>
Signed-off-by: Jacopo Mondi <[email protected]>
During the probe() routine, the PiSP BE driver needs to power up the
interface in order to identify and initialize the hardware.

The driver resumes the interface by calling the
pispbe_runtime_resume() function directly, without going
through the pm_runtime helpers, but later suspends it by calling
pm_runtime_put_autosuspend().

This causes a PM usage count imbalance at probe time, notified by the
runtime_pm framework with the below message in the system log:

 pispbe 1000880000.pisp_be: Runtime PM usage count underflow!

Fix this by resuming the interface using the pm runtime helpers instead
of calling the resume function directly and use the pm_runtime framework
in the probe() error path. While at it, remove manual suspend of the
interface in the remove() function. The driver cannot be unloaded if in
use, so simply disable runtime pm.

To simplify the implementation, make the driver depend on PM as the
RPI5 platform where the ISP is integrated in uses the PM framework by
default.

Fixes: 12187bd ("media: raspberrypi: Add support for PiSP BE")
Cc: [email protected]
Reviewed-by: Laurent Pinchart <[email protected]>
Signed-off-by: Jacopo Mondi <[email protected]>
Set NET_DSA=m to allow some DSA-based switch devices to be used. Note
that no switch models have been enabled, the intention being that DKMS
can be used to build them. Note also that the feature has only been
added to 64-bit kernels, since it causes the kernel to grow by about
65kB.

See: raspberrypi#6899

Signed-off-by: Phil Elwell <[email protected]>
Use the clamp() from minmax.h and provide a define for the max size as
they will be used in sequent patches.

Signed-off-by: Jacopo Mondi <[email protected]>
A missing pointer increment meant that not only was the same buffer
being reused again and again, there was also no protection against
using it simultaneously for multiple transfers. Fix that basic bug, and
also move a similar increment to before the transfer is started, which
feels less racy.

See: raspberrypi#6919

Signed-off-by: Phil Elwell <[email protected]>
This incorrectly matches on urb->setup_packet instead of checking the
pipe type, so recycled URBs were incorrectly matched.

A more comprehensive fix is forthcoming.

This reverts commit 2f27224.

Signed-off-by: Jonathan Bell <[email protected]>
The version of the dwc-otg core used in BCM2835 through BCM2712 only does
whole-word writes, as well as needing the documented requirement for DMA
buffers to start on a word boundary.

Also, the alignment method used in the dwc2 driver doesn't handle the
case where the URB has the NO_TRANSFER_DMA_MAP flag set, so reject
buffers that have unaligned DMA start addresses. At least one whole page
should be mapped, so the BCM283x whole-word-write bug should be benign
in this case.

Signed-off-by: Jonathan Bell <[email protected]>
Enable drivers required by the SECO Pi Vision 10.1 CM5 HMI in all
CM5-compatible defconfigs.

Specifically, this commit enables:
* driver for Atmel MaxTouch controllers
* panel-lvds
* TI SN65DSI83 DSI-LVDS bridge

Signed-off-by: Alessandro Pecugi <[email protected]>
Add overlay for SECO Pi Vision adapter HAT, with the
sn65dsi83 LVDS bridge, a 10.1-inch LVDS panel, and Atmel
mxt touch controller

For the pi4ioe5v6408 GPIO expander, the equivalent fxl6408 driver
is used.

Signed-off-by: Alessandro Pecugi <[email protected]>
Mayqueen is a Taiwan-based company primarily focused on the development
of arm64 development boards and e-paper displays.

Signed-off-by: Wig Cheng <[email protected]>
Introduce a DRM driver for the Mayqueen PIxpaper e-ink display panel,
which iscontrolled via SPI. The driver supports a 122x250 resolution
display with XRGB8888 format, using the DRM simple KMS helper framework.

Signed-off-by: LiangCheng Wang <[email protected]>
The binding is for the Mayqueen Pixpaper e-ink display panel,
controlled via an SPI interface.

Signed-off-by: LiangCheng Wang <[email protected]>
@6by9
Copy link
Contributor

6by9 commented Jul 2, 2025

This series really wants to go upstream to the dri-devel mailing list for review, particularly as it's missing a dtoverlay to make it useful on a Raspberry Pi.

I can make a couple of comments based on a very quick read through:

  • Whilst other tinydrm drivers are using drm_simple_display_pipeline, recent guidance has been not to use it as it is viewed as an unneeded layer of indirection. https://lore.kernel.org/dri-devel/[email protected]/
  • Handling around init_completed_successfully looks suspicious. It shouldn't be possible to call update before init is complete.
  • SPI drivers need a struct spi_device_id table as well as the compatible string match table, otherwise you'll get a warning logged from https://elixir.bootlin.com/linux/v6.15.4/source/drivers/spi/spi.c#L487
  • Having a load of vmap type operations in there makes me think something may be off, but it may be necessary for this display. UDL is a different display that needs to do similar packing of image buffers, and that doesn't have to do similar mappings.

Hope that helps.

@lc-wang
Copy link
Author

lc-wang commented Jul 3, 2025

Understood, thank you for the clarification.

I'll prioritize getting this driver upstream first, following the suggestions you gave. Once it lands upstream or gets reviewed, I can revisit integration with Raspberry Pi if needed.

Thanks again for the guidance!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.