drm/amd/display: add dsc stream overhead for dp only
[why] Based on hardware team recommendation this additional dsc overhead is only required for DP DSC. [how] Add a check for is_dp and only apply the overhead if this flag is set. Signed-off-by: Wenjing Liu <wenjing.liu@amd.com> Reviewed-by: Chris Park <Chris.Park@amd.com> Acked-by: Wayne Lin <Wayne.Lin@amd.com> Tested-by: Daniel Wheeler <daniel.wheeler@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
committed by
Alex Deucher
parent
cf8b92a756
commit
df0a271cc7
@@ -3489,7 +3489,8 @@ uint32_t dc_bandwidth_in_kbps_from_timing(
|
|||||||
if (timing->flags.DSC)
|
if (timing->flags.DSC)
|
||||||
return dc_dsc_stream_bandwidth_in_kbps(timing,
|
return dc_dsc_stream_bandwidth_in_kbps(timing,
|
||||||
timing->dsc_cfg.bits_per_pixel,
|
timing->dsc_cfg.bits_per_pixel,
|
||||||
timing->dsc_cfg.num_slices_h);
|
timing->dsc_cfg.num_slices_h,
|
||||||
|
timing->dsc_cfg.is_dp);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch (timing->display_color_depth) {
|
switch (timing->display_color_depth) {
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ bool dc_dsc_compute_config(
|
|||||||
struct dc_dsc_config *dsc_cfg);
|
struct dc_dsc_config *dsc_cfg);
|
||||||
|
|
||||||
uint32_t dc_dsc_stream_bandwidth_in_kbps(const struct dc_crtc_timing *timing,
|
uint32_t dc_dsc_stream_bandwidth_in_kbps(const struct dc_crtc_timing *timing,
|
||||||
uint32_t bpp_x16, uint32_t num_slices_h);
|
uint32_t bpp_x16, uint32_t num_slices_h, bool is_dp);
|
||||||
|
|
||||||
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_x16,
|
uint32_t max_target_bpp_limit_override_x16,
|
||||||
@@ -89,4 +89,6 @@ void dc_dsc_policy_set_max_target_bpp_limit(uint32_t limit);
|
|||||||
|
|
||||||
void dc_dsc_policy_set_enable_dsc_when_not_needed(bool enable);
|
void dc_dsc_policy_set_enable_dsc_when_not_needed(bool enable);
|
||||||
|
|
||||||
|
void dc_dsc_policy_set_disable_dsc_stream_overhead(bool disable);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -739,6 +739,7 @@ struct dc_dsc_config {
|
|||||||
uint32_t version_minor; /* DSC minor version. Full version is formed as 1.version_minor. */
|
uint32_t version_minor; /* DSC minor version. Full version is formed as 1.version_minor. */
|
||||||
bool ycbcr422_simple; /* Tell DSC engine to convert YCbCr 4:2:2 to 'YCbCr 4:2:2 simple'. */
|
bool ycbcr422_simple; /* Tell DSC engine to convert YCbCr 4:2:2 to 'YCbCr 4:2:2 simple'. */
|
||||||
int32_t rc_buffer_size; /* DSC RC buffer block size in bytes */
|
int32_t rc_buffer_size; /* DSC RC buffer block size in bytes */
|
||||||
|
bool is_dp; /* indicate if DSC is applied based on DP's capability */
|
||||||
};
|
};
|
||||||
struct dc_crtc_timing {
|
struct dc_crtc_timing {
|
||||||
uint32_t h_total;
|
uint32_t h_total;
|
||||||
|
|||||||
@@ -909,6 +909,7 @@ struct dsc_dec_dpcd_caps {
|
|||||||
uint32_t branch_overall_throughput_0_mps; /* In MPs */
|
uint32_t branch_overall_throughput_0_mps; /* In MPs */
|
||||||
uint32_t branch_overall_throughput_1_mps; /* In MPs */
|
uint32_t branch_overall_throughput_1_mps; /* In MPs */
|
||||||
uint32_t branch_max_line_width;
|
uint32_t branch_max_line_width;
|
||||||
|
bool is_dp;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dc_golden_table {
|
struct dc_golden_table {
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ static uint32_t dsc_policy_max_target_bpp_limit = 16;
|
|||||||
/* default DSC policy enables DSC only when needed */
|
/* default DSC policy enables DSC only when needed */
|
||||||
static bool dsc_policy_enable_dsc_when_not_needed;
|
static bool dsc_policy_enable_dsc_when_not_needed;
|
||||||
|
|
||||||
|
static bool dsc_policy_disable_dsc_stream_overhead;
|
||||||
|
|
||||||
static bool dsc_buff_block_size_from_dpcd(int dpcd_buff_block_size, int *buff_block_size)
|
static bool dsc_buff_block_size_from_dpcd(int dpcd_buff_block_size, int *buff_block_size)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -250,6 +252,7 @@ static bool intersect_dsc_caps(
|
|||||||
if (pixel_encoding == PIXEL_ENCODING_YCBCR422 || pixel_encoding == PIXEL_ENCODING_YCBCR420)
|
if (pixel_encoding == PIXEL_ENCODING_YCBCR422 || pixel_encoding == PIXEL_ENCODING_YCBCR420)
|
||||||
dsc_common_caps->bpp_increment_div = min(dsc_common_caps->bpp_increment_div, (uint32_t)8);
|
dsc_common_caps->bpp_increment_div = min(dsc_common_caps->bpp_increment_div, (uint32_t)8);
|
||||||
|
|
||||||
|
dsc_common_caps->is_dp = dsc_sink_caps->is_dp;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,11 +263,15 @@ static inline uint32_t dsc_div_by_10_round_up(uint32_t value)
|
|||||||
|
|
||||||
static struct fixed31_32 compute_dsc_max_bandwidth_overhead(
|
static struct fixed31_32 compute_dsc_max_bandwidth_overhead(
|
||||||
const struct dc_crtc_timing *timing,
|
const struct dc_crtc_timing *timing,
|
||||||
const int num_slices_h)
|
const int num_slices_h,
|
||||||
|
const bool is_dp)
|
||||||
{
|
{
|
||||||
struct fixed31_32 max_dsc_overhead;
|
struct fixed31_32 max_dsc_overhead;
|
||||||
struct fixed31_32 refresh_rate;
|
struct fixed31_32 refresh_rate;
|
||||||
|
|
||||||
|
if (dsc_policy_disable_dsc_stream_overhead || !is_dp)
|
||||||
|
return dc_fixpt_from_int(0);
|
||||||
|
|
||||||
/* use target bpp that can take entire target bandwidth */
|
/* use target bpp that can take entire target bandwidth */
|
||||||
refresh_rate = dc_fixpt_from_int(timing->pix_clk_100hz);
|
refresh_rate = dc_fixpt_from_int(timing->pix_clk_100hz);
|
||||||
refresh_rate = dc_fixpt_div_int(refresh_rate, timing->h_total);
|
refresh_rate = dc_fixpt_div_int(refresh_rate, timing->h_total);
|
||||||
@@ -272,7 +279,7 @@ static struct fixed31_32 compute_dsc_max_bandwidth_overhead(
|
|||||||
refresh_rate = dc_fixpt_mul_int(refresh_rate, 100);
|
refresh_rate = dc_fixpt_mul_int(refresh_rate, 100);
|
||||||
|
|
||||||
max_dsc_overhead = dc_fixpt_from_int(num_slices_h);
|
max_dsc_overhead = dc_fixpt_from_int(num_slices_h);
|
||||||
max_dsc_overhead = dc_fixpt_mul_int(max_dsc_overhead, timing->v_addressable);
|
max_dsc_overhead = dc_fixpt_mul_int(max_dsc_overhead, timing->v_total);
|
||||||
max_dsc_overhead = dc_fixpt_mul_int(max_dsc_overhead, 256);
|
max_dsc_overhead = dc_fixpt_mul_int(max_dsc_overhead, 256);
|
||||||
max_dsc_overhead = dc_fixpt_div_int(max_dsc_overhead, 1000);
|
max_dsc_overhead = dc_fixpt_div_int(max_dsc_overhead, 1000);
|
||||||
max_dsc_overhead = dc_fixpt_mul(max_dsc_overhead, refresh_rate);
|
max_dsc_overhead = dc_fixpt_mul(max_dsc_overhead, refresh_rate);
|
||||||
@@ -284,14 +291,15 @@ static uint32_t compute_bpp_x16_from_target_bandwidth(
|
|||||||
const uint32_t bandwidth_in_kbps,
|
const uint32_t bandwidth_in_kbps,
|
||||||
const struct dc_crtc_timing *timing,
|
const struct dc_crtc_timing *timing,
|
||||||
const uint32_t num_slices_h,
|
const uint32_t num_slices_h,
|
||||||
const uint32_t bpp_increment_div)
|
const uint32_t bpp_increment_div,
|
||||||
|
const bool is_dp)
|
||||||
{
|
{
|
||||||
struct fixed31_32 overhead_in_kbps;
|
struct fixed31_32 overhead_in_kbps;
|
||||||
struct fixed31_32 effective_bandwidth_in_kbps;
|
struct fixed31_32 effective_bandwidth_in_kbps;
|
||||||
struct fixed31_32 bpp_x16;
|
struct fixed31_32 bpp_x16;
|
||||||
|
|
||||||
overhead_in_kbps = compute_dsc_max_bandwidth_overhead(
|
overhead_in_kbps = compute_dsc_max_bandwidth_overhead(
|
||||||
timing, num_slices_h);
|
timing, num_slices_h, is_dp);
|
||||||
effective_bandwidth_in_kbps = dc_fixpt_from_int(bandwidth_in_kbps);
|
effective_bandwidth_in_kbps = dc_fixpt_from_int(bandwidth_in_kbps);
|
||||||
effective_bandwidth_in_kbps = dc_fixpt_sub(effective_bandwidth_in_kbps,
|
effective_bandwidth_in_kbps = dc_fixpt_sub(effective_bandwidth_in_kbps,
|
||||||
overhead_in_kbps);
|
overhead_in_kbps);
|
||||||
@@ -319,19 +327,20 @@ static void get_dsc_bandwidth_range(
|
|||||||
|
|
||||||
/* max dsc target bpp */
|
/* max dsc target bpp */
|
||||||
range->max_kbps = dc_dsc_stream_bandwidth_in_kbps(timing,
|
range->max_kbps = dc_dsc_stream_bandwidth_in_kbps(timing,
|
||||||
max_bpp_x16, num_slices_h);
|
max_bpp_x16, num_slices_h, dsc_caps->is_dp);
|
||||||
range->max_target_bpp_x16 = max_bpp_x16;
|
range->max_target_bpp_x16 = max_bpp_x16;
|
||||||
if (range->max_kbps > range->stream_kbps) {
|
if (range->max_kbps > range->stream_kbps) {
|
||||||
/* max dsc target bpp is capped to native bandwidth */
|
/* max dsc target bpp is capped to native bandwidth */
|
||||||
range->max_kbps = range->stream_kbps;
|
range->max_kbps = range->stream_kbps;
|
||||||
range->max_target_bpp_x16 = compute_bpp_x16_from_target_bandwidth(
|
range->max_target_bpp_x16 = compute_bpp_x16_from_target_bandwidth(
|
||||||
range->max_kbps, timing, num_slices_h,
|
range->max_kbps, timing, num_slices_h,
|
||||||
dsc_caps->bpp_increment_div);
|
dsc_caps->bpp_increment_div,
|
||||||
|
dsc_caps->is_dp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* min dsc target bpp */
|
/* min dsc target bpp */
|
||||||
range->min_kbps = dc_dsc_stream_bandwidth_in_kbps(timing,
|
range->min_kbps = dc_dsc_stream_bandwidth_in_kbps(timing,
|
||||||
min_bpp_x16, num_slices_h);
|
min_bpp_x16, num_slices_h, dsc_caps->is_dp);
|
||||||
range->min_target_bpp_x16 = min_bpp_x16;
|
range->min_target_bpp_x16 = min_bpp_x16;
|
||||||
if (range->min_kbps > range->max_kbps) {
|
if (range->min_kbps > range->max_kbps) {
|
||||||
/* min dsc target bpp is capped to max dsc bandwidth*/
|
/* min dsc target bpp is capped to max dsc bandwidth*/
|
||||||
@@ -378,10 +387,9 @@ static bool decide_dsc_target_bpp_x16(
|
|||||||
} else if (target_bandwidth_kbps >= range.min_kbps) {
|
} else if (target_bandwidth_kbps >= range.min_kbps) {
|
||||||
/* use target bpp that can take entire target bandwidth */
|
/* use target bpp that can take entire target bandwidth */
|
||||||
*target_bpp_x16 = compute_bpp_x16_from_target_bandwidth(
|
*target_bpp_x16 = compute_bpp_x16_from_target_bandwidth(
|
||||||
range.max_kbps, timing, num_slices_h,
|
target_bandwidth_kbps, timing, num_slices_h,
|
||||||
dsc_common_caps->bpp_increment_div);
|
dsc_common_caps->bpp_increment_div,
|
||||||
if (*target_bpp_x16 < range.min_kbps)
|
dsc_common_caps->is_dp);
|
||||||
*target_bpp_x16 = range.min_kbps;
|
|
||||||
should_use_dsc = true;
|
should_use_dsc = true;
|
||||||
} else {
|
} else {
|
||||||
/* not enough bandwidth to fulfill minimum requirement */
|
/* not enough bandwidth to fulfill minimum requirement */
|
||||||
@@ -751,6 +759,7 @@ static bool setup_dsc_config(
|
|||||||
dsc_cfg->block_pred_enable = dsc_common_caps.is_block_pred_supported;
|
dsc_cfg->block_pred_enable = dsc_common_caps.is_block_pred_supported;
|
||||||
dsc_cfg->linebuf_depth = dsc_common_caps.lb_bit_depth;
|
dsc_cfg->linebuf_depth = dsc_common_caps.lb_bit_depth;
|
||||||
dsc_cfg->version_minor = (dsc_common_caps.dsc_version & 0xf0) >> 4;
|
dsc_cfg->version_minor = (dsc_common_caps.dsc_version & 0xf0) >> 4;
|
||||||
|
dsc_cfg->is_dp = dsc_sink_caps->is_dp;
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
@@ -861,6 +870,7 @@ bool dc_dsc_parse_dsc_dpcd(const struct dc *dc, const uint8_t *dpcd_dsc_basic_da
|
|||||||
dsc_sink_caps->branch_max_line_width = dpcd_dsc_branch_decoder_caps[DP_DSC_BRANCH_MAX_LINE_WIDTH - DP_DSC_BRANCH_OVERALL_THROUGHPUT_0] * 320;
|
dsc_sink_caps->branch_max_line_width = dpcd_dsc_branch_decoder_caps[DP_DSC_BRANCH_MAX_LINE_WIDTH - DP_DSC_BRANCH_OVERALL_THROUGHPUT_0] * 320;
|
||||||
ASSERT(dsc_sink_caps->branch_max_line_width == 0 || dsc_sink_caps->branch_max_line_width >= 5120);
|
ASSERT(dsc_sink_caps->branch_max_line_width == 0 || dsc_sink_caps->branch_max_line_width >= 5120);
|
||||||
|
|
||||||
|
dsc_sink_caps->is_dp = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -921,14 +931,14 @@ bool dc_dsc_compute_config(
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t dc_dsc_stream_bandwidth_in_kbps(const struct dc_crtc_timing *timing,
|
uint32_t dc_dsc_stream_bandwidth_in_kbps(const struct dc_crtc_timing *timing,
|
||||||
uint32_t bpp_x16, uint32_t num_slices_h)
|
uint32_t bpp_x16, uint32_t num_slices_h, bool is_dp)
|
||||||
{
|
{
|
||||||
struct fixed31_32 overhead_in_kbps;
|
struct fixed31_32 overhead_in_kbps;
|
||||||
struct fixed31_32 bpp;
|
struct fixed31_32 bpp;
|
||||||
struct fixed31_32 actual_bandwidth_in_kbps;
|
struct fixed31_32 actual_bandwidth_in_kbps;
|
||||||
|
|
||||||
overhead_in_kbps = compute_dsc_max_bandwidth_overhead(
|
overhead_in_kbps = compute_dsc_max_bandwidth_overhead(
|
||||||
timing, num_slices_h);
|
timing, num_slices_h, is_dp);
|
||||||
bpp = dc_fixpt_from_fraction(bpp_x16, 16);
|
bpp = dc_fixpt_from_fraction(bpp_x16, 16);
|
||||||
actual_bandwidth_in_kbps = dc_fixpt_from_fraction(timing->pix_clk_100hz, 10);
|
actual_bandwidth_in_kbps = dc_fixpt_from_fraction(timing->pix_clk_100hz, 10);
|
||||||
actual_bandwidth_in_kbps = dc_fixpt_mul(actual_bandwidth_in_kbps, bpp);
|
actual_bandwidth_in_kbps = dc_fixpt_mul(actual_bandwidth_in_kbps, bpp);
|
||||||
@@ -1017,3 +1027,8 @@ void dc_dsc_policy_set_enable_dsc_when_not_needed(bool enable)
|
|||||||
{
|
{
|
||||||
dsc_policy_enable_dsc_when_not_needed = enable;
|
dsc_policy_enable_dsc_when_not_needed = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dc_dsc_policy_set_disable_dsc_stream_overhead(bool disable)
|
||||||
|
{
|
||||||
|
dsc_policy_disable_dsc_stream_overhead = disable;
|
||||||
|
}
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ struct dsc_enc_caps {
|
|||||||
int32_t max_total_throughput_mps; /* Maximum total throughput with all the slices combined */
|
int32_t max_total_throughput_mps; /* Maximum total throughput with all the slices combined */
|
||||||
int32_t max_slice_width;
|
int32_t max_slice_width;
|
||||||
uint32_t bpp_increment_div; /* bpp increment divisor, e.g. if 16, it's 1/16th of a bit */
|
uint32_t bpp_increment_div; /* bpp increment divisor, e.g. if 16, it's 1/16th of a bit */
|
||||||
|
bool is_dp;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dsc_funcs {
|
struct dsc_funcs {
|
||||||
|
|||||||
Reference in New Issue
Block a user