Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/display: refactor DSC cap calculation for dcn35

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 <nicholas.kazlauskas@amd.com>
Reviewed-by: Charlene Liu <charlene.liu@amd.com>
Reviewed-by: Wenjing Liu <wenjing.liu@amd.com>
Signed-off-by: Mohit Bawa <Mohit.Bawa@amd.com>
Signed-off-by: Fangzhi Zuo <jerry.zuo@amd.com>
Tested-by: Dan Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Mohit Bawa and committed by
Alex Deucher
d7ef56db 3953a7ba

+60 -1
+30
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn35/dcn35_clk_mgr.c
··· 1295 1295 dcn35_update_clocks_update_dtb_dto(clk_mgr_int, context, clk_mgr->clks.ref_dtbclk_khz); 1296 1296 } 1297 1297 1298 + static unsigned int dcn35_get_max_clock_khz(struct clk_mgr *clk_mgr_base, enum clk_type clk_type) 1299 + { 1300 + struct clk_mgr_internal *clk_mgr = TO_CLK_MGR_INTERNAL(clk_mgr_base); 1301 + 1302 + unsigned int num_clk_levels; 1303 + 1304 + switch (clk_type) { 1305 + case CLK_TYPE_DISPCLK: 1306 + num_clk_levels = clk_mgr->base.bw_params->clk_table.num_entries_per_clk.num_dispclk_levels; 1307 + return num_clk_levels ? 1308 + clk_mgr->base.bw_params->clk_table.entries[num_clk_levels - 1].dispclk_mhz * 1000 : 1309 + clk_mgr->base.boot_snapshot.dispclk; 1310 + case CLK_TYPE_DPPCLK: 1311 + num_clk_levels = clk_mgr->base.bw_params->clk_table.num_entries_per_clk.num_dppclk_levels; 1312 + return num_clk_levels ? 1313 + clk_mgr->base.bw_params->clk_table.entries[num_clk_levels - 1].dppclk_mhz * 1000 : 1314 + clk_mgr->base.boot_snapshot.dppclk; 1315 + case CLK_TYPE_DSCCLK: 1316 + num_clk_levels = clk_mgr->base.bw_params->clk_table.num_entries_per_clk.num_dispclk_levels; 1317 + return num_clk_levels ? 1318 + clk_mgr->base.bw_params->clk_table.entries[num_clk_levels - 1].dispclk_mhz * 1000 / 3 : 1319 + clk_mgr->base.boot_snapshot.dispclk / 3; 1320 + default: 1321 + break; 1322 + } 1323 + 1324 + return 0; 1325 + } 1326 + 1298 1327 static struct clk_mgr_funcs dcn35_funcs = { 1299 1328 .get_dp_ref_clk_frequency = dce12_get_dp_ref_freq_khz, 1300 1329 .get_dtb_ref_clk_frequency = dcn31_get_dtb_ref_freq_khz, ··· 1335 1306 .set_low_power_state = dcn35_set_low_power_state, 1336 1307 .exit_low_power_state = dcn35_exit_low_power_state, 1337 1308 .is_ips_supported = dcn35_is_ips_supported, 1309 + .get_max_clock_khz = dcn35_get_max_clock_khz, 1338 1310 }; 1339 1311 1340 1312 struct clk_mgr_funcs dcn35_fpga_funcs = {
+30 -1
drivers/gpu/drm/amd/display/dc/dsc/dcn35/dcn35_dsc.c
··· 28 28 #include "reg_helper.h" 29 29 30 30 static void dsc35_enable(struct display_stream_compressor *dsc, int opp_pipe); 31 + static void dsc35_get_single_enc_caps(struct dsc_enc_caps *dsc_enc_caps, unsigned int max_dscclk_khz); 31 32 32 33 static const struct dsc_funcs dcn35_dsc_funcs = { 33 - .dsc_get_enc_caps = dsc2_get_enc_caps, 34 34 .dsc_read_state = dsc2_read_state, 35 35 .dsc_read_reg_state = dsc2_read_reg_state, 36 36 .dsc_validate_stream = dsc2_validate_stream, ··· 40 40 .dsc_disable = dsc2_disable, 41 41 .dsc_disconnect = dsc2_disconnect, 42 42 .dsc_wait_disconnect_pending_clear = dsc2_wait_disconnect_pending_clear, 43 + .dsc_get_single_enc_caps = dsc35_get_single_enc_caps, 43 44 }; 44 45 45 46 /* Macro definitios for REG_SET macros*/ ··· 111 110 void dsc35_set_fgcg(struct dcn20_dsc *dsc20, bool enable) 112 111 { 113 112 REG_UPDATE(DSC_TOP_CONTROL, DSC_FGCG_REP_DIS, !enable); 113 + } 114 + 115 + void dsc35_get_single_enc_caps(struct dsc_enc_caps *dsc_enc_caps, unsigned int max_dscclk_khz) 116 + { 117 + dsc_enc_caps->dsc_version = 0x21; /* v1.2 - DP spec defined it in reverse order and we kept it */ 118 + 119 + dsc_enc_caps->slice_caps.bits.NUM_SLICES_1 = 1; 120 + dsc_enc_caps->slice_caps.bits.NUM_SLICES_2 = 1; 121 + dsc_enc_caps->slice_caps.bits.NUM_SLICES_3 = 1; 122 + dsc_enc_caps->slice_caps.bits.NUM_SLICES_4 = 1; 123 + 124 + dsc_enc_caps->lb_bit_depth = 13; 125 + dsc_enc_caps->is_block_pred_supported = true; 126 + 127 + dsc_enc_caps->color_formats.bits.RGB = 1; 128 + dsc_enc_caps->color_formats.bits.YCBCR_444 = 1; 129 + dsc_enc_caps->color_formats.bits.YCBCR_SIMPLE_422 = 1; 130 + dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_422 = 0; 131 + dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_420 = 1; 132 + 133 + dsc_enc_caps->color_depth.bits.COLOR_DEPTH_8_BPC = 1; 134 + dsc_enc_caps->color_depth.bits.COLOR_DEPTH_10_BPC = 1; 135 + dsc_enc_caps->color_depth.bits.COLOR_DEPTH_12_BPC = 1; 136 + 137 + dsc_enc_caps->max_total_throughput_mps = max_dscclk_khz * 3 / 1000; 138 + 139 + dsc_enc_caps->max_slice_width = 5184; /* (including 64 overlap pixels for eDP MSO mode) */ 140 + dsc_enc_caps->bpp_increment_div = 16; /* 1/16th of a bit */ 114 141 }