nRF54H20: TWIM RTIO driver does not bounce tiny writes (RTIO_OP_TINY_TX) and fails with -EACCES

Environment

nRF Connect SDK v3.4.0 (Zephyr v4.4.0, sdk-zephyr bf801e4e3d1)
SoC: nRF54H20, application core
Bus: i2c133 (TWIM on the low-speed peripheral bus), memory-regions = <&cpuapp_dma_region>
CONFIG_I2C_RTIO=y, so the driver is drivers/i2c/i2c_nrfx_twim_rtio.c


Problem

We read a sensor with the sensor async API (sensor_read_async_mempool()). The sensor driver puts the register address in an RTIO tiny write (rtio_sqe_prep_tiny_write()). On nRF54H20, every tiny write fails with -EACCES. The same code works on nRF5340.

Cause, as we understand it : 

In i2c_nrfx_twim_rtio_start(), the driver handles RX, TX and tiny TX differently:

RTIO_OP_RX and RTIO_OP_TX call nrf_dma_accessible_check(). If DMA cannot reach the buffer, the driver copies it through msg_buf (zephyr,concat-buf-size).
RTIO_OP_TINY_TX gives sqe->tiny_tx.buf straight to i2c_nrfx_twim_msg_transfer(), with no check.
A tiny write keeps its data inside the SQE, and the SQE pool is in normal RAM. On nRF54H20 the low-speed TWIM can only use DMA from cpuapp_dma_region (GRAM3x). The nrfx twim_xfer() checks this with nrf_dma_accessible_check() and returns -EACCES.

The upstream Zephyr main branch has the same code for RTIO_OP_TINY_TX.

How to reproduce

On nRF54H20, enable an I2C bus with memory-regions = <&cpuapp_dma_region> and zephyr,concat-buf-size.
Set CONFIG_I2C_RTIO=y.
Submit an RTIO tiny write to a device on that bus, for example with rtio_sqe_prep_tiny_write() and i2c_iodev.
The completion has result -EACCES. The same request with rtio_sqe_prep_write() and a buffer in normal RAM works, because the driver copies it through msg_buf.
Our workaround

Our driver uses rtio_sqe_prep_write() with a buffer that stays valid until the transfer ends. We also set zephyr,concat-buf-size on the bus.

Questions

Is it intended that RTIO_OP_TINY_TX is not copied through msg_buf? Should RTIO users avoid tiny writes on nRF54H20?
If it is not intended, can the driver copy tiny writes through msg_buf, as it does for RTIO_OP_TX? A tiny write is at most 7 bytes, so it always fits in msg_buf when the buffer is set.
Other Zephyr sensor drivers also use tiny writes for register addresses, for example in i2c_rtio_copy_reg_burst_read(). Do those also fail on nRF54H20 with CONFIG_I2C_RTIO?

Related