On Sat, 3 Oct 2026 at 07:28, Finn Zeruhn <[email protected]> wrote: > > When aux->no_zero_sized is set, drm_dp_i2c_xfer() cannot use a bare > address packet to close the transaction, so it clears MOT on the last > data packet instead. The check only looks at the position within the > current i2c_msg, so MOT is cleared at the end of every message and each > one is terminated by an I2C stop. > > This breaks E-DDC reads of EDID blocks 2 and up. Those are read as three > messages: a write of the segment pointer to 0x30, a write of the offset > to 0x50, and the read. The stop after the first message resets the > segment pointer, so the read returns segment 0 again. > > On a Pimax Dream Air (three EDID blocks, native timings in a DisplayID > extension in block 2) connected to an RTX 5070 Ti with nouveau, block 2 > reads back as a copy of block 0. The checksum is valid, so nothing is > reported, and the connector only offers fallback modes. > > Clear MOT only on the last packet of the last message, as the commit > that added the option describes. With this, block 2 reads correctly and > the native 7104x3840 modes are listed for the Dream Air. > > The same problem was pointed out by the Sashiko review of the patch that > sets no_zero_sized for all DisplayPort connectors in nouveau.
nice catch, Reviwed-by Dave Airlie <[email protected]> > > Fixes: f0ddbb1eed18 ("drm/dp: add option to disable zero sized address only > transactions.") > Link: https://lore.kernel.org/all/[email protected]/ > Cc: [email protected] > Assisted-by: Claude:claude-opus-5-5 > Signed-off-by: Finn Zeruhn <[email protected]> > --- > drivers/gpu/drm/display/drm_dp_helper.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/display/drm_dp_helper.c > b/drivers/gpu/drm/display/drm_dp_helper.c > index 488fd123a01a..7676285c19f8 100644 > --- a/drivers/gpu/drm/display/drm_dp_helper.c > +++ b/drivers/gpu/drm/display/drm_dp_helper.c > @@ -2192,7 +2192,8 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, > struct i2c_msg *msgs, > msg.buffer = msgs[i].buf + j; > msg.size = min(transfer_size, msgs[i].len - j); > > - if (j + msg.size == msgs[i].len && aux->no_zero_sized) > + if (aux->no_zero_sized && i == num - 1 && > + j + msg.size == msgs[i].len) > msg.request &= ~DP_AUX_I2C_MOT; > err = drm_dp_i2c_drain_msg(aux, &msg); > > > base-commit: bca45af5998a05f34b13a2ef11e639bac9c62643 > -- > 2.56.0 >
