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 { ...@@ -45,6 +45,14 @@ struct display_stream_compressor {
int inst; 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, bool dc_dsc_parse_dsc_dpcd(const uint8_t *dpcd_dsc_basic_data,
const uint8_t *dpcd_dsc_ext_data, const uint8_t *dpcd_dsc_ext_data,
struct dsc_dec_dpcd_caps *dsc_sink_caps); struct dsc_dec_dpcd_caps *dsc_sink_caps);
...@@ -66,7 +74,7 @@ bool dc_dsc_compute_config( ...@@ -66,7 +74,7 @@ bool dc_dsc_compute_config(
const struct dc_crtc_timing *timing, const struct dc_crtc_timing *timing,
struct dc_dsc_config *dsc_cfg); struct dc_dsc_config *dsc_cfg);
bool dc_dsc_get_bpp_range_for_pixel_encoding(enum dc_pixel_encoding pixel_enc, void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing,
uint32_t *min_bpp, struct dc_dsc_policy *policy);
uint32_t *max_bpp);
#endif #endif
...@@ -27,19 +27,6 @@ ...@@ -27,19 +27,6 @@
#include <drm/drm_dp_helper.h> #include <drm/drm_dp_helper.h>
#include "dc.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 */ /* This module's internal functions */
static uint32_t dc_dsc_bandwidth_in_kbps_from_timing( static uint32_t dc_dsc_bandwidth_in_kbps_from_timing(
...@@ -370,6 +357,7 @@ static void get_dsc_bandwidth_range( ...@@ -370,6 +357,7 @@ static void get_dsc_bandwidth_range(
* or if it couldn't be applied based on DSC policy. * or if it couldn't be applied based on DSC policy.
*/ */
static bool decide_dsc_target_bpp_x16( static bool decide_dsc_target_bpp_x16(
const struct dc_dsc_policy *policy,
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,
...@@ -377,13 +365,10 @@ static bool decide_dsc_target_bpp_x16( ...@@ -377,13 +365,10 @@ static bool decide_dsc_target_bpp_x16(
{ {
bool should_use_dsc = false; bool should_use_dsc = false;
struct dc_dsc_bw_range range; struct dc_dsc_bw_range range;
uint32_t min_target_bpp = 0;
uint32_t max_target_bpp = 0;
memset(&range, 0, sizeof(range)); 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(policy->min_target_bpp, policy->max_target_bpp,
get_dsc_bandwidth_range(min_target_bpp, max_target_bpp,
dsc_common_caps, timing, &range); dsc_common_caps, timing, &range);
if (target_bandwidth_kbps >= range.stream_kbps) { if (target_bandwidth_kbps >= range.stream_kbps) {
/* enough bandwidth without dsc */ /* enough bandwidth without dsc */
...@@ -579,9 +564,11 @@ static bool setup_dsc_config( ...@@ -579,9 +564,11 @@ static bool setup_dsc_config(
bool is_dsc_possible = false; bool is_dsc_possible = false;
int pic_height; int pic_height;
int slice_height; int slice_height;
struct dc_dsc_policy policy;
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, &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;
...@@ -597,7 +584,12 @@ static bool setup_dsc_config( ...@@ -597,7 +584,12 @@ static bool setup_dsc_config(
goto done; goto done;
if (target_bandwidth_kbps > 0) { 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; dsc_cfg->bits_per_pixel = target_bpp;
} }
if (!is_dsc_possible) if (!is_dsc_possible)
...@@ -699,20 +691,20 @@ static bool setup_dsc_config( ...@@ -699,20 +691,20 @@ static bool setup_dsc_config(
if (!is_dsc_possible) if (!is_dsc_possible)
goto done; goto done;
if (dsc_policy.use_min_slices_h) { if (policy.use_min_slices_h) {
if (min_slices_h > 0) if (min_slices_h > 0)
num_slices_h = min_slices_h; num_slices_h = min_slices_h;
else if (max_slices_h > 0) { // Fall back to max slices if min slices is not working out else if (max_slices_h > 0) { // Fall back to max slices if min slices is not working out
if (dsc_policy.max_slices_h) if (policy.max_slices_h)
num_slices_h = min(dsc_policy.max_slices_h, max_slices_h); num_slices_h = min(policy.max_slices_h, max_slices_h);
else else
num_slices_h = max_slices_h; num_slices_h = max_slices_h;
} else } else
is_dsc_possible = false; is_dsc_possible = false;
} else { } else {
if (max_slices_h > 0) { if (max_slices_h > 0) {
if (dsc_policy.max_slices_h) if (policy.max_slices_h)
num_slices_h = min(dsc_policy.max_slices_h, max_slices_h); num_slices_h = min(policy.max_slices_h, max_slices_h);
else else
num_slices_h = max_slices_h; num_slices_h = max_slices_h;
} else if (min_slices_h > 0) // Fall back to min slices if max slices is not possible } 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( ...@@ -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. // 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. // For 4:2:0 make sure the slice height is divisible by 2 as well.
if (min_slice_height_override == 0) 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 else
slice_height = min(min_slice_height_override, pic_height); slice_height = min(min_slice_height_override, pic_height);
...@@ -905,28 +897,61 @@ bool dc_dsc_compute_config( ...@@ -905,28 +897,61 @@ bool dc_dsc_compute_config(
return is_dsc_possible; return is_dsc_possible;
} }
bool dc_dsc_get_bpp_range_for_pixel_encoding(enum dc_pixel_encoding pixel_enc, void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, struct dc_dsc_policy *policy)
uint32_t *min_bpp,
uint32_t *max_bpp)
{ {
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_RGB:
case PIXEL_ENCODING_YCBCR444: case PIXEL_ENCODING_YCBCR444:
case PIXEL_ENCODING_YCBCR422: case PIXEL_ENCODING_YCBCR422: /* assume no YCbCr422 native support */
*min_bpp = 8; /* DP specs limits to 8 */
*max_bpp = 16; policy->min_target_bpp = 8;
/* DP specs limits to 3 x bpc */
policy->max_target_bpp = 3 * bpc;
break; break;
case PIXEL_ENCODING_YCBCR420: case PIXEL_ENCODING_YCBCR420:
*min_bpp = 6; /* DP specs limits to 6 */
*max_bpp = 16; 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; break;
default: default:
*min_bpp = 0; return;
*max_bpp = 0;
result = false;
} }
/* internal upper limit to 16 bpp */
return result; 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