]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
drm/amd/display: Add optional optimization for IPS handshake
authorNicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Thu, 7 Mar 2024 19:50:00 +0000 (14:50 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Fri, 22 Mar 2024 19:49:38 +0000 (15:49 -0400)
[Why]
It's possible to skip parts of the eval and exit sequencing if we know
whether DCN is in IPS2 already or if it's committed to going to idle
and not in IPS2.

[How]
Skip IPS2 entry/exit if DMCUB is idle but the IPS2 commit is not set.

Skip the eval delay if DMCUB is already in IPS2 since we know we need
to exit.

These are turned off by default.

Reviewed-by: Duncan Ma <duncan.ma@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/dc/dc.h
drivers/gpu/drm/amd/display/dc/dc_dmub_srv.c
drivers/gpu/drm/amd/display/dmub/inc/dmub_cmd.h

index 7b22c2efed77e53b5eb87b4e417c9ec3007dc90b..d280f55ebe50b8416588a15df7d80f3f0d557d5d 100644 (file)
@@ -988,6 +988,7 @@ struct dc_debug_options {
        bool psp_disabled_wa;
        unsigned int ips2_eval_delay_us;
        unsigned int ips2_entry_delay_us;
+       bool optimize_ips_handshake;
        bool disable_dmub_reallow_idle;
        bool disable_timeout;
        bool disable_extblankadj;
index 4878e9e50440523e2d5197bdb7fff6412ab2f54d..12c142cae78bf63e98f2c581b92eafd20451d959 100644 (file)
@@ -1318,13 +1318,16 @@ static void dc_dmub_srv_exit_low_power_state(const struct dc *dc)
                 */
                dc_dmub_srv->needs_idle_wake = false;
 
-               if (prev_driver_signals.bits.allow_ips2) {
+               if (prev_driver_signals.bits.allow_ips2 &&
+                   (!dc->debug.optimize_ips_handshake ||
+                    ips_fw->signals.bits.ips2_commit || !ips_fw->signals.bits.in_idle)) {
                        DC_LOG_IPS(
                                "wait IPS2 eval (ips1_commit=%d ips2_commit=%d)",
                                ips_fw->signals.bits.ips1_commit,
                                ips_fw->signals.bits.ips2_commit);
 
-                       udelay(dc->debug.ips2_eval_delay_us);
+                       if (!dc->debug.optimize_ips_handshake || !ips_fw->signals.bits.ips2_commit)
+                               udelay(dc->debug.ips2_eval_delay_us);
 
                        if (ips_fw->signals.bits.ips2_commit) {
                                DC_LOG_IPS(
index 7b807aea8aa7176a6bfe70ed42ff5010054b829f..818e5d87f0daeb328b47114243a34f348ca874df 100644 (file)
@@ -700,7 +700,8 @@ union dmub_shared_state_ips_fw_signals {
        struct {
                uint32_t ips1_commit : 1;  /**< 1 if in IPS1 */
                uint32_t ips2_commit : 1; /**< 1 if in IPS2 */
-               uint32_t reserved_bits : 30; /**< Reversed */
+               uint32_t in_idle : 1; /**< 1 if DMCUB is in idle */
+               uint32_t reserved_bits : 29; /**< Reversed */
        } bits;
        uint32_t all;
 };