mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-24 19:40:21 +09:00
drm/amd/display: move bpp range decision in decide dsc bw range function
[why] Before get dsc bw range is used to compute DSC bw range based on the given fixed bpp min/max input. The new change will merge any specs, signal, timing specific bpp range decision into this function. So the function needs to make a decision with all aspects considered. Acked-by: Mikita Lipski <mikita.lipski@amd.com> Signed-off-by: Wenjing Liu <wenjing.liu@amd.com> Reviewed-by: George Shen <george.shen@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
952ab0b302
commit
e0d09634ac
@@ -51,7 +51,6 @@ struct dc_dsc_policy {
|
||||
int min_slice_height; // Must not be less than 8
|
||||
uint32_t max_target_bpp;
|
||||
uint32_t min_target_bpp;
|
||||
uint32_t preferred_bpp_x16;
|
||||
bool enable_dsc_when_not_needed;
|
||||
};
|
||||
|
||||
@@ -86,6 +85,11 @@ uint32_t dc_dsc_stream_bandwidth_overhead_in_kbps(
|
||||
const int num_slices_h,
|
||||
const bool is_dp);
|
||||
|
||||
/* TODO - Hardware/specs limitation should be owned by dc dsc and returned to DM,
|
||||
* and DM can choose to OVERRIDE the limitation on CASE BY CASE basis.
|
||||
* Hardware/specs limitation should not be writable by DM.
|
||||
* It should be decoupled from DM specific policy and named differently.
|
||||
*/
|
||||
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);
|
||||
|
||||
@@ -40,8 +40,15 @@ static bool dsc_policy_enable_dsc_when_not_needed;
|
||||
|
||||
static bool dsc_policy_disable_dsc_stream_overhead;
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
|
||||
#endif
|
||||
#ifndef MIN
|
||||
#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
|
||||
#endif
|
||||
|
||||
/* Forward Declerations */
|
||||
static void get_dsc_bandwidth_range(
|
||||
static bool decide_dsc_bandwidth_range(
|
||||
const uint32_t min_bpp_x16,
|
||||
const uint32_t max_bpp_x16,
|
||||
const uint32_t num_slices_h,
|
||||
@@ -356,7 +363,7 @@ bool dc_dsc_compute_bandwidth_range(
|
||||
dsc_min_slice_height_override, max_bpp_x16, &config);
|
||||
|
||||
if (is_dsc_possible)
|
||||
get_dsc_bandwidth_range(min_bpp_x16, max_bpp_x16,
|
||||
is_dsc_possible = decide_dsc_bandwidth_range(min_bpp_x16, max_bpp_x16,
|
||||
config.num_slices_h, &dsc_common_caps, timing, range);
|
||||
|
||||
return is_dsc_possible;
|
||||
@@ -481,10 +488,12 @@ static uint32_t compute_bpp_x16_from_target_bandwidth(
|
||||
return dc_fixpt_floor(bpp_x16);
|
||||
}
|
||||
|
||||
/* Get DSC bandwidth range based on [min_bpp, max_bpp] target bitrate range, and timing's pixel clock
|
||||
* and uncompressed bandwidth.
|
||||
/* Decide DSC bandwidth range based on signal, timing, specs specific and input min and max
|
||||
* requirements.
|
||||
* The range output includes decided min/max target bpp, the respective bandwidth requirements
|
||||
* and native timing bandwidth requirement when DSC is not used.
|
||||
*/
|
||||
static void get_dsc_bandwidth_range(
|
||||
static bool decide_dsc_bandwidth_range(
|
||||
const uint32_t min_bpp_x16,
|
||||
const uint32_t max_bpp_x16,
|
||||
const uint32_t num_slices_h,
|
||||
@@ -492,39 +501,45 @@ static void get_dsc_bandwidth_range(
|
||||
const struct dc_crtc_timing *timing,
|
||||
struct dc_dsc_bw_range *range)
|
||||
{
|
||||
/* native stream bandwidth */
|
||||
range->stream_kbps = dc_bandwidth_in_kbps_from_timing(timing);
|
||||
uint32_t preferred_bpp_x16 = timing->dsc_fixed_bits_per_pixel_x16;
|
||||
|
||||
/* max dsc target bpp */
|
||||
range->max_kbps = dc_dsc_stream_bandwidth_in_kbps(timing,
|
||||
max_bpp_x16, num_slices_h, dsc_caps->is_dp);
|
||||
range->max_target_bpp_x16 = max_bpp_x16;
|
||||
if (range->max_kbps > range->stream_kbps) {
|
||||
/* max dsc target bpp is capped to native bandwidth */
|
||||
range->max_kbps = range->stream_kbps;
|
||||
range->max_target_bpp_x16 = compute_bpp_x16_from_target_bandwidth(
|
||||
range->max_kbps, timing, num_slices_h,
|
||||
dsc_caps->bpp_increment_div,
|
||||
dsc_caps->is_dp);
|
||||
memset(range, 0, sizeof(*range));
|
||||
|
||||
/* apply signal, timing, specs and explicitly specified DSC range requirements */
|
||||
if (preferred_bpp_x16) {
|
||||
if (preferred_bpp_x16 <= max_bpp_x16 &&
|
||||
preferred_bpp_x16 >= min_bpp_x16) {
|
||||
range->max_target_bpp_x16 = preferred_bpp_x16;
|
||||
range->min_target_bpp_x16 = preferred_bpp_x16;
|
||||
}
|
||||
}
|
||||
else {
|
||||
range->max_target_bpp_x16 = max_bpp_x16;
|
||||
range->min_target_bpp_x16 = min_bpp_x16;
|
||||
}
|
||||
|
||||
/* min dsc target bpp */
|
||||
range->min_kbps = dc_dsc_stream_bandwidth_in_kbps(timing,
|
||||
min_bpp_x16, num_slices_h, dsc_caps->is_dp);
|
||||
range->min_target_bpp_x16 = min_bpp_x16;
|
||||
if (range->min_kbps > range->max_kbps) {
|
||||
/* min dsc target bpp is capped to max dsc bandwidth*/
|
||||
range->min_kbps = range->max_kbps;
|
||||
range->min_target_bpp_x16 = range->max_target_bpp_x16;
|
||||
/* populate output structure */
|
||||
if (range->max_target_bpp_x16 >= range->min_target_bpp_x16 && range->min_target_bpp_x16 > 0) {
|
||||
/* native stream bandwidth */
|
||||
range->stream_kbps = dc_bandwidth_in_kbps_from_timing(timing);
|
||||
|
||||
/* max dsc target bpp */
|
||||
range->max_kbps = dc_dsc_stream_bandwidth_in_kbps(timing,
|
||||
range->max_target_bpp_x16, num_slices_h, dsc_caps->is_dp);
|
||||
|
||||
/* min dsc target bpp */
|
||||
range->min_kbps = dc_dsc_stream_bandwidth_in_kbps(timing,
|
||||
range->min_target_bpp_x16, num_slices_h, dsc_caps->is_dp);
|
||||
}
|
||||
|
||||
return range->max_kbps >= range->min_kbps && range->min_kbps > 0;
|
||||
}
|
||||
|
||||
/* Decides if DSC should be used and calculates target bpp if it should, applying DSC policy.
|
||||
*
|
||||
* Returns:
|
||||
* - 'true' if DSC was required by policy and was successfully applied
|
||||
* - 'false' if DSC was not necessary (e.g. if uncompressed stream fits 'target_bandwidth_kbps'),
|
||||
* or if it couldn't be applied based on DSC policy.
|
||||
* - 'true' if target bpp is decided
|
||||
* - 'false' if target bpp cannot be decided (e.g. cannot fit even with min DSC bpp),
|
||||
*/
|
||||
static bool decide_dsc_target_bpp_x16(
|
||||
const struct dc_dsc_policy *policy,
|
||||
@@ -534,40 +549,29 @@ static bool decide_dsc_target_bpp_x16(
|
||||
const int num_slices_h,
|
||||
int *target_bpp_x16)
|
||||
{
|
||||
bool should_use_dsc = false;
|
||||
struct dc_dsc_bw_range range;
|
||||
|
||||
memset(&range, 0, sizeof(range));
|
||||
*target_bpp_x16 = 0;
|
||||
|
||||
get_dsc_bandwidth_range(policy->min_target_bpp * 16, policy->max_target_bpp * 16,
|
||||
num_slices_h, dsc_common_caps, timing, &range);
|
||||
if (!policy->enable_dsc_when_not_needed && target_bandwidth_kbps >= range.stream_kbps) {
|
||||
/* enough bandwidth without dsc */
|
||||
*target_bpp_x16 = 0;
|
||||
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) {
|
||||
/* use max target bpp allowed */
|
||||
*target_bpp_x16 = range.max_target_bpp_x16;
|
||||
should_use_dsc = true;
|
||||
} else if (target_bandwidth_kbps >= range.min_kbps) {
|
||||
/* use target bpp that can take entire target bandwidth */
|
||||
*target_bpp_x16 = compute_bpp_x16_from_target_bandwidth(
|
||||
target_bandwidth_kbps, timing, num_slices_h,
|
||||
dsc_common_caps->bpp_increment_div,
|
||||
dsc_common_caps->is_dp);
|
||||
should_use_dsc = true;
|
||||
} else {
|
||||
/* not enough bandwidth to fulfill minimum requirement */
|
||||
*target_bpp_x16 = 0;
|
||||
should_use_dsc = false;
|
||||
if (decide_dsc_bandwidth_range(policy->min_target_bpp * 16, policy->max_target_bpp * 16,
|
||||
num_slices_h, dsc_common_caps, timing, &range)) {
|
||||
if (target_bandwidth_kbps >= range.stream_kbps) {
|
||||
if (policy->enable_dsc_when_not_needed)
|
||||
/* enable max bpp even dsc is not needed */
|
||||
*target_bpp_x16 = range.max_target_bpp_x16;
|
||||
} else if (target_bandwidth_kbps >= range.max_kbps) {
|
||||
/* use max target bpp allowed */
|
||||
*target_bpp_x16 = range.max_target_bpp_x16;
|
||||
} else if (target_bandwidth_kbps >= range.min_kbps) {
|
||||
/* use target bpp that can take entire target bandwidth */
|
||||
*target_bpp_x16 = compute_bpp_x16_from_target_bandwidth(
|
||||
target_bandwidth_kbps, timing, num_slices_h,
|
||||
dsc_common_caps->bpp_increment_div,
|
||||
dsc_common_caps->is_dp);
|
||||
}
|
||||
}
|
||||
|
||||
return should_use_dsc;
|
||||
return *target_bpp_x16 != 0;
|
||||
}
|
||||
|
||||
#define MIN_AVAILABLE_SLICES_SIZE 4
|
||||
@@ -1059,8 +1063,6 @@ void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing,
|
||||
return;
|
||||
}
|
||||
|
||||
policy->preferred_bpp_x16 = timing->dsc_fixed_bits_per_pixel_x16;
|
||||
|
||||
/* internal upper limit, default 16 bpp */
|
||||
if (policy->max_target_bpp > dsc_policy_max_target_bpp_limit)
|
||||
policy->max_target_bpp = dsc_policy_max_target_bpp_limit;
|
||||
|
||||
Reference in New Issue
Block a user