Skip to content

rp1-pio+dw-axi-dmac: add cyclic DMA support, ability to select light vs heavy DMA - #7598

Merged
pelwell merged 5 commits into
raspberrypi:rpi-6.18.yfrom
hansverkuil:rp1-pio
Sep 3, 2026
Merged

rp1-pio+dw-axi-dmac: add cyclic DMA support, ability to select light vs heavy DMA#7598
pelwell merged 5 commits into
raspberrypi:rpi-6.18.yfrom
hansverkuil:rp1-pio

Conversation

@hansverkuil

Copy link
Copy Markdown

This PR adds support for cyclic DMA for FROM_SM and the ability to select a 'heavy' or 'light' DMA engine. This required adding a new PIO_IOC_SM_CONFIG_XFER_V2 ioctl with a new flags field.

It also adds a fix where old corrupt data would be DMAed when you do a second DMA run.

With these changes it is possible to sample up to 6 pins at full speed (200 MHz) from the PIO using 4 SMs and both 'heavy' DMAs and two 'light' DMAs for a total of about 150 MB/s.

The cyclic DMA implementation of the dw-axi-dmac driver was broken: it
actually stopped the DMA at the end of each period and had to be restarted
by the interrupt handler. That can cause data loss.

The root cause is the use of the CH_CTL_H_LLI_LAST flag in the last
period DMA descriptor: this stops the DMA and triggers an irq. But for
cyclic DMA you just want to get an interrupt and not stop the DMA. For
that use the CH_CTL_H_LLI_BLKTRF: that just raises an interrupt but does
not stop the DMA.

In the interrupt handler we need to mark all the used descriptors from
the last period as valid again: the DMA HW clears the CH_CTL_H_LLI_VALID
bit after retiring that descriptor, and so it has to be set again or
the DMA would stop.

With these changes the cyclic DMA works as it should.

In addition, when the current dw_axi_dma_chan_prep_cyclic implementation
is given a span larger than the maximum supported by the DMAC it attempts
to divide it into a number of roughly equal-sized segments. This requires
care that the results are all multiples of the transfer unit, e.g. words
for transfers with a hardware register.

Simplify the logic by making all segments as large as possible except for
the last one.

Signed-off-by: Hans Verkuil <hverkuil@kernel.org>
We want to be able to select 'light' DMAs (25 MB/s), so add eight more
entries without the DMA_FLAG_HEAVY flag and name them with the 'l' suffix
for 'light'.

Signed-off-by: Hans Verkuil <hverkuil@kernel.org>
Add a new ioctl to be able to pass flags to the driver. This new
flags field can be used to select 'heavy' (50 MB/s) and 'light'
(25 MB/s) DMA engines.

The existing PIO_IOC_SM_CONFIG_XFER(32) ioctls keep their current
behavior of preferring to use the 'heavy' DMA engine and fall back
to the 'light' variant.

Signed-off-by: Hans Verkuil <hverkuil@kernel.org>
If the DMA is freed first, and the SMs are disabled afterwards, then the
next time you use the DMA the first 4-8 words are corrupt (old data).

Disable the SMs first, then free the DMA. With this change there is no
longer old data seen in the next run.

Signed-off-by: Hans Verkuil <hverkuil@kernel.org>
Add a new RP1_PIO_SM_CONFIG_XFER_FL_DMA_CYCLE flag to select cyclic
DMA. In that case buf_size is the size of a single cycle and there
are buf_count cycles. So the total buffer size will be buf_size *
buf_count.

Signed-off-by: Hans Verkuil <hverkuil@kernel.org>
@pelwell

pelwell commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

It looks great - I can't think of a reason not to merge as-is.

@pelwell
pelwell merged commit 5000010 into raspberrypi:rpi-6.18.y Sep 3, 2026
12 checks passed
popcornmix added a commit to raspberrypi/firmware that referenced this pull request Sep 4, 2026
kernel: staging: vc04_services: fix pointer arithmetic in create_pagelist
See: raspberrypi/linux#7593

kernel: rp1-pio+dw-axi-dmac: add cyclic DMA support, ability to select light vs heavy DMA
See: raspberrypi/linux#7598

kernel: overlays: ed-backlight-pwm: Add EDATEC PWM backlight overlay
See: raspberrypi/linux#7597

kernel: configs: Add CAN_VXCAN=m
See: raspberrypi/linux#7592

kernel: media/hevc_d: Improve checking and cleanup of decoder
See: raspberrypi/linux#7583

kernel: drm/vc4: hdmi: Don't write past the end of a packet RAM slot
See: raspberrypi/linux#7579

kernel: bcm2835-i2s: fail capture open cleanly when FIFO clear has no clock
See: raspberrypi/linux#7586

kernel: vc04_services: bounds and fd handling fixes
See: raspberrypi/linux#7576

kernel: overlays: wm8960-soundcard: Add media parameter
See: raspberrypi/linux#7577

kernel: overlays: rt5616: Add RT5616 audio codec overlay
See: raspberrypi/linux#7574

kernel: arm64: defconfig: Enable RT5616 codec in Pi configurations
See: raspberrypi/linux#7575
popcornmix added a commit to raspberrypi/rpi-firmware that referenced this pull request Sep 4, 2026
kernel: staging: vc04_services: fix pointer arithmetic in create_pagelist
See: raspberrypi/linux#7593

kernel: rp1-pio+dw-axi-dmac: add cyclic DMA support, ability to select light vs heavy DMA
See: raspberrypi/linux#7598

kernel: overlays: ed-backlight-pwm: Add EDATEC PWM backlight overlay
See: raspberrypi/linux#7597

kernel: configs: Add CAN_VXCAN=m
See: raspberrypi/linux#7592

kernel: media/hevc_d: Improve checking and cleanup of decoder
See: raspberrypi/linux#7583

kernel: drm/vc4: hdmi: Don't write past the end of a packet RAM slot
See: raspberrypi/linux#7579

kernel: bcm2835-i2s: fail capture open cleanly when FIFO clear has no clock
See: raspberrypi/linux#7586

kernel: vc04_services: bounds and fd handling fixes
See: raspberrypi/linux#7576

kernel: overlays: wm8960-soundcard: Add media parameter
See: raspberrypi/linux#7577

kernel: overlays: rt5616: Add RT5616 audio codec overlay
See: raspberrypi/linux#7574

kernel: arm64: defconfig: Enable RT5616 codec in Pi configurations
See: raspberrypi/linux#7575
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.

3 participants