drm/amd/display: Only flush delta from last command execution
authorNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Tue, 2 Nov 2021 18:27:30 +0000 (14:27 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 22 Nov 2021 19:45:01 +0000 (14:45 -0500)
[Why]
We're currently flushing commands that had been previously been
flushed or are currently being processed by the DMCUB when we don't
immediately wait for idle after command execution.

[How]
Avoiding reflushing the data by keeping track of the last wptr.

We'll treat this as the actual rptr by creating a copy of the inbox
and modifying the copy's rptr.

Reviewed-by: Eric Yang <Eric.Yang2@amd.com>
Acked-by: Wayne Lin <wayne.lin@amd.com>
Signed-off-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dmub/dmub_srv.h
drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c

index 90065a09e76a35114e1dfa51d17e2e3b735f6a8b..83855b8a32e9077c66bc5249c178f2fa52e075a4 100644 (file)
@@ -411,6 +411,7 @@ struct dmub_srv {
        struct dmub_srv_base_funcs funcs;
        struct dmub_srv_hw_funcs hw_funcs;
        struct dmub_rb inbox1_rb;
+       uint32_t inbox1_last_wptr;
        /**
         * outbox1_rb is accessed without locks (dal & dc)
         * and to be used only in dmub_srv_stat_get_notification()
index 56a03328e8e611a649c60b2c687eb788be433327..6cc897dacd92a5420584a09a06a5db2e248bd783 100644 (file)
@@ -609,6 +609,8 @@ enum dmub_status dmub_srv_cmd_queue(struct dmub_srv *dmub,
 
 enum dmub_status dmub_srv_cmd_execute(struct dmub_srv *dmub)
 {
+       struct dmub_rb flush_rb;
+
        if (!dmub->hw_init)
                return DMUB_STATUS_INVALID;
 
@@ -617,9 +619,14 @@ enum dmub_status dmub_srv_cmd_execute(struct dmub_srv *dmub)
         * been flushed to framebuffer memory. Otherwise DMCUB might
         * read back stale, fully invalid or partially invalid data.
         */
-       dmub_rb_flush_pending(&dmub->inbox1_rb);
+       flush_rb = dmub->inbox1_rb;
+       flush_rb.rptr = dmub->inbox1_last_wptr;
+       dmub_rb_flush_pending(&flush_rb);
 
                dmub->hw_funcs.set_inbox1_wptr(dmub, dmub->inbox1_rb.wrpt);
+
+       dmub->inbox1_last_wptr = dmub->inbox1_rb.wrpt;
+
        return DMUB_STATUS_OK;
 }