Skip to content

Commit 3637e45

Browse files
Wayne Linalexdeucher
authored andcommitted
drm/amd/display: Fix wrong handling for AUX_DEFER case
[Why] We incorrectly ack all bytes get written when the reply actually is defer. When it's defer, means sink is not ready for the request. We should retry the request. [How] Only reply all data get written when receive I2C_ACK|AUX_ACK. Otherwise, reply the number of actual written bytes received from the sink. Add some messages to facilitate debugging as well. Fixes: ad6756b ("drm/amd/display: Shift dc link aux to aux_payload") Cc: Mario Limonciello <[email protected]> Cc: Alex Deucher <[email protected]> Reviewed-by: Ray Wu <[email protected]> Signed-off-by: Wayne Lin <[email protected]> Signed-off-by: Ray Wu <[email protected]> Tested-by: Daniel Wheeler <[email protected]> Signed-off-by: Alex Deucher <[email protected]>
1 parent 9b540e3 commit 3637e45

File tree

1 file changed

+24
-4
lines changed

1 file changed

+24
-4
lines changed

drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@
5151

5252
#define PEAK_FACTOR_X1000 1006
5353

54+
/*
55+
* This function handles both native AUX and I2C-Over-AUX transactions.
56+
*/
5457
static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
5558
struct drm_dp_aux_msg *msg)
5659
{
@@ -87,15 +90,25 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
8790
if (adev->dm.aux_hpd_discon_quirk) {
8891
if (msg->address == DP_SIDEBAND_MSG_DOWN_REQ_BASE &&
8992
operation_result == AUX_RET_ERROR_HPD_DISCON) {
90-
result = 0;
93+
result = msg->size;
9194
operation_result = AUX_RET_SUCCESS;
9295
}
9396
}
9497

95-
if (payload.write && result >= 0)
96-
result = msg->size;
98+
/*
99+
* result equals to 0 includes the cases of AUX_DEFER/I2C_DEFER
100+
*/
101+
if (payload.write && result >= 0) {
102+
if (result) {
103+
/*one byte indicating partially written bytes. Force 0 to retry*/
104+
drm_info(adev_to_drm(adev), "amdgpu: AUX partially written\n");
105+
result = 0;
106+
} else if (!payload.reply[0])
107+
/*I2C_ACK|AUX_ACK*/
108+
result = msg->size;
109+
}
97110

98-
if (result < 0)
111+
if (result < 0) {
99112
switch (operation_result) {
100113
case AUX_RET_SUCCESS:
101114
break;
@@ -114,6 +127,13 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
114127
break;
115128
}
116129

130+
drm_info(adev_to_drm(adev), "amdgpu: DP AUX transfer fail:%d\n", operation_result);
131+
}
132+
133+
if (payload.reply[0])
134+
drm_info(adev_to_drm(adev), "amdgpu: AUX reply command not ACK: 0x%02x.",
135+
payload.reply[0]);
136+
117137
return result;
118138
}
119139

0 commit comments

Comments
 (0)