Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.9.
   1// SPDX-License-Identifier: MIT
   2/*
   3 * Copyright © 2018 Intel Corp
   4 *
   5 * Author:
   6 * Manasi Navare <manasi.d.navare@intel.com>
   7 */
   8
   9#include <linux/kernel.h>
  10#include <linux/module.h>
  11#include <linux/init.h>
  12#include <linux/errno.h>
  13#include <linux/byteorder/generic.h>
  14
  15#include <drm/display/drm_dp_helper.h>
  16#include <drm/display/drm_dsc_helper.h>
  17#include <drm/drm_fixed.h>
  18#include <drm/drm_print.h>
  19
  20/**
  21 * DOC: dsc helpers
  22 *
  23 * VESA specification for DP 1.4 adds a new feature called Display Stream
  24 * Compression (DSC) used to compress the pixel bits before sending it on
  25 * DP/eDP/MIPI DSI interface. DSC is required to be enabled so that the existing
  26 * display interfaces can support high resolutions at higher frames rates uisng
  27 * the maximum available link capacity of these interfaces.
  28 *
  29 * These functions contain some common logic and helpers to deal with VESA
  30 * Display Stream Compression standard required for DSC on Display Port/eDP or
  31 * MIPI display interfaces.
  32 */
  33
  34/**
  35 * drm_dsc_dp_pps_header_init() - Initializes the PPS Header
  36 * for DisplayPort as per the DP 1.4 spec.
  37 * @pps_header: Secondary data packet header for DSC Picture
  38 *              Parameter Set as defined in &struct dp_sdp_header
  39 *
  40 * DP 1.4 spec defines the secondary data packet for sending the
  41 * picture parameter infoframes from the source to the sink.
  42 * This function populates the SDP header defined in
  43 * &struct dp_sdp_header.
  44 */
  45void drm_dsc_dp_pps_header_init(struct dp_sdp_header *pps_header)
  46{
  47	memset(pps_header, 0, sizeof(*pps_header));
  48
  49	pps_header->HB1 = DP_SDP_PPS;
  50	pps_header->HB2 = DP_SDP_PPS_HEADER_PAYLOAD_BYTES_MINUS_1;
  51}
  52EXPORT_SYMBOL(drm_dsc_dp_pps_header_init);
  53
  54/**
  55 * drm_dsc_dp_rc_buffer_size - get rc buffer size in bytes
  56 * @rc_buffer_block_size: block size code, according to DPCD offset 62h
  57 * @rc_buffer_size: number of blocks - 1, according to DPCD offset 63h
  58 *
  59 * return:
  60 * buffer size in bytes, or 0 on invalid input
  61 */
  62int drm_dsc_dp_rc_buffer_size(u8 rc_buffer_block_size, u8 rc_buffer_size)
  63{
  64	int size = 1024 * (rc_buffer_size + 1);
  65
  66	switch (rc_buffer_block_size) {
  67	case DP_DSC_RC_BUF_BLK_SIZE_1:
  68		return 1 * size;
  69	case DP_DSC_RC_BUF_BLK_SIZE_4:
  70		return 4 * size;
  71	case DP_DSC_RC_BUF_BLK_SIZE_16:
  72		return 16 * size;
  73	case DP_DSC_RC_BUF_BLK_SIZE_64:
  74		return 64 * size;
  75	default:
  76		return 0;
  77	}
  78}
  79EXPORT_SYMBOL(drm_dsc_dp_rc_buffer_size);
  80
  81/**
  82 * drm_dsc_pps_payload_pack() - Populates the DSC PPS
  83 *
  84 * @pps_payload:
  85 * Bitwise struct for DSC Picture Parameter Set. This is defined
  86 * by &struct drm_dsc_picture_parameter_set
  87 * @dsc_cfg:
  88 * DSC Configuration data filled by driver as defined by
  89 * &struct drm_dsc_config
  90 *
  91 * DSC source device sends a picture parameter set (PPS) containing the
  92 * information required by the sink to decode the compressed frame. Driver
  93 * populates the DSC PPS struct using the DSC configuration parameters in
  94 * the order expected by the DSC Display Sink device. For the DSC, the sink
  95 * device expects the PPS payload in big endian format for fields
  96 * that span more than 1 byte.
  97 */
  98void drm_dsc_pps_payload_pack(struct drm_dsc_picture_parameter_set *pps_payload,
  99				const struct drm_dsc_config *dsc_cfg)
 100{
 101	int i;
 102
 103	/* Protect against someone accidentally changing struct size */
 104	BUILD_BUG_ON(sizeof(*pps_payload) !=
 105		     DP_SDP_PPS_HEADER_PAYLOAD_BYTES_MINUS_1 + 1);
 106
 107	memset(pps_payload, 0, sizeof(*pps_payload));
 108
 109	/* PPS 0 */
 110	pps_payload->dsc_version =
 111		dsc_cfg->dsc_version_minor |
 112		dsc_cfg->dsc_version_major << DSC_PPS_VERSION_MAJOR_SHIFT;
 113
 114	/* PPS 1, 2 is 0 */
 115
 116	/* PPS 3 */
 117	pps_payload->pps_3 =
 118		dsc_cfg->line_buf_depth |
 119		dsc_cfg->bits_per_component << DSC_PPS_BPC_SHIFT;
 120
 121	/* PPS 4 */
 122	pps_payload->pps_4 =
 123		((dsc_cfg->bits_per_pixel & DSC_PPS_BPP_HIGH_MASK) >>
 124		 DSC_PPS_MSB_SHIFT) |
 125		dsc_cfg->vbr_enable << DSC_PPS_VBR_EN_SHIFT |
 126		dsc_cfg->simple_422 << DSC_PPS_SIMPLE422_SHIFT |
 127		dsc_cfg->convert_rgb << DSC_PPS_CONVERT_RGB_SHIFT |
 128		dsc_cfg->block_pred_enable << DSC_PPS_BLOCK_PRED_EN_SHIFT;
 129
 130	/* PPS 5 */
 131	pps_payload->bits_per_pixel_low =
 132		(dsc_cfg->bits_per_pixel & DSC_PPS_LSB_MASK);
 133
 134	/*
 135	 * The DSC panel expects the PPS packet to have big endian format
 136	 * for data spanning 2 bytes. Use a macro cpu_to_be16() to convert
 137	 * to big endian format. If format is little endian, it will swap
 138	 * bytes to convert to Big endian else keep it unchanged.
 139	 */
 140
 141	/* PPS 6, 7 */
 142	pps_payload->pic_height = cpu_to_be16(dsc_cfg->pic_height);
 143
 144	/* PPS 8, 9 */
 145	pps_payload->pic_width = cpu_to_be16(dsc_cfg->pic_width);
 146
 147	/* PPS 10, 11 */
 148	pps_payload->slice_height = cpu_to_be16(dsc_cfg->slice_height);
 149
 150	/* PPS 12, 13 */
 151	pps_payload->slice_width = cpu_to_be16(dsc_cfg->slice_width);
 152
 153	/* PPS 14, 15 */
 154	pps_payload->chunk_size = cpu_to_be16(dsc_cfg->slice_chunk_size);
 155
 156	/* PPS 16 */
 157	pps_payload->initial_xmit_delay_high =
 158		((dsc_cfg->initial_xmit_delay &
 159		  DSC_PPS_INIT_XMIT_DELAY_HIGH_MASK) >>
 160		 DSC_PPS_MSB_SHIFT);
 161
 162	/* PPS 17 */
 163	pps_payload->initial_xmit_delay_low =
 164		(dsc_cfg->initial_xmit_delay & DSC_PPS_LSB_MASK);
 165
 166	/* PPS 18, 19 */
 167	pps_payload->initial_dec_delay =
 168		cpu_to_be16(dsc_cfg->initial_dec_delay);
 169
 170	/* PPS 20 is 0 */
 171
 172	/* PPS 21 */
 173	pps_payload->initial_scale_value =
 174		dsc_cfg->initial_scale_value;
 175
 176	/* PPS 22, 23 */
 177	pps_payload->scale_increment_interval =
 178		cpu_to_be16(dsc_cfg->scale_increment_interval);
 179
 180	/* PPS 24 */
 181	pps_payload->scale_decrement_interval_high =
 182		((dsc_cfg->scale_decrement_interval &
 183		  DSC_PPS_SCALE_DEC_INT_HIGH_MASK) >>
 184		 DSC_PPS_MSB_SHIFT);
 185
 186	/* PPS 25 */
 187	pps_payload->scale_decrement_interval_low =
 188		(dsc_cfg->scale_decrement_interval & DSC_PPS_LSB_MASK);
 189
 190	/* PPS 26[7:0], PPS 27[7:5] RESERVED */
 191
 192	/* PPS 27 */
 193	pps_payload->first_line_bpg_offset =
 194		dsc_cfg->first_line_bpg_offset;
 195
 196	/* PPS 28, 29 */
 197	pps_payload->nfl_bpg_offset =
 198		cpu_to_be16(dsc_cfg->nfl_bpg_offset);
 199
 200	/* PPS 30, 31 */
 201	pps_payload->slice_bpg_offset =
 202		cpu_to_be16(dsc_cfg->slice_bpg_offset);
 203
 204	/* PPS 32, 33 */
 205	pps_payload->initial_offset =
 206		cpu_to_be16(dsc_cfg->initial_offset);
 207
 208	/* PPS 34, 35 */
 209	pps_payload->final_offset = cpu_to_be16(dsc_cfg->final_offset);
 210
 211	/* PPS 36 */
 212	pps_payload->flatness_min_qp = dsc_cfg->flatness_min_qp;
 213
 214	/* PPS 37 */
 215	pps_payload->flatness_max_qp = dsc_cfg->flatness_max_qp;
 216
 217	/* PPS 38, 39 */
 218	pps_payload->rc_model_size = cpu_to_be16(dsc_cfg->rc_model_size);
 219
 220	/* PPS 40 */
 221	pps_payload->rc_edge_factor = DSC_RC_EDGE_FACTOR_CONST;
 222
 223	/* PPS 41 */
 224	pps_payload->rc_quant_incr_limit0 =
 225		dsc_cfg->rc_quant_incr_limit0;
 226
 227	/* PPS 42 */
 228	pps_payload->rc_quant_incr_limit1 =
 229		dsc_cfg->rc_quant_incr_limit1;
 230
 231	/* PPS 43 */
 232	pps_payload->rc_tgt_offset = DSC_RC_TGT_OFFSET_LO_CONST |
 233		DSC_RC_TGT_OFFSET_HI_CONST << DSC_PPS_RC_TGT_OFFSET_HI_SHIFT;
 234
 235	/* PPS 44 - 57 */
 236	for (i = 0; i < DSC_NUM_BUF_RANGES - 1; i++)
 237		pps_payload->rc_buf_thresh[i] =
 238			dsc_cfg->rc_buf_thresh[i];
 239
 240	/* PPS 58 - 87 */
 241	/*
 242	 * For DSC sink programming the RC Range parameter fields
 243	 * are as follows: Min_qp[15:11], max_qp[10:6], offset[5:0]
 244	 */
 245	for (i = 0; i < DSC_NUM_BUF_RANGES; i++) {
 246		pps_payload->rc_range_parameters[i] =
 247			cpu_to_be16((dsc_cfg->rc_range_params[i].range_min_qp <<
 248				     DSC_PPS_RC_RANGE_MINQP_SHIFT) |
 249				    (dsc_cfg->rc_range_params[i].range_max_qp <<
 250				     DSC_PPS_RC_RANGE_MAXQP_SHIFT) |
 251				    (dsc_cfg->rc_range_params[i].range_bpg_offset));
 252	}
 253
 254	/* PPS 88 */
 255	pps_payload->native_422_420 = dsc_cfg->native_422 |
 256		dsc_cfg->native_420 << DSC_PPS_NATIVE_420_SHIFT;
 257
 258	/* PPS 89 */
 259	pps_payload->second_line_bpg_offset =
 260		dsc_cfg->second_line_bpg_offset;
 261
 262	/* PPS 90, 91 */
 263	pps_payload->nsl_bpg_offset =
 264		cpu_to_be16(dsc_cfg->nsl_bpg_offset);
 265
 266	/* PPS 92, 93 */
 267	pps_payload->second_line_offset_adj =
 268		cpu_to_be16(dsc_cfg->second_line_offset_adj);
 269
 270	/* PPS 94 - 127 are O */
 271}
 272EXPORT_SYMBOL(drm_dsc_pps_payload_pack);
 273
 274/**
 275 * drm_dsc_set_const_params() - Set DSC parameters considered typically
 276 * constant across operation modes
 277 *
 278 * @vdsc_cfg:
 279 * DSC Configuration data partially filled by driver
 280 */
 281void drm_dsc_set_const_params(struct drm_dsc_config *vdsc_cfg)
 282{
 283	if (!vdsc_cfg->rc_model_size)
 284		vdsc_cfg->rc_model_size = DSC_RC_MODEL_SIZE_CONST;
 285	vdsc_cfg->rc_edge_factor = DSC_RC_EDGE_FACTOR_CONST;
 286	vdsc_cfg->rc_tgt_offset_high = DSC_RC_TGT_OFFSET_HI_CONST;
 287	vdsc_cfg->rc_tgt_offset_low = DSC_RC_TGT_OFFSET_LO_CONST;
 288
 289	if (vdsc_cfg->bits_per_component <= 10)
 290		vdsc_cfg->mux_word_size = DSC_MUX_WORD_SIZE_8_10_BPC;
 291	else
 292		vdsc_cfg->mux_word_size = DSC_MUX_WORD_SIZE_12_BPC;
 293}
 294EXPORT_SYMBOL(drm_dsc_set_const_params);
 295
 296/* From DSC_v1.11 spec, rc_parameter_Set syntax element typically constant */
 297static const u16 drm_dsc_rc_buf_thresh[] = {
 298	896, 1792, 2688, 3584, 4480, 5376, 6272, 6720, 7168, 7616,
 299	7744, 7872, 8000, 8064
 300};
 301
 302/**
 303 * drm_dsc_set_rc_buf_thresh() - Set thresholds for the RC model
 304 * in accordance with the DSC 1.2 specification.
 305 *
 306 * @vdsc_cfg: DSC Configuration data partially filled by driver
 307 */
 308void drm_dsc_set_rc_buf_thresh(struct drm_dsc_config *vdsc_cfg)
 309{
 310	int i;
 311
 312	BUILD_BUG_ON(ARRAY_SIZE(drm_dsc_rc_buf_thresh) !=
 313		     DSC_NUM_BUF_RANGES - 1);
 314	BUILD_BUG_ON(ARRAY_SIZE(drm_dsc_rc_buf_thresh) !=
 315		     ARRAY_SIZE(vdsc_cfg->rc_buf_thresh));
 316
 317	for (i = 0; i < ARRAY_SIZE(drm_dsc_rc_buf_thresh); i++)
 318		vdsc_cfg->rc_buf_thresh[i] = drm_dsc_rc_buf_thresh[i] >> 6;
 319
 320	/*
 321	 * For 6bpp, RC Buffer threshold 12 and 13 need a different value
 322	 * as per C Model
 323	 */
 324	if (vdsc_cfg->bits_per_pixel == 6 << 4) {
 325		vdsc_cfg->rc_buf_thresh[12] = 7936 >> 6;
 326		vdsc_cfg->rc_buf_thresh[13] = 8000 >> 6;
 327	}
 328}
 329EXPORT_SYMBOL(drm_dsc_set_rc_buf_thresh);
 330
 331struct rc_parameters {
 332	u16 initial_xmit_delay;
 333	u8 first_line_bpg_offset;
 334	u16 initial_offset;
 335	u8 flatness_min_qp;
 336	u8 flatness_max_qp;
 337	u8 rc_quant_incr_limit0;
 338	u8 rc_quant_incr_limit1;
 339	struct drm_dsc_rc_range_parameters rc_range_params[DSC_NUM_BUF_RANGES];
 340};
 341
 342struct rc_parameters_data {
 343	u8 bpp;
 344	u8 bpc;
 345	struct rc_parameters params;
 346};
 347
 348#define DSC_BPP(bpp)	((bpp) << 4)
 349
 350/*
 351 * Rate Control Related Parameter Recommended Values from DSC_v1.1 spec prior
 352 * to DSC 1.1 fractional bpp underflow SCR (DSC_v1.1_E1.pdf)
 353 *
 354 * Cross-checked against C Model releases: DSC_model_20161212 and 20210623
 355 */
 356static const struct rc_parameters_data rc_parameters_pre_scr[] = {
 357	{
 358		.bpp = DSC_BPP(6), .bpc = 8,
 359		{ 683, 15, 6144, 3, 13, 11, 11, {
 360			{ 0, 2, 0 }, { 1, 4, -2 }, { 3, 6, -2 }, { 4, 6, -4 },
 361			{ 5, 7, -6 }, { 5, 7, -6 }, { 6, 7, -6 }, { 6, 8, -8 },
 362			{ 7, 9, -8 }, { 8, 10, -10 }, { 9, 11, -10 }, { 10, 12, -12 },
 363			{ 10, 13, -12 }, { 12, 14, -12 }, { 15, 15, -12 }
 364			}
 365		}
 366	},
 367	{
 368		.bpp = DSC_BPP(8), .bpc = 8,
 369		{ 512, 12, 6144, 3, 12, 11, 11, {
 370			{ 0, 4, 2 }, { 0, 4, 0 }, { 1, 5, 0 }, { 1, 6, -2 },
 371			{ 3, 7, -4 }, { 3, 7, -6 }, { 3, 7, -8 }, { 3, 8, -8 },
 372			{ 3, 9, -8 }, { 3, 10, -10 }, { 5, 11, -10 }, { 5, 12, -12 },
 373			{ 5, 13, -12 }, { 7, 13, -12 }, { 13, 15, -12 }
 374			}
 375		}
 376	},
 377	{
 378		.bpp = DSC_BPP(8), .bpc = 10,
 379		{ 512, 12, 6144, 7, 16, 15, 15, {
 380			/*
 381			 * DSC model/pre-SCR-cfg has 8 for range_max_qp[0], however
 382			 * VESA DSC 1.1 Table E-5 sets it to 4.
 383			 */
 384			{ 0, 4, 2 }, { 4, 8, 0 }, { 5, 9, 0 }, { 5, 10, -2 },
 385			{ 7, 11, -4 }, { 7, 11, -6 }, { 7, 11, -8 }, { 7, 12, -8 },
 386			{ 7, 13, -8 }, { 7, 14, -10 }, { 9, 15, -10 }, { 9, 16, -12 },
 387			{ 9, 17, -12 }, { 11, 17, -12 }, { 17, 19, -12 }
 388			}
 389		}
 390	},
 391	{
 392		.bpp = DSC_BPP(8), .bpc = 12,
 393		{ 512, 12, 6144, 11, 20, 19, 19, {
 394			{ 0, 12, 2 }, { 4, 12, 0 }, { 9, 13, 0 }, { 9, 14, -2 },
 395			{ 11, 15, -4 }, { 11, 15, -6 }, { 11, 15, -8 }, { 11, 16, -8 },
 396			{ 11, 17, -8 }, { 11, 18, -10 }, { 13, 19, -10 },
 397			{ 13, 20, -12 }, { 13, 21, -12 }, { 15, 21, -12 },
 398			{ 21, 23, -12 }
 399			}
 400		}
 401	},
 402	{
 403		.bpp = DSC_BPP(10), .bpc = 8,
 404		{ 410, 12, 5632, 3, 12, 11, 11, {
 405			{ 0, 3, 2 }, { 0, 4, 0 }, { 1, 5, 0 }, { 2, 6, -2 },
 406			{ 3, 7, -4 }, { 3, 7, -6 }, { 3, 7, -8 }, { 3, 8, -8 },
 407			{ 3, 9, -8 }, { 3, 9, -10 }, { 5, 10, -10 }, { 5, 11, -10 },
 408			{ 5, 12, -12 }, { 7, 13, -12 }, { 13, 15, -12 }
 409			}
 410		}
 411	},
 412	{
 413		.bpp = DSC_BPP(10), .bpc = 10,
 414		{ 410, 12, 5632, 7, 16, 15, 15, {
 415			{ 0, 7, 2 }, { 4, 8, 0 }, { 5, 9, 0 }, { 6, 10, -2 },
 416			{ 7, 11, -4 }, { 7, 11, -6 }, { 7, 11, -8 }, { 7, 12, -8 },
 417			{ 7, 13, -8 }, { 7, 13, -10 }, { 9, 14, -10 }, { 9, 15, -10 },
 418			{ 9, 16, -12 }, { 11, 17, -12 }, { 17, 19, -12 }
 419			}
 420		}
 421	},
 422	{
 423		.bpp = DSC_BPP(10), .bpc = 12,
 424		{ 410, 12, 5632, 11, 20, 19, 19, {
 425			{ 0, 11, 2 }, { 4, 12, 0 }, { 9, 13, 0 }, { 10, 14, -2 },
 426			{ 11, 15, -4 }, { 11, 15, -6 }, { 11, 15, -8 }, { 11, 16, -8 },
 427			{ 11, 17, -8 }, { 11, 17, -10 }, { 13, 18, -10 },
 428			{ 13, 19, -10 }, { 13, 20, -12 }, { 15, 21, -12 },
 429			{ 21, 23, -12 }
 430			}
 431		}
 432	},
 433	{
 434		.bpp = DSC_BPP(12), .bpc = 8,
 435		{ 341, 15, 2048, 3, 12, 11, 11, {
 436			{ 0, 2, 2 }, { 0, 4, 0 }, { 1, 5, 0 }, { 1, 6, -2 },
 437			{ 3, 7, -4 }, { 3, 7, -6 }, { 3, 7, -8 }, { 3, 8, -8 },
 438			{ 3, 9, -8 }, { 3, 10, -10 }, { 5, 11, -10 },
 439			{ 5, 12, -12 }, { 5, 13, -12 }, { 7, 13, -12 }, { 13, 15, -12 }
 440			}
 441		}
 442	},
 443	{
 444		.bpp = DSC_BPP(12), .bpc = 10,
 445		{ 341, 15, 2048, 7, 16, 15, 15, {
 446			{ 0, 2, 2 }, { 2, 5, 0 }, { 3, 7, 0 }, { 4, 8, -2 },
 447			{ 6, 9, -4 }, { 7, 10, -6 }, { 7, 11, -8 }, { 7, 12, -8 },
 448			{ 7, 13, -8 }, { 7, 14, -10 }, { 9, 15, -10 }, { 9, 16, -12 },
 449			{ 9, 17, -12 }, { 11, 17, -12 }, { 17, 19, -12 }
 450			}
 451		}
 452	},
 453	{
 454		.bpp = DSC_BPP(12), .bpc = 12,
 455		{ 341, 15, 2048, 11, 20, 19, 19, {
 456			{ 0, 6, 2 }, { 4, 9, 0 }, { 7, 11, 0 }, { 8, 12, -2 },
 457			{ 10, 13, -4 }, { 11, 14, -6 }, { 11, 15, -8 }, { 11, 16, -8 },
 458			{ 11, 17, -8 }, { 11, 18, -10 }, { 13, 19, -10 },
 459			{ 13, 20, -12 }, { 13, 21, -12 }, { 15, 21, -12 },
 460			{ 21, 23, -12 }
 461			}
 462		}
 463	},
 464	{
 465		.bpp = DSC_BPP(15), .bpc = 8,
 466		{ 273, 15, 2048, 3, 12, 11, 11, {
 467			{ 0, 0, 10 }, { 0, 1, 8 }, { 0, 1, 6 }, { 0, 2, 4 },
 468			{ 1, 2, 2 }, { 1, 3, 0 }, { 1, 4, -2 }, { 2, 4, -4 },
 469			{ 3, 4, -6 }, { 3, 5, -8 }, { 4, 6, -10 }, { 5, 7, -10 },
 470			{ 5, 8, -12 }, { 7, 13, -12 }, { 13, 15, -12 }
 471			}
 472		}
 473	},
 474	{
 475		.bpp = DSC_BPP(15), .bpc = 10,
 476		{ 273, 15, 2048, 7, 16, 15, 15, {
 477			{ 0, 2, 10 }, { 2, 5, 8 }, { 3, 5, 6 }, { 4, 6, 4 },
 478			{ 5, 6, 2 }, { 5, 7, 0 }, { 5, 8, -2 }, { 6, 8, -4 },
 479			{ 7, 8, -6 }, { 7, 9, -8 }, { 8, 10, -10 }, { 9, 11, -10 },
 480			{ 9, 12, -12 }, { 11, 17, -12 }, { 17, 19, -12 }
 481			}
 482		}
 483	},
 484	{
 485		.bpp = DSC_BPP(15), .bpc = 12,
 486		{ 273, 15, 2048, 11, 20, 19, 19, {
 487			{ 0, 4, 10 }, { 2, 7, 8 }, { 4, 9, 6 }, { 6, 11, 4 },
 488			{ 9, 11, 2 }, { 9, 11, 0 }, { 9, 12, -2 }, { 10, 12, -4 },
 489			{ 11, 12, -6 }, { 11, 13, -8 }, { 12, 14, -10 },
 490			{ 13, 15, -10 }, { 13, 16, -12 }, { 15, 21, -12 },
 491			{ 21, 23, -12 }
 492			}
 493		}
 494	},
 495	{ /* sentinel */ }
 496};
 497
 498/*
 499 * Selected Rate Control Related Parameter Recommended Values from DSC v1.2, v1.2a, v1.2b and
 500 * DSC_v1.1_E1 specs.
 501 *
 502 * Cross-checked against C Model releases: DSC_model_20161212 and 20210623
 503 */
 504static const struct rc_parameters_data rc_parameters_1_2_444[] = {
 505	{
 506		.bpp = DSC_BPP(6), .bpc = 8,
 507		{ 768, 15, 6144, 3, 13, 11, 11, {
 508			{ 0, 4, 0 }, { 1, 6, -2 }, { 3, 8, -2 }, { 4, 8, -4 },
 509			{ 5, 9, -6 }, { 5, 9, -6 }, { 6, 9, -6 }, { 6, 10, -8 },
 510			{ 7, 11, -8 }, { 8, 12, -10 }, { 9, 12, -10 }, { 10, 12, -12 },
 511			{ 10, 12, -12 }, { 11, 12, -12 }, { 13, 14, -12 }
 512			}
 513		}
 514	},
 515	{
 516		.bpp = DSC_BPP(6), .bpc = 10,
 517		{ 768, 15, 6144, 7, 17, 15, 15, {
 518			{ 0, 8, 0 }, { 3, 10, -2 }, { 7, 12, -2 }, { 8, 12, -4 },
 519			{ 9, 13, -6 }, { 9, 13, -6 }, { 10, 13, -6 }, { 10, 14, -8 },
 520			{ 11, 15, -8 }, { 12, 16, -10 }, { 13, 16, -10 },
 521			{ 14, 16, -12 }, { 14, 16, -12 }, { 15, 16, -12 },
 522			{ 17, 18, -12 }
 523			}
 524		}
 525	},
 526	{
 527		.bpp = DSC_BPP(6), .bpc = 12,
 528		{ 768, 15, 6144, 11, 21, 19, 19, {
 529			{ 0, 12, 0 }, { 5, 14, -2 }, { 11, 16, -2 }, { 12, 16, -4 },
 530			{ 13, 17, -6 }, { 13, 17, -6 }, { 14, 17, -6 }, { 14, 18, -8 },
 531			{ 15, 19, -8 }, { 16, 20, -10 }, { 17, 20, -10 },
 532			{ 18, 20, -12 }, { 18, 20, -12 }, { 19, 20, -12 },
 533			{ 21, 22, -12 }
 534			}
 535		}
 536	},
 537	{
 538		.bpp = DSC_BPP(6), .bpc = 14,
 539		{ 768, 15, 6144, 15, 25, 23, 23, {
 540			{ 0, 16, 0 }, { 7, 18, -2 }, { 15, 20, -2 }, { 16, 20, -4 },
 541			{ 17, 21, -6 }, { 17, 21, -6 }, { 18, 21, -6 }, { 18, 22, -8 },
 542			{ 19, 23, -8 }, { 20, 24, -10 }, { 21, 24, -10 },
 543			{ 22, 24, -12 }, { 22, 24, -12 }, { 23, 24, -12 },
 544			{ 25, 26, -12 }
 545			}
 546		}
 547	},
 548	{
 549		.bpp = DSC_BPP(6), .bpc = 16,
 550		{ 768, 15, 6144, 19, 29, 27, 27, {
 551			{ 0, 20, 0 }, { 9, 22, -2 }, { 19, 24, -2 }, { 20, 24, -4 },
 552			{ 21, 25, -6 }, { 21, 25, -6 }, { 22, 25, -6 }, { 22, 26, -8 },
 553			{ 23, 27, -8 }, { 24, 28, -10 }, { 25, 28, -10 },
 554			{ 26, 28, -12 }, { 26, 28, -12 }, { 27, 28, -12 },
 555			{ 29, 30, -12 }
 556			}
 557		}
 558	},
 559	{
 560		.bpp = DSC_BPP(8), .bpc = 8,
 561		{ 512, 12, 6144, 3, 12, 11, 11, {
 562			{ 0, 4, 2 }, { 0, 4, 0 }, { 1, 5, 0 }, { 1, 6, -2 },
 563			{ 3, 7, -4 }, { 3, 7, -6 }, { 3, 7, -8 }, { 3, 8, -8 },
 564			{ 3, 9, -8 }, { 3, 10, -10 }, { 5, 10, -10 }, { 5, 11, -12 },
 565			{ 5, 11, -12 }, { 9, 12, -12 }, { 12, 13, -12 }
 566			}
 567		}
 568	},
 569	{
 570		.bpp = DSC_BPP(8), .bpc = 10,
 571		{ 512, 12, 6144, 7, 16, 15, 15, {
 572			{ 0, 8, 2 }, { 4, 8, 0 }, { 5, 9, 0 }, { 5, 10, -2 },
 573			{ 7, 11, -4 }, { 7, 11, -6 }, { 7, 11, -8 }, { 7, 12, -8 },
 574			{ 7, 13, -8 }, { 7, 14, -10 }, { 9, 14, -10 }, { 9, 15, -12 },
 575			{ 9, 15, -12 }, { 13, 16, -12 }, { 16, 17, -12 }
 576			}
 577		}
 578	},
 579	{
 580		.bpp = DSC_BPP(8), .bpc = 12,
 581		{ 512, 12, 6144, 11, 20, 19, 19, {
 582			{ 0, 12, 2 }, { 4, 12, 0 }, { 9, 13, 0 }, { 9, 14, -2 },
 583			{ 11, 15, -4 }, { 11, 15, -6 }, { 11, 15, -8 }, { 11, 16, -8 },
 584			{ 11, 17, -8 }, { 11, 18, -10 }, { 13, 18, -10 },
 585			{ 13, 19, -12 }, { 13, 19, -12 }, { 17, 20, -12 },
 586			{ 20, 21, -12 }
 587			}
 588		}
 589	},
 590	{
 591		.bpp = DSC_BPP(8), .bpc = 14,
 592		{ 512, 12, 6144, 15, 24, 23, 23, {
 593			{ 0, 12, 2 }, { 5, 13, 0 }, { 11, 15, 0 }, { 12, 17, -2 },
 594			{ 15, 19, -4 }, { 15, 19, -6 }, { 15, 19, -8 }, { 15, 20, -8 },
 595			{ 15, 21, -8 }, { 15, 22, -10 }, { 17, 22, -10 },
 596			{ 17, 23, -12 }, { 17, 23, -12 }, { 21, 24, -12 },
 597			{ 24, 25, -12 }
 598			}
 599		}
 600	},
 601	{
 602		.bpp = DSC_BPP(8), .bpc = 16,
 603		{ 512, 12, 6144, 19, 28, 27, 27, {
 604			{ 0, 12, 2 }, { 6, 14, 0 }, { 13, 17, 0 }, { 15, 20, -2 },
 605			{ 19, 23, -4 }, { 19, 23, -6 }, { 19, 23, -8 }, { 19, 24, -8 },
 606			{ 19, 25, -8 }, { 19, 26, -10 }, { 21, 26, -10 },
 607			{ 21, 27, -12 }, { 21, 27, -12 }, { 25, 28, -12 },
 608			{ 28, 29, -12 }
 609			}
 610		}
 611	},
 612	{
 613		.bpp = DSC_BPP(10), .bpc = 8,
 614		{ 410, 15, 5632, 3, 12, 11, 11, {
 615			{ 0, 3, 2 }, { 0, 4, 0 }, { 1, 5, 0 }, { 2, 6, -2 },
 616			{ 3, 7, -4 }, { 3, 7, -6 }, { 3, 7, -8 }, { 3, 8, -8 },
 617			{ 3, 9, -8 }, { 3, 9, -10 }, { 5, 10, -10 }, { 5, 10, -10 },
 618			{ 5, 11, -12 }, { 7, 11, -12 }, { 11, 12, -12 }
 619			}
 620		}
 621	},
 622	{
 623		.bpp = DSC_BPP(10), .bpc = 10,
 624		{ 410, 15, 5632, 7, 16, 15, 15, {
 625			{ 0, 7, 2 }, { 4, 8, 0 }, { 5, 9, 0 }, { 6, 10, -2 },
 626			{ 7, 11, -4 }, { 7, 11, -6 }, { 7, 11, -8 }, { 7, 12, -8 },
 627			{ 7, 13, -8 }, { 7, 13, -10 }, { 9, 14, -10 }, { 9, 14, -10 },
 628			{ 9, 15, -12 }, { 11, 15, -12 }, { 15, 16, -12 }
 629			}
 630		}
 631	},
 632	{
 633		.bpp = DSC_BPP(10), .bpc = 12,
 634		{ 410, 15, 5632, 11, 20, 19, 19, {
 635			{ 0, 11, 2 }, { 4, 12, 0 }, { 9, 13, 0 }, { 10, 14, -2 },
 636			{ 11, 15, -4 }, { 11, 15, -6 }, { 11, 15, -8 }, { 11, 16, -8 },
 637			{ 11, 17, -8 }, { 11, 17, -10 }, { 13, 18, -10 },
 638			{ 13, 18, -10 }, { 13, 19, -12 }, { 15, 19, -12 },
 639			{ 19, 20, -12 }
 640			}
 641		}
 642	},
 643	{
 644		.bpp = DSC_BPP(10), .bpc = 14,
 645		{ 410, 15, 5632, 15, 24, 23, 23, {
 646			{ 0, 11, 2 }, { 5, 13, 0 }, { 11, 15, 0 }, { 13, 18, -2 },
 647			{ 15, 19, -4 }, { 15, 19, -6 }, { 15, 19, -8 }, { 15, 20, -8 },
 648			{ 15, 21, -8 }, { 15, 21, -10 }, { 17, 22, -10 },
 649			{ 17, 22, -10 }, { 17, 23, -12 }, { 19, 23, -12 },
 650			{ 23, 24, -12 }
 651			}
 652		}
 653	},
 654	{
 655		.bpp = DSC_BPP(10), .bpc = 16,
 656		{ 410, 15, 5632, 19, 28, 27, 27, {
 657			{ 0, 11, 2 }, { 6, 14, 0 }, { 13, 17, 0 }, { 16, 20, -2 },
 658			{ 19, 23, -4 }, { 19, 23, -6 }, { 19, 23, -8 }, { 19, 24, -8 },
 659			{ 19, 25, -8 }, { 19, 25, -10 }, { 21, 26, -10 },
 660			{ 21, 26, -10 }, { 21, 27, -12 }, { 23, 27, -12 },
 661			{ 27, 28, -12 }
 662			}
 663		}
 664	},
 665	{
 666		.bpp = DSC_BPP(12), .bpc = 8,
 667		{ 341, 15, 2048, 3, 12, 11, 11, {
 668			{ 0, 2, 2 }, { 0, 4, 0 }, { 1, 5, 0 }, { 1, 6, -2 },
 669			{ 3, 7, -4 }, { 3, 7, -6 }, { 3, 7, -8 }, { 3, 8, -8 },
 670			{ 3, 8, -8 }, { 3, 9, -10 }, { 5, 9, -10 }, { 5, 9, -12 },
 671			{ 5, 9, -12 }, { 7, 10, -12 }, { 10, 11, -12 }
 672			}
 673		}
 674	},
 675	{
 676		.bpp = DSC_BPP(12), .bpc = 10,
 677		{ 341, 15, 2048, 7, 16, 15, 15, {
 678			{ 0, 2, 2 }, { 2, 5, 0 }, { 3, 7, 0 }, { 4, 8, -2 },
 679			{ 6, 9, -4 }, { 7, 10, -6 }, { 7, 11, -8 }, { 7, 12, -8 },
 680			{ 7, 12, -8 }, { 7, 13, -10 }, { 9, 13, -10 }, { 9, 13, -12 },
 681			{ 9, 13, -12 }, { 11, 14, -12 }, { 14, 15, -12 }
 682			}
 683		}
 684	},
 685	{
 686		.bpp = DSC_BPP(12), .bpc = 12,
 687		{ 341, 15, 2048, 11, 20, 19, 19, {
 688			{ 0, 6, 2 }, { 4, 9, 0 }, { 7, 11, 0 }, { 8, 12, -2 },
 689			{ 10, 13, -4 }, { 11, 14, -6 }, { 11, 15, -8 }, { 11, 16, -8 },
 690			{ 11, 16, -8 }, { 11, 17, -10 }, { 13, 17, -10 },
 691			{ 13, 17, -12 }, { 13, 17, -12 }, { 15, 18, -12 },
 692			{ 18, 19, -12 }
 693			}
 694		}
 695	},
 696	{
 697		.bpp = DSC_BPP(12), .bpc = 14,
 698		{ 341, 15, 2048, 15, 24, 23, 23, {
 699			{ 0, 6, 2 }, { 7, 10, 0 }, { 9, 13, 0 }, { 11, 16, -2 },
 700			{ 14, 17, -4 }, { 15, 18, -6 }, { 15, 19, -8 }, { 15, 20, -8 },
 701			{ 15, 20, -8 }, { 15, 21, -10 }, { 17, 21, -10 },
 702			{ 17, 21, -12 }, { 17, 21, -12 }, { 19, 22, -12 },
 703			{ 22, 23, -12 }
 704			}
 705		}
 706	},
 707	{
 708		.bpp = DSC_BPP(12), .bpc = 16,
 709		{ 341, 15, 2048, 19, 28, 27, 27, {
 710			{ 0, 6, 2 }, { 6, 11, 0 }, { 11, 15, 0 }, { 14, 18, -2 },
 711			{ 18, 21, -4 }, { 19, 22, -6 }, { 19, 23, -8 }, { 19, 24, -8 },
 712			{ 19, 24, -8 }, { 19, 25, -10 }, { 21, 25, -10 },
 713			{ 21, 25, -12 }, { 21, 25, -12 }, { 23, 26, -12 },
 714			{ 26, 27, -12 }
 715			}
 716		}
 717	},
 718	{
 719		.bpp = DSC_BPP(15), .bpc = 8,
 720		{ 273, 15, 2048, 3, 12, 11, 11, {
 721			{ 0, 0, 10 }, { 0, 1, 8 }, { 0, 1, 6 }, { 0, 2, 4 },
 722			{ 1, 2, 2 }, { 1, 3, 0 }, { 1, 3, -2 }, { 2, 4, -4 },
 723			{ 2, 5, -6 }, { 3, 5, -8 }, { 4, 6, -10 }, { 4, 7, -10 },
 724			{ 5, 7, -12 }, { 7, 8, -12 }, { 8, 9, -12 }
 725			}
 726		}
 727	},
 728	{
 729		.bpp = DSC_BPP(15), .bpc = 10,
 730		{ 273, 15, 2048, 7, 16, 15, 15, {
 731			{ 0, 2, 10 }, { 2, 5, 8 }, { 3, 5, 6 }, { 4, 6, 4 },
 732			{ 5, 6, 2 }, { 5, 7, 0 }, { 5, 7, -2 }, { 6, 8, -4 },
 733			{ 6, 9, -6 }, { 7, 9, -8 }, { 8, 10, -10 }, { 8, 11, -10 },
 734			{ 9, 11, -12 }, { 11, 12, -12 }, { 12, 13, -12 }
 735			}
 736		}
 737	},
 738	{
 739		.bpp = DSC_BPP(15), .bpc = 12,
 740		{ 273, 15, 2048, 11, 20, 19, 19, {
 741			{ 0, 4, 10 }, { 2, 7, 8 }, { 4, 9, 6 }, { 6, 11, 4 },
 742			{ 9, 11, 2 }, { 9, 11, 0 }, { 9, 12, -2 }, { 10, 12, -4 },
 743			{ 11, 13, -6 }, { 11, 13, -8 }, { 12, 14, -10 },
 744			{ 13, 15, -10 }, { 13, 15, -12 }, { 15, 16, -12 },
 745			{ 16, 17, -12 }
 746			}
 747		}
 748	},
 749	{
 750		.bpp = DSC_BPP(15), .bpc = 14,
 751		{ 273, 15, 2048, 15, 24, 23, 23, {
 752			{ 0, 4, 10 }, { 3, 8, 8 }, { 6, 11, 6 }, { 9, 14, 4 },
 753			{ 13, 15, 2 }, { 13, 15, 0 }, { 13, 16, -2 }, { 14, 16, -4 },
 754			{ 15, 17, -6 }, { 15, 17, -8 }, { 16, 18, -10 },
 755			{ 17, 19, -10 }, { 17, 19, -12 }, { 19, 20, -12 },
 756			{ 20, 21, -12 }
 757			}
 758		}
 759	},
 760	{
 761		.bpp = DSC_BPP(15), .bpc = 16,
 762		{ 273, 15, 2048, 19, 28, 27, 27, {
 763			{ 0, 4, 10 }, { 4, 9, 8 }, { 8, 13, 6 }, { 12, 17, 4 },
 764			{ 17, 19, 2 }, { 17, 20, 0 }, { 17, 20, -2 }, { 18, 20, -4 },
 765			{ 19, 21, -6 }, { 19, 21, -8 }, { 20, 22, -10 },
 766			{ 21, 23, -10 }, { 21, 23, -12 }, { 23, 24, -12 },
 767			{ 24, 25, -12 }
 768			}
 769		}
 770	},
 771	{ /* sentinel */ }
 772};
 773
 774/*
 775 * Selected Rate Control Related Parameter Recommended Values for 4:2:2 from
 776 * DSC v1.2, v1.2a, v1.2b
 777 *
 778 * Cross-checked against C Model releases: DSC_model_20161212 and 20210623
 779 */
 780static const struct rc_parameters_data rc_parameters_1_2_422[] = {
 781	{
 782		.bpp = DSC_BPP(6), .bpc = 8,
 783		{ 512, 15, 6144, 3, 12, 11, 11, {
 784			{ 0, 4, 2 }, { 0, 4, 0 }, { 1, 5, 0 }, { 1, 6, -2 },
 785			{ 3, 7, -4 }, { 3, 7, -6 }, { 3, 7, -8 }, { 3, 8, -8 },
 786			{ 3, 9, -8 }, { 3, 10, -10 }, { 5, 10, -10 }, { 5, 11, -12 },
 787			{ 5, 11, -12 }, { 9, 12, -12 }, { 12, 13, -12 }
 788			}
 789		}
 790	},
 791	{
 792		.bpp = DSC_BPP(6), .bpc = 10,
 793		{ 512, 15, 6144, 7, 16, 15, 15, {
 794			{ 0, 8, 2 }, { 4, 8, 0 }, { 5, 9, 0 }, { 5, 10, -2 },
 795			{ 7, 11, -4 }, { 7, 11, -6 }, { 7, 11, -8 }, { 7, 12, -8 },
 796			{ 7, 13, -8 }, { 7, 14, -10 }, { 9, 14, -10 }, { 9, 15, -12 },
 797			{ 9, 15, -12 }, { 13, 16, -12 }, { 16, 17, -12 }
 798			}
 799		}
 800	},
 801	{
 802		.bpp = DSC_BPP(6), .bpc = 12,
 803		{ 512, 15, 6144, 11, 20, 19, 19, {
 804			{ 0, 12, 2 }, { 4, 12, 0 }, { 9, 13, 0 }, { 9, 14, -2 },
 805			{ 11, 15, -4 }, { 11, 15, -6 }, { 11, 15, -8 }, { 11, 16, -8 },
 806			{ 11, 17, -8 }, { 11, 18, -10 }, { 13, 18, -10 },
 807			{ 13, 19, -12 }, { 13, 19, -12 }, { 17, 20, -12 },
 808			{ 20, 21, -12 }
 809			}
 810		}
 811	},
 812	{
 813		.bpp = DSC_BPP(6), .bpc = 14,
 814		{ 512, 15, 6144, 15, 24, 23, 23, {
 815			{ 0, 12, 2 }, { 5, 13, 0 }, { 11, 15, 0 }, { 12, 17, -2 },
 816			{ 15, 19, -4 }, { 15, 19, -6 }, { 15, 19, -8 }, { 15, 20, -8 },
 817			{ 15, 21, -8 }, { 15, 22, -10 }, { 17, 22, -10 },
 818			{ 17, 23, -12 }, { 17, 23, -12 }, { 21, 24, -12 },
 819			{ 24, 25, -12 }
 820			}
 821		}
 822	},
 823	{
 824		.bpp = DSC_BPP(6), .bpc = 16,
 825		{ 512, 15, 6144, 19, 28, 27, 27, {
 826			{ 0, 12, 2 }, { 6, 14, 0 }, { 13, 17, 0 }, { 15, 20, -2 },
 827			{ 19, 23, -4 }, { 19, 23, -6 }, { 19, 23, -8 }, { 19, 24, -8 },
 828			{ 19, 25, -8 }, { 19, 26, -10 }, { 21, 26, -10 },
 829			{ 21, 27, -12 }, { 21, 27, -12 }, { 25, 28, -12 },
 830			{ 28, 29, -12 }
 831			}
 832		}
 833	},
 834	{
 835		.bpp = DSC_BPP(7), .bpc = 8,
 836		{ 410, 15, 5632, 3, 12, 11, 11, {
 837			{ 0, 3, 2 }, { 0, 4, 0 }, { 1, 5, 0 }, { 2, 6, -2 },
 838			{ 3, 7, -4 }, { 3, 7, -6 }, { 3, 7, -8 }, { 3, 8, -8 },
 839			{ 3, 9, -8 }, { 3, 9, -10 }, { 5, 10, -10 }, { 5, 10, -10 },
 840			{ 5, 11, -12 }, { 7, 11, -12 }, { 11, 12, -12 }
 841			}
 842		}
 843	},
 844	{
 845		.bpp = DSC_BPP(7), .bpc = 10,
 846		{ 410, 15, 5632, 7, 16, 15, 15, {
 847			{ 0, 7, 2 }, { 4, 8, 0 }, { 5, 9, 0 }, { 6, 10, -2 },
 848			{ 7, 11, -4 }, { 7, 11, -6 }, { 7, 11, -8 }, { 7, 12, -8 },
 849			{ 7, 13, -8 }, { 7, 13, -10 }, { 9, 14, -10 }, { 9, 14, -10 },
 850			{ 9, 15, -12 }, { 11, 15, -12 }, { 15, 16, -12 }
 851			}
 852		}
 853	},
 854	{
 855		.bpp = DSC_BPP(7), .bpc = 12,
 856		{ 410, 15, 5632, 11, 20, 19, 19, {
 857			{ 0, 11, 2 }, { 4, 12, 0 }, { 9, 13, 0 }, { 10, 14, -2 },
 858			{ 11, 15, -4 }, { 11, 15, -6 }, { 11, 15, -8 }, { 11, 16, -8 },
 859			{ 11, 17, -8 }, { 11, 17, -10 }, { 13, 18, -10 },
 860			{ 13, 18, -10 }, { 13, 19, -12 }, { 15, 19, -12 },
 861			{ 19, 20, -12 }
 862			}
 863		}
 864	},
 865	{
 866		.bpp = DSC_BPP(7), .bpc = 14,
 867		{ 410, 15, 5632, 15, 24, 23, 23, {
 868			{ 0, 11, 2 }, { 5, 13, 0 }, { 11, 15, 0 }, { 13, 18, -2 },
 869			{ 15, 19, -4 }, { 15, 19, -6 }, { 15, 19, -8 }, { 15, 20, -8 },
 870			{ 15, 21, -8 }, { 15, 21, -10 }, { 17, 22, -10 },
 871			{ 17, 22, -10 }, { 17, 23, -12 }, { 19, 23, -12 },
 872			{ 23, 24, -12 }
 873			}
 874		}
 875	},
 876	{
 877		.bpp = DSC_BPP(7), .bpc = 16,
 878		{ 410, 15, 5632, 19, 28, 27, 27, {
 879			{ 0, 11, 2 }, { 6, 14, 0 }, { 13, 17, 0 }, { 16, 20, -2 },
 880			{ 19, 23, -4 }, { 19, 23, -6 }, { 19, 23, -8 }, { 19, 24, -8 },
 881			{ 19, 25, -8 }, { 19, 25, -10 }, { 21, 26, -10 },
 882			{ 21, 26, -10 }, { 21, 27, -12 }, { 23, 27, -12 },
 883			{ 27, 28, -12 }
 884			}
 885		}
 886	},
 887	{
 888		.bpp = DSC_BPP(8), .bpc = 8,
 889		{ 341, 15, 2048, 3, 12, 11, 11, {
 890			{ 0, 2, 2 }, { 0, 4, 0 }, { 1, 5, 0 }, { 1, 6, -2 },
 891			{ 3, 7, -4 }, { 3, 7, -6 }, { 3, 7, -8 }, { 3, 8, -8 },
 892			{ 3, 8, -8 }, { 3, 9, -10 }, { 5, 9, -10 }, { 5, 9, -12 },
 893			{ 5, 9, -12 }, { 7, 10, -12 }, { 10, 11, -12 }
 894			}
 895		}
 896	},
 897	{
 898		.bpp = DSC_BPP(8), .bpc = 10,
 899		{ 341, 15, 2048, 7, 16, 15, 15, {
 900			{ 0, 2, 2 }, { 2, 5, 0 }, { 3, 7, 0 }, { 4, 8, -2 },
 901			{ 6, 9, -4 }, { 7, 10, -6 }, { 7, 11, -8 }, { 7, 12, -8 },
 902			{ 7, 12, -8 }, { 7, 13, -10 }, { 9, 13, -10 }, { 9, 13, -12 },
 903			{ 9, 13, -12 }, { 11, 14, -12 }, { 14, 15, -12 }
 904			}
 905		}
 906	},
 907	{
 908		.bpp = DSC_BPP(8), .bpc = 12,
 909		{ 341, 15, 2048, 11, 20, 19, 19, {
 910			{ 0, 6, 2 }, { 4, 9, 0 }, { 7, 11, 0 }, { 8, 12, -2 },
 911			{ 10, 13, -4 }, { 11, 14, -6 }, { 11, 15, -8 }, { 11, 16, -8 },
 912			{ 11, 16, -8 }, { 11, 17, -10 }, { 13, 17, -10 },
 913			{ 13, 17, -12 }, { 13, 17, -12 }, { 15, 18, -12 },
 914			{ 18, 19, -12 }
 915			}
 916		}
 917	},
 918	{
 919		.bpp = DSC_BPP(8), .bpc = 14,
 920		{ 341, 15, 2048, 15, 24, 23, 23, {
 921			{ 0, 6, 2 }, { 7, 10, 0 }, { 9, 13, 0 }, { 11, 16, -2 },
 922			{ 14, 17, -4 }, { 15, 18, -6 }, { 15, 19, -8 }, { 15, 20, -8 },
 923			{ 15, 20, -8 }, { 15, 21, -10 }, { 17, 21, -10 },
 924			{ 17, 21, -12 }, { 17, 21, -12 }, { 19, 22, -12 },
 925			{ 22, 23, -12 }
 926			}
 927		}
 928	},
 929	{
 930		.bpp = DSC_BPP(8), .bpc = 16,
 931		{ 341, 15, 2048, 19, 28, 27, 27, {
 932			{ 0, 6, 2 }, { 6, 11, 0 }, { 11, 15, 0 }, { 14, 18, -2 },
 933			{ 18, 21, -4 }, { 19, 22, -6 }, { 19, 23, -8 }, { 19, 24, -8 },
 934			{ 19, 24, -8 }, { 19, 25, -10 }, { 21, 25, -10 },
 935			{ 21, 25, -12 }, { 21, 25, -12 }, { 23, 26, -12 },
 936			{ 26, 27, -12 }
 937			}
 938		}
 939	},
 940	{
 941		.bpp = DSC_BPP(10), .bpc = 8,
 942		{ 273, 15, 2048, 3, 12, 11, 11, {
 943			{ 0, 0, 10 }, { 0, 1, 8 }, { 0, 1, 6 }, { 0, 2, 4 },
 944			{ 1, 2, 2 }, { 1, 3, 0 }, { 1, 3, -2 }, { 2, 4, -4 },
 945			{ 2, 5, -6 }, { 3, 5, -8 }, { 4, 6, -10 }, { 4, 7, -10 },
 946			{ 5, 7, -12 }, { 7, 8, -12 }, { 8, 9, -12 }
 947			}
 948		}
 949	},
 950	{
 951		.bpp = DSC_BPP(10), .bpc = 10,
 952		{ 273, 15, 2048, 7, 16, 15, 15, {
 953			{ 0, 2, 10 }, { 2, 5, 8 }, { 3, 5, 6 }, { 4, 6, 4 },
 954			{ 5, 6, 2 }, { 5, 7, 0 }, { 5, 7, -2 }, { 6, 8, -4 },
 955			{ 6, 9, -6 }, { 7, 9, -8 }, { 8, 10, -10 }, { 8, 11, -10 },
 956			{ 9, 11, -12 }, { 11, 12, -12 }, { 12, 13, -12 }
 957			}
 958		}
 959	},
 960	{
 961		.bpp = DSC_BPP(10), .bpc = 12,
 962		{ 273, 15, 2048, 11, 20, 19, 19, {
 963			{ 0, 4, 10 }, { 2, 7, 8 }, { 4, 9, 6 }, { 6, 11, 4 },
 964			{ 9, 11, 2 }, { 9, 11, 0 }, { 9, 12, -2 }, { 10, 12, -4 },
 965			{ 11, 13, -6 }, { 11, 13, -8 }, { 12, 14, -10 },
 966			{ 13, 15, -10 }, { 13, 15, -12 }, { 15, 16, -12 },
 967			{ 16, 17, -12 }
 968			}
 969		}
 970	},
 971	{
 972		.bpp = DSC_BPP(10), .bpc = 14,
 973		{ 273, 15, 2048, 15, 24, 23, 23, {
 974			{ 0, 4, 10 }, { 3, 8, 8 }, { 6, 11, 6 }, { 9, 14, 4 },
 975			{ 13, 15, 2 }, { 13, 15, 0 }, { 13, 16, -2 }, { 14, 16, -4 },
 976			{ 15, 17, -6 }, { 15, 17, -8 }, { 16, 18, -10 },
 977			{ 17, 19, -10 }, { 17, 19, -12 }, { 19, 20, -12 },
 978			{ 20, 21, -12 }
 979			}
 980		}
 981	},
 982	{
 983		.bpp = DSC_BPP(10), .bpc = 16,
 984		{ 273, 15, 2048, 19, 28, 27, 27, {
 985			{ 0, 4, 10 }, { 4, 9, 8 }, { 8, 13, 6 }, { 12, 17, 4 },
 986			{ 17, 19, 2 }, { 17, 20, 0 }, { 17, 20, -2 }, { 18, 20, -4 },
 987			{ 19, 21, -6 }, { 19, 21, -8 }, { 20, 22, -10 },
 988			{ 21, 23, -10 }, { 21, 23, -12 }, { 23, 24, -12 },
 989			{ 24, 25, -12 }
 990			}
 991		}
 992	},
 993	{ /* sentinel */ }
 994};
 995
 996/*
 997 * Selected Rate Control Related Parameter Recommended Values for 4:2:2 from
 998 * DSC v1.2, v1.2a, v1.2b
 999 *
1000 * Cross-checked against C Model releases: DSC_model_20161212 and 20210623
1001 */
1002static const struct rc_parameters_data rc_parameters_1_2_420[] = {
1003	{
1004		.bpp = DSC_BPP(4), .bpc = 8,
1005		{ 512, 12, 6144, 3, 12, 11, 11, {
1006			{ 0, 4, 2 }, { 0, 4, 0 }, { 1, 5, 0 }, { 1, 6, -2 },
1007			{ 3, 7, -4 }, { 3, 7, -6 }, { 3, 7, -8 }, { 3, 8, -8 },
1008			{ 3, 9, -8 }, { 3, 10, -10 }, { 5, 10, -10 }, { 5, 11, -12 },
1009			{ 5, 11, -12 }, { 9, 12, -12 }, { 12, 13, -12 }
1010			}
1011		}
1012	},
1013	{
1014		.bpp = DSC_BPP(4), .bpc = 10,
1015		{ 512, 12, 6144, 7, 16, 15, 15, {
1016			{ 0, 8, 2 }, { 4, 8, 0 }, { 5, 9, 0 }, { 5, 10, -2 },
1017			{ 7, 11, -4 }, { 7, 11, -6 }, { 7, 11, -8 }, { 7, 12, -8 },
1018			{ 7, 13, -8 }, { 7, 14, -10 }, { 9, 14, -10 }, { 9, 15, -12 },
1019			{ 9, 15, -12 }, { 13, 16, -12 }, { 16, 17, -12 }
1020			}
1021		}
1022	},
1023	{
1024		.bpp = DSC_BPP(4), .bpc = 12,
1025		{ 512, 12, 6144, 11, 20, 19, 19, {
1026			{ 0, 12, 2 }, { 4, 12, 0 }, { 9, 13, 0 }, { 9, 14, -2 },
1027			{ 11, 15, -4 }, { 11, 15, -6 }, { 11, 15, -8 }, { 11, 16, -8 },
1028			{ 11, 17, -8 }, { 11, 18, -10 }, { 13, 18, -10 },
1029			{ 13, 19, -12 }, { 13, 19, -12 }, { 17, 20, -12 },
1030			{ 20, 21, -12 }
1031			}
1032		}
1033	},
1034	{
1035		.bpp = DSC_BPP(4), .bpc = 14,
1036		{ 512, 12, 6144, 15, 24, 23, 23, {
1037			{ 0, 12, 2 }, { 5, 13, 0 }, { 11, 15, 0 }, { 12, 17, -2 },
1038			{ 15, 19, -4 }, { 15, 19, -6 }, { 15, 19, -8 }, { 15, 20, -8 },
1039			{ 15, 21, -8 }, { 15, 22, -10 }, { 17, 22, -10 },
1040			{ 17, 23, -12 }, { 17, 23, -12 }, { 21, 24, -12 },
1041			{ 24, 25, -12 }
1042			}
1043		}
1044	},
1045	{
1046		.bpp = DSC_BPP(4), .bpc = 16,
1047		{ 512, 12, 6144, 19, 28, 27, 27, {
1048			{ 0, 12, 2 }, { 6, 14, 0 }, { 13, 17, 0 }, { 15, 20, -2 },
1049			{ 19, 23, -4 }, { 19, 23, -6 }, { 19, 23, -8 }, { 19, 24, -8 },
1050			{ 19, 25, -8 }, { 19, 26, -10 }, { 21, 26, -10 },
1051			{ 21, 27, -12 }, { 21, 27, -12 }, { 25, 28, -12 },
1052			{ 28, 29, -12 }
1053			}
1054		}
1055	},
1056	{
1057		.bpp = DSC_BPP(5), .bpc = 8,
1058		{ 410, 15, 5632, 3, 12, 11, 11, {
1059			{ 0, 3, 2 }, { 0, 4, 0 }, { 1, 5, 0 }, { 2, 6, -2 },
1060			{ 3, 7, -4 }, { 3, 7, -6 }, { 3, 7, -8 }, { 3, 8, -8 },
1061			{ 3, 9, -8 }, { 3, 9, -10 }, { 5, 10, -10 }, { 5, 10, -10 },
1062			{ 5, 11, -12 }, { 7, 11, -12 }, { 11, 12, -12 }
1063			}
1064		}
1065	},
1066	{
1067		.bpp = DSC_BPP(5), .bpc = 10,
1068		{ 410, 15, 5632, 7, 16, 15, 15, {
1069			{ 0, 7, 2 }, { 4, 8, 0 }, { 5, 9, 0 }, { 6, 10, -2 },
1070			{ 7, 11, -4 }, { 7, 11, -6 }, { 7, 11, -8 }, { 7, 12, -8 },
1071			{ 7, 13, -8 }, { 7, 13, -10 }, { 9, 14, -10 }, { 9, 14, -10 },
1072			{ 9, 15, -12 }, { 11, 15, -12 }, { 15, 16, -12 }
1073			}
1074		}
1075	},
1076	{
1077		.bpp = DSC_BPP(5), .bpc = 12,
1078		{ 410, 15, 5632, 11, 20, 19, 19, {
1079			{ 0, 11, 2 }, { 4, 12, 0 }, { 9, 13, 0 }, { 10, 14, -2 },
1080			{ 11, 15, -4 }, { 11, 15, -6 }, { 11, 15, -8 }, { 11, 16, -8 },
1081			{ 11, 17, -8 }, { 11, 17, -10 }, { 13, 18, -10 },
1082			{ 13, 18, -10 }, { 13, 19, -12 }, { 15, 19, -12 },
1083			{ 19, 20, -12 }
1084			}
1085		}
1086	},
1087	{
1088		.bpp = DSC_BPP(5), .bpc = 14,
1089		{ 410, 15, 5632, 15, 24, 23, 23, {
1090			{ 0, 11, 2 }, { 5, 13, 0 }, { 11, 15, 0 }, { 13, 18, -2 },
1091			{ 15, 19, -4 }, { 15, 19, -6 }, { 15, 19, -8 }, { 15, 20, -8 },
1092			{ 15, 21, -8 }, { 15, 21, -10 }, { 17, 22, -10 },
1093			{ 17, 22, -10 }, { 17, 23, -12 }, { 19, 23, -12 },
1094			{ 23, 24, -12 }
1095			}
1096		}
1097	},
1098	{
1099		.bpp = DSC_BPP(5), .bpc = 16,
1100		{ 410, 15, 5632, 19, 28, 27, 27, {
1101			{ 0, 11, 2 }, { 6, 14, 0 }, { 13, 17, 0 }, { 16, 20, -2 },
1102			{ 19, 23, -4 }, { 19, 23, -6 }, { 19, 23, -8 }, { 19, 24, -8 },
1103			{ 19, 25, -8 }, { 19, 25, -10 }, { 21, 26, -10 },
1104			{ 21, 26, -10 }, { 21, 27, -12 }, { 23, 27, -12 },
1105			{ 27, 28, -12 }
1106			}
1107		}
1108	},
1109	{
1110		.bpp = DSC_BPP(6), .bpc = 8,
1111		{ 341, 15, 2048, 3, 12, 11, 11, {
1112			{ 0, 2, 2 }, { 0, 4, 0 }, { 1, 5, 0 }, { 1, 6, -2 },
1113			{ 3, 7, -4 }, { 3, 7, -6 }, { 3, 7, -8 }, { 3, 8, -8 },
1114			{ 3, 8, -8 }, { 3, 9, -10 }, { 5, 9, -10 }, { 5, 9, -12 },
1115			{ 5, 9, -12 }, { 7, 10, -12 }, { 10, 12, -12 }
1116			}
1117		}
1118	},
1119	{
1120		.bpp = DSC_BPP(6), .bpc = 10,
1121		{ 341, 15, 2048, 7, 16, 15, 15, {
1122			{ 0, 2, 2 }, { 2, 5, 0 }, { 3, 7, 0 }, { 4, 8, -2 },
1123			{ 6, 9, -4 }, { 7, 10, -6 }, { 7, 11, -8 }, { 7, 12, -8 },
1124			{ 7, 12, -8 }, { 7, 13, -10 }, { 9, 13, -10 }, { 9, 13, -12 },
1125			{ 9, 13, -12 }, { 11, 14, -12 }, { 14, 15, -12 }
1126			}
1127		}
1128	},
1129	{
1130		.bpp = DSC_BPP(6), .bpc = 12,
1131		{ 341, 15, 2048, 11, 20, 19, 19, {
1132			{ 0, 6, 2 }, { 4, 9, 0 }, { 7, 11, 0 }, { 8, 12, -2 },
1133			{ 10, 13, -4 }, { 11, 14, -6 }, { 11, 15, -8 }, { 11, 16, -8 },
1134			{ 11, 16, -8 }, { 11, 17, -10 }, { 13, 17, -10 },
1135			{ 13, 17, -12 }, { 13, 17, -12 }, { 15, 18, -12 },
1136			{ 18, 19, -12 }
1137			}
1138		}
1139	},
1140	{
1141		.bpp = DSC_BPP(6), .bpc = 14,
1142		{ 341, 15, 2048, 15, 24, 23, 23, {
1143			{ 0, 6, 2 }, { 7, 10, 0 }, { 9, 13, 0 }, { 11, 16, -2 },
1144			{ 14, 17, -4 }, { 15, 18, -6 }, { 15, 19, -8 }, { 15, 20, -8 },
1145			{ 15, 20, -8 }, { 15, 21, -10 }, { 17, 21, -10 },
1146			{ 17, 21, -12 }, { 17, 21, -12 }, { 19, 22, -12 },
1147			{ 22, 23, -12 }
1148			}
1149		}
1150	},
1151	{
1152		.bpp = DSC_BPP(6), .bpc = 16,
1153		{ 341, 15, 2048, 19, 28, 27, 27, {
1154			{ 0, 6, 2 }, { 6, 11, 0 }, { 11, 15, 0 }, { 14, 18, -2 },
1155			{ 18, 21, -4 }, { 19, 22, -6 }, { 19, 23, -8 }, { 19, 24, -8 },
1156			{ 19, 24, -8 }, { 19, 25, -10 }, { 21, 25, -10 },
1157			{ 21, 25, -12 }, { 21, 25, -12 }, { 23, 26, -12 },
1158			{ 26, 27, -12 }
1159			}
1160		}
1161	},
1162	{
1163		.bpp = DSC_BPP(8), .bpc = 8,
1164		{ 256, 15, 2048, 3, 12, 11, 11, {
1165			{ 0, 0, 10 }, { 0, 1, 8 }, { 0, 1, 6 }, { 0, 2, 4 },
1166			{ 1, 2, 2 }, { 1, 3, 0 }, { 1, 3, -2 }, { 2, 4, -4 },
1167			{ 2, 5, -6 }, { 3, 5, -8 }, { 4, 6, -10 }, { 4, 7, -10 },
1168			{ 5, 7, -12 }, { 7, 8, -12 }, { 8, 9, -12 }
1169			}
1170		}
1171	},
1172	{
1173		.bpp = DSC_BPP(8), .bpc = 10,
1174		{ 256, 15, 2048, 7, 16, 15, 15, {
1175			{ 0, 2, 10 }, { 2, 5, 8 }, { 3, 5, 6 }, { 4, 6, 4 },
1176			{ 5, 6, 2 }, { 5, 7, 0 }, { 5, 7, -2 }, { 6, 8, -4 },
1177			{ 6, 9, -6 }, { 7, 9, -8 }, { 8, 10, -10 }, { 8, 11, -10 },
1178			{ 9, 11, -12 }, { 11, 12, -12 }, { 12, 13, -12 }
1179			}
1180		}
1181	},
1182	{
1183		.bpp = DSC_BPP(8), .bpc = 12,
1184		{ 256, 15, 2048, 11, 20, 19, 19, {
1185			{ 0, 4, 10 }, { 2, 7, 8 }, { 4, 9, 6 }, { 6, 11, 4 },
1186			{ 9, 11, 2 }, { 9, 11, 0 }, { 9, 12, -2 }, { 10, 12, -4 },
1187			{ 11, 13, -6 }, { 11, 13, -8 }, { 12, 14, -10 },
1188			{ 13, 15, -10 }, { 13, 15, -12 }, { 15, 16, -12 },
1189			{ 16, 17, -12 }
1190			}
1191		}
1192	},
1193	{
1194		.bpp = DSC_BPP(8), .bpc = 14,
1195		{ 256, 15, 2048, 15, 24, 23, 23, {
1196			{ 0, 4, 10 }, { 3, 8, 8 }, { 6, 11, 6 }, { 9, 14, 4 },
1197			{ 13, 15, 2 }, { 13, 15, 0 }, { 13, 16, -2 }, { 14, 16, -4 },
1198			{ 15, 17, -6 }, { 15, 17, -8 }, { 16, 18, -10 },
1199			{ 17, 19, -10 }, { 17, 19, -12 }, { 19, 20, -12 },
1200			{ 20, 21, -12 }
1201			}
1202		}
1203	},
1204	{
1205		.bpp = DSC_BPP(8), .bpc = 16,
1206		{ 256, 15, 2048, 19, 28, 27, 27, {
1207			{ 0, 4, 10 }, { 4, 9, 8 }, { 8, 13, 6 }, { 12, 17, 4 },
1208			{ 17, 19, 2 }, { 17, 20, 0 }, { 17, 20, -2 }, { 18, 20, -4 },
1209			{ 19, 21, -6 }, { 19, 21, -8 }, { 20, 22, -10 },
1210			{ 21, 23, -10 }, { 21, 23, -12 }, { 23, 24, -12 },
1211			{ 24, 25, -12 }
1212			}
1213		}
1214	},
1215	{ /* sentinel */ }
1216};
1217
1218static const struct rc_parameters *get_rc_params(const struct rc_parameters_data *rc_parameters,
1219						 u16 dsc_bpp,
1220						 u8 bits_per_component)
1221{
1222	int i;
1223
1224	for (i = 0; rc_parameters[i].bpp; i++)
1225		if (rc_parameters[i].bpp == dsc_bpp &&
1226		    rc_parameters[i].bpc == bits_per_component)
1227			return &rc_parameters[i].params;
1228
1229	return NULL;
1230}
1231
1232/**
1233 * drm_dsc_setup_rc_params() - Set parameters and limits for RC model in
1234 * accordance with the DSC 1.1 or 1.2 specification and DSC C Model
1235 * Required bits_per_pixel and bits_per_component to be set before calling this
1236 * function.
1237 *
1238 * @vdsc_cfg: DSC Configuration data partially filled by driver
1239 * @type: operating mode and standard to follow
1240 *
1241 * Return: 0 or -error code in case of an error
1242 */
1243int drm_dsc_setup_rc_params(struct drm_dsc_config *vdsc_cfg, enum drm_dsc_params_type type)
1244{
1245	const struct rc_parameters_data *data;
1246	const struct rc_parameters *rc_params;
1247	int i;
1248
1249	if (WARN_ON_ONCE(!vdsc_cfg->bits_per_pixel ||
1250			 !vdsc_cfg->bits_per_component))
1251		return -EINVAL;
1252
1253	switch (type) {
1254	case DRM_DSC_1_2_444:
1255		data = rc_parameters_1_2_444;
1256		break;
1257	case DRM_DSC_1_1_PRE_SCR:
1258		data = rc_parameters_pre_scr;
1259		break;
1260	case DRM_DSC_1_2_422:
1261		data = rc_parameters_1_2_422;
1262		break;
1263	case DRM_DSC_1_2_420:
1264		data = rc_parameters_1_2_420;
1265		break;
1266	default:
1267		return -EINVAL;
1268	}
1269
1270	rc_params = get_rc_params(data,
1271				  vdsc_cfg->bits_per_pixel,
1272				  vdsc_cfg->bits_per_component);
1273	if (!rc_params)
1274		return -EINVAL;
1275
1276	vdsc_cfg->first_line_bpg_offset = rc_params->first_line_bpg_offset;
1277	vdsc_cfg->initial_xmit_delay = rc_params->initial_xmit_delay;
1278	vdsc_cfg->initial_offset = rc_params->initial_offset;
1279	vdsc_cfg->flatness_min_qp = rc_params->flatness_min_qp;
1280	vdsc_cfg->flatness_max_qp = rc_params->flatness_max_qp;
1281	vdsc_cfg->rc_quant_incr_limit0 = rc_params->rc_quant_incr_limit0;
1282	vdsc_cfg->rc_quant_incr_limit1 = rc_params->rc_quant_incr_limit1;
1283
1284	for (i = 0; i < DSC_NUM_BUF_RANGES; i++) {
1285		vdsc_cfg->rc_range_params[i].range_min_qp =
1286			rc_params->rc_range_params[i].range_min_qp;
1287		vdsc_cfg->rc_range_params[i].range_max_qp =
1288			rc_params->rc_range_params[i].range_max_qp;
1289		/*
1290		 * Range BPG Offset uses 2's complement and is only a 6 bits. So
1291		 * mask it to get only 6 bits.
1292		 */
1293		vdsc_cfg->rc_range_params[i].range_bpg_offset =
1294			rc_params->rc_range_params[i].range_bpg_offset &
1295			DSC_RANGE_BPG_OFFSET_MASK;
1296	}
1297
1298	return 0;
1299}
1300EXPORT_SYMBOL(drm_dsc_setup_rc_params);
1301
1302/**
1303 * drm_dsc_compute_rc_parameters() - Write rate control
1304 * parameters to the dsc configuration defined in
1305 * &struct drm_dsc_config in accordance with the DSC 1.2
1306 * specification. Some configuration fields must be present
1307 * beforehand.
1308 *
1309 * @vdsc_cfg:
1310 * DSC Configuration data partially filled by driver
1311 */
1312int drm_dsc_compute_rc_parameters(struct drm_dsc_config *vdsc_cfg)
1313{
1314	unsigned long groups_per_line = 0;
1315	unsigned long groups_total = 0;
1316	unsigned long num_extra_mux_bits = 0;
1317	unsigned long slice_bits = 0;
1318	unsigned long hrd_delay = 0;
1319	unsigned long final_scale = 0;
1320	unsigned long rbs_min = 0;
1321
1322	if (vdsc_cfg->native_420 || vdsc_cfg->native_422) {
1323		/* Number of groups used to code each line of a slice */
1324		groups_per_line = DIV_ROUND_UP(vdsc_cfg->slice_width / 2,
1325					       DSC_RC_PIXELS_PER_GROUP);
1326
1327		/* chunksize in Bytes */
1328		vdsc_cfg->slice_chunk_size = DIV_ROUND_UP(vdsc_cfg->slice_width / 2 *
1329							  vdsc_cfg->bits_per_pixel,
1330							  (8 * 16));
1331	} else {
1332		/* Number of groups used to code each line of a slice */
1333		groups_per_line = DIV_ROUND_UP(vdsc_cfg->slice_width,
1334					       DSC_RC_PIXELS_PER_GROUP);
1335
1336		/* chunksize in Bytes */
1337		vdsc_cfg->slice_chunk_size = DIV_ROUND_UP(vdsc_cfg->slice_width *
1338							  vdsc_cfg->bits_per_pixel,
1339							  (8 * 16));
1340	}
1341
1342	if (vdsc_cfg->convert_rgb)
1343		num_extra_mux_bits = 3 * (vdsc_cfg->mux_word_size +
1344					  (4 * vdsc_cfg->bits_per_component + 4)
1345					  - 2);
1346	else if (vdsc_cfg->native_422)
1347		num_extra_mux_bits = 4 * vdsc_cfg->mux_word_size +
1348			(4 * vdsc_cfg->bits_per_component + 4) +
1349			3 * (4 * vdsc_cfg->bits_per_component) - 2;
1350	else
1351		num_extra_mux_bits = 3 * vdsc_cfg->mux_word_size +
1352			(4 * vdsc_cfg->bits_per_component + 4) +
1353			2 * (4 * vdsc_cfg->bits_per_component) - 2;
1354	/* Number of bits in one Slice */
1355	slice_bits = 8 * vdsc_cfg->slice_chunk_size * vdsc_cfg->slice_height;
1356
1357	while ((num_extra_mux_bits > 0) &&
1358	       ((slice_bits - num_extra_mux_bits) % vdsc_cfg->mux_word_size))
1359		num_extra_mux_bits--;
1360
1361	if (groups_per_line < vdsc_cfg->initial_scale_value - 8)
1362		vdsc_cfg->initial_scale_value = groups_per_line + 8;
1363
1364	/* scale_decrement_interval calculation according to DSC spec 1.11 */
1365	if (vdsc_cfg->initial_scale_value > 8)
1366		vdsc_cfg->scale_decrement_interval = groups_per_line /
1367			(vdsc_cfg->initial_scale_value - 8);
1368	else
1369		vdsc_cfg->scale_decrement_interval = DSC_SCALE_DECREMENT_INTERVAL_MAX;
1370
1371	vdsc_cfg->final_offset = vdsc_cfg->rc_model_size -
1372		(vdsc_cfg->initial_xmit_delay *
1373		 vdsc_cfg->bits_per_pixel + 8) / 16 + num_extra_mux_bits;
1374
1375	if (vdsc_cfg->final_offset >= vdsc_cfg->rc_model_size) {
1376		DRM_DEBUG_KMS("FinalOfs < RcModelSze for this InitialXmitDelay\n");
1377		return -ERANGE;
1378	}
1379
1380	final_scale = (vdsc_cfg->rc_model_size * 8) /
1381		(vdsc_cfg->rc_model_size - vdsc_cfg->final_offset);
1382	if (vdsc_cfg->slice_height > 1)
1383		/*
1384		 * NflBpgOffset is 16 bit value with 11 fractional bits
1385		 * hence we multiply by 2^11 for preserving the
1386		 * fractional part
1387		 */
1388		vdsc_cfg->nfl_bpg_offset = DIV_ROUND_UP((vdsc_cfg->first_line_bpg_offset << 11),
1389							(vdsc_cfg->slice_height - 1));
1390	else
1391		vdsc_cfg->nfl_bpg_offset = 0;
1392
1393	/* Number of groups used to code the entire slice */
1394	groups_total = groups_per_line * vdsc_cfg->slice_height;
1395
1396	/* slice_bpg_offset is 16 bit value with 11 fractional bits */
1397	vdsc_cfg->slice_bpg_offset = DIV_ROUND_UP(((vdsc_cfg->rc_model_size -
1398						    vdsc_cfg->initial_offset +
1399						    num_extra_mux_bits) << 11),
1400						  groups_total);
1401
1402	if (final_scale > 9) {
1403		/*
1404		 * ScaleIncrementInterval =
1405		 * finaloffset/((NflBpgOffset + SliceBpgOffset)*8(finalscale - 1.125))
1406		 * as (NflBpgOffset + SliceBpgOffset) has 11 bit fractional value,
1407		 * we need divide by 2^11 from pstDscCfg values
1408		 */
1409		vdsc_cfg->scale_increment_interval =
1410				(vdsc_cfg->final_offset * (1 << 11)) /
1411				((vdsc_cfg->nfl_bpg_offset +
1412				vdsc_cfg->slice_bpg_offset) *
1413				(final_scale - 9));
1414	} else {
1415		/*
1416		 * If finalScaleValue is less than or equal to 9, a value of 0 should
1417		 * be used to disable the scale increment at the end of the slice
1418		 */
1419		vdsc_cfg->scale_increment_interval = 0;
1420	}
1421
1422	/*
1423	 * DSC spec mentions that bits_per_pixel specifies the target
1424	 * bits/pixel (bpp) rate that is used by the encoder,
1425	 * in steps of 1/16 of a bit per pixel
1426	 */
1427	rbs_min = vdsc_cfg->rc_model_size - vdsc_cfg->initial_offset +
1428		DIV_ROUND_UP(vdsc_cfg->initial_xmit_delay *
1429			     vdsc_cfg->bits_per_pixel, 16) +
1430		groups_per_line * vdsc_cfg->first_line_bpg_offset;
1431
1432	hrd_delay = DIV_ROUND_UP((rbs_min * 16), vdsc_cfg->bits_per_pixel);
1433	vdsc_cfg->rc_bits = (hrd_delay * vdsc_cfg->bits_per_pixel) / 16;
1434	vdsc_cfg->initial_dec_delay = hrd_delay - vdsc_cfg->initial_xmit_delay;
1435
1436	return 0;
1437}
1438EXPORT_SYMBOL(drm_dsc_compute_rc_parameters);
1439
1440/**
1441 * drm_dsc_get_bpp_int() - Get integer bits per pixel value for the given DRM DSC config
1442 * @vdsc_cfg: Pointer to DRM DSC config struct
1443 *
1444 * Return: Integer BPP value
1445 */
1446u32 drm_dsc_get_bpp_int(const struct drm_dsc_config *vdsc_cfg)
1447{
1448	WARN_ON_ONCE(vdsc_cfg->bits_per_pixel & 0xf);
1449	return vdsc_cfg->bits_per_pixel >> 4;
1450}
1451EXPORT_SYMBOL(drm_dsc_get_bpp_int);
1452
1453/**
1454 * drm_dsc_initial_scale_value() - Calculate the initial scale value for the given DSC config
1455 * @dsc: Pointer to DRM DSC config struct
1456 *
1457 * Return: Calculated initial scale value
1458 */
1459u8 drm_dsc_initial_scale_value(const struct drm_dsc_config *dsc)
1460{
1461	return 8 * dsc->rc_model_size / (dsc->rc_model_size - dsc->initial_offset);
1462}
1463EXPORT_SYMBOL(drm_dsc_initial_scale_value);
1464
1465/**
1466 * drm_dsc_flatness_det_thresh() - Calculate the flatness_det_thresh for the given DSC config
1467 * @dsc: Pointer to DRM DSC config struct
1468 *
1469 * Return: Calculated flatness det thresh value
1470 */
1471u32 drm_dsc_flatness_det_thresh(const struct drm_dsc_config *dsc)
1472{
1473	return 2 << (dsc->bits_per_component - 8);
1474}
1475EXPORT_SYMBOL(drm_dsc_flatness_det_thresh);
1476
1477static void drm_dsc_dump_config_main_params(struct drm_printer *p, int indent,
1478					    const struct drm_dsc_config *cfg)
1479{
1480	drm_printf_indent(p, indent,
1481			  "dsc-cfg: version: %d.%d, picture: w=%d, h=%d, slice: count=%d, w=%d, h=%d, size=%d\n",
1482			  cfg->dsc_version_major, cfg->dsc_version_minor,
1483			  cfg->pic_width, cfg->pic_height,
1484			  cfg->slice_count, cfg->slice_width, cfg->slice_height, cfg->slice_chunk_size);
1485	drm_printf_indent(p, indent,
1486			  "dsc-cfg: mode: block-pred=%s, vbr=%s, rgb=%s, simple-422=%s, native-422=%s, native-420=%s\n",
1487			  str_yes_no(cfg->block_pred_enable), str_yes_no(cfg->vbr_enable),
1488			  str_yes_no(cfg->convert_rgb),
1489			  str_yes_no(cfg->simple_422), str_yes_no(cfg->native_422), str_yes_no(cfg->native_420));
1490	drm_printf_indent(p, indent,
1491			  "dsc-cfg: color-depth: uncompressed-bpc=%d, compressed-bpp=" FXP_Q4_FMT " line-buf-bpp=%d\n",
1492			  cfg->bits_per_component, FXP_Q4_ARGS(cfg->bits_per_pixel), cfg->line_buf_depth);
1493	drm_printf_indent(p, indent,
1494			  "dsc-cfg: rc-model: size=%d, bits=%d, mux-word-size: %d, initial-delays: xmit=%d, dec=%d\n",
1495			  cfg->rc_model_size, cfg->rc_bits, cfg->mux_word_size,
1496			  cfg->initial_xmit_delay, cfg->initial_dec_delay);
1497	drm_printf_indent(p, indent,
1498			  "dsc-cfg: offsets: initial=%d, final=%d, slice-bpg=%d\n",
1499			  cfg->initial_offset, cfg->final_offset, cfg->slice_bpg_offset);
1500	drm_printf_indent(p, indent,
1501			  "dsc-cfg: line-bpg-offsets: first=%d, non-first=%d, second=%d, non-second=%d, second-adj=%d\n",
1502			  cfg->first_line_bpg_offset, cfg->nfl_bpg_offset,
1503			  cfg->second_line_bpg_offset, cfg->nsl_bpg_offset, cfg->second_line_offset_adj);
1504	drm_printf_indent(p, indent,
1505			  "dsc-cfg: rc-tgt-offsets: low=%d, high=%d, rc-edge-factor: %d, rc-quant-incr-limits: [0]=%d, [1]=%d\n",
1506			  cfg->rc_tgt_offset_low, cfg->rc_tgt_offset_high,
1507			  cfg->rc_edge_factor, cfg->rc_quant_incr_limit0, cfg->rc_quant_incr_limit1);
1508	drm_printf_indent(p, indent,
1509			  "dsc-cfg: initial-scale: %d, scale-intervals: increment=%d, decrement=%d\n",
1510			  cfg->initial_scale_value, cfg->scale_increment_interval, cfg->scale_decrement_interval);
1511	drm_printf_indent(p, indent,
1512			  "dsc-cfg: flatness: min-qp=%d, max-qp=%d\n",
1513			  cfg->flatness_min_qp, cfg->flatness_max_qp);
1514}
1515
1516static void drm_dsc_dump_config_rc_params(struct drm_printer *p, int indent,
1517					  const struct drm_dsc_config *cfg)
1518{
1519	const u16 *bt = cfg->rc_buf_thresh;
1520	const struct drm_dsc_rc_range_parameters *rp = cfg->rc_range_params;
1521
1522	BUILD_BUG_ON(ARRAY_SIZE(cfg->rc_buf_thresh) != 14);
1523	BUILD_BUG_ON(ARRAY_SIZE(cfg->rc_range_params) != 15);
1524
1525	drm_printf_indent(p, indent,
1526			  "dsc-cfg: rc-level:         0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14\n");
1527	drm_printf_indent(p, indent,
1528			  "dsc-cfg: rc-buf-thresh:  %3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d\n",
1529			  bt[0], bt[1], bt[2],  bt[3],  bt[4],  bt[5], bt[6], bt[7],
1530			  bt[8], bt[9], bt[10], bt[11], bt[12], bt[13]);
1531	drm_printf_indent(p, indent,
1532			  "dsc-cfg: rc-min-qp:      %3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d\n",
1533			  rp[0].range_min_qp,  rp[1].range_min_qp,  rp[2].range_min_qp,  rp[3].range_min_qp,
1534			  rp[4].range_min_qp,  rp[5].range_min_qp,  rp[6].range_min_qp,  rp[7].range_min_qp,
1535			  rp[8].range_min_qp,  rp[9].range_min_qp,  rp[10].range_min_qp, rp[11].range_min_qp,
1536			  rp[12].range_min_qp, rp[13].range_min_qp, rp[14].range_min_qp);
1537	drm_printf_indent(p, indent,
1538			  "dsc-cfg: rc-max-qp:      %3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d\n",
1539			  rp[0].range_max_qp,  rp[1].range_max_qp,  rp[2].range_max_qp,  rp[3].range_max_qp,
1540			  rp[4].range_max_qp,  rp[5].range_max_qp,  rp[6].range_max_qp,  rp[7].range_max_qp,
1541			  rp[8].range_max_qp,  rp[9].range_max_qp,  rp[10].range_max_qp, rp[11].range_max_qp,
1542			  rp[12].range_max_qp, rp[13].range_max_qp, rp[14].range_max_qp);
1543	drm_printf_indent(p, indent,
1544			  "dsc-cfg: rc-bpg-offset:  %3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d,%3d\n",
1545			  rp[0].range_bpg_offset,  rp[1].range_bpg_offset,  rp[2].range_bpg_offset,  rp[3].range_bpg_offset,
1546			  rp[4].range_bpg_offset,  rp[5].range_bpg_offset,  rp[6].range_bpg_offset,  rp[7].range_bpg_offset,
1547			  rp[8].range_bpg_offset,  rp[9].range_bpg_offset,  rp[10].range_bpg_offset, rp[11].range_bpg_offset,
1548			  rp[12].range_bpg_offset, rp[13].range_bpg_offset, rp[14].range_bpg_offset);
1549}
1550
1551/**
1552 * drm_dsc_dump_config - Dump the provided DSC configuration
1553 * @p: The printer used for output
1554 * @indent: Tab indentation level (max 5)
1555 * @cfg: DSC configuration to print
1556 *
1557 * Print the provided DSC configuration in @cfg.
1558 */
1559void drm_dsc_dump_config(struct drm_printer *p, int indent,
1560			 const struct drm_dsc_config *cfg)
1561{
1562	drm_dsc_dump_config_main_params(p, indent, cfg);
1563	drm_dsc_dump_config_rc_params(p, indent, cfg);
1564}
1565EXPORT_SYMBOL(drm_dsc_dump_config);