On 5/28/2026 11:24 PM, Philippe Mathieu-Daudé wrote:
Thanks Philippe for the review
> On 29/5/26 03:40, Jithu Joseph wrote:
>> The Linux DW-I3C master driver infers controller queue depths at probe
>> by reading two status registers that report free queue slots, which at
>> probe (queues empty) equals the full depth. It then uses those values
>> to gate every I3C transfer -- any batch whose word count exceeds the
>> advertised depth is rejected with -EOPNOTSUPP.
>>
>> QUEUE_STATUS_LEVEL (0x4c) [7:0] -> cmdfifodepth (cmd slots)
>> DATA_BUFFER_STATUS_LEVEL (0x50) [7:0] -> datafifodepth (32-bit words)
>>
>> Per the AST2600 datasheet the reset values are 0x10 and 0x40 (16 cmd
>> slots, 64 words = 256 B). QEMU was advertising 0x02 and 0x10, making
>> the kernel believe the controller can only do 64-byte transfers. The
>> visible symptom was -EOPNOTSUPP on any I3C transfer whose payload
>> exceeded 64 B (datafifodepth = 0x10 = 16 words = 64 B).
>>
>> The underlying FIFOs in QEMU were already allocated at the right size
>> (fifo32_create takes word counts; the existing defaults give 16 cmd
>> slots and 64 data words). Only the advertised reset values were
>> wrong. With this fix the guest sees datafifodepth=64 words and
>> accepts transfers up to 256 B.
>>
>> Fixes: e974c6957576 ("hw/i3c/dw-i3c: Add more reset values")
>> Signed-off-by: Jithu Joseph <[email protected]>
>> ---
>> hw/i3c/dw-i3c.c | 4 ++--
>> 1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/hw/i3c/dw-i3c.c b/hw/i3c/dw-i3c.c
>> index 17ff484c5df1..e1bcf083210b 100644
>> --- a/hw/i3c/dw-i3c.c
>> +++ b/hw/i3c/dw-i3c.c
>> @@ -282,8 +282,8 @@ static const uint32_t dw_i3c_resets[DW_I3C_NR_REGS] = {
>> [R_QUEUE_THLD_CTRL] = 0x01000101,
>> [R_DATA_BUFFER_THLD_CTRL] = 0x01010100,
>> [R_SLV_EVENT_CTRL] = 0x0000000b,
>> - [R_QUEUE_STATUS_LEVEL] = 0x00000002,
>> - [R_DATA_BUFFER_STATUS_LEVEL] = 0x00000010,
>> + [R_QUEUE_STATUS_LEVEL] = 0x00000010,
>> + [R_DATA_BUFFER_STATUS_LEVEL] = 0x00000040,
>
> [R_QUEUE_STATUS_LEVEL] = s->cfg.cmd_resp_queue_capacity_words;
> [R_DATA_BUFFER_STATUS_LEVEL] = s->cfg.tx_rx_queue_capacity_words;
>
> ?
You're right — hardcoding 0x10/0x40 in dw_i3c_resets[] ignores the configured
values
and would silently advertise wrong depths if these properties are ever
overridden
Since literally initializing here would give compile errors, I can try
overriding
it in reset functions (dw_i3c_reset() / dw_i3c_reset_enter()) after memcpying
from
this array (similar to what is done for R_DEV_CHAR_TABLE_POINTER /
R_DEVICE_ADDR_TABLE_POINTER)
>
>> [R_PRESENT_STATE] = 0x00000003,
>> [R_I3C_VER_ID] = 0x3130302a,
>> [R_I3C_VER_TYPE] = 0x6c633033,
>
Thanks
Jithu