Commit 799a5f74 authored by Wenjing Liu's avatar Wenjing Liu Committed by Alex Deucher

drm/amd/display: add dsc policy getter

dc needs to expose its internal dsc policy.
Signed-off-by: default avatarWenjing Liu <Wenjing.Liu@amd.com>
Reviewed-by: default avatarNikola Cornij <Nikola.Cornij@amd.com>
Acked-by: default avatarLeo Li <sunpeng.li@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent c5e53707
......@@ -45,6 +45,14 @@ struct display_stream_compressor {
int inst;
};
struct dc_dsc_policy {
bool use_min_slices_h;
int max_slices_h; // Maximum available if 0
int min_slice_height; // Must not be less than 8
uint32_t max_target_bpp;
uint32_t min_target_bpp;
};
bool dc_dsc_parse_dsc_dpcd(const uint8_t *dpcd_dsc_basic_data,
const uint8_t *dpcd_dsc_ext_data,
struct dsc_dec_dpcd_caps *dsc_sink_caps);
......@@ -66,7 +74,7 @@ bool dc_dsc_compute_config(
const struct dc_crtc_timing *timing,
struct dc_dsc_config *dsc_cfg);
bool dc_dsc_get_bpp_range_for_pixel_encoding(enum dc_pixel_encoding pixel_enc,
uint32_t *min_bpp,
uint32_t *max_bpp);
void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing,
struct dc_dsc_policy *policy);
#endif
......@@ -27,19 +27,6 @@
#include <drm/drm_dp_helper.h>
#include "dc.h"
struct dc_dsc_policy {
bool use_min_slices_h;
int max_slices_h; // Maximum available if 0
int min_sice_height; // Must not be less than 8
};
const struct dc_dsc_policy dsc_policy = {
.use_min_slices_h = true, // DSC Policy: Use minimum number of slices that fits the pixel clock
.max_slices_h = 0, // DSC Policy: Use max available slices (in our case 4 for or 8, depending on the mode)
.min_sice_height = 108, // DSC Policy: Use slice height recommended by VESA DSC Spreadsheet user guide
};
/* This module's internal functions */
static uint32_t dc_dsc_bandwidth_in_kbps_from_timing(
......@@ -370,6 +357,7 @@ static void get_dsc_bandwidth_range(
* or if it couldn't be applied based on DSC policy.
*/
static bool decide_dsc_target_bpp_x16(
const struct dc_dsc_policy *policy,
const struct dsc_enc_caps *dsc_common_caps,
const int target_bandwidth_kbps,
const struct dc_crtc_timing *timing,
......@@ -377,13 +365,10 @@ static bool decide_dsc_target_bpp_x16(
{
bool should_use_dsc = false;
struct dc_dsc_bw_range range;
uint32_t min_target_bpp = 0;
uint32_t max_target_bpp = 0;
memset(&range, 0, sizeof(range));
dc_dsc_get_bpp_range_for_pixel_encoding(timing->pixel_encoding, &min_target_bpp, &max_target_bpp);
get_dsc_bandwidth_range(min_target_bpp, max_target_bpp,
get_dsc_bandwidth_range(policy->min_target_bpp, policy->max_target_bpp,
dsc_common_caps, timing, &range);
if (target_bandwidth_kbps >= range.stream_kbps) {
/* enough bandwidth without dsc */
......@@ -579,9 +564,11 @@ static bool setup_dsc_config(
bool is_dsc_possible = false;
int pic_height;
int slice_height;
struct dc_dsc_policy policy;
memset(dsc_cfg, 0, sizeof(struct dc_dsc_config));
dc_dsc_get_policy_for_timing(timing, &policy);
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;
......@@ -597,7 +584,12 @@ static bool setup_dsc_config(
goto done;
if (target_bandwidth_kbps > 0) {
is_dsc_possible = decide_dsc_target_bpp_x16(&dsc_common_caps, target_bandwidth_kbps, timing, &target_bpp);
is_dsc_possible = decide_dsc_target_bpp_x16(
&policy,
&dsc_common_caps,
target_bandwidth_kbps,
timing,
&target_bpp);
dsc_cfg->bits_per_pixel = target_bpp;
}
if (!is_dsc_possible)
......@@ -699,20 +691,20 @@ static bool setup_dsc_config(
if (!is_dsc_possible)
goto done;
if (dsc_policy.use_min_slices_h) {
if (policy.use_min_slices_h) {
if (min_slices_h > 0)
num_slices_h = min_slices_h;
else if (max_slices_h > 0) { // Fall back to max slices if min slices is not working out
if (dsc_policy.max_slices_h)
num_slices_h = min(dsc_policy.max_slices_h, max_slices_h);
if (policy.max_slices_h)
num_slices_h = min(policy.max_slices_h, max_slices_h);
else
num_slices_h = max_slices_h;
} else
is_dsc_possible = false;
} else {
if (max_slices_h > 0) {
if (dsc_policy.max_slices_h)
num_slices_h = min(dsc_policy.max_slices_h, max_slices_h);
if (policy.max_slices_h)
num_slices_h = min(policy.max_slices_h, max_slices_h);
else
num_slices_h = max_slices_h;
} else if (min_slices_h > 0) // Fall back to min slices if max slices is not possible
......@@ -734,7 +726,7 @@ static bool setup_dsc_config(
// Slice height (i.e. number of slices per column): start with policy and pick the first one that height is divisible by.
// For 4:2:0 make sure the slice height is divisible by 2 as well.
if (min_slice_height_override == 0)
slice_height = min(dsc_policy.min_sice_height, pic_height);
slice_height = min(policy.min_slice_height, pic_height);
else
slice_height = min(min_slice_height_override, pic_height);
......@@ -905,28 +897,61 @@ bool dc_dsc_compute_config(
return is_dsc_possible;
}
bool dc_dsc_get_bpp_range_for_pixel_encoding(enum dc_pixel_encoding pixel_enc,
uint32_t *min_bpp,
uint32_t *max_bpp)
void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, struct dc_dsc_policy *policy)
{
bool result = true;
uint32_t bpc = 0;
policy->min_target_bpp = 0;
policy->max_target_bpp = 0;
/* DSC Policy: Use minimum number of slices that fits the pixel clock */
policy->use_min_slices_h = true;
switch (pixel_enc) {
/* DSC Policy: Use max available slices
* (in our case 4 for or 8, depending on the mode)
*/
policy->max_slices_h = 0;
/* DSC Policy: Use slice height recommended
* by VESA DSC Spreadsheet user guide
*/
policy->min_slice_height = 108;
/* DSC Policy: follow DP specs with an internal upper limit to 16 bpp
* for better interoperability
*/
switch (timing->display_color_depth) {
case COLOR_DEPTH_888:
bpc = 8;
break;
case COLOR_DEPTH_101010:
bpc = 10;
break;
case COLOR_DEPTH_121212:
bpc = 12;
break;
default:
return;
}
switch (timing->pixel_encoding) {
case PIXEL_ENCODING_RGB:
case PIXEL_ENCODING_YCBCR444:
case PIXEL_ENCODING_YCBCR422:
*min_bpp = 8;
*max_bpp = 16;
case PIXEL_ENCODING_YCBCR422: /* assume no YCbCr422 native support */
/* DP specs limits to 8 */
policy->min_target_bpp = 8;
/* DP specs limits to 3 x bpc */
policy->max_target_bpp = 3 * bpc;
break;
case PIXEL_ENCODING_YCBCR420:
*min_bpp = 6;
*max_bpp = 16;
/* DP specs limits to 6 */
policy->min_target_bpp = 6;
/* DP specs limits to 1.5 x bpc assume bpc is an even number */
policy->max_target_bpp = bpc * 3 / 2;
break;
default:
*min_bpp = 0;
*max_bpp = 0;
result = false;
return;
}
return result;
/* internal upper limit to 16 bpp */
if (policy->max_target_bpp > 16)
policy->max_target_bpp = 16;
}
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