diff options
Diffstat (limited to 'drivers/gpu/drm/amd/display/dc/dsc')
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dsc/Makefile | 35 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c | 253 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dsc/drm_dsc_dc.c | 388 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dsc/dscc_types.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dsc/qp_tables.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c | 2 |
8 files changed, 215 insertions, 474 deletions
diff --git a/drivers/gpu/drm/amd/display/dc/dsc/Makefile b/drivers/gpu/drm/amd/display/dc/dsc/Makefile index e019cd9447e8..3f66868df171 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/Makefile +++ b/drivers/gpu/drm/amd/display/dc/dsc/Makefile @@ -1,18 +1,35 @@ +# SPDX-License-Identifier: MIT # # Makefile for the 'dsc' sub-component of DAL. -ifneq ($(call cc-option, -mpreferred-stack-boundary=4),) - cc_stack_align := -mpreferred-stack-boundary=4 -else ifneq ($(call cc-option, -mstack-alignment=16),) - cc_stack_align := -mstack-alignment=16 +ifdef CONFIG_X86 +dsc_ccflags := -mhard-float -msse endif -dsc_ccflags := -mhard-float -msse $(cc_stack_align) +ifdef CONFIG_PPC64 +dsc_ccflags := -mhard-float -maltivec +endif + +ifdef CONFIG_CC_IS_GCC +ifeq ($(call cc-ifversion, -lt, 0701, y), y) +IS_OLD_GCC = 1 +endif +endif + +ifdef CONFIG_X86 +ifdef IS_OLD_GCC +# Stack alignment mismatch, proceed with caution. +# GCC < 7.1 cannot compile code using `double` and -mpreferred-stack-boundary=3 +# (8B stack alignment). +dsc_ccflags += -mpreferred-stack-boundary=4 +else +dsc_ccflags += -msse2 +endif +endif -CFLAGS_rc_calc.o := $(dsc_ccflags) -CFLAGS_rc_calc_dpi.o := $(dsc_ccflags) -CFLAGS_codec_main_amd.o := $(dsc_ccflags) -CFLAGS_dc_dsc.o := $(dsc_ccflags) +CFLAGS_$(AMDDALPATH)/dc/dsc/rc_calc.o := $(dsc_ccflags) +CFLAGS_$(AMDDALPATH)/dc/dsc/rc_calc_dpi.o := $(dsc_ccflags) +CFLAGS_$(AMDDALPATH)/dc/dsc/dc_dsc.o := $(dsc_ccflags) DSC = dc_dsc.o rc_calc.o rc_calc_dpi.o 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..87d682d25278 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c +++ b/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c @@ -22,14 +22,69 @@ * Author: AMD */ -#ifdef CONFIG_DRM_AMD_DC_DSC_SUPPORT -#include "dc.h" -#include "core_types.h" +#include "dc_hw_types.h" #include "dsc.h" #include <drm/drm_dp_helper.h> +#include "dc.h" /* This module's internal functions */ +/* default DSC policy target bitrate limit is 16bpp */ +static uint32_t dsc_policy_max_target_bpp_limit = 16; + +static uint32_t dc_dsc_bandwidth_in_kbps_from_timing( + const struct dc_crtc_timing *timing) +{ + uint32_t bits_per_channel = 0; + uint32_t kbps; + + if (timing->flags.DSC) { + kbps = (timing->pix_clk_100hz * timing->dsc_cfg.bits_per_pixel); + kbps = kbps / 160 + ((kbps % 160) ? 1 : 0); + return kbps; + } + + switch (timing->display_color_depth) { + case COLOR_DEPTH_666: + bits_per_channel = 6; + break; + case COLOR_DEPTH_888: + bits_per_channel = 8; + break; + case COLOR_DEPTH_101010: + bits_per_channel = 10; + break; + case COLOR_DEPTH_121212: + bits_per_channel = 12; + break; + case COLOR_DEPTH_141414: + bits_per_channel = 14; + break; + case COLOR_DEPTH_161616: + bits_per_channel = 16; + break; + default: + break; + } + + ASSERT(bits_per_channel != 0); + + kbps = timing->pix_clk_100hz / 10; + kbps *= bits_per_channel; + + if (timing->flags.Y_ONLY != 1) { + /*Only YOnly make reduce bandwidth by 1/3 compares to RGB*/ + kbps *= 3; + if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR420) + kbps /= 2; + else if (timing->pixel_encoding == PIXEL_ENCODING_YCBCR422) + kbps = kbps * 2 / 3; + } + + return kbps; + +} + static bool dsc_buff_block_size_from_dpcd(int dpcd_buff_block_size, int *buff_block_size) { @@ -161,16 +216,19 @@ static bool dsc_bpp_increment_div_from_dpcd(int bpp_increment_dpcd, uint32_t *bp } static void get_dsc_enc_caps( - const struct dc *dc, + const struct display_stream_compressor *dsc, struct dsc_enc_caps *dsc_enc_caps, int pixel_clock_100Hz) { // This is a static HW query, so we can use any DSC - struct display_stream_compressor *dsc = dc->res_pool->dscs[0]; memset(dsc_enc_caps, 0, sizeof(struct dsc_enc_caps)); - if (dsc) - dsc->funcs->dsc_get_enc_caps(dsc_enc_caps, pixel_clock_100Hz); + if (dsc) { + if (!dsc->ctx->dc->debug.disable_dsc) + dsc->funcs->dsc_get_enc_caps(dsc_enc_caps, pixel_clock_100Hz); + if (dsc->ctx->dc->debug.native422_support) + dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_422 = 1; + } } /* Returns 'false' if no intersection was found for at least one capablity. @@ -241,14 +299,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 +320,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. */ @@ -294,7 +331,7 @@ static void get_dsc_bandwidth_range( struct dc_dsc_bw_range *range) { /* native stream bandwidth */ - range->stream_kbps = dc_bandwidth_in_kbps_from_timing(timing); + range->stream_kbps = dc_dsc_bandwidth_in_kbps_from_timing(timing); /* max dsc target bpp */ range->max_kbps = dsc_div_by_10_round_up(max_bpp * timing->pix_clk_100hz); @@ -516,6 +553,7 @@ static bool setup_dsc_config( const struct dsc_enc_caps *dsc_enc_caps, int target_bandwidth_kbps, const struct dc_crtc_timing *timing, + int min_slice_height_override, struct dc_dsc_config *dsc_cfg) { struct dsc_enc_caps dsc_common_caps; @@ -528,11 +566,13 @@ 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; + 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; @@ -548,7 +588,12 @@ static bool setup_dsc_config( goto done; if (target_bandwidth_kbps > 0) { - is_dsc_possible = decide_dsc_target_bpp_x16(&dsc_policy, &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) @@ -615,7 +660,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) { @@ -650,20 +695,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 @@ -678,29 +723,29 @@ 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; + if (min_slice_height_override == 0) + slice_height = min(policy.min_slice_height, pic_height); + else + slice_height = min(min_slice_height_override, 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 @@ -716,7 +761,7 @@ done: return is_dsc_possible; } -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) +bool dc_dsc_parse_dsc_dpcd(const struct dc *dc, const uint8_t *dpcd_dsc_basic_data, const uint8_t *dpcd_dsc_ext_data, struct dsc_dec_dpcd_caps *dsc_sink_caps) { if (!dpcd_dsc_basic_data) return false; @@ -769,6 +814,23 @@ bool dc_dsc_parse_dsc_dpcd(const uint8_t *dpcd_dsc_basic_data, const uint8_t *dp if (!dsc_bpp_increment_div_from_dpcd(dpcd_dsc_basic_data[DP_DSC_BITS_PER_PIXEL_INC - DP_DSC_SUPPORT], &dsc_sink_caps->bpp_increment_div)) return false; + if (dc->debug.dsc_bpp_increment_div) { + /* dsc_bpp_increment_div should onl be 1, 2, 4, 8 or 16, but rather than rejecting invalid values, + * we'll accept all and get it into range. This also makes the above check against 0 redundant, + * but that one stresses out the override will be only used if it's not 0. + */ + if (dc->debug.dsc_bpp_increment_div >= 1) + dsc_sink_caps->bpp_increment_div = 1; + if (dc->debug.dsc_bpp_increment_div >= 2) + dsc_sink_caps->bpp_increment_div = 2; + if (dc->debug.dsc_bpp_increment_div >= 4) + dsc_sink_caps->bpp_increment_div = 4; + if (dc->debug.dsc_bpp_increment_div >= 8) + dsc_sink_caps->bpp_increment_div = 8; + if (dc->debug.dsc_bpp_increment_div >= 16) + dsc_sink_caps->bpp_increment_div = 16; + } + /* Extended caps */ if (dpcd_dsc_ext_data == NULL) { // Extended DPCD DSC data can be null, e.g. because it doesn't apply to SST dsc_sink_caps->branch_overall_throughput_0_mps = 0; @@ -809,7 +871,8 @@ bool dc_dsc_parse_dsc_dpcd(const uint8_t *dpcd_dsc_basic_data, const uint8_t *dp * If DSC is not possible, leave '*range' untouched. */ bool dc_dsc_compute_bandwidth_range( - const struct dc *dc, + const struct display_stream_compressor *dsc, + const uint32_t dsc_min_slice_height_override, const uint32_t min_bpp, const uint32_t max_bpp, const struct dsc_dec_dpcd_caps *dsc_sink_caps, @@ -821,16 +884,14 @@ bool dc_dsc_compute_bandwidth_range( struct dsc_enc_caps dsc_common_caps; struct dc_dsc_config config; - get_dsc_enc_caps(dc, &dsc_enc_caps, timing->pix_clk_100hz); + get_dsc_enc_caps(dsc, &dsc_enc_caps, timing->pix_clk_100hz); is_dsc_possible = intersect_dsc_caps(dsc_sink_caps, &dsc_enc_caps, timing->pixel_encoding, &dsc_common_caps); if (is_dsc_possible) - is_dsc_possible = setup_dsc_config(dsc_sink_caps, - &dsc_enc_caps, - 0, - timing, &config); + is_dsc_possible = setup_dsc_config(dsc_sink_caps, &dsc_enc_caps, 0, timing, + dsc_min_slice_height_override, &config); if (is_dsc_possible) get_dsc_bandwidth_range(min_bpp, max_bpp, &dsc_common_caps, timing, range); @@ -839,8 +900,9 @@ bool dc_dsc_compute_bandwidth_range( } bool dc_dsc_compute_config( - const struct dc *dc, + const struct display_stream_compressor *dsc, const struct dsc_dec_dpcd_caps *dsc_sink_caps, + const uint32_t dsc_min_slice_height_override, uint32_t target_bandwidth_kbps, const struct dc_crtc_timing *timing, struct dc_dsc_config *dsc_cfg) @@ -848,11 +910,74 @@ bool dc_dsc_compute_config( bool is_dsc_possible = false; struct dsc_enc_caps dsc_enc_caps; - get_dsc_enc_caps(dc, &dsc_enc_caps, timing->pix_clk_100hz); + get_dsc_enc_caps(dsc, &dsc_enc_caps, timing->pix_clk_100hz); is_dsc_possible = setup_dsc_config(dsc_sink_caps, &dsc_enc_caps, target_bandwidth_kbps, - timing, dsc_cfg); + timing, dsc_min_slice_height_override, dsc_cfg); return is_dsc_possible; } -#endif /* CONFIG_DRM_AMD_DC_DSC_SUPPORT */ + +void dc_dsc_get_policy_for_timing(const struct dc_crtc_timing *timing, struct dc_dsc_policy *policy) +{ + 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; + + /* 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_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, default 16 bpp */ + if (policy->max_target_bpp > dsc_policy_max_target_bpp_limit) + policy->max_target_bpp = dsc_policy_max_target_bpp_limit; +} + +void dc_dsc_policy_set_max_target_bpp_limit(uint32_t limit) +{ + dsc_policy_max_target_bpp_limit = limit; +} diff --git a/drivers/gpu/drm/amd/display/dc/dsc/drm_dsc_dc.c b/drivers/gpu/drm/amd/display/dc/dsc/drm_dsc_dc.c deleted file mode 100644 index 340ef4d41ebd..000000000000 --- a/drivers/gpu/drm/amd/display/dc/dsc/drm_dsc_dc.c +++ /dev/null @@ -1,388 +0,0 @@ -// SPDX-License-Identifier: MIT -/* - * Copyright © 2018 Intel Corp - * - * Author: - * Manasi Navare <manasi.d.navare@intel.com> - */ - -/* DC versions of linux includes */ -#include <include/drm_dsc_dc.h> - -#define EXPORT_SYMBOL(symbol) /* nothing */ -#define BUILD_BUG_ON(cond) /* nothing */ -#define DIV_ROUND_UP(a, b) (((b) + (a) - 1) / (b)) -#define ERANGE -1 -#define DRM_DEBUG_KMS(msg) /* nothing */ -#define cpu_to_be16(__x) little_to_big(__x) - -static unsigned short little_to_big(int data) -{ - /* Swap lower and upper byte. DMCU uses big endian format. */ - return (0xff & (data >> 8)) + ((data & 0xff) << 8); -} - -/* - * Everything below this comment was copied directly from drm_dsc.c. - * Only the functions needed in DC are included. - * Please keep this file synced with upstream. - */ - -/** - * DOC: dsc helpers - * - * These functions contain some common logic and helpers to deal with VESA - * Display Stream Compression standard required for DSC on Display Port/eDP or - * MIPI display interfaces. - */ - -/** - * drm_dsc_pps_payload_pack() - Populates the DSC PPS - * - * @pps_payload: - * Bitwise struct for DSC Picture Parameter Set. This is defined - * by &struct drm_dsc_picture_parameter_set - * @dsc_cfg: - * DSC Configuration data filled by driver as defined by - * &struct drm_dsc_config - * - * DSC source device sends a picture parameter set (PPS) containing the - * information required by the sink to decode the compressed frame. Driver - * populates the DSC PPS struct using the DSC configuration parameters in - * the order expected by the DSC Display Sink device. For the DSC, the sink - * device expects the PPS payload in big endian format for fields - * that span more than 1 byte. - */ -void drm_dsc_pps_payload_pack(struct drm_dsc_picture_parameter_set *pps_payload, - const struct drm_dsc_config *dsc_cfg) -{ - int i; - - /* Protect against someone accidently changing struct size */ - BUILD_BUG_ON(sizeof(*pps_payload) != - DP_SDP_PPS_HEADER_PAYLOAD_BYTES_MINUS_1 + 1); - - memset(pps_payload, 0, sizeof(*pps_payload)); - - /* PPS 0 */ - pps_payload->dsc_version = - dsc_cfg->dsc_version_minor | - dsc_cfg->dsc_version_major << DSC_PPS_VERSION_MAJOR_SHIFT; - - /* PPS 1, 2 is 0 */ - - /* PPS 3 */ - pps_payload->pps_3 = - dsc_cfg->line_buf_depth | - dsc_cfg->bits_per_component << DSC_PPS_BPC_SHIFT; - - /* PPS 4 */ - pps_payload->pps_4 = - ((dsc_cfg->bits_per_pixel & DSC_PPS_BPP_HIGH_MASK) >> - DSC_PPS_MSB_SHIFT) | - dsc_cfg->vbr_enable << DSC_PPS_VBR_EN_SHIFT | - dsc_cfg->simple_422 << DSC_PPS_SIMPLE422_SHIFT | - dsc_cfg->convert_rgb << DSC_PPS_CONVERT_RGB_SHIFT | - dsc_cfg->block_pred_enable << DSC_PPS_BLOCK_PRED_EN_SHIFT; - - /* PPS 5 */ - pps_payload->bits_per_pixel_low = - (dsc_cfg->bits_per_pixel & DSC_PPS_LSB_MASK); - - /* - * The DSC panel expects the PPS packet to have big endian format - * for data spanning 2 bytes. Use a macro cpu_to_be16() to convert - * to big endian format. If format is little endian, it will swap - * bytes to convert to Big endian else keep it unchanged. - */ - - /* PPS 6, 7 */ - pps_payload->pic_height = cpu_to_be16(dsc_cfg->pic_height); - - /* PPS 8, 9 */ - pps_payload->pic_width = cpu_to_be16(dsc_cfg->pic_width); - - /* PPS 10, 11 */ - pps_payload->slice_height = cpu_to_be16(dsc_cfg->slice_height); - - /* PPS 12, 13 */ - pps_payload->slice_width = cpu_to_be16(dsc_cfg->slice_width); - - /* PPS 14, 15 */ - pps_payload->chunk_size = cpu_to_be16(dsc_cfg->slice_chunk_size); - - /* PPS 16 */ - pps_payload->initial_xmit_delay_high = - ((dsc_cfg->initial_xmit_delay & - DSC_PPS_INIT_XMIT_DELAY_HIGH_MASK) >> - DSC_PPS_MSB_SHIFT); - - /* PPS 17 */ - pps_payload->initial_xmit_delay_low = - (dsc_cfg->initial_xmit_delay & DSC_PPS_LSB_MASK); - - /* PPS 18, 19 */ - pps_payload->initial_dec_delay = - cpu_to_be16(dsc_cfg->initial_dec_delay); - - /* PPS 20 is 0 */ - - /* PPS 21 */ - pps_payload->initial_scale_value = - dsc_cfg->initial_scale_value; - - /* PPS 22, 23 */ - pps_payload->scale_increment_interval = - cpu_to_be16(dsc_cfg->scale_increment_interval); - - /* PPS 24 */ - pps_payload->scale_decrement_interval_high = - ((dsc_cfg->scale_decrement_interval & - DSC_PPS_SCALE_DEC_INT_HIGH_MASK) >> - DSC_PPS_MSB_SHIFT); - - /* PPS 25 */ - pps_payload->scale_decrement_interval_low = - (dsc_cfg->scale_decrement_interval & DSC_PPS_LSB_MASK); - - /* PPS 26[7:0], PPS 27[7:5] RESERVED */ - - /* PPS 27 */ - pps_payload->first_line_bpg_offset = - dsc_cfg->first_line_bpg_offset; - - /* PPS 28, 29 */ - pps_payload->nfl_bpg_offset = - cpu_to_be16(dsc_cfg->nfl_bpg_offset); - - /* PPS 30, 31 */ - pps_payload->slice_bpg_offset = - cpu_to_be16(dsc_cfg->slice_bpg_offset); - - /* PPS 32, 33 */ - pps_payload->initial_offset = - cpu_to_be16(dsc_cfg->initial_offset); - - /* PPS 34, 35 */ - pps_payload->final_offset = cpu_to_be16(dsc_cfg->final_offset); - - /* PPS 36 */ - pps_payload->flatness_min_qp = dsc_cfg->flatness_min_qp; - - /* PPS 37 */ - pps_payload->flatness_max_qp = dsc_cfg->flatness_max_qp; - - /* PPS 38, 39 */ - pps_payload->rc_model_size = - cpu_to_be16(DSC_RC_MODEL_SIZE_CONST); - - /* PPS 40 */ - pps_payload->rc_edge_factor = DSC_RC_EDGE_FACTOR_CONST; - - /* PPS 41 */ - pps_payload->rc_quant_incr_limit0 = - dsc_cfg->rc_quant_incr_limit0; - - /* PPS 42 */ - pps_payload->rc_quant_incr_limit1 = - dsc_cfg->rc_quant_incr_limit1; - - /* PPS 43 */ - pps_payload->rc_tgt_offset = DSC_RC_TGT_OFFSET_LO_CONST | - DSC_RC_TGT_OFFSET_HI_CONST << DSC_PPS_RC_TGT_OFFSET_HI_SHIFT; - - /* PPS 44 - 57 */ - for (i = 0; i < DSC_NUM_BUF_RANGES - 1; i++) - pps_payload->rc_buf_thresh[i] = - dsc_cfg->rc_buf_thresh[i]; - - /* PPS 58 - 87 */ - /* - * For DSC sink programming the RC Range parameter fields - * are as follows: Min_qp[15:11], max_qp[10:6], offset[5:0] - */ - for (i = 0; i < DSC_NUM_BUF_RANGES; i++) { - pps_payload->rc_range_parameters[i] = - ((dsc_cfg->rc_range_params[i].range_min_qp << - DSC_PPS_RC_RANGE_MINQP_SHIFT) | - (dsc_cfg->rc_range_params[i].range_max_qp << - DSC_PPS_RC_RANGE_MAXQP_SHIFT) | - (dsc_cfg->rc_range_params[i].range_bpg_offset)); - pps_payload->rc_range_parameters[i] = - cpu_to_be16(pps_payload->rc_range_parameters[i]); - } - - /* PPS 88 */ - pps_payload->native_422_420 = dsc_cfg->native_422 | - dsc_cfg->native_420 << DSC_PPS_NATIVE_420_SHIFT; - - /* PPS 89 */ - pps_payload->second_line_bpg_offset = - dsc_cfg->second_line_bpg_offset; - - /* PPS 90, 91 */ - pps_payload->nsl_bpg_offset = - cpu_to_be16(dsc_cfg->nsl_bpg_offset); - - /* PPS 92, 93 */ - pps_payload->second_line_offset_adj = - cpu_to_be16(dsc_cfg->second_line_offset_adj); - - /* PPS 94 - 127 are O */ -} -EXPORT_SYMBOL(drm_dsc_pps_payload_pack); - -/** - * drm_dsc_compute_rc_parameters() - Write rate control - * parameters to the dsc configuration defined in - * &struct drm_dsc_config in accordance with the DSC 1.2 - * specification. Some configuration fields must be present - * beforehand. - * - * @vdsc_cfg: - * DSC Configuration data partially filled by driver - */ -int drm_dsc_compute_rc_parameters(struct drm_dsc_config *vdsc_cfg) -{ - unsigned long groups_per_line = 0; - unsigned long groups_total = 0; - unsigned long num_extra_mux_bits = 0; - unsigned long slice_bits = 0; - unsigned long hrd_delay = 0; - unsigned long final_scale = 0; - unsigned long rbs_min = 0; - - if (vdsc_cfg->native_420 || vdsc_cfg->native_422) { - /* Number of groups used to code each line of a slice */ - groups_per_line = DIV_ROUND_UP(vdsc_cfg->slice_width / 2, - DSC_RC_PIXELS_PER_GROUP); - - /* chunksize in Bytes */ - vdsc_cfg->slice_chunk_size = DIV_ROUND_UP(vdsc_cfg->slice_width / 2 * - vdsc_cfg->bits_per_pixel, - (8 * 16)); - } else { - /* Number of groups used to code each line of a slice */ - groups_per_line = DIV_ROUND_UP(vdsc_cfg->slice_width, - DSC_RC_PIXELS_PER_GROUP); - - /* chunksize in Bytes */ - vdsc_cfg->slice_chunk_size = DIV_ROUND_UP(vdsc_cfg->slice_width * - vdsc_cfg->bits_per_pixel, - (8 * 16)); - } - - if (vdsc_cfg->convert_rgb) - num_extra_mux_bits = 3 * (vdsc_cfg->mux_word_size + - (4 * vdsc_cfg->bits_per_component + 4) - - 2); - else if (vdsc_cfg->native_422) - num_extra_mux_bits = 4 * vdsc_cfg->mux_word_size + - (4 * vdsc_cfg->bits_per_component + 4) + - 3 * (4 * vdsc_cfg->bits_per_component) - 2; - else - num_extra_mux_bits = 3 * vdsc_cfg->mux_word_size + - (4 * vdsc_cfg->bits_per_component + 4) + - 2 * (4 * vdsc_cfg->bits_per_component) - 2; - /* Number of bits in one Slice */ - slice_bits = 8 * vdsc_cfg->slice_chunk_size * vdsc_cfg->slice_height; - - while ((num_extra_mux_bits > 0) && - ((slice_bits - num_extra_mux_bits) % vdsc_cfg->mux_word_size)) - num_extra_mux_bits--; - - if (groups_per_line < vdsc_cfg->initial_scale_value - 8) - vdsc_cfg->initial_scale_value = groups_per_line + 8; - - /* scale_decrement_interval calculation according to DSC spec 1.11 */ - if (vdsc_cfg->initial_scale_value > 8) - vdsc_cfg->scale_decrement_interval = groups_per_line / - (vdsc_cfg->initial_scale_value - 8); - else - vdsc_cfg->scale_decrement_interval = DSC_SCALE_DECREMENT_INTERVAL_MAX; - - vdsc_cfg->final_offset = vdsc_cfg->rc_model_size - - (vdsc_cfg->initial_xmit_delay * - vdsc_cfg->bits_per_pixel + 8) / 16 + num_extra_mux_bits; - - if (vdsc_cfg->final_offset >= vdsc_cfg->rc_model_size) { - DRM_DEBUG_KMS("FinalOfs < RcModelSze for this InitialXmitDelay\n"); - return -ERANGE; - } - - final_scale = (vdsc_cfg->rc_model_size * 8) / - (vdsc_cfg->rc_model_size - vdsc_cfg->final_offset); - if (vdsc_cfg->slice_height > 1) - /* - * NflBpgOffset is 16 bit value with 11 fractional bits - * hence we multiply by 2^11 for preserving the - * fractional part - */ - vdsc_cfg->nfl_bpg_offset = DIV_ROUND_UP((vdsc_cfg->first_line_bpg_offset << 11), - (vdsc_cfg->slice_height - 1)); - else - vdsc_cfg->nfl_bpg_offset = 0; - - /* 2^16 - 1 */ - if (vdsc_cfg->nfl_bpg_offset > 65535) { - DRM_DEBUG_KMS("NflBpgOffset is too large for this slice height\n"); - return -ERANGE; - } - - /* Number of groups used to code the entire slice */ - groups_total = groups_per_line * vdsc_cfg->slice_height; - - /* slice_bpg_offset is 16 bit value with 11 fractional bits */ - vdsc_cfg->slice_bpg_offset = DIV_ROUND_UP(((vdsc_cfg->rc_model_size - - vdsc_cfg->initial_offset + - num_extra_mux_bits) << 11), - groups_total); - - if (final_scale > 9) { - /* - * ScaleIncrementInterval = - * finaloffset/((NflBpgOffset + SliceBpgOffset)*8(finalscale - 1.125)) - * as (NflBpgOffset + SliceBpgOffset) has 11 bit fractional value, - * we need divide by 2^11 from pstDscCfg values - */ - vdsc_cfg->scale_increment_interval = - (vdsc_cfg->final_offset * (1 << 11)) / - ((vdsc_cfg->nfl_bpg_offset + - vdsc_cfg->slice_bpg_offset) * - (final_scale - 9)); - } else { - /* - * If finalScaleValue is less than or equal to 9, a value of 0 should - * be used to disable the scale increment at the end of the slice - */ - vdsc_cfg->scale_increment_interval = 0; - } - - if (vdsc_cfg->scale_increment_interval > 65535) { - DRM_DEBUG_KMS("ScaleIncrementInterval is large for slice height\n"); - return -ERANGE; - } - - /* - * DSC spec mentions that bits_per_pixel specifies the target - * bits/pixel (bpp) rate that is used by the encoder, - * in steps of 1/16 of a bit per pixel - */ - rbs_min = vdsc_cfg->rc_model_size - vdsc_cfg->initial_offset + - DIV_ROUND_UP(vdsc_cfg->initial_xmit_delay * - vdsc_cfg->bits_per_pixel, 16) + - groups_per_line * vdsc_cfg->first_line_bpg_offset; - - hrd_delay = DIV_ROUND_UP((rbs_min * 16), vdsc_cfg->bits_per_pixel); - vdsc_cfg->rc_bits = (hrd_delay * vdsc_cfg->bits_per_pixel) / 16; - vdsc_cfg->initial_dec_delay = hrd_delay - vdsc_cfg->initial_xmit_delay; - - /* As per DSC spec v1.2a recommendation: */ - if (vdsc_cfg->native_420) - vdsc_cfg->second_line_offset_adj = 512; - else - vdsc_cfg->second_line_offset_adj = 0; - - return 0; -} -EXPORT_SYMBOL(drm_dsc_compute_rc_parameters); diff --git a/drivers/gpu/drm/amd/display/dc/dsc/dscc_types.h b/drivers/gpu/drm/amd/display/dc/dsc/dscc_types.h index 020ad8f685ea..9f70e87b3ecb 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/dscc_types.h +++ b/drivers/gpu/drm/amd/display/dc/dsc/dscc_types.h @@ -1,4 +1,3 @@ -#if defined(CONFIG_DRM_AMD_DC_DCN2_0) /* * Copyright 2017 Advanced Micro Devices, Inc. @@ -51,4 +50,3 @@ int dscc_compute_dsc_parameters(const struct drm_dsc_config *pps, struct dsc_par #endif -#endif diff --git a/drivers/gpu/drm/amd/display/dc/dsc/qp_tables.h b/drivers/gpu/drm/amd/display/dc/dsc/qp_tables.h index f66d006eac5d..e5fac9f4181d 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/qp_tables.h +++ b/drivers/gpu/drm/amd/display/dc/dsc/qp_tables.h @@ -1,4 +1,3 @@ -#if defined(CONFIG_DRM_AMD_DC_DCN2_0) /* * Copyright 2017 Advanced Micro Devices, Inc. @@ -703,4 +702,3 @@ const qp_table qp_table_422_8bpc_max = { { 16, { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 4} } }; -#endif diff --git a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c index ca51e83f8764..03ae15946c6d 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c +++ b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.c @@ -1,4 +1,3 @@ -#if defined(CONFIG_DRM_AMD_DC_DSC_SUPPORT) /* * Copyright 2017 Advanced Micro Devices, Inc. @@ -177,7 +176,6 @@ void calc_rc_params(struct rc_params *rc, enum colour_mode cm, enum bits_per_com { float bpp_group; float initial_xmit_delay_factor; - int source_bpp; int padding_pixels; int i; @@ -217,8 +215,6 @@ void calc_rc_params(struct rc_params *rc, enum colour_mode cm, enum bits_per_com rc->initial_xmit_delay++; } - source_bpp = MODE_SELECT(bpc * 3, bpc * 2, bpc * 1.5); - rc->flatness_min_qp = ((bpc == BPC_8) ? (3) : ((bpc == BPC_10) ? (7) : (11))) - ((minor_version == 1 && cm == CM_444) ? 1 : 0); rc->flatness_max_qp = ((bpc == BPC_8) ? (12) : ((bpc == BPC_10) ? (16) : (20))) - ((minor_version == 1 && cm == CM_444) ? 1 : 0); rc->flatness_det_thresh = 2 << (bpc - 8); @@ -255,4 +251,3 @@ void calc_rc_params(struct rc_params *rc, enum colour_mode cm, enum bits_per_com rc->rc_buf_thresh[13] = 8064; } -#endif diff --git a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h index f1d6e793bc61..b6b1f09c2009 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h +++ b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc.h @@ -1,4 +1,3 @@ -#if defined(CONFIG_DRM_AMD_DC_DCN2_0) /* * Copyright 2017 Advanced Micro Devices, Inc. @@ -82,4 +81,3 @@ void calc_rc_params(struct rc_params *rc, enum colour_mode cm, enum bits_per_com #endif -#endif diff --git a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c index 73172fd0b529..1f6e63b71456 100644 --- a/drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c +++ b/drivers/gpu/drm/amd/display/dc/dsc/rc_calc_dpi.c @@ -1,4 +1,3 @@ -#if defined(CONFIG_DRM_AMD_DC_DSC_SUPPORT) /* * Copyright 2012-17 Advanced Micro Devices, Inc. * @@ -144,4 +143,3 @@ int dscc_compute_dsc_parameters(const struct drm_dsc_config *pps, struct dsc_par return ret; } -#endif |