drm/amd/display: w/a to program DISPCLK_R_GATE_DISABLE DCN35
authorYihan Zhu <Yihan.Zhu@amd.com>
Mon, 7 Oct 2024 18:32:59 +0000 (14:32 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Tue, 22 Oct 2024 21:50:38 +0000 (17:50 -0400)
[WHY & HOW]
Cursor corruption observed on USBC display with specific system setup with a
reboot. Cursor memory might still in the lightsleep state due to voltage
issue, we need program DISPCLK_R_GATE_DISABLE to avoid this issue only on
DCN35.

Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Yihan Zhu <Yihan.Zhu@amd.com>
Signed-off-by: Wayne Lin <wayne.lin@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/dpp/dcn20/dcn20_dpp.h
drivers/gpu/drm/amd/display/dc/dpp/dcn30/dcn30_dpp.h
drivers/gpu/drm/amd/display/dc/dpp/dcn35/dcn35_dpp.c

index cd1706d..f09cba8 100644 (file)
@@ -690,6 +690,7 @@ struct dcn20_dpp {
        int lb_memory_size;
        int lb_bits_per_entry;
        bool is_write_to_ram_a_safe;
+       bool dispclk_r_gate_disable;
        struct scaler_data scl_data;
        struct pwl_params pwl_data;
 };
index b110f35..f236824 100644 (file)
@@ -572,6 +572,7 @@ struct dcn3_dpp {
        int lb_memory_size;
        int lb_bits_per_entry;
        bool is_write_to_ram_a_safe;
+       bool dispclk_r_gate_disable;
        struct scaler_data scl_data;
        struct pwl_params pwl_data;
 };
index 9f885a0..62b7012 100644 (file)
@@ -50,11 +50,21 @@ void dpp35_dppclk_control(
                                DPPCLK_RATE_CONTROL, dppclk_div,
                                DPP_CLOCK_ENABLE, 1);
                else
-                       REG_UPDATE(DPP_CONTROL,
-                                       DPP_CLOCK_ENABLE, 1);
+                       if (dpp->dispclk_r_gate_disable)
+                               REG_UPDATE_2(DPP_CONTROL,
+                                       DPP_CLOCK_ENABLE, 1,
+                                       DISPCLK_R_GATE_DISABLE, 1);
+                       else
+                               REG_UPDATE(DPP_CONTROL,
+                                               DPP_CLOCK_ENABLE, 1);
        } else
-               REG_UPDATE(DPP_CONTROL,
-                               DPP_CLOCK_ENABLE, 0);
+               if (dpp->dispclk_r_gate_disable)
+                       REG_UPDATE_2(DPP_CONTROL,
+                               DPP_CLOCK_ENABLE, 0,
+                               DISPCLK_R_GATE_DISABLE, 0);
+               else
+                       REG_UPDATE(DPP_CONTROL,
+                                       DPP_CLOCK_ENABLE, 0);
 }
 
 void dpp35_program_bias_and_scale_fcnv(
@@ -126,6 +136,10 @@ bool dpp35_construct(
                              (const struct dcn3_dpp_mask *)(tf_mask));
 
        dpp->base.funcs = &dcn35_dpp_funcs;
+
+       // w/a for cursor memory stuck in LS by programming DISPCLK_R_GATE_DISABLE, limit w/a to some ASIC revs
+       if (dpp->base.ctx->asic_id.hw_internal_rev <= 0x10)
+               dpp->dispclk_r_gate_disable = true;
        return ret;
 }