From d7cd0e053b17dfa0dd4669dfb388c100be272823 Mon Sep 17 00:00:00 2001 From: Nikola Cornij Date: Mon, 15 Apr 2019 17:31:44 -0400 Subject: [PATCH] drm/amd/display: Add 170Mpix/sec DSC throughput support [why] It was missing, although defined in DP spec [how] - Add handling of this value to DSC code - Also remove unused file dsc_helpers.c Signed-off-by: Nikola Cornij Reviewed-by: Joshua Aberback Acked-by: Bhawanpreet Lakha Signed-off-by: Alex Deucher --- drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c | 10 +- .../gpu/drm/amd/display/dc/dsc/dsc_helpers.c | 243 ------------------ include/drm/drm_dp_helper.h | 4 + 3 files changed, 12 insertions(+), 245 deletions(-) delete mode 100644 drivers/gpu/drm/amd/display/dc/dsc/dsc_helpers.c 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 d58d718171b5..f09f23707a94 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c +++ b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c @@ -74,6 +74,12 @@ static bool dsc_line_buff_depth_from_dpcd(int dpcd_line_buff_bit_depth, int *lin static bool dsc_throughput_from_dpcd(int dpcd_throughput, int *throughput) { switch (dpcd_throughput) { + case DP_DSC_THROUGHPUT_MODE_0_UPSUPPORTED: + *throughput = 0; + break; + case DP_DSC_THROUGHPUT_MODE_0_170: + *throughput = 170; + break; case DP_DSC_THROUGHPUT_MODE_0_340: *throughput = 340; break; @@ -170,7 +176,7 @@ static void get_dsc_enc_caps( /* Returns 'false' if no intersection was found for at least one capablity. * It also implicitly validates some sink caps against invalid value of zero. */ -static bool dc_intersect_dsc_caps( +static bool intersect_dsc_caps( const struct dsc_dec_dpcd_caps *dsc_sink_caps, const struct dsc_enc_caps *dsc_enc_caps, enum dc_pixel_encoding pixel_encoding, @@ -537,7 +543,7 @@ static bool setup_dsc_config( goto done; // Intersect decoder with encoder DSC caps and validate DSC settings - is_dsc_possible = dc_intersect_dsc_caps(dsc_sink_caps, dsc_enc_caps, timing->pixel_encoding, &dsc_common_caps); + is_dsc_possible = intersect_dsc_caps(dsc_sink_caps, dsc_enc_caps, timing->pixel_encoding, &dsc_common_caps); if (!is_dsc_possible) goto done; diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dsc_helpers.c b/drivers/gpu/drm/amd/display/dc/dsc/dsc_helpers.c deleted file mode 100644 index 0ecd5065d120..000000000000 --- a/drivers/gpu/drm/amd/display/dc/dsc/dsc_helpers.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright 2018 Advanced Micro Devices, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: AMD - * - */ - -#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT - -#include "dc.h" -#include "dsc.h" -#include "dc_hw_types.h" -#include - -#define DC_LOGGER \ - dsc->ctx->logger - -static bool dsc_buff_block_size_from_dpcd(int dpcd_buff_block_size, int *buff_block_size); -static bool dsc_line_buff_depth_from_dpcd(int dpcd_line_buff_bit_depth, int *line_buff_bit_depth); -static bool dsc_throughput_from_dpcd(int dpcd_throughput, int *throughput); -static bool dsc_bpp_increment_div_from_dpcd(int bpp_increment_dpcd, uint32_t *bpp_increment_div); - -void dsc_optc_config_log(struct display_stream_compressor *dsc, - struct dsc_optc_config *config) -{ - DC_LOG_DSC("Setting optc DSC config at DSC inst %d", dsc->inst); - DC_LOG_DSC("\n\tbytes_per_pixel %d\n\tis_pixel_format_444 %d\n\tslice_width %d", - config->bytes_per_pixel, - config->is_pixel_format_444, config->slice_width); -} - -void dsc_config_log(struct display_stream_compressor *dsc, - const struct dsc_config *config) -{ - DC_LOG_DSC("Setting DSC Config at DSC inst %d", dsc->inst); - DC_LOG_DSC("\n\tnum_slices_h %d\n\tnum_slices_v %d\n\tbits_per_pixel %d\n\tcolor_depth %d", - config->dc_dsc_cfg.num_slices_h, - config->dc_dsc_cfg.num_slices_v, - config->dc_dsc_cfg.bits_per_pixel, - config->color_depth); -} - - -bool dsc_parse_dsc_dpcd(const uint8_t *dpcd_dsc_data, struct dsc_dec_dpcd_caps *dsc_sink_caps) -{ - dsc_sink_caps->is_dsc_supported = (dpcd_dsc_data[DP_DSC_SUPPORT - DP_DSC_SUPPORT] & DP_DSC_DECOMPRESSION_IS_SUPPORTED) != 0; - if (!dsc_sink_caps->is_dsc_supported) - return true; - - dsc_sink_caps->dsc_version = dpcd_dsc_data[DP_DSC_REV - DP_DSC_SUPPORT]; - - { - int buff_block_size; - int buff_size; - - if (!dsc_buff_block_size_from_dpcd(dpcd_dsc_data[DP_DSC_RC_BUF_BLK_SIZE - DP_DSC_SUPPORT], &buff_block_size)) - return false; - - buff_size = dpcd_dsc_data[DP_DSC_RC_BUF_SIZE - DP_DSC_SUPPORT] + 1; - dsc_sink_caps->rc_buffer_size = buff_size * buff_block_size; - } - - dsc_sink_caps->slice_caps1.raw = dpcd_dsc_data[DP_DSC_SLICE_CAP_1 - DP_DSC_SUPPORT]; - if (!dsc_line_buff_depth_from_dpcd(dpcd_dsc_data[DP_DSC_LINE_BUF_BIT_DEPTH - DP_DSC_SUPPORT], &dsc_sink_caps->lb_bit_depth)) - return false; - - dsc_sink_caps->is_block_pred_supported = - (dpcd_dsc_data[DP_DSC_BLK_PREDICTION_SUPPORT - DP_DSC_SUPPORT] & DP_DSC_BLK_PREDICTION_IS_SUPPORTED) != 0; - - dsc_sink_caps->edp_max_bits_per_pixel = - dpcd_dsc_data[DP_DSC_MAX_BITS_PER_PIXEL_LOW - DP_DSC_SUPPORT] | - dpcd_dsc_data[DP_DSC_MAX_BITS_PER_PIXEL_HI - DP_DSC_SUPPORT] << 8; - - dsc_sink_caps->color_formats.raw = dpcd_dsc_data[DP_DSC_DEC_COLOR_FORMAT_CAP - DP_DSC_SUPPORT]; - dsc_sink_caps->color_depth.raw = dpcd_dsc_data[DP_DSC_DEC_COLOR_DEPTH_CAP - DP_DSC_SUPPORT]; - - { - int dpcd_throughput = dpcd_dsc_data[DP_DSC_PEAK_THROUGHPUT - DP_DSC_SUPPORT]; - - if (!dsc_throughput_from_dpcd(dpcd_throughput & DP_DSC_THROUGHPUT_MODE_0_MASK, &dsc_sink_caps->throughput_mode_0_mps)) - return false; - - dpcd_throughput = (dpcd_throughput & DP_DSC_THROUGHPUT_MODE_1_MASK) >> DP_DSC_THROUGHPUT_MODE_1_SHIFT; - if (!dsc_throughput_from_dpcd(dpcd_throughput, &dsc_sink_caps->throughput_mode_1_mps)) - return false; - } - - dsc_sink_caps->max_slice_width = dpcd_dsc_data[DP_DSC_MAX_SLICE_WIDTH - DP_DSC_SUPPORT] * 320; - dsc_sink_caps->slice_caps2.raw = dpcd_dsc_data[DP_DSC_SLICE_CAP_2 - DP_DSC_SUPPORT]; - - if (!dsc_bpp_increment_div_from_dpcd(dpcd_dsc_data[DP_DSC_BITS_PER_PIXEL_INC - DP_DSC_SUPPORT], &dsc_sink_caps->bpp_increment_div)) - return false; - - return true; -} - - -/* This module's internal functions */ - -static bool dsc_buff_block_size_from_dpcd(int dpcd_buff_block_size, int *buff_block_size) -{ - - switch (dpcd_buff_block_size) { - case DP_DSC_RC_BUF_BLK_SIZE_1: - *buff_block_size = 1024; - break; - case DP_DSC_RC_BUF_BLK_SIZE_4: - *buff_block_size = 4 * 1024; - break; - case DP_DSC_RC_BUF_BLK_SIZE_16: - *buff_block_size = 16 * 1024; - break; - case DP_DSC_RC_BUF_BLK_SIZE_64: - *buff_block_size = 64 * 1024; - break; - default: { - dm_error("%s: DPCD DSC buffer size not recoginzed.\n", __func__); - return false; - } - } - - return true; -} - - -static bool dsc_line_buff_depth_from_dpcd(int dpcd_line_buff_bit_depth, int *line_buff_bit_depth) -{ - if (0 <= dpcd_line_buff_bit_depth && dpcd_line_buff_bit_depth <= 7) - *line_buff_bit_depth = dpcd_line_buff_bit_depth + 9; - else if (dpcd_line_buff_bit_depth == 8) - *line_buff_bit_depth = 8; - else { - dm_error("%s: DPCD DSC buffer depth not recoginzed.\n", __func__); - return false; - } - - return true; -} - - -static bool dsc_throughput_from_dpcd(int dpcd_throughput, int *throughput) -{ - switch (dpcd_throughput) { - case DP_DSC_THROUGHPUT_MODE_0_340: - *throughput = 340; - break; - case DP_DSC_THROUGHPUT_MODE_0_400: - *throughput = 400; - break; - case DP_DSC_THROUGHPUT_MODE_0_450: - *throughput = 450; - break; - case DP_DSC_THROUGHPUT_MODE_0_500: - *throughput = 500; - break; - case DP_DSC_THROUGHPUT_MODE_0_550: - *throughput = 550; - break; - case DP_DSC_THROUGHPUT_MODE_0_600: - *throughput = 600; - break; - case DP_DSC_THROUGHPUT_MODE_0_650: - *throughput = 650; - break; - case DP_DSC_THROUGHPUT_MODE_0_700: - *throughput = 700; - break; - case DP_DSC_THROUGHPUT_MODE_0_750: - *throughput = 750; - break; - case DP_DSC_THROUGHPUT_MODE_0_800: - *throughput = 800; - break; - case DP_DSC_THROUGHPUT_MODE_0_850: - *throughput = 850; - break; - case DP_DSC_THROUGHPUT_MODE_0_900: - *throughput = 900; - break; - case DP_DSC_THROUGHPUT_MODE_0_950: - *throughput = 950; - break; - case DP_DSC_THROUGHPUT_MODE_0_1000: - *throughput = 1000; - break; - default: { - dm_error("%s: DPCD DSC througput mode not recoginzed.\n", __func__); - return false; - } - } - - return true; -} - - -static bool dsc_bpp_increment_div_from_dpcd(int bpp_increment_dpcd, uint32_t *bpp_increment_div) -{ - - switch (bpp_increment_dpcd) { - case 0: - *bpp_increment_div = 16; - break; - case 1: - *bpp_increment_div = 8; - break; - case 2: - *bpp_increment_div = 4; - break; - case 3: - *bpp_increment_div = 2; - break; - case 4: - *bpp_increment_div = 1; - break; - default: { - dm_error("%s: DPCD DSC bits-per-pixel increment not recoginzed.\n", __func__); - return false; - } - } - - return true; -} - - -#endif // CONFIG_DRM_AMD_DC_DSC_SUPPORT diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h index 3fc534ee8174..c0c947a42a59 100644 --- a/include/drm/drm_dp_helper.h +++ b/include/drm/drm_dp_helper.h @@ -249,6 +249,7 @@ #define DP_DSC_PEAK_THROUGHPUT 0x06B # define DP_DSC_THROUGHPUT_MODE_0_MASK (0xf << 0) # define DP_DSC_THROUGHPUT_MODE_0_SHIFT 0 +# define DP_DSC_THROUGHPUT_MODE_0_UPSUPPORTED 0 # define DP_DSC_THROUGHPUT_MODE_0_340 (1 << 0) # define DP_DSC_THROUGHPUT_MODE_0_400 (2 << 0) # define DP_DSC_THROUGHPUT_MODE_0_450 (3 << 0) @@ -263,8 +264,10 @@ # define DP_DSC_THROUGHPUT_MODE_0_900 (12 << 0) # define DP_DSC_THROUGHPUT_MODE_0_950 (13 << 0) # define DP_DSC_THROUGHPUT_MODE_0_1000 (14 << 0) +# define DP_DSC_THROUGHPUT_MODE_0_170 (15 << 4) # define DP_DSC_THROUGHPUT_MODE_1_MASK (0xf << 4) # define DP_DSC_THROUGHPUT_MODE_1_SHIFT 4 +# define DP_DSC_THROUGHPUT_MODE_1_UPSUPPORTED 0 # define DP_DSC_THROUGHPUT_MODE_1_340 (1 << 4) # define DP_DSC_THROUGHPUT_MODE_1_400 (2 << 4) # define DP_DSC_THROUGHPUT_MODE_1_450 (3 << 4) @@ -279,6 +282,7 @@ # define DP_DSC_THROUGHPUT_MODE_1_900 (12 << 4) # define DP_DSC_THROUGHPUT_MODE_1_950 (13 << 4) # define DP_DSC_THROUGHPUT_MODE_1_1000 (14 << 4) +# define DP_DSC_THROUGHPUT_MODE_1_170 (15 << 4) #define DP_DSC_MAX_SLICE_WIDTH 0x06C #define DP_DSC_MIN_SLICE_WIDTH_VALUE 2560