From 7b6a4a7c42ae8aa4c2e2ff0892af2152f6d2cd14 Mon Sep 17 00:00:00 2001 From: Thomas Glanzmann Date: Sun, 11 Oct 2026 21:00:37 +0200 Subject: [PATCH] drm: apple: audio: limit the number of periods to what SIO can serve SIO has 64 descriptor slots, shared by all its channels, and its cyclic prep takes one slot per period. The PCM allowed any number of periods, so PipeWire's default of 256-frame periods in a 32768-frame buffer asked for 128 of them. sio_prep_dma_cyclic() then ran out of slots, snd_dmaengine_pcm_trigger() returned -ENOMEM, ALSA undid the START with a STOP (a stop_link round trip to DCP), and PipeWire retried about 100 times a second with no sound. Up to three DP audio outputs share one SIO on t600x and t602x, so allow at most 16 periods per stream, 48 slots for all three. Fixes: cb24343242a7 ("gpu: drm: apple: Add DCP audio driver") Signed-off-by: Thomas Glanzmann --- drivers/gpu/drm/apple/audio.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/apple/audio.c b/drivers/gpu/drm/apple/audio.c index ac55f1f30f6ac..86d94af964503 100644 --- a/drivers/gpu/drm/apple/audio.c +++ b/drivers/gpu/drm/apple/audio.c @@ -33,6 +33,13 @@ #define DCPAUD_ELEMENTS_MAXSIZE 16384 #define DCPAUD_PRODUCTATTRS_MAXSIZE 1024 +/* + * SIO takes one of its 64 descriptor slots per period, shared by all its + * channels, and up to three DP audio outputs use one SIO. A stream with + * more periods fails START with -ENOMEM. + */ +#define DCPAUD_PERIODS_MAX 16 + struct dcp_audio { struct device *dev; struct device *dcp_dev; @@ -72,7 +79,7 @@ static const struct snd_pcm_hardware dcp_pcm_hw = { .period_bytes_min = 4096, /* TODO */ .period_bytes_max = SIZE_MAX, .periods_min = 2, - .periods_max = UINT_MAX, + .periods_max = DCPAUD_PERIODS_MAX, }; /* @@ -98,7 +105,7 @@ static const struct snd_pcm_hardware dcp_pcm_hw_unplugged = { .period_bytes_min = 4096, .period_bytes_max = SIZE_MAX, .periods_min = 2, - .periods_max = UINT_MAX, + .periods_max = DCPAUD_PERIODS_MAX, }; static int dcpaud_read_remote_info(struct dcp_audio *dcpaud) @@ -311,7 +318,7 @@ static int dcp_pcm_open(struct snd_pcm_substream *substream) hw.info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED; hw.periods_min = 2; - hw.periods_max = UINT_MAX; + hw.periods_max = DCPAUD_PERIODS_MAX; hw.period_bytes_min = 256; hw.period_bytes_max = SIZE_MAX; // TODO dma_get_max_seg_size(dma_dev); hw.buffer_bytes_max = SIZE_MAX;