]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
drm/amd/display: Correct the reply value when AUX write incomplete
authorWayne Lin <Wayne.Lin@amd.com>
Fri, 25 Apr 2025 06:44:02 +0000 (14:44 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 22 May 2025 12:12:19 +0000 (14:12 +0200)
commit d433981385c62c72080e26f1c00a961d18b233be upstream.

[Why]
Now forcing aux->transfer to return 0 when incomplete AUX write is
inappropriate. It should return bytes have been transferred.

[How]
aux->transfer is asked not to change original msg except reply field of
drm_dp_aux_msg structure. Copy the msg->buffer when it's write request,
and overwrite the first byte when sink reply 1 byte indicating partially
written byte number. Then we can return the correct value without
changing the original msg.

Fixes: 3637e457eb00 ("drm/amd/display: Fix wrong handling for AUX_DEFER case")
Cc: Mario Limonciello <mario.limonciello@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Ray Wu <ray.wu@amd.com>
Signed-off-by: Wayne Lin <Wayne.Lin@amd.com>
Signed-off-by: Ray Wu <ray.wu@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 7ac37f0dcd2e0b729fa7b5513908dc8ab802b540)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c

index f6017be8f9957e3128d3ac775daeb2d23911abff..bcf0dc05c7676546750fcf3dea76af460aa6a6a3 100644 (file)
@@ -11069,7 +11069,8 @@ int amdgpu_dm_process_dmub_aux_transfer_sync(
                /* The reply is stored in the top nibble of the command. */
                payload->reply[0] = (adev->dm.dmub_notify->aux_reply.command >> 4) & 0xF;
 
-       if (!payload->write && p_notify->aux_reply.length)
+       /*write req may receive a byte indicating partially written number as well*/
+       if (p_notify->aux_reply.length)
                memcpy(payload->data, p_notify->aux_reply.data,
                                p_notify->aux_reply.length);
 
index c0cacd501c83eb7c9a13fad9316f6e9562d5ef6b..e625b3dd4aabf992d79acaee949aff60a8709383 100644 (file)
@@ -59,6 +59,7 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
        enum aux_return_code_type operation_result;
        struct amdgpu_device *adev;
        struct ddc_service *ddc;
+       uint8_t copy[16];
 
        if (WARN_ON(msg->size > 16))
                return -E2BIG;
@@ -74,6 +75,11 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
                        (msg->request & DP_AUX_I2C_WRITE_STATUS_UPDATE) != 0;
        payload.defer_delay = 0;
 
+       if (payload.write) {
+               memcpy(copy, msg->buffer, msg->size);
+               payload.data = copy;
+       }
+
        result = dc_link_aux_transfer_raw(TO_DM_AUX(aux)->ddc_service, &payload,
                                      &operation_result);
 
@@ -97,9 +103,9 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
         */
        if (payload.write && result >= 0) {
                if (result) {
-                       /*one byte indicating partially written bytes. Force 0 to retry*/
+                       /*one byte indicating partially written bytes*/
                        drm_info(adev_to_drm(adev), "amdgpu: AUX partially written\n");
-                       result = 0;
+                       result = payload.data[0];
                } else if (!payload.reply[0])
                        /*I2C_ACK|AUX_ACK*/
                        result = msg->size;