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

drm/amd/display: Implement new DPCD register handling

[WHY]
There are some monitor timings that seem to be supported without
DSC but actually require DSC to be displayed. A VESA SCR introduced
a new max uncompressed pixel rate cap register that we can use to
handle these edge cases.

[HOW]
SST: Read caps from link and invalidate timings that exceed the
max limit but do not support DSC. Then check for options override
when determining BPP.

MST: Read caps from virtual DPCD peer device or daisy chained SST
monitor and set validation set BPPs to max if pixel rate exceeds
uncompressed limit. Validation set optimization continues as normal.

Reviewed-by: Wenjing Liu <wenjing.liu@amd.com>
Signed-off-by: Ryan Seto <ryanseto@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>

authored by

Ryan Seto and committed by
Alex Deucher
f588da30 c2ed7002

+30 -5
+12
drivers/gpu/drm/amd/display/dc/dc_dp_types.h
··· 969 969 uint8_t raw; 970 970 }; 971 971 972 + union dpcd_max_uncompressed_pixel_rate_cap { 973 + struct { 974 + uint16_t max_uncompressed_pixel_rate_cap :15; 975 + uint16_t valid :1; 976 + } bits; 977 + uint8_t raw[2]; 978 + }; 979 + 972 980 union dp_fec_capability1 { 973 981 struct { 974 982 uint8_t AGGREGATED_ERROR_COUNTERS_CAPABLE :1; ··· 1178 1170 struct dc_lttpr_caps lttpr_caps; 1179 1171 struct adaptive_sync_caps adaptive_sync_caps; 1180 1172 struct dpcd_usb4_dp_tunneling_info usb4_dp_tun_info; 1173 + union dpcd_max_uncompressed_pixel_rate_cap max_uncompressed_pixel_rate_cap; 1181 1174 1182 1175 union dp_128b_132b_supported_link_rates dp_128b_132b_supported_link_rates; 1183 1176 union dp_main_line_channel_coding_cap channel_coding_cap; ··· 1348 1339 #endif 1349 1340 #ifndef DP_CABLE_ATTRIBUTES_UPDATED_BY_DPTX 1350 1341 #define DP_CABLE_ATTRIBUTES_UPDATED_BY_DPTX 0x110 1342 + #endif 1343 + #ifndef DPCD_MAX_UNCOMPRESSED_PIXEL_RATE_CAP 1344 + #define DPCD_MAX_UNCOMPRESSED_PIXEL_RATE_CAP 0x221c 1351 1345 #endif 1352 1346 #ifndef DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE 1353 1347 #define DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE 0x50
+1
drivers/gpu/drm/amd/display/dc/dc_dsc.h
··· 59 59 uint32_t max_target_bpp_limit_override_x16; 60 60 uint32_t slice_height_granularity; 61 61 uint32_t dsc_force_odm_hslice_override; 62 + bool force_dsc_when_not_needed; 62 63 }; 63 64 64 65 bool dc_dsc_parse_dsc_dpcd(const struct dc *dc,
+5 -5
drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
··· 668 668 */ 669 669 static bool decide_dsc_target_bpp_x16( 670 670 const struct dc_dsc_policy *policy, 671 + const struct dc_dsc_config_options *options, 671 672 const struct dsc_enc_caps *dsc_common_caps, 672 673 const int target_bandwidth_kbps, 673 674 const struct dc_crtc_timing *timing, ··· 683 682 if (decide_dsc_bandwidth_range(policy->min_target_bpp * 16, policy->max_target_bpp * 16, 684 683 num_slices_h, dsc_common_caps, timing, link_encoding, &range)) { 685 684 if (target_bandwidth_kbps >= range.stream_kbps) { 686 - if (policy->enable_dsc_when_not_needed) 685 + if (policy->enable_dsc_when_not_needed || options->force_dsc_when_not_needed) 687 686 /* enable max bpp even dsc is not needed */ 688 687 *target_bpp_x16 = range.max_target_bpp_x16; 689 688 } else if (target_bandwidth_kbps >= range.max_kbps) { ··· 1081 1080 if (target_bandwidth_kbps > 0) { 1082 1081 is_dsc_possible = decide_dsc_target_bpp_x16( 1083 1082 &policy, 1083 + options, 1084 1084 &dsc_common_caps, 1085 1085 target_bandwidth_kbps, 1086 1086 timing, ··· 1237 1235 policy->max_target_bpp = max_target_bpp_limit_override_x16 / 16; 1238 1236 1239 1237 /* enable DSC when not needed, default false */ 1240 - if (dsc_policy_enable_dsc_when_not_needed) 1241 - policy->enable_dsc_when_not_needed = dsc_policy_enable_dsc_when_not_needed; 1242 - else 1243 - policy->enable_dsc_when_not_needed = false; 1238 + policy->enable_dsc_when_not_needed = dsc_policy_enable_dsc_when_not_needed; 1244 1239 } 1245 1240 1246 1241 void dc_dsc_policy_set_max_target_bpp_limit(uint32_t limit) ··· 1266 1267 options->dsc_force_odm_hslice_override = dc->debug.force_odm_combine; 1267 1268 options->max_target_bpp_limit_override_x16 = 0; 1268 1269 options->slice_height_granularity = 1; 1270 + options->force_dsc_when_not_needed = false; 1269 1271 }