linux/drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c

/*
 * Copyright 2019 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.
 *
 * Author: AMD
 */

#include <drm/display/drm_dp_helper.h>
#include <drm/display/drm_dsc_helper.h>
#include "dc_hw_types.h"
#include "dsc.h"
#include "dc.h"
#include "rc_calc.h"
#include "fixed31_32.h"

/* This module's internal functions */

/* default DSC policy target bitrate limit is 16bpp */
static uint32_t dsc_policy_max_target_bpp_limit =;

/* default DSC policy enables DSC only when needed */
static bool dsc_policy_enable_dsc_when_not_needed;

static bool dsc_policy_disable_dsc_stream_overhead;

static bool disable_128b_132b_stream_overhead;

#ifndef MAX
#define MAX
#endif
#ifndef MIN
#define MIN
#endif

/* Need to account for padding due to pixel-to-symbol packing
 * for uncompressed 128b/132b streams.
 */
static uint32_t apply_128b_132b_stream_overhead(
	const struct dc_crtc_timing *timing, const uint32_t kbps)
{}

uint32_t dc_bandwidth_in_kbps_from_timing(
	const struct dc_crtc_timing *timing,
	const enum dc_link_encoding_format link_encoding)
{}

/* Forward Declerations */
static bool decide_dsc_bandwidth_range(
		const uint32_t min_bpp_x16,
		const uint32_t max_bpp_x16,
		const uint32_t num_slices_h,
		const struct dsc_enc_caps *dsc_caps,
		const struct dc_crtc_timing *timing,
		const enum dc_link_encoding_format link_encoding,
		struct dc_dsc_bw_range *range);

static uint32_t compute_bpp_x16_from_target_bandwidth(
		const uint32_t bandwidth_in_kbps,
		const struct dc_crtc_timing *timing,
		const uint32_t num_slices_h,
		const uint32_t bpp_increment_div,
		const bool is_dp);

static void get_dsc_enc_caps(
		const struct display_stream_compressor *dsc,
		struct dsc_enc_caps *dsc_enc_caps,
		int pixel_clock_100Hz);

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,
		struct dsc_enc_caps *dsc_common_caps);

static bool setup_dsc_config(
		const struct dsc_dec_dpcd_caps *dsc_sink_caps,
		const struct dsc_enc_caps *dsc_enc_caps,
		int target_bandwidth_kbps,
		const struct dc_crtc_timing *timing,
		const struct dc_dsc_config_options *options,
		const enum dc_link_encoding_format link_encoding,
		struct dc_dsc_config *dsc_cfg);

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(uint8_t bpp_increment_dpcd, uint32_t *bpp_increment_div)
{}



bool dc_dsc_parse_dsc_dpcd(const struct dc *dc,
		const uint8_t *dpcd_dsc_basic_data,
		const uint8_t *dpcd_dsc_branch_decoder_caps,
		struct dsc_dec_dpcd_caps *dsc_sink_caps)
{}


/* If DSC is possbile, get DSC bandwidth range based on [min_bpp, max_bpp] target bitrate range and
 * timing's pixel clock and uncompressed bandwidth.
 * If DSC is not possible, leave '*range' untouched.
 */
bool dc_dsc_compute_bandwidth_range(
		const struct display_stream_compressor *dsc,
		uint32_t dsc_min_slice_height_override,
		uint32_t min_bpp_x16,
		uint32_t max_bpp_x16,
		const struct dsc_dec_dpcd_caps *dsc_sink_caps,
		const struct dc_crtc_timing *timing,
		const enum dc_link_encoding_format link_encoding,
		struct dc_dsc_bw_range *range)
{}

static void get_dsc_enc_caps(
		const struct display_stream_compressor *dsc,
		struct dsc_enc_caps *dsc_enc_caps,
		int pixel_clock_100Hz)
{}

/* Returns 'false' if no intersection was found for at least one capability.
 * It also implicitly validates some sink caps against invalid value of zero.
 */
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,
		struct dsc_enc_caps *dsc_common_caps)
{}

static inline uint32_t dsc_div_by_10_round_up(uint32_t value)
{}

static uint32_t compute_bpp_x16_from_target_bandwidth(
	const uint32_t bandwidth_in_kbps,
	const struct dc_crtc_timing *timing,
	const uint32_t num_slices_h,
	const uint32_t bpp_increment_div,
	const bool is_dp)
{}

/* 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 bool decide_dsc_bandwidth_range(
		const uint32_t min_bpp_x16,
		const uint32_t max_bpp_x16,
		const uint32_t num_slices_h,
		const struct dsc_enc_caps *dsc_caps,
		const struct dc_crtc_timing *timing,
		const enum dc_link_encoding_format link_encoding,
		struct dc_dsc_bw_range *range)
{}

/* Decides if DSC should be used and calculates target bpp if it should, applying DSC policy.
 *
 * Returns:
 *     - '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,
		const struct dsc_enc_caps *dsc_common_caps,
		const int target_bandwidth_kbps,
		const struct dc_crtc_timing *timing,
		const int num_slices_h,
		const enum dc_link_encoding_format link_encoding,
		int *target_bpp_x16)
{}

#define MIN_AVAILABLE_SLICES_SIZE

static int get_available_dsc_slices(union dsc_enc_slice_caps slice_caps, int *available_slices)
{}


static int get_max_dsc_slices(union dsc_enc_slice_caps slice_caps)
{}


// Increment slice number in available slice numbers stops if possible, or just increment if not
static int inc_num_slices(union dsc_enc_slice_caps slice_caps, int num_slices)
{}


// Decrement slice number in available slice numbers stops if possible, or just decrement if not. Stop at zero.
static int dec_num_slices(union dsc_enc_slice_caps slice_caps, int num_slices)
{}


// Choose next bigger number of slices if the requested number of slices is not available
static int fit_num_slices_up(union dsc_enc_slice_caps slice_caps, int num_slices)
{}


/* Attempts to set DSC configuration for the stream, applying DSC policy.
 * Returns 'true' if successful or 'false' if not.
 *
 * Parameters:
 *
 * dsc_sink_caps       - DSC sink decoder capabilities (from DPCD)
 *
 * dsc_enc_caps        - DSC encoder capabilities
 *
 * target_bandwidth_kbps  - Target bandwidth to fit the stream into.
 *                          If 0, do not calculate target bpp.
 *
 * timing              - The stream timing to fit into 'target_bandwidth_kbps' or apply
 *                       maximum compression to, if 'target_badwidth == 0'
 *
 * dsc_cfg             - DSC configuration to use if it was possible to come up with
 *                       one for the given inputs.
 *                       The target bitrate after DSC can be calculated by multiplying
 *                       dsc_cfg.bits_per_pixel (in U6.4 format) by pixel rate, e.g.
 *
 *                       dsc_stream_bitrate_kbps = (int)ceil(timing->pix_clk_khz * dsc_cfg.bits_per_pixel / 16.0);
 */
static bool setup_dsc_config(
		const struct dsc_dec_dpcd_caps *dsc_sink_caps,
		const struct dsc_enc_caps *dsc_enc_caps,
		int target_bandwidth_kbps,
		const struct dc_crtc_timing *timing,
		const struct dc_dsc_config_options *options,
		const enum dc_link_encoding_format link_encoding,
		struct dc_dsc_config *dsc_cfg)
{}

bool dc_dsc_compute_config(
		const struct display_stream_compressor *dsc,
		const struct dsc_dec_dpcd_caps *dsc_sink_caps,
		const struct dc_dsc_config_options *options,
		uint32_t target_bandwidth_kbps,
		const struct dc_crtc_timing *timing,
		const enum dc_link_encoding_format link_encoding,
		struct dc_dsc_config *dsc_cfg)
{}

uint32_t dc_dsc_stream_bandwidth_in_kbps(const struct dc_crtc_timing *timing,
	uint32_t bpp_x16, uint32_t num_slices_h, bool is_dp)
{}

uint32_t dc_dsc_stream_bandwidth_overhead_in_kbps(
		const struct dc_crtc_timing *timing,
		const int num_slices_h,
		const bool is_dp)
{}

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)
{}

void dc_dsc_policy_set_max_target_bpp_limit(uint32_t limit)
{}

void dc_dsc_policy_set_enable_dsc_when_not_needed(bool enable)
{}

void dc_dsc_policy_set_disable_dsc_stream_overhead(bool disable)
{}

void dc_set_disable_128b_132b_stream_overhead(bool disable)
{}

void dc_dsc_get_default_config_option(const struct dc *dc, struct dc_dsc_config_options *options)
{}