diff options
author | Nikola Cornij <nikola.cornij@amd.com> | 2019-07-19 02:13:26 +0300 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2019-08-15 18:54:46 +0300 |
commit | 7470673340b118b744e629383e8374ced4100b84 (patch) | |
tree | d897681ba260a53bbc30c8261e9e04243cfc41d1 /drivers/gpu/drm/amd/display/dc/dsc | |
parent | 33ca0475b8c42fb5650b3b764a2b1217d9a1bb06 (diff) | |
download | linux-7470673340b118b744e629383e8374ced4100b84.tar.xz |
drm/amd/display: Change DSC policy from slices per column to minimum slice height
[why] Minimum slice height is recommended by VESA DSC Spreadsheet user guide
Signed-off-by: Nikola Cornij <nikola.cornij@amd.com>
Reviewed-by: Jun Lei <Jun.Lei@amd.com>
Acked-by: Leo Li <sunpeng.li@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dsc')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c | 71 |
1 files changed, 32 insertions, 39 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c index ef5f84a144c3..5995bcdfed54 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c +++ b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c @@ -28,6 +28,23 @@ #include "dsc.h" #include <drm/drm_dp_helper.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 + int max_target_bpp; + int min_target_bpp; // Minimum target bits per pixel +}; + +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 + .max_target_bpp = 16, + .min_target_bpp = 8, +}; + + /* This module's internal functions */ static bool dsc_buff_block_size_from_dpcd(int dpcd_buff_block_size, int *buff_block_size) @@ -241,14 +258,6 @@ static bool intersect_dsc_caps( return true; } -struct dc_dsc_policy { - bool use_min_slices_h; - int max_slices_h; // Maximum available if 0 - int num_slices_v; - int max_target_bpp; - int min_target_bpp; // Minimum target bits per pixel -}; - static inline uint32_t dsc_div_by_10_round_up(uint32_t value) { return (value + 9) / 10; @@ -270,19 +279,6 @@ static inline uint32_t calc_dsc_bpp_x16(uint32_t stream_bandwidth_kbps, uint32_t return dsc_target_bpp_x16; } -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) - /* DSC Policy: Number of vertical slices set to 2 for no particular reason. - * Seems small enough to not affect the quality too much, while still providing some error - * propagation control (which may also help debugging). - */ - .num_slices_v = 16, - .max_target_bpp = 16, - .min_target_bpp = 8, -}; - - /* Get DSC bandwidth range based on [min_bpp, max_bpp] target bitrate range, and timing's pixel clock * and uncompressed bandwidth. */ @@ -528,8 +524,8 @@ static bool setup_dsc_config( int sink_per_slice_throughput_mps; int branch_max_throughput_mps = 0; bool is_dsc_possible = false; - int num_slices_v; int pic_height; + int slice_height; memset(dsc_cfg, 0, sizeof(struct dc_dsc_config)); @@ -615,7 +611,7 @@ static bool setup_dsc_config( if (!is_dsc_possible) goto done; - // DSC slicing + // Slice width (i.e. number of slices per line) max_slices_h = get_max_dsc_slices(dsc_common_caps.slice_caps); while (max_slices_h > 0) { @@ -678,29 +674,26 @@ static bool setup_dsc_config( dsc_cfg->num_slices_h = num_slices_h; slice_width = pic_width / num_slices_h; - // Vertical number of slices: start from policy and pick the first one that height is divisible by. + is_dsc_possible = slice_width <= dsc_common_caps.max_slice_width; + if (!is_dsc_possible) + goto done; + + // 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. - num_slices_v = dsc_policy.num_slices_v; - if (num_slices_v < 1) - num_slices_v = 1; - - while (num_slices_v >= 1) { - if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) { - int slice_height = pic_height / num_slices_v; - if (pic_height % num_slices_v == 0 && slice_height % 2 == 0) - break; - } else if (pic_height % num_slices_v == 0) - break; + slice_height = min(dsc_policy.min_sice_height, pic_height); - num_slices_v--; - } + while (slice_height < pic_height && (pic_height % slice_height != 0 || + (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420 && slice_height % 2 != 0))) + slice_height++; - dsc_cfg->num_slices_v = num_slices_v; + if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) // For the case when pic_height < dsc_policy.min_sice_height + is_dsc_possible = (slice_height % 2 == 0); - is_dsc_possible = slice_width <= dsc_common_caps.max_slice_width; if (!is_dsc_possible) goto done; + dsc_cfg->num_slices_v = pic_height/slice_height; + // Final decission: can we do DSC or not? if (is_dsc_possible) { // Fill out the rest of DSC settings |