Commit 43c78873 authored by Jun Lei's avatar Jun Lei Committed by Alex Deucher

drm/amd/display: implement support for DID2.0 dsc passthrough

[Why]
Some panels contain active converters (e.g. DP to MIPI) which only support
restricted DSC configurations.  DID2.0 adds support for such displays to
explicitly define per timing BPP restrictions on DSC.  Ignoring these
restrictions leads to blackscreen.

[How]
Add parsing in DID2.0 parser to get this bpp info.
Add support in DSC module to constraint target bpp based
on this info.
Signed-off-by: default avatarJun Lei <jun.lei@amd.com>
Reviewed-by: default avatarWenjing Liu <Wenjing.Liu@amd.com>
Acked-by: default avatarAnson Jacob <Anson.Jacob@amd.com>
Tested-by: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 30164a16
...@@ -51,6 +51,7 @@ struct dc_dsc_policy { ...@@ -51,6 +51,7 @@ struct dc_dsc_policy {
int min_slice_height; // Must not be less than 8 int min_slice_height; // Must not be less than 8
uint32_t max_target_bpp; uint32_t max_target_bpp;
uint32_t min_target_bpp; uint32_t min_target_bpp;
uint32_t preferred_bpp_x16;
bool enable_dsc_when_not_needed; bool enable_dsc_when_not_needed;
}; };
...@@ -62,8 +63,8 @@ bool dc_dsc_parse_dsc_dpcd(const struct dc *dc, ...@@ -62,8 +63,8 @@ bool dc_dsc_parse_dsc_dpcd(const struct dc *dc,
bool dc_dsc_compute_bandwidth_range( bool dc_dsc_compute_bandwidth_range(
const struct display_stream_compressor *dsc, const struct display_stream_compressor *dsc,
uint32_t dsc_min_slice_height_override, uint32_t dsc_min_slice_height_override,
uint32_t min_bpp, uint32_t min_bpp_x16,
uint32_t max_bpp, uint32_t max_bpp_x16,
const struct dsc_dec_dpcd_caps *dsc_sink_caps, const struct dsc_dec_dpcd_caps *dsc_sink_caps,
const struct dc_crtc_timing *timing, const struct dc_crtc_timing *timing,
struct dc_dsc_bw_range *range); struct dc_dsc_bw_range *range);
...@@ -78,7 +79,7 @@ bool dc_dsc_compute_config( ...@@ -78,7 +79,7 @@ bool dc_dsc_compute_config(
struct dc_dsc_config *dsc_cfg); struct dc_dsc_config *dsc_cfg);
void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing,
uint32_t max_target_bpp_limit_override, uint32_t max_target_bpp_limit_override_x16,
struct dc_dsc_policy *policy); struct dc_dsc_policy *policy);
void dc_dsc_policy_set_max_target_bpp_limit(uint32_t limit); void dc_dsc_policy_set_max_target_bpp_limit(uint32_t limit);
......
...@@ -769,6 +769,7 @@ struct dc_crtc_timing { ...@@ -769,6 +769,7 @@ struct dc_crtc_timing {
#endif #endif
struct dc_crtc_timing_flags flags; struct dc_crtc_timing_flags flags;
uint32_t dsc_fixed_bits_per_pixel_x16; /* DSC target bitrate in 1/16 of bpp (e.g. 128 -> 8bpp) */
struct dc_dsc_config dsc_cfg; struct dc_dsc_config dsc_cfg;
}; };
......
...@@ -369,6 +369,11 @@ static bool decide_dsc_target_bpp_x16( ...@@ -369,6 +369,11 @@ static bool decide_dsc_target_bpp_x16(
/* enough bandwidth without dsc */ /* enough bandwidth without dsc */
*target_bpp_x16 = 0; *target_bpp_x16 = 0;
should_use_dsc = false; should_use_dsc = false;
} else if (policy->preferred_bpp_x16 > 0 &&
policy->preferred_bpp_x16 <= range.max_target_bpp_x16 &&
policy->preferred_bpp_x16 >= range.min_target_bpp_x16) {
*target_bpp_x16 = policy->preferred_bpp_x16;
should_use_dsc = true;
} else if (target_bandwidth_kbps >= range.max_kbps) { } else if (target_bandwidth_kbps >= range.max_kbps) {
/* use max target bpp allowed */ /* use max target bpp allowed */
*target_bpp_x16 = range.max_target_bpp_x16; *target_bpp_x16 = range.max_target_bpp_x16;
...@@ -545,7 +550,7 @@ static bool setup_dsc_config( ...@@ -545,7 +550,7 @@ static bool setup_dsc_config(
int target_bandwidth_kbps, int target_bandwidth_kbps,
const struct dc_crtc_timing *timing, const struct dc_crtc_timing *timing,
int min_slice_height_override, int min_slice_height_override,
int max_dsc_target_bpp_limit_override, int max_dsc_target_bpp_limit_override_x16,
struct dc_dsc_config *dsc_cfg) struct dc_dsc_config *dsc_cfg)
{ {
struct dsc_enc_caps dsc_common_caps; struct dsc_enc_caps dsc_common_caps;
...@@ -564,7 +569,7 @@ static bool setup_dsc_config( ...@@ -564,7 +569,7 @@ static bool setup_dsc_config(
memset(dsc_cfg, 0, sizeof(struct dc_dsc_config)); memset(dsc_cfg, 0, sizeof(struct dc_dsc_config));
dc_dsc_get_policy_for_timing(timing, max_dsc_target_bpp_limit_override, &policy); dc_dsc_get_policy_for_timing(timing, max_dsc_target_bpp_limit_override_x16, &policy);
pic_width = timing->h_addressable + timing->h_border_left + timing->h_border_right; pic_width = timing->h_addressable + timing->h_border_left + timing->h_border_right;
pic_height = timing->v_addressable + timing->v_border_top + timing->v_border_bottom; pic_height = timing->v_addressable + timing->v_border_top + timing->v_border_bottom;
...@@ -865,8 +870,8 @@ bool dc_dsc_parse_dsc_dpcd(const struct dc *dc, const uint8_t *dpcd_dsc_basic_da ...@@ -865,8 +870,8 @@ bool dc_dsc_parse_dsc_dpcd(const struct dc *dc, const uint8_t *dpcd_dsc_basic_da
bool dc_dsc_compute_bandwidth_range( bool dc_dsc_compute_bandwidth_range(
const struct display_stream_compressor *dsc, const struct display_stream_compressor *dsc,
uint32_t dsc_min_slice_height_override, uint32_t dsc_min_slice_height_override,
uint32_t min_bpp, uint32_t min_bpp_x16,
uint32_t max_bpp, uint32_t max_bpp_x16,
const struct dsc_dec_dpcd_caps *dsc_sink_caps, const struct dsc_dec_dpcd_caps *dsc_sink_caps,
const struct dc_crtc_timing *timing, const struct dc_crtc_timing *timing,
struct dc_dsc_bw_range *range) struct dc_dsc_bw_range *range)
...@@ -883,10 +888,10 @@ bool dc_dsc_compute_bandwidth_range( ...@@ -883,10 +888,10 @@ bool dc_dsc_compute_bandwidth_range(
if (is_dsc_possible) if (is_dsc_possible)
is_dsc_possible = setup_dsc_config(dsc_sink_caps, &dsc_enc_caps, 0, timing, is_dsc_possible = setup_dsc_config(dsc_sink_caps, &dsc_enc_caps, 0, timing,
dsc_min_slice_height_override, max_bpp, &config); dsc_min_slice_height_override, max_bpp_x16, &config);
if (is_dsc_possible) if (is_dsc_possible)
get_dsc_bandwidth_range(min_bpp, max_bpp, &dsc_common_caps, timing, range); get_dsc_bandwidth_range(min_bpp_x16, max_bpp_x16, &dsc_common_caps, timing, range);
return is_dsc_possible; return is_dsc_possible;
} }
...@@ -895,7 +900,7 @@ bool dc_dsc_compute_config( ...@@ -895,7 +900,7 @@ bool dc_dsc_compute_config(
const struct display_stream_compressor *dsc, const struct display_stream_compressor *dsc,
const struct dsc_dec_dpcd_caps *dsc_sink_caps, const struct dsc_dec_dpcd_caps *dsc_sink_caps,
uint32_t dsc_min_slice_height_override, uint32_t dsc_min_slice_height_override,
uint32_t max_target_bpp_limit_override, uint32_t max_target_bpp_limit_override_x16,
uint32_t target_bandwidth_kbps, uint32_t target_bandwidth_kbps,
const struct dc_crtc_timing *timing, const struct dc_crtc_timing *timing,
struct dc_dsc_config *dsc_cfg) struct dc_dsc_config *dsc_cfg)
...@@ -908,11 +913,11 @@ bool dc_dsc_compute_config( ...@@ -908,11 +913,11 @@ bool dc_dsc_compute_config(
&dsc_enc_caps, &dsc_enc_caps,
target_bandwidth_kbps, target_bandwidth_kbps,
timing, dsc_min_slice_height_override, timing, dsc_min_slice_height_override,
max_target_bpp_limit_override, dsc_cfg); max_target_bpp_limit_override_x16, dsc_cfg);
return is_dsc_possible; return is_dsc_possible;
} }
void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, uint32_t max_target_bpp_limit_override, struct dc_dsc_policy *policy) void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, uint32_t max_target_bpp_limit_override_x16, struct dc_dsc_policy *policy)
{ {
uint32_t bpc = 0; uint32_t bpc = 0;
...@@ -967,13 +972,15 @@ void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, uint32_t ...@@ -967,13 +972,15 @@ void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, uint32_t
return; return;
} }
policy->preferred_bpp_x16 = timing->dsc_fixed_bits_per_pixel_x16;
/* internal upper limit, default 16 bpp */ /* internal upper limit, default 16 bpp */
if (policy->max_target_bpp > dsc_policy_max_target_bpp_limit) if (policy->max_target_bpp > dsc_policy_max_target_bpp_limit)
policy->max_target_bpp = dsc_policy_max_target_bpp_limit; policy->max_target_bpp = dsc_policy_max_target_bpp_limit;
/* apply override */ /* apply override */
if (max_target_bpp_limit_override && policy->max_target_bpp > max_target_bpp_limit_override) if (max_target_bpp_limit_override_x16 && policy->max_target_bpp > max_target_bpp_limit_override_x16 / 16)
policy->max_target_bpp = max_target_bpp_limit_override; 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) if (dsc_policy_enable_dsc_when_not_needed)
......
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