Skip to content

RP1 DesignWare I2S: 8-channel multi-lane playback can lose/remap physical channels after XRUN recovery #7584

Description

@chohyeonsou

Reporter / AI-assistance disclosure

I encountered this problem on my own Raspberry Pi 5 + HiFiBerry DAC8x system and personally ran the commands, reboot/recovery trials, and listening checks described below.

I used AI-assisted tools (ChatGPT, Codex and Claude) to help:

  • inspect and compare kernel source,
  • organize hypotheses,
  • interpret logs and traces,
  • prepare the test patch,
  • and structure this report.

Therefore, I do not claim that I personally wrote the kernel analysis or independently discovered the root cause. The hardware observations and test results are from my system; the analysis and patch preparation were AI-assisted.

I am reporting the result because it may help other Raspberry Pi / DAC8x users and the kernel maintainers.

Describe the bug

On Raspberry Pi 5, 8-channel playback through RP1 DesignWare I2S and a HiFiBerry DAC8x can recover at the ALSA/CamillaDSP software level after an XRUN/underrun while the physical DAC outputs are no longer trustworthy: some physical stereo pairs can disappear or appear to carry audio intended for a different logical pair.

The failure is intermittent and is associated with STOP/PREPARE/START recovery activity. In the affected state, ALSA can report the DAC8x PCM as RUNNING, hw_ptr/appl_ptr continue to advance, CamillaDSP remains Running, and the logical mixer/output channels still contain signal, but the physical RCA outputs can be wrong.

I am reporting this upstream at the request of HiFiBerry support. HiFiBerry confirmed that their DAC8x driver relies on the kernel I2S infrastructure and asked that the issue and tested patch be provided to the Raspberry Pi kernel team.

With AI-assisted analysis, a small playback-side test patch was prepared that makes the STOP path fully tear down the transmitter/DMA state. I tested that patch on my system. With it installed, repeated XRUN/recovery trials no longer reproduced the physical-channel fault in my listening checks.

I am not claiming that the internal TXDMA selector hypothesis below is proven. The patch result is evidence that STOP/restart state handling is involved, but I have not directly instrumented the internal TXDMA channel selector or objectively measured the exact bad logical-to-physical permutation.

Platform

  • Raspberry Pi 5 Model B Rev 1.0
  • Kernel: 6.18.34+rpt-rpi-2712
  • Debian kernel package: 1:6.18.34-1+rpt1
  • Raspberry Pi kernel source revision used for the source-level investigation:
    c8c7494100e99ee05b11aaa4f0588a223a63d1af
  • Audio output: HiFiBerry DAC8x
  • ALSA format: S32_LE, RW_INTERLEAVED, 8 channels
  • Native rates used: 44.1 / 48 / 88.2 / 96 / 176.4 / 192 kHz
  • Playback stack:
    CamillaDSP -> ALSA PCM -> snd_pcm_dmaengine -> snd_soc_core -> snd_soc_rpi_simple_soundcard -> designware_i2s -> RP1 I2S0 -> DAC8x
  • RP1 TX DMA observed:
    dma2chan2 -> 1f000a0000.i2s:tx

8-channel physical topology

This is not an 8-slot single-data-line TDM configuration.

The DAC8x uses four stereo transmit lanes sharing SCLK/WS:

  • TER0 / SDO0 / GPIO21 -> channels 1/2
  • TER1 / SDO1 / GPIO23 -> channels 3/4
  • TER2 / SDO2 / GPIO25 -> channels 5/6
  • TER3 / SDO3 / GPIO27 -> channels 7/8
  • SCLK -> GPIO18
  • WS -> GPIO19

All four stereo lanes are fed from the same cyclic TX DMA stream.

Failure observation

A representative event on 2026-08-30 showed approximately 15 playback prepare/recovery cycles within about 1.15 seconds while the UAC2 capture side was not reopened.

During failure investigation I observed cases where:

  • DAC8x ALSA PCM was still RUNNING
  • hw_ptr / appl_ptr were advancing
  • CamillaDSP was Running
  • logical output signal/routing remained present
  • physical DAC output pairs were nevertheless missing or appeared to contain the wrong band/channel

The exact bad permutation was not instrumented and should be treated as an observation, not a proven mapping.

There are also recovery logs containing:

dma dma2chan2: dma2chan2 failed to stop

and repeated:

PB: Prepare playback after buffer underrun

The issue is therefore more than a simple application routing problem: the software-visible PCM state can look healthy while the physical multi-lane output state is not.

Source-level finding

The following source-level findings were obtained with AI-assisted analysis and then checked against the exact Raspberry Pi source revision listed above.

In the Raspberry Pi rpi-6.18.y DesignWare I2S driver, i2s_stop() currently clears IRQ state and disables IRQs, but does not:

  • disable ITER for playback
  • disable the TX DMA handshake
  • write I2S_RTXDMA = 1
  • disable CER when the last stream stops
  • disable IER when the last stream stops

However, the existing i2s_disable_dma() function already performs the important TX DMA reset operation:

  • clears I2S_DMAEN_TXBLOCK
  • writes I2S_RTXDMA = 1

By comparison, current upstream Linux sound/soc/dwc/dwc-i2s.c performs a substantially stronger stop sequence: it disables the stream (ITER/IRER), calls i2s_disable_dma() on DMA paths, masks IRQs, and disables CER/IER when no stream remains active.

This downstream/upstream difference is why the playback-only test change was tried.

Tested patch

The attached patch is the exact functional playback-side change that was tested on my hardware. It was prepared with AI assistance based on the observed source differences. Diagnostic instrumentation used during the experiment is intentionally not part of the patch attachment.

The tested playback STOP sequence does:

  1. clear IRQs
  2. set ITER = 0
  3. call i2s_disable_dma() for DMA playback
    • this clears the TX block handshake and writes I2S_RTXDMA = 1
  4. disable IRQs
  5. if no stream remains active, set CER = 0 and IER = 0

I am not proposing that maintainers must merge this exact patch shape; current mainline already has a broader playback/capture form.

Test result

The instrumented patched module used for the field test had:

  • module path:
    /lib/modules/6.18.34+rpt-rpi-2712/updates/cdsp/designware_i2s.ko
  • srcversion:
    682B459B61FF9821F859F2A
  • SHA256:
    079602643846e9b215f23ac951f08f08fd6d19d7a104cd83b00d0eb367763695

Note: this module hash includes the functional PATCH1 plus diagnostic instrumentation, so it is not the hash of a clean functional-patch-only build.

At the recorded audit point:

  • 18 trial START markers were present
  • 15 trials had explicit user-confirmed RESULT=GOOD markers
  • no RESULT=BAD marker was present in that captured test log
  • 88 PREPARE_ENTER / 88 PREPARE_EXIT events
  • 86 START_ENTER / 86 START_EXIT events
  • 86 STOP_ENTER / 86 STOP_EXIT events
  • all 86 observed STOP_EXIT states passed the instrumentation's "fully sanitized" check

The system also went through repeated XRUN/underrun recovery cycles after patching, with the DAC returning to RUNNING/8/44100 in the captured 44.1 kHz test sequence.

Physical channel correctness in these trials was confirmed by listening, not by an automated multi-channel measurement fixture. I want to be explicit about that limitation.

Working hypothesis (not proven)

AI-assisted analysis suggested one possible mechanism: stale state in the DW_apb_i2s TX DMA channel-cycling machinery across the four enabled transmit pairs.

The existing i2s_disable_dma() writes I2S_RTXDMA = 1, while the Raspberry Pi downstream i2s_stop() does not call it. If an XRUN terminates/restarts the external RP1 cyclic DMA while the I2S TX/DMA state remains enabled, a stale multi-lane transmit state could plausibly survive into the next descriptor.

This is a hypothesis only. I have not directly observed the internal selector, and I do not want the issue to depend on that theory. The reproducible field result is that the stronger STOP teardown changed the behaviour on my system.

Possibly related Raspberry Pi issues

Request to maintainers

Could you please review whether Raspberry Pi rpi-6.18.y should pick up the current upstream DesignWare I2S stop-state teardown (or an equivalent safe fix), particularly for RP1 multi-channel/multi-lane playback?

I can provide additional traces or test a maintainer-provided patch if needed. Because this Pi is connected to a multi-amplified loudspeaker system, I would prefer read-only tracing first and will apply any new kernel module only with the amplifiers muted/off.

Attachments

  • 02_PATCH1_TESTED_PLAYBACK_STOP_FIX.patch
  • 03_SELECTED_BEFORE_AFTER_EVIDENCE.txt
  • 05_PUBLIC_REPO_CROSSCHECK.txt

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions