From 997503160ef8248395ac9f0f69ad68f090ae862b Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 8 Jan 2026 12:04:10 +0000 Subject: [PATCH 1/2] misc: rp1-pio: Use DMA burst size for threshold Always set the FIFO threshold to the same as the DMA burst size. A higher value will potentially reduce performance by waiting longer before refilling, while a lower value could cause over/underflow. Also, ensure that some structures are zeroed. See: https://forums.raspberrypi.com/viewtopic.php?t=395186 https://github.com/raspberrypi/utils/issues/116 Signed-off-by: Phil Elwell --- drivers/misc/rp1-pio.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/misc/rp1-pio.c b/drivers/misc/rp1-pio.c index 5758647fc7971c..885cd00f43fbd2 100644 --- a/drivers/misc/rp1-pio.c +++ b/drivers/misc/rp1-pio.c @@ -610,7 +610,7 @@ static int rp1_pio_sm_config_xfer_internal(struct rp1_pio_client *client, uint s struct rp1_pio_device *pio = client->pio; struct platform_device *pdev = pio->pdev; struct device *dev = &pdev->dev; - struct dma_slave_config config = {}; + struct dma_slave_config config = { 0 }; struct dma_slave_caps dma_caps; phys_addr_t fifo_addr; struct dma_info *dma; @@ -690,9 +690,8 @@ static int rp1_pio_sm_config_xfer_internal(struct rp1_pio_client *client, uint s set_dmactrl_args.sm = sm; set_dmactrl_args.is_tx = (dir == RP1_PIO_DIR_TO_SM); - set_dmactrl_args.ctrl = RP1_PIO_DMACTRL_DEFAULT; - if (dir == RP1_PIO_DIR_FROM_SM) - set_dmactrl_args.ctrl = (RP1_PIO_DMACTRL_DEFAULT & ~0x1f) | 1; + set_dmactrl_args.rsvd = 0; + set_dmactrl_args.ctrl = (RP1_PIO_DMACTRL_DEFAULT & ~0x1f) | dma_caps.max_burst; ret = rp1_pio_sm_set_dmactrl(client, &set_dmactrl_args); if (ret) From 7ce12d4a51ba87ba61bd453be9166f3444fa0227 Mon Sep 17 00:00:00 2001 From: Phil Elwell Date: Thu, 8 Jan 2026 12:11:26 +0000 Subject: [PATCH 2/2] misc: rp1-pio: Increase DMA timeouts to 10 seconds A DMA wait timeout is likely to be fatal, so increase it to 10 seconds to reduce the chance it could be triggered by slow transfers. Signed-off-by: Phil Elwell --- drivers/misc/rp1-pio.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/drivers/misc/rp1-pio.c b/drivers/misc/rp1-pio.c index 885cd00f43fbd2..504244bbc11ae7 100644 --- a/drivers/misc/rp1-pio.c +++ b/drivers/misc/rp1-pio.c @@ -52,6 +52,8 @@ #define RP1_PIO_DMACTRL_DEFAULT 0x80000104 +#define WAIT_TIMEOUT 10000 + #define HANDLER(_n, _f) \ [_IOC_NR(PIO_IOC_ ## _n)] = { #_n, rp1_pio_ ## _f, _IOC_SIZE(PIO_IOC_ ## _n) } @@ -746,7 +748,7 @@ static int rp1_pio_sm_tx_user(struct rp1_pio_device *pio, struct dma_info *dma, /* grab the next free buffer, waiting if they're all full */ if (dma->head_idx - dma->tail_idx == dma->buf_count) { if (down_timeout(&dma->buf_sem, - msecs_to_jiffies(1000))) { + msecs_to_jiffies(WAIT_TIMEOUT))) { dev_err(dev, "DMA bounce timed out\n"); break; } @@ -790,7 +792,7 @@ static int rp1_pio_sm_tx_user(struct rp1_pio_device *pio, struct dma_info *dma, /* Block for completion */ while (dma->tail_idx != dma->head_idx) { - if (down_timeout(&dma->buf_sem, msecs_to_jiffies(1000))) { + if (down_timeout(&dma->buf_sem, msecs_to_jiffies(WAIT_TIMEOUT))) { dev_err(dev, "DMA wait timed out\n"); ret = -ETIMEDOUT; break; @@ -823,7 +825,7 @@ static int rp1_pio_sm_rx_user(struct rp1_pio_device *pio, struct dma_info *dma, */ if (!bytes || dma->head_idx - dma->tail_idx == dma->buf_count) { if (down_timeout(&dma->buf_sem, - msecs_to_jiffies(1000))) { + msecs_to_jiffies(WAIT_TIMEOUT))) { dev_err(dev, "DMA wait timed out\n"); ret = -ETIMEDOUT; break;