]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
drm/amd/display: Clean up dsc blocks in accelerated mode
authorMartin Tsai <martin.tsai@amd.com>
Mon, 22 Jul 2024 06:12:25 +0000 (14:12 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 4 Oct 2024 14:38:36 +0000 (16:38 +0200)
commit 3766a840e093d30e1a2522f650d8a6ac892a8719 upstream.

[WHY]
DSC on eDP could be enabled during VBIOS post. The enabled
DSC may not be disabled when enter to OS, once the system was
in second screen only mode before entering to S4. In this
case, OS will not send setTimings to reset eDP path again.

The enabled DSC HW will make a new stream without DSC cannot
output normally if it reused this pipe with enabled DSC.

[HOW]
In accelerated mode, to clean up DSC blocks if eDP is on link
but not active when we are not in fast boot and seamless boot.

Cc: Mario Limonciello <mario.limonciello@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
Reviewed-by: Charlene Liu <charlene.liu@amd.com>
Signed-off-by: Martin Tsai <martin.tsai@amd.com>
Signed-off-by: Alex Hung <alex.hung@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c

index 1f2eb2f727dc1ebb53c6aaca3ac1fb50c65fc2fa..4d6e90c49ad531a758e11874d92b5ac5f1422d6b 100644 (file)
@@ -57,6 +57,7 @@
 #include "panel_cntl.h"
 #include "dc_state_priv.h"
 #include "dpcd_defs.h"
+#include "dsc.h"
 /* include DCE11 register header files */
 #include "dce/dce_11_0_d.h"
 #include "dce/dce_11_0_sh_mask.h"
@@ -1815,6 +1816,48 @@ static void get_edp_links_with_sink(
        }
 }
 
+static void clean_up_dsc_blocks(struct dc *dc)
+{
+       struct display_stream_compressor *dsc = NULL;
+       struct timing_generator *tg = NULL;
+       struct stream_encoder *se = NULL;
+       struct dccg *dccg = dc->res_pool->dccg;
+       struct pg_cntl *pg_cntl = dc->res_pool->pg_cntl;
+       int i;
+
+       if (dc->ctx->dce_version != DCN_VERSION_3_5 &&
+               dc->ctx->dce_version != DCN_VERSION_3_51)
+               return;
+
+       for (i = 0; i < dc->res_pool->res_cap->num_dsc; i++) {
+               struct dcn_dsc_state s  = {0};
+
+               dsc = dc->res_pool->dscs[i];
+               dsc->funcs->dsc_read_state(dsc, &s);
+               if (s.dsc_fw_en) {
+                       /* disable DSC in OPTC */
+                       if (i < dc->res_pool->timing_generator_count) {
+                               tg = dc->res_pool->timing_generators[i];
+                               tg->funcs->set_dsc_config(tg, OPTC_DSC_DISABLED, 0, 0);
+                       }
+                       /* disable DSC in stream encoder */
+                       if (i < dc->res_pool->stream_enc_count) {
+                               se = dc->res_pool->stream_enc[i];
+                               se->funcs->dp_set_dsc_config(se, OPTC_DSC_DISABLED, 0, 0);
+                               se->funcs->dp_set_dsc_pps_info_packet(se, false, NULL, true);
+                       }
+                       /* disable DSC block */
+                       if (dccg->funcs->set_ref_dscclk)
+                               dccg->funcs->set_ref_dscclk(dccg, dsc->inst);
+                       dsc->funcs->dsc_disable(dsc);
+
+                       /* power down DSC */
+                       if (pg_cntl != NULL)
+                               pg_cntl->funcs->dsc_pg_control(pg_cntl, dsc->inst, false);
+               }
+       }
+}
+
 /*
  * When ASIC goes from VBIOS/VGA mode to driver/accelerated mode we need:
  *  1. Power down all DC HW blocks
@@ -1917,6 +1960,13 @@ void dce110_enable_accelerated_mode(struct dc *dc, struct dc_state *context)
                clk_mgr_exit_optimized_pwr_state(dc, dc->clk_mgr);
 
                power_down_all_hw_blocks(dc);
+
+               /* DSC could be enabled on eDP during VBIOS post.
+                * To clean up dsc blocks if eDP is in link but not active.
+                */
+               if (edp_link_with_sink && (edp_stream_num == 0))
+                       clean_up_dsc_blocks(dc);
+
                disable_vga_and_power_gate_all_controllers(dc);
                if (edp_link_with_sink && !keep_edp_vdd_on)
                        dc->hwss.edp_power_control(edp_link_with_sink, false);