mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-22 23:22:24 +07:00
drm/amd/display: add dsc policy getter
dc needs to expose its internal dsc policy. Signed-off-by: Wenjing Liu <Wenjing.Liu@amd.com> Reviewed-by: Nikola Cornij <Nikola.Cornij@amd.com> Acked-by: Leo Li <sunpeng.li@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
c5e53707e2
commit
799a5f74d1
@ -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;
|
||||
|
||||
switch (pixel_enc) {
|
||||
case PIXEL_ENCODING_RGB:
|
||||
case PIXEL_ENCODING_YCBCR444:
|
||||
case PIXEL_ENCODING_YCBCR422:
|
||||
*min_bpp = 8;
|
||||
*max_bpp = 16;
|
||||
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;
|
||||
|
||||
/* 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 PIXEL_ENCODING_YCBCR420:
|
||||
*min_bpp = 6;
|
||||
*max_bpp = 16;
|
||||
case COLOR_DEPTH_101010:
|
||||
bpc = 10;
|
||||
break;
|
||||
case COLOR_DEPTH_121212:
|
||||
bpc = 12;
|
||||
break;
|
||||
default:
|
||||
*min_bpp = 0;
|
||||
*max_bpp = 0;
|
||||
result = false;
|
||||
return;
|
||||
}
|
||||
|
||||
return result;
|
||||
switch (timing->pixel_encoding) {
|
||||
case PIXEL_ENCODING_RGB:
|
||||
case PIXEL_ENCODING_YCBCR444:
|
||||
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:
|
||||
/* 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:
|
||||
return;
|
||||
}
|
||||
/* internal upper limit to 16 bpp */
|
||||
if (policy->max_target_bpp > 16)
|
||||
policy->max_target_bpp = 16;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user