Rock Pi S - I2S0 - anyone getting clean 96/192kHz?

Hi, I cannot get clean 192kHz I2S0 loopback (SDOx -> SDIy) on Pi S, despite the RK3308 I2S0 192kHz specs.

I am testing maximum working I2S samplerates. Simple kernel modification allows samplerates up to 768kHz (just increasing limits in the alsa drivers).

I have already tested other RKs:
RK3566 (Radxa CM3) - clean 192kHz, clean 384kHz, few issues at 768kHz
RK3588S (Radxa CM5) - clean 192kHz, few issues at 384kHz, many issues at 768kHz

By “issues” I mean dropped samples and added zero samples in the captured stream, clearly visible on the sine signal in audacity. These are not alsa xruns (none reported), it’s always just a few samples (1 to 10). My hypothesis is the I2S FIFO - AHB - DMACx - RAM chain does not keep up transferring samples reliably: dropped samples in the captured stream are I2S FIFO overflows on the RX side, zero samples are I2S FIFO underflows on the TX side (I2S sending zeros instead).

The RK3566 and RK3588S “issues” are OK, the interfaces are specced only up to 192kHz where their performance is flawless. But I get consistent “issues” on RK3308 8ch I2S interface at 192kHz, even if transferring only 2 channels. 96kHz performance is OK.

I tried changing DMA burst size to the maximum 16 and to small 4 in https://elixir.bootlin.com/linux/latest/source/sound/soc/rockchip/rockchip_i2s_tdm.c#L1634 + https://elixir.bootlin.com/linux/latest/source/sound/soc/rockchip/rockchip_i2s_tdm.c#L1640 , with more “issues” than the original 8.

On RK3308 the HCLK (the AHB clock, IIUC) runs at 98MHz which perhaps may be too low for 192kHz samplerate. AHB clock on RK3566 runs at 150MHz default (I actually increased that to 200MHz by reverting the patch https://github.com/radxa/u-boot/commit/65bd598f415b92d2165e52a757e70f85352eba25 ). I think AHB clock of RK3588 is at least 200MHz, IIRC.

Cpufreq governor is set to “performance” on all cores, no switching cpu frequencies. Only ethernet is being used, no USB gadget etc.

Please has anyone had consistent success with 192kHz I2S0 on the Pi S?

Please see the attached spectrogram - 8ch 192kHz 1kHz signal - first 4 secs issues, then suddenly perfectly clean. Somehow the transport “recovered”. Next time issues again. The captured wav was stored to tmpfs, no slow SD card involved. Is there any way to troubleshoot these low-level issues?

This is detail from audacity - a few extra zero samples added, no real samples dropped.

This is spectrogram from 96kHz which is not 100% reliably clean either. IMO the added zero samples only in the first 4 channels really suggest that the bottleneck is somewhere in the delivery between RAM/DMAC1 and the I2S FIFOs. The spectrogram suggests that the 4 FIFOs are served on round-robin basis, and in this particular case the first two FIFOs underflew while the remaining two FIFOs were served on time. Note how samples in the corrupted tracks are shifted to the right, by the one added zero sample.

Please is there any way to improve performance of the bus, at least to make the 96kHz samplerate practically usable? Any missing/corrupted sample is a show stopper for practical usage as it produces an audible click.

Increased clock hclk_audio (clocking the I2S hclk) from 100MHz to 400MHz (max working)

      clk_audio_src               2        2        0  1179647999          0     0  50000         Y
         pclk_audio               1        1        0    98304000          0     0  50000         Y
            pclk_acodec           0        0        0    98304000          0     0  50000         N
            pclk_audio_niu        0        0        0    98304000          0     0  50000         Y
         hclk_audio               2        2        0   393216000          0     0  50000         Y
            hclk_vad              0        0        0   393216000          0     0  50000         N
            hclk_i2s1_2ch         0        0        0   393216000          0     0  50000         N
            hclk_i2s0_2ch         0        0        0   393216000          0     0  50000         N
            hclk_i2s3_8ch         0        0        0   393216000          0     0  50000         N
            hclk_i2s2_8ch         0        0        0   393216000          0     0  50000         N
            hclk_i2s1_8ch         0        0        0   393216000          0     0  50000         N
            hclk_i2s0_8ch         2        2        0   393216000          0     0  50000         Y
            hclk_spdifrx          0        0        0   393216000          0     0  50000         N
            hclk_spdiftx          0        0        0   393216000          0     0  50000         N
            hclk_pdm              0        0        0   393216000          0     0  50000         N
            hclk_audio_niu        0        0        0   393216000          0     0  50000         Y
      clk_wifi_vpll0              0        0        0  1179647999          0     0  50000

and aclk_bus (clocking the DMACs) from 200MHz to 430MHz (max working)

      clk_bus_src                 3        3        0  1300000000          0     0  50000         Y
         aclk_bus                 2        3        0   433333334          0     0  50000         Y
            aclk_dmac1            1        1        0   433333334          0     0  50000         Y
            aclk_dmac0            0        1        0   433333334          0     0  50000         Y
            aclk_gic              0        0        0   433333334          0     0  50000         Y
            aclk_vop              0        0        0   433333334          0     0  50000         N
            aclk_crypto           0        0        0   433333334          0     0  50000         N
            aclk_intmem           0        0        0   433333334          0     0  50000         Y
            aclk_bus_niu          0        0        0   433333334          0     0  50000         Y
         hclk_bus                 1        1        0   100000000          0     0  50000         Y

No notable improvement in 96kHz. Default clocks (11 minutes recording):

The substantially faster clocks:


I really have no idea what to tweak more to improve the throughput and reliability. I tend to worry the SoC performance is not up to the task (which is sad as even smaller STM32s run I2S at 768kHz).

Really nobody has properly tested this board at > 48kHz?

Hi, Pavel!

Did you make to get the i2s working without skipped/zero samples?

The HW seems to work OK, with radxa kernel - see RockPi S + CS42448 I2S/I2C DAC setup . But the mainline is broken somehow and I could not get any pointers where to start. I could not find any difference in the I2S driver. IMO it’s some low-level setting/timing issue, perhaps for the clocks, DMA, …

Yes, I also tried this kernel and found no sound issues, but found a very slow Ethernet, so playback from NAS of bitrates greater than 96k in mpd is choppy (message from mpd.log: alsa_output: Decoder is too slow; playing silence to avoid xrun). With mainline kernel network works fine, but audio is buggy.
iperf on Radxa kernel - 10 MBit, mainline - 95 MBit/

That’s interesting. My radxa kernel 6.1.43 does 94Mbps with iperf on local network.

What kernel sources (branch) did you use?

https://github.com/radxa/kernel/tree/linux-6.1-stan-rkr4.1 , commit 8c5a7e2ee229007f8f430df4c463cd755c017e9f , but then I applied quite a few patches to make it work for Pi S and the USB audio gadget, maybe some of them are already in the newer commits. E.g. Rock Pi S + radxa kernel linux-6.1-stan-rkr1 - inactive USB host? - see the last post, it was never fixed by Radxa.

It would definitely be good to have a properly working relatively recent Pi-S kernel :slight_smile:

I also used this repository, but the HEAD branch, and I found in kernel.log a message that ethernet can only run on 10Mb.
Have you tried linux kernel version 5? I built an armbian image with mainline kernel 5.19 and quickly tested it. And I did not find the choppy sound like in mainline kernel version 6.
BTW, I found similar problem with NanoPi Neo3 (rk3328) and kernel version 6.

IIRC I tested only newer kernels, not 5. Older kernels are unusable for developing and submitting patches to mainline (I am interested in the USB audio gadget, specifically).

That 10Mb message could perhaps be troubleshooted, to find out what is causing it.

I found Radxa kernel configurations lacking important options (like that USB support, also missing support for overlays etc.).

Pavel, can you check your test case with kernel 6.12 where file drivers/dma/pl330.c is replaced with this one? I tried playback and haven’t noticed any issues yet, but your case to be creating a higher load and I’m very interested in your results.
PS. I used Armbian build with BRANCH=current

Please can you specify how you built your kernel version? If possibly some github repo with config file used for the build, and optionally the patches you applied. There are many various kernel versions available online. The goal would be having a working repo (ideally tied to mainline https://github.com/torvalds/linux/tree/master, or some other up-to-date reference related to mainline). Thanks a lot.

There are quite a few recent commits in https://github.com/torvalds/linux/commits/5bc55a333a2f7316b58edc7573e8e893f7acb532/drivers/dma/pl330.c , some of them seem to be already present in that bulk commit https://github.com/kvn61/rk3308/commit/ae6a75f8a551229ee2af7d6b5a7de1db112b24f1 .

Hello!

I was investigating the problem separately for my own concerns, and then I discovered this thread.
I can confirm that there is an issue in the mainline kernel pl330.c driver code, and applying a patch to that driver fixes the problem in the most common scenario. Yet I have discovered that, under heavy memory load, the issues still appears.

Since I am a maintainer at Armbian, I supplied a pull request to the project with some more details and a way to consistently reproduce the issue:

I used the current version of the armbian build tool. It can build u-boot, kernel packages or full image with the 6.12 kernel with armbian and custom users patches.
The Armbian build tool uses the mainline repository with some patches from the armbian team.

At the first step, I create a custom patch by command
./compile.sh kernel-patch BOARD=rockpi-s BRANCH=current
and simply replacing original pl330.c file to new file after prompt from build tool.
At the second step I copy created patch to specified folder and build the kernel (kernel only or full image) with my patch.

PS this file pl330.c is taken from the radxa repository with one small change at lines 3454-3457

Hello!
Your patch is similar radxa linux-6.1-stan-rkr4.1. You say rockchip 4.4 has no problem. But rockchip has some additional code in pl330.
And, rk3308 Support 16-bit data width memory access. May be memory benchmark simultaneously with other task is too hard test for our purposes

IIUC you took armbian 6.12 kernel (which has mainline pl330.c, no patches to this file in the build-tool repository) and used the radxa pl330.c version (your patch just disables the error msg, IIUC).

I have not tested yet, but your results suggest it fixes the problem, just like the linux-6.1-stan-rkr4.1 kernel was running OK with me up to 384kHz/32bit sample (I did get dropped-packets with I2S at 768kHz samplerate but that’s way above the HW specs and I2S data loopback is already randomly delayed by one bit).

Hi, thanks for the work. IIUC armbian uses mainline 6.12 pl330.c https://github.com/torvalds/linux/commits/master/drivers/dma/pl330.c which does not contain that crucial rockchip commit https://github.com/radxa/kernel/commit/ec0b65dbc59793426b6dc7af06ab6675f4a24940 yet.

But the two files https://github.com/radxa/kernel/commits/linux-6.1-stan-rkr4.1/drivers/dma/pl330.c and https://github.com/torvalds/linux/commits/master/drivers/dma/pl330.c differ in a number of commits, some only in mainline, some only in radxa/rockchip. I wonder why the rockchip people did not submit to the mainline instead… This way it’s almost impossible to use the mainline and test/develop new features not tied specifically to rockchip (patches based on other files in 6.1 kernel are unlikely to fit 6.12 mainline).