Commit f588da30 authored by Ryan Seto's avatar Ryan Seto Committed by Alex Deucher

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: default avatarWenjing Liu <wenjing.liu@amd.com>
Signed-off-by: default avatarRyan Seto <ryanseto@amd.com>
Signed-off-by: default avatarAlex Hung <alex.hung@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent c2ed7002
...@@ -969,6 +969,14 @@ union dp_sink_video_fallback_formats { ...@@ -969,6 +969,14 @@ union dp_sink_video_fallback_formats {
uint8_t raw; uint8_t raw;
}; };
union dpcd_max_uncompressed_pixel_rate_cap {
struct {
uint16_t max_uncompressed_pixel_rate_cap :15;
uint16_t valid :1;
} bits;
uint8_t raw[2];
};
union dp_fec_capability1 { union dp_fec_capability1 {
struct { struct {
uint8_t AGGREGATED_ERROR_COUNTERS_CAPABLE :1; uint8_t AGGREGATED_ERROR_COUNTERS_CAPABLE :1;
...@@ -1170,6 +1178,7 @@ struct dpcd_caps { ...@@ -1170,6 +1178,7 @@ struct dpcd_caps {
struct dc_lttpr_caps lttpr_caps; struct dc_lttpr_caps lttpr_caps;
struct adaptive_sync_caps adaptive_sync_caps; struct adaptive_sync_caps adaptive_sync_caps;
struct dpcd_usb4_dp_tunneling_info usb4_dp_tun_info; struct dpcd_usb4_dp_tunneling_info usb4_dp_tun_info;
union dpcd_max_uncompressed_pixel_rate_cap max_uncompressed_pixel_rate_cap;
union dp_128b_132b_supported_link_rates dp_128b_132b_supported_link_rates; union dp_128b_132b_supported_link_rates dp_128b_132b_supported_link_rates;
union dp_main_line_channel_coding_cap channel_coding_cap; union dp_main_line_channel_coding_cap channel_coding_cap;
...@@ -1340,6 +1349,9 @@ struct dp_trace { ...@@ -1340,6 +1349,9 @@ struct dp_trace {
#ifndef DP_CABLE_ATTRIBUTES_UPDATED_BY_DPTX #ifndef DP_CABLE_ATTRIBUTES_UPDATED_BY_DPTX
#define DP_CABLE_ATTRIBUTES_UPDATED_BY_DPTX 0x110 #define DP_CABLE_ATTRIBUTES_UPDATED_BY_DPTX 0x110
#endif #endif
#ifndef DPCD_MAX_UNCOMPRESSED_PIXEL_RATE_CAP
#define DPCD_MAX_UNCOMPRESSED_PIXEL_RATE_CAP 0x221c
#endif
#ifndef DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE #ifndef DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE
#define DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE 0x50 #define DP_REPEATER_CONFIGURATION_AND_STATUS_SIZE 0x50
#endif #endif
......
...@@ -59,6 +59,7 @@ struct dc_dsc_config_options { ...@@ -59,6 +59,7 @@ struct dc_dsc_config_options {
uint32_t max_target_bpp_limit_override_x16; uint32_t max_target_bpp_limit_override_x16;
uint32_t slice_height_granularity; uint32_t slice_height_granularity;
uint32_t dsc_force_odm_hslice_override; uint32_t dsc_force_odm_hslice_override;
bool force_dsc_when_not_needed;
}; };
bool dc_dsc_parse_dsc_dpcd(const struct dc *dc, bool dc_dsc_parse_dsc_dpcd(const struct dc *dc,
......
...@@ -668,6 +668,7 @@ static bool decide_dsc_bandwidth_range( ...@@ -668,6 +668,7 @@ static bool decide_dsc_bandwidth_range(
*/ */
static bool decide_dsc_target_bpp_x16( static bool decide_dsc_target_bpp_x16(
const struct dc_dsc_policy *policy, const struct dc_dsc_policy *policy,
const struct dc_dsc_config_options *options,
const struct dsc_enc_caps *dsc_common_caps, const struct dsc_enc_caps *dsc_common_caps,
const int target_bandwidth_kbps, const int target_bandwidth_kbps,
const struct dc_crtc_timing *timing, const struct dc_crtc_timing *timing,
...@@ -682,7 +683,7 @@ static bool decide_dsc_target_bpp_x16( ...@@ -682,7 +683,7 @@ static bool decide_dsc_target_bpp_x16(
if (decide_dsc_bandwidth_range(policy->min_target_bpp * 16, policy->max_target_bpp * 16, if (decide_dsc_bandwidth_range(policy->min_target_bpp * 16, policy->max_target_bpp * 16,
num_slices_h, dsc_common_caps, timing, link_encoding, &range)) { num_slices_h, dsc_common_caps, timing, link_encoding, &range)) {
if (target_bandwidth_kbps >= range.stream_kbps) { if (target_bandwidth_kbps >= range.stream_kbps) {
if (policy->enable_dsc_when_not_needed) if (policy->enable_dsc_when_not_needed || options->force_dsc_when_not_needed)
/* enable max bpp even dsc is not needed */ /* enable max bpp even dsc is not needed */
*target_bpp_x16 = range.max_target_bpp_x16; *target_bpp_x16 = range.max_target_bpp_x16;
} else if (target_bandwidth_kbps >= range.max_kbps) { } else if (target_bandwidth_kbps >= range.max_kbps) {
...@@ -1080,6 +1081,7 @@ static bool setup_dsc_config( ...@@ -1080,6 +1081,7 @@ static bool setup_dsc_config(
if (target_bandwidth_kbps > 0) { if (target_bandwidth_kbps > 0) {
is_dsc_possible = decide_dsc_target_bpp_x16( is_dsc_possible = decide_dsc_target_bpp_x16(
&policy, &policy,
options,
&dsc_common_caps, &dsc_common_caps,
target_bandwidth_kbps, target_bandwidth_kbps,
timing, timing,
...@@ -1235,10 +1237,7 @@ void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, ...@@ -1235,10 +1237,7 @@ void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing,
policy->max_target_bpp = max_target_bpp_limit_override_x16 / 16; policy->max_target_bpp = max_target_bpp_limit_override_x16 / 16;
/* enable DSC when not needed, default false */ /* enable DSC when not needed, default false */
if (dsc_policy_enable_dsc_when_not_needed)
policy->enable_dsc_when_not_needed = dsc_policy_enable_dsc_when_not_needed; policy->enable_dsc_when_not_needed = dsc_policy_enable_dsc_when_not_needed;
else
policy->enable_dsc_when_not_needed = false;
} }
void dc_dsc_policy_set_max_target_bpp_limit(uint32_t limit) void dc_dsc_policy_set_max_target_bpp_limit(uint32_t limit)
...@@ -1267,4 +1266,5 @@ void dc_dsc_get_default_config_option(const struct dc *dc, struct dc_dsc_config_ ...@@ -1267,4 +1266,5 @@ void dc_dsc_get_default_config_option(const struct dc *dc, struct dc_dsc_config_
options->dsc_force_odm_hslice_override = dc->debug.force_odm_combine; options->dsc_force_odm_hslice_override = dc->debug.force_odm_combine;
options->max_target_bpp_limit_override_x16 = 0; options->max_target_bpp_limit_override_x16 = 0;
options->slice_height_granularity = 1; options->slice_height_granularity = 1;
options->force_dsc_when_not_needed = false;
} }
...@@ -287,6 +287,13 @@ static bool dp_validate_mode_timing( ...@@ -287,6 +287,13 @@ static bool dp_validate_mode_timing(
req_bw = dc_bandwidth_in_kbps_from_timing(timing, dc_link_get_highest_encoding_format(link)); req_bw = dc_bandwidth_in_kbps_from_timing(timing, dc_link_get_highest_encoding_format(link));
max_bw = dp_link_bandwidth_kbps(link, link_setting); max_bw = dp_link_bandwidth_kbps(link, link_setting);
bool is_max_uncompressed_pixel_rate_exceeded = link->dpcd_caps.max_uncompressed_pixel_rate_cap.bits.valid &&
timing->pix_clk_100hz > link->dpcd_caps.max_uncompressed_pixel_rate_cap.bits.max_uncompressed_pixel_rate_cap * 10000;
if (is_max_uncompressed_pixel_rate_exceeded && !timing->flags.DSC) {
return false;
}
if (req_bw <= max_bw) { if (req_bw <= max_bw) {
/* remember the biggest mode here, during /* remember the biggest mode here, during
* initial link training (to get * initial link training (to get
......
...@@ -1942,6 +1942,11 @@ static bool retrieve_link_cap(struct dc_link *link) ...@@ -1942,6 +1942,11 @@ static bool retrieve_link_cap(struct dc_link *link)
DC_LOG_DP2("\tFEC aggregated error counters are supported"); DC_LOG_DP2("\tFEC aggregated error counters are supported");
} }
core_link_read_dpcd(link,
DPCD_MAX_UNCOMPRESSED_PIXEL_RATE_CAP,
link->dpcd_caps.max_uncompressed_pixel_rate_cap.raw,
sizeof(link->dpcd_caps.max_uncompressed_pixel_rate_cap.raw));
retrieve_cable_id(link); retrieve_cable_id(link);
dpcd_write_cable_id_to_dprx(link); dpcd_write_cable_id_to_dprx(link);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment