From: Mohit Bawa <[email protected]>

why:
dcn35 currently uses a hardcoded DSC display clock value which is incorrect
for some asic types. Newer DCN versions retrieve dsc display clock from
clk_mgr. The same can be done for dcn35.

how:
Refactor the DSC cap calculation using pre-existing logic.
Handle ODM combine requirements in dc_dsc.c.
Replace hardcoded display clock with actual value retrieved from clk_mgr.

Reviewed-by: Nicholas Kazlauskas <[email protected]>
Reviewed-by: Charlene Liu <[email protected]>
Reviewed-by: Wenjing Liu <[email protected]>
Signed-off-by: Mohit Bawa <[email protected]>
Signed-off-by: Fangzhi Zuo <[email protected]>
---
 .../display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c  | 30 ++++++++++++++++++
 .../drm/amd/display/dc/dsc/dcn35/dcn35_dsc.c  | 31 ++++++++++++++++++-
 2 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c 
b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
index 35d20a663d67..dfd0c9505af0 100644
--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
+++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
@@ -1295,6 +1295,35 @@ static void dcn35_update_clocks_fpga(struct clk_mgr 
*clk_mgr,
        dcn35_update_clocks_update_dtb_dto(clk_mgr_int, context, 
clk_mgr->clks.ref_dtbclk_khz);
 }
 
+static unsigned int dcn35_get_max_clock_khz(struct clk_mgr *clk_mgr_base, enum 
clk_type clk_type)
+{
+       struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base);
+
+       unsigned int num_clk_levels;
+
+       switch (clk_type) {
+       case CLK_TYPE_DISPCLK:
+               num_clk_levels = 
clk_mgr->base.bw_params->clk_table.num_entries_per_clk.num_dispclk_levels;
+               return num_clk_levels ?
+                               
clk_mgr->base.bw_params->clk_table.entries[num_clk_levels - 1].dispclk_mhz * 
1000 :
+                               clk_mgr->base.boot_snapshot.dispclk;
+       case CLK_TYPE_DPPCLK:
+               num_clk_levels = 
clk_mgr->base.bw_params->clk_table.num_entries_per_clk.num_dppclk_levels;
+               return num_clk_levels ?
+                               
clk_mgr->base.bw_params->clk_table.entries[num_clk_levels - 1].dppclk_mhz * 
1000 :
+                               clk_mgr->base.boot_snapshot.dppclk;
+       case CLK_TYPE_DSCCLK:
+               num_clk_levels = 
clk_mgr->base.bw_params->clk_table.num_entries_per_clk.num_dispclk_levels;
+               return num_clk_levels ?
+                               
clk_mgr->base.bw_params->clk_table.entries[num_clk_levels - 1].dispclk_mhz * 
1000 / 3 :
+                               clk_mgr->base.boot_snapshot.dispclk / 3;
+       default:
+               break;
+       }
+
+       return 0;
+}
+
 static struct clk_mgr_funcs dcn35_funcs = {
        .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz,
        .get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz,
@@ -1306,6 +1335,7 @@ static struct clk_mgr_funcs dcn35_funcs = {
        .set_low_power_state = dcn35_set_low_power_state,
        .exit_low_power_state = dcn35_exit_low_power_state,
        .is_ips_supported = dcn35_is_ips_supported,
+       .get_max_clock_khz = dcn35_get_max_clock_khz,
 };
 
 struct clk_mgr_funcs dcn35_fpga_funcs = {
diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dcn35/dcn35_dsc.c 
b/drivers/gpu/drm/amd/display/dc/dsc/dcn35/dcn35_dsc.c
index f9c6377ac66c..e712985f7abd 100644
--- a/drivers/gpu/drm/amd/display/dc/dsc/dcn35/dcn35_dsc.c
+++ b/drivers/gpu/drm/amd/display/dc/dsc/dcn35/dcn35_dsc.c
@@ -28,9 +28,9 @@
 #include "reg_helper.h"
 
 static void dsc35_enable(struct display_stream_compressor *dsc, int opp_pipe);
+static void dsc35_get_single_enc_caps(struct dsc_enc_caps *dsc_enc_caps, 
unsigned int max_dscclk_khz);
 
 static const struct dsc_funcs dcn35_dsc_funcs = {
-       .dsc_get_enc_caps = dsc2_get_enc_caps,
        .dsc_read_state = dsc2_read_state,
        .dsc_read_reg_state = dsc2_read_reg_state,
        .dsc_validate_stream = dsc2_validate_stream,
@@ -40,6 +40,7 @@ static const struct dsc_funcs dcn35_dsc_funcs = {
        .dsc_disable = dsc2_disable,
        .dsc_disconnect = dsc2_disconnect,
        .dsc_wait_disconnect_pending_clear = dsc2_wait_disconnect_pending_clear,
+       .dsc_get_single_enc_caps = dsc35_get_single_enc_caps,
 };
 
 /* Macro definitios for REG_SET macros*/
@@ -111,3 +112,31 @@ void dsc35_set_fgcg(struct dcn20_dsc *dsc20, bool enable)
 {
        REG_UPDATE(DSC_TOP_CONTROL, DSC_FGCG_REP_DIS, !enable);
 }
+
+void dsc35_get_single_enc_caps(struct dsc_enc_caps *dsc_enc_caps, unsigned int 
max_dscclk_khz)
+{
+       dsc_enc_caps->dsc_version = 0x21; /* v1.2 - DP spec defined it in 
reverse order and we kept it */
+
+       dsc_enc_caps->slice_caps.bits.NUM_SLICES_1 = 1;
+       dsc_enc_caps->slice_caps.bits.NUM_SLICES_2 = 1;
+       dsc_enc_caps->slice_caps.bits.NUM_SLICES_3 = 1;
+       dsc_enc_caps->slice_caps.bits.NUM_SLICES_4 = 1;
+
+       dsc_enc_caps->lb_bit_depth = 13;
+       dsc_enc_caps->is_block_pred_supported = true;
+
+       dsc_enc_caps->color_formats.bits.RGB = 1;
+       dsc_enc_caps->color_formats.bits.YCBCR_444 = 1;
+       dsc_enc_caps->color_formats.bits.YCBCR_SIMPLE_422 = 1;
+       dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_422 = 0;
+       dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_420 = 1;
+
+       dsc_enc_caps->color_depth.bits.COLOR_DEPTH_8_BPC = 1;
+       dsc_enc_caps->color_depth.bits.COLOR_DEPTH_10_BPC = 1;
+       dsc_enc_caps->color_depth.bits.COLOR_DEPTH_12_BPC = 1;
+
+       dsc_enc_caps->max_total_throughput_mps = max_dscclk_khz * 3 / 1000;
+
+       dsc_enc_caps->max_slice_width = 5184; /* (including 64 overlap pixels 
for eDP MSO mode) */
+       dsc_enc_caps->bpp_increment_div = 16; /* 1/16th of a bit */
+}
-- 
2.43.0

Reply via email to