Skip to content

Commit f0ddbb1

Browse files
committed
drm/dp: add option to disable zero sized address only transactions.
Some older NVIDIA and some newer NVIDIA hardware/firmware seems to have issues with address only transactions (firmware rejects them). Add an option to the core drm dp to avoid address only transactions, This just puts the MOT flag removal on the last message of the transfer and avoids the start of transfer transaction. This with the flag set in nouveau, allows eDP probing on GB203 device. Signed-off-by: Dave Airlie <[email protected]> Reviewed-by: Ben Skeggs <[email protected]> Reviewed-by: Timur Tabi <[email protected]> Tested-by: Timur Tabi <[email protected]> Signed-off-by: Dave Airlie <[email protected]>
1 parent 284ad70 commit f0ddbb1

File tree

2 files changed

+28
-16
lines changed

2 files changed

+28
-16
lines changed

drivers/gpu/drm/display/drm_dp_helper.c

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2137,14 +2137,17 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
21372137

21382138
for (i = 0; i < num; i++) {
21392139
msg.address = msgs[i].addr;
2140-
drm_dp_i2c_msg_set_request(&msg, &msgs[i]);
2141-
/* Send a bare address packet to start the transaction.
2142-
* Zero sized messages specify an address only (bare
2143-
* address) transaction.
2144-
*/
2145-
msg.buffer = NULL;
2146-
msg.size = 0;
2147-
err = drm_dp_i2c_do_msg(aux, &msg);
2140+
2141+
if (!aux->no_zero_sized) {
2142+
drm_dp_i2c_msg_set_request(&msg, &msgs[i]);
2143+
/* Send a bare address packet to start the transaction.
2144+
* Zero sized messages specify an address only (bare
2145+
* address) transaction.
2146+
*/
2147+
msg.buffer = NULL;
2148+
msg.size = 0;
2149+
err = drm_dp_i2c_do_msg(aux, &msg);
2150+
}
21482151

21492152
/*
21502153
* Reset msg.request in case in case it got
@@ -2163,6 +2166,8 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
21632166
msg.buffer = msgs[i].buf + j;
21642167
msg.size = min(transfer_size, msgs[i].len - j);
21652168

2169+
if (j + msg.size == msgs[i].len && aux->no_zero_sized)
2170+
msg.request &= ~DP_AUX_I2C_MOT;
21662171
err = drm_dp_i2c_drain_msg(aux, &msg);
21672172

21682173
/*
@@ -2180,15 +2185,17 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
21802185
}
21812186
if (err >= 0)
21822187
err = num;
2183-
/* Send a bare address packet to close out the transaction.
2184-
* Zero sized messages specify an address only (bare
2185-
* address) transaction.
2186-
*/
2187-
msg.request &= ~DP_AUX_I2C_MOT;
2188-
msg.buffer = NULL;
2189-
msg.size = 0;
2190-
(void)drm_dp_i2c_do_msg(aux, &msg);
21912188

2189+
if (!aux->no_zero_sized) {
2190+
/* Send a bare address packet to close out the transaction.
2191+
* Zero sized messages specify an address only (bare
2192+
* address) transaction.
2193+
*/
2194+
msg.request &= ~DP_AUX_I2C_MOT;
2195+
msg.buffer = NULL;
2196+
msg.size = 0;
2197+
(void)drm_dp_i2c_do_msg(aux, &msg);
2198+
}
21922199
return err;
21932200
}
21942201

include/drm/display/drm_dp_helper.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,11 @@ struct drm_dp_aux {
518518
* @powered_down: If true then the remote endpoint is powered down.
519519
*/
520520
bool powered_down;
521+
522+
/**
523+
* @no_zero_sized: If the hw can't use zero sized transfers (NVIDIA)
524+
*/
525+
bool no_zero_sized;
521526
};
522527

523528
int drm_dp_dpcd_probe(struct drm_dp_aux *aux, unsigned int offset);

0 commit comments

Comments
 (0)