File Index
Files and directories
Sign in
FILE

intel_vdsc.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/i915/display/intel_vdsc.c C
   1// SPDX-License-Identifier: MIT
   2/*
   3 * Copyright © 2018 Intel Corporation
   4 *
   5 * Author: Gaurav K Singh <gaurav.k.singh@intel.com>
   6 *         Manasi Navare <manasi.d.navare@intel.com>
   7 */
   8#include <linux/limits.h>
   9
  10#include <drm/display/drm_dsc_helper.h>
  11#include <drm/drm_fixed.h>
  12#include <drm/drm_print.h>
  13
  14#include "intel_crtc.h"
  15#include "intel_de.h"
  16#include "intel_display_types.h"
  17#include "intel_display_utils.h"
  18#include "intel_dp.h"
  19#include "intel_dsi.h"
  20#include "intel_qp_tables.h"
  21#include "intel_vdsc.h"
  22#include "intel_vdsc_regs.h"
  23
  24bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state)
  25{
  26	struct intel_display *display = to_intel_display(crtc_state);
  27	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
  28
  29	if (!HAS_DSC(display))
  30		return false;
  31
  32	if (DISPLAY_VER(display) == 11 && cpu_transcoder == TRANSCODER_A)
  33		return false;
  34
  35	return true;
  36}
  37
  38static bool is_pipe_dsc(struct intel_crtc *crtc, enum transcoder cpu_transcoder)
  39{
  40	struct intel_display *display = to_intel_display(crtc);
  41
  42	if (DISPLAY_VER(display) >= 12)
  43		return true;
  44
  45	if (cpu_transcoder == TRANSCODER_EDP ||
  46	    cpu_transcoder == TRANSCODER_DSI_0 ||
  47	    cpu_transcoder == TRANSCODER_DSI_1)
  48		return false;
  49
  50	/* There's no pipe A DSC engine on ICL */
  51	drm_WARN_ON(display->drm, crtc->pipe == PIPE_A);
  52
  53	return true;
  54}
  55
  56static void
  57intel_vdsc_set_min_max_qp(struct drm_dsc_config *vdsc_cfg, int buf,
  58			  int bpp)
  59{
  60	int bpc = vdsc_cfg->bits_per_component;
  61
  62	/* Read range_minqp and range_max_qp from qp tables */
  63	vdsc_cfg->rc_range_params[buf].range_min_qp =
  64		intel_lookup_range_min_qp(bpc, buf, bpp, vdsc_cfg->native_420);
  65	vdsc_cfg->rc_range_params[buf].range_max_qp =
  66		intel_lookup_range_max_qp(bpc, buf, bpp, vdsc_cfg->native_420);
  67}
  68
  69static int
  70get_range_bpg_offset(int bpp_low, int offset_low, int bpp_high, int offset_high, int bpp)
  71{
  72	return offset_low + DIV_ROUND_UP((offset_high - offset_low) * (bpp - bpp_low),
  73					 (bpp_low - bpp_high));
  74}
  75
  76/*
  77 * We are using the method provided in DSC 1.2a C-Model in codec_main.c
  78 * Above method use a common formula to derive values for any combination of DSC
  79 * variables. The formula approach may yield slight differences in the derived PPS
  80 * parameters from the original parameter sets. These differences are not consequential
  81 * to the coding performance because all parameter sets have been shown to produce
  82 * visually lossless quality (provides the same PPS values as
  83 * DSCParameterValuesVESA V1-2 spreadsheet).
  84 */
  85static void
  86calculate_rc_params(struct drm_dsc_config *vdsc_cfg)
  87{
  88	int bpp = fxp_q4_to_int(vdsc_cfg->bits_per_pixel);
  89	int bpc = vdsc_cfg->bits_per_component;
  90	int qp_bpc_modifier = (bpc - 8) * 2;
  91	int uncompressed_bpg_rate;
  92	int first_line_bpg_offset;
  93	u32 buf_i, bpp_i;
  94
  95	if (vdsc_cfg->slice_height >= 8)
  96		first_line_bpg_offset =
  97			12 + (9 * min(34, vdsc_cfg->slice_height - 8)) / 100;
  98	else
  99		first_line_bpg_offset = 2 * (vdsc_cfg->slice_height - 1);
 100
 101	uncompressed_bpg_rate = (3 * bpc + (vdsc_cfg->convert_rgb ? 0 : 2)) * 3;
 102	vdsc_cfg->first_line_bpg_offset = clamp(first_line_bpg_offset, 0,
 103						uncompressed_bpg_rate - 3 * bpp);
 104
 105	/*
 106	 * According to DSC 1.2 spec in Section 4.1 if native_420 is set:
 107	 * -second_line_bpg_offset is 12 in general and equal to 2*(slice_height-1) if slice
 108	 * height < 8.
 109	 * -second_line_offset_adj is 512 as shown by empirical values to yield best chroma
 110	 * preservation in second line.
 111	 * -nsl_bpg_offset is calculated as second_line_offset/slice_height -1 then rounded
 112	 * up to 16 fractional bits, we left shift second line offset by 11 to preserve 11
 113	 * fractional bits.
 114	 */
 115	if (vdsc_cfg->native_420) {
 116		if (vdsc_cfg->slice_height >= 8)
 117			vdsc_cfg->second_line_bpg_offset = 12;
 118		else
 119			vdsc_cfg->second_line_bpg_offset =
 120				2 * (vdsc_cfg->slice_height - 1);
 121
 122		vdsc_cfg->second_line_offset_adj = 512;
 123		vdsc_cfg->nsl_bpg_offset = DIV_ROUND_UP(vdsc_cfg->second_line_bpg_offset << 11,
 124							vdsc_cfg->slice_height - 1);
 125	}
 126
 127	if (bpp >= 12)
 128		vdsc_cfg->initial_offset = 2048;
 129	else if (bpp >= 10)
 130		vdsc_cfg->initial_offset = 5632 - DIV_ROUND_UP(((bpp - 10) * 3584), 2);
 131	else if (bpp >= 8)
 132		vdsc_cfg->initial_offset = 6144 - DIV_ROUND_UP(((bpp - 8) * 512), 2);
 133	else
 134		vdsc_cfg->initial_offset = 6144;
 135
 136	/* initial_xmit_delay = rc_model_size/2/compression_bpp */
 137	vdsc_cfg->initial_xmit_delay = DIV_ROUND_UP(DSC_RC_MODEL_SIZE_CONST, 2 * bpp);
 138
 139	vdsc_cfg->flatness_min_qp = 3 + qp_bpc_modifier;
 140	vdsc_cfg->flatness_max_qp = 12 + qp_bpc_modifier;
 141
 142	vdsc_cfg->rc_quant_incr_limit0 = 11 + qp_bpc_modifier;
 143	vdsc_cfg->rc_quant_incr_limit1 = 11 + qp_bpc_modifier;
 144
 145	if (vdsc_cfg->native_420) {
 146		static const s8 ofs_und4[] = {
 147			2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12
 148		};
 149		static const s8 ofs_und5[] = {
 150			2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -10, -12, -12, -12
 151		};
 152		static const s8 ofs_und6[] = {
 153			2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -10, -12, -12, -12
 154		};
 155		static const s8 ofs_und8[] = {
 156			10, 8, 6, 4, 2, 0, -2, -4, -6, -8, -10, -10, -12, -12, -12
 157		};
 158		/*
 159		 * For 420 format since bits_per_pixel (bpp) is set to target bpp * 2,
 160		 * QP table values for target bpp 4.0 to 4.4375 (rounded to 4.0) are
 161		 * actually for bpp 8 to 8.875 (rounded to 4.0 * 2 i.e 8).
 162		 * Similarly values for target bpp 4.5 to 4.8375 (rounded to 4.5)
 163		 * are for bpp 9 to 9.875 (rounded to 4.5 * 2 i.e 9), and so on.
 164		 */
 165		bpp_i  = bpp - 8;
 166		for (buf_i = 0; buf_i < DSC_NUM_BUF_RANGES; buf_i++) {
 167			u8 range_bpg_offset;
 168
 169			intel_vdsc_set_min_max_qp(vdsc_cfg, buf_i, bpp_i);
 170
 171			/* Calculate range_bpg_offset */
 172			if (bpp <= 8)
 173				range_bpg_offset = ofs_und4[buf_i];
 174			else if (bpp <= 10)
 175				range_bpg_offset = get_range_bpg_offset(8, ofs_und4[buf_i],
 176									10, ofs_und5[buf_i], bpp);
 177			else if (bpp <= 12)
 178				range_bpg_offset = get_range_bpg_offset(10, ofs_und5[buf_i],
 179									12, ofs_und6[buf_i], bpp);
 180			else if (bpp <= 16)
 181				range_bpg_offset = get_range_bpg_offset(12, ofs_und6[buf_i],
 182									16, ofs_und8[buf_i], bpp);
 183			else
 184				range_bpg_offset = ofs_und8[buf_i];
 185
 186			vdsc_cfg->rc_range_params[buf_i].range_bpg_offset =
 187				range_bpg_offset & DSC_RANGE_BPG_OFFSET_MASK;
 188		}
 189	} else {
 190		/* fractional bpp part * 10000 (for precision up to 4 decimal places) */
 191		int fractional_bits = fxp_q4_to_frac(vdsc_cfg->bits_per_pixel);
 192
 193		static const s8 ofs_und6[] = {
 194			0, -2, -2, -4, -6, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12
 195		};
 196		static const s8 ofs_und8[] = {
 197			2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -10, -12, -12, -12
 198		};
 199		static const s8 ofs_und12[] = {
 200			2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -10, -12, -12, -12
 201		};
 202		static const s8 ofs_und15[] = {
 203			10, 8, 6, 4, 2, 0, -2, -4, -6, -8, -10, -10, -12, -12, -12
 204		};
 205
 206		/*
 207		 * QP table rows have values in increment of 0.5.
 208		 * So 6.0 bpp to 6.4375 will have index 0, 6.5 to 6.9375 will have index 1,
 209		 * and so on.
 210		 * 0.5 fractional part with 4 decimal precision becomes 5000
 211		 */
 212		bpp_i  = ((bpp - 6) + (fractional_bits < 5000 ? 0 : 1));
 213
 214		for (buf_i = 0; buf_i < DSC_NUM_BUF_RANGES; buf_i++) {
 215			u8 range_bpg_offset;
 216
 217			intel_vdsc_set_min_max_qp(vdsc_cfg, buf_i, bpp_i);
 218
 219			/* Calculate range_bpg_offset */
 220			if (bpp <= 6)
 221				range_bpg_offset = ofs_und6[buf_i];
 222			else if (bpp <= 8)
 223				range_bpg_offset = get_range_bpg_offset(6, ofs_und6[buf_i],
 224									8, ofs_und8[buf_i], bpp);
 225			else if (bpp <= 12)
 226				range_bpg_offset = get_range_bpg_offset(8, ofs_und8[buf_i],
 227									12, ofs_und12[buf_i], bpp);
 228			else if (bpp <= 15)
 229				range_bpg_offset = get_range_bpg_offset(12, ofs_und12[buf_i],
 230									15, ofs_und15[buf_i], bpp);
 231			else
 232				range_bpg_offset = ofs_und15[buf_i];
 233
 234			vdsc_cfg->rc_range_params[buf_i].range_bpg_offset =
 235				range_bpg_offset & DSC_RANGE_BPG_OFFSET_MASK;
 236		}
 237	}
 238}
 239
 240static int intel_dsc_slice_dimensions_valid(struct intel_crtc_state *pipe_config,
 241					    struct drm_dsc_config *vdsc_cfg)
 242{
 243	if (pipe_config->output_format == INTEL_OUTPUT_FORMAT_RGB ||
 244	    pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR444) {
 245		if (vdsc_cfg->slice_height > 4095)
 246			return -EINVAL;
 247		if (vdsc_cfg->slice_height * vdsc_cfg->slice_width < 15000)
 248			return -EINVAL;
 249	} else if (pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) {
 250		if (vdsc_cfg->slice_width % 2)
 251			return -EINVAL;
 252		if (vdsc_cfg->slice_height % 2)
 253			return -EINVAL;
 254		if (vdsc_cfg->slice_height > 4094)
 255			return -EINVAL;
 256		if (vdsc_cfg->slice_height * vdsc_cfg->slice_width < 30000)
 257			return -EINVAL;
 258	}
 259
 260	return 0;
 261}
 262
 263static bool is_dsi_dsc_1_1(struct intel_crtc_state *crtc_state)
 264{
 265	struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
 266
 267	return vdsc_cfg->dsc_version_major == 1 &&
 268		vdsc_cfg->dsc_version_minor == 1 &&
 269		intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI);
 270}
 271
 272int intel_dsc_compute_params(struct intel_crtc_state *pipe_config)
 273{
 274	struct intel_display *display = to_intel_display(pipe_config);
 275	struct drm_dsc_config *vdsc_cfg = &pipe_config->dsc.config;
 276	u16 compressed_bpp = fxp_q4_to_int(pipe_config->dsc.compressed_bpp_x16);
 277	int err;
 278	int ret;
 279
 280	vdsc_cfg->pic_width = pipe_config->hw.adjusted_mode.crtc_hdisplay;
 281	vdsc_cfg->slice_width = DIV_ROUND_UP(vdsc_cfg->pic_width,
 282					     pipe_config->dsc.slice_count);
 283
 284	err = intel_dsc_slice_dimensions_valid(pipe_config, vdsc_cfg);
 285
 286	if (err) {
 287		drm_dbg_kms(display->drm, "Slice dimension requirements not met\n");
 288		return err;
 289	}
 290
 291	/*
 292	 * According to DSC 1.2 specs if colorspace is YCbCr then convert_rgb is 0
 293	 * else 1
 294	 */
 295	vdsc_cfg->convert_rgb = pipe_config->output_format != INTEL_OUTPUT_FORMAT_YCBCR420 &&
 296				pipe_config->output_format != INTEL_OUTPUT_FORMAT_YCBCR444;
 297
 298	if (DISPLAY_VER(display) >= 14 &&
 299	    pipe_config->output_format == INTEL_OUTPUT_FORMAT_YCBCR420)
 300		vdsc_cfg->native_420 = true;
 301	/* We do not support YcBCr422 as of now */
 302	vdsc_cfg->native_422 = false;
 303	vdsc_cfg->simple_422 = false;
 304	/* Gen 11 does not support VBR */
 305	vdsc_cfg->vbr_enable = false;
 306
 307	vdsc_cfg->bits_per_pixel = pipe_config->dsc.compressed_bpp_x16;
 308
 309	/*
 310	 * According to DSC 1.2 specs in Section 4.1 if native_420 is set
 311	 * we need to double the current bpp.
 312	 */
 313	if (vdsc_cfg->native_420)
 314		vdsc_cfg->bits_per_pixel <<= 1;
 315
 316	vdsc_cfg->bits_per_component = pipe_config->pipe_bpp / 3;
 317
 318	if (vdsc_cfg->bits_per_component < 8) {
 319		drm_dbg_kms(display->drm, "DSC bpc requirements not met bpc: %d\n",
 320			    vdsc_cfg->bits_per_component);
 321		return -EINVAL;
 322	}
 323
 324	drm_dsc_set_rc_buf_thresh(vdsc_cfg);
 325
 326	/*
 327	 * From XE_LPD onwards we supports compression bpps in steps of 1
 328	 * upto uncompressed bpp-1, hence add calculations for all the rc
 329	 * parameters
 330	 *
 331	 * We don't want to calculate all rc parameters when the panel
 332	 * is MIPI DSI and it's using DSC 1.1. The reason being that some
 333	 * DSI panels vendors have hardcoded PPS params in the VBT causing
 334	 * the parameters sent from the source which are derived through
 335	 * interpolation to differ from the params the panel expects.
 336	 * This causes a noise in the display.
 337	 * Furthermore for DSI panels we are currently using  bits_per_pixel
 338	 * (compressed bpp) hardcoded from VBT, (unlike other encoders where we
 339	 * find the optimum compressed bpp) so dont need to rely on interpolation,
 340	 * as we can get the required rc parameters from the tables.
 341	 */
 342	if (DISPLAY_VER(display) >= 13 && !is_dsi_dsc_1_1(pipe_config)) {
 343		calculate_rc_params(vdsc_cfg);
 344	} else {
 345		if ((compressed_bpp == 8 ||
 346		     compressed_bpp == 12) &&
 347		    (vdsc_cfg->bits_per_component == 8 ||
 348		     vdsc_cfg->bits_per_component == 10 ||
 349		     vdsc_cfg->bits_per_component == 12))
 350			ret = drm_dsc_setup_rc_params(vdsc_cfg, DRM_DSC_1_1_PRE_SCR);
 351		else
 352			ret = drm_dsc_setup_rc_params(vdsc_cfg, DRM_DSC_1_2_444);
 353
 354		if (ret)
 355			return ret;
 356	}
 357
 358	/*
 359	 * BitsPerComponent value determines mux_word_size:
 360	 * When BitsPerComponent is less than or 10bpc, muxWordSize will be equal to
 361	 * 48 bits otherwise 64
 362	 */
 363	if (vdsc_cfg->bits_per_component <= 10)
 364		vdsc_cfg->mux_word_size = DSC_MUX_WORD_SIZE_8_10_BPC;
 365	else
 366		vdsc_cfg->mux_word_size = DSC_MUX_WORD_SIZE_12_BPC;
 367
 368	/* InitialScaleValue is a 6 bit value with 3 fractional bits (U3.3) */
 369	vdsc_cfg->initial_scale_value = (vdsc_cfg->rc_model_size << 3) /
 370		(vdsc_cfg->rc_model_size - vdsc_cfg->initial_offset);
 371
 372	return 0;
 373}
 374
 375void intel_dsc_enable_on_crtc(struct intel_crtc_state *crtc_state)
 376{
 377	crtc_state->dsc.compression_enabled_on_link = true;
 378	crtc_state->dsc.compression_enable = true;
 379}
 380
 381bool intel_dsc_enabled_on_link(const struct intel_crtc_state *crtc_state)
 382{
 383	struct intel_display *display = to_intel_display(crtc_state);
 384
 385	drm_WARN_ON(display->drm, crtc_state->dsc.compression_enable &&
 386		    !crtc_state->dsc.compression_enabled_on_link);
 387
 388	return crtc_state->dsc.compression_enabled_on_link;
 389}
 390
 391enum intel_display_power_domain
 392intel_dsc_power_domain(struct intel_crtc *crtc, enum transcoder cpu_transcoder)
 393{
 394	struct intel_display *display = to_intel_display(crtc);
 395	enum pipe pipe = crtc->pipe;
 396
 397	/*
 398	 * VDSC/joining uses a separate power well, PW2, and requires
 399	 * POWER_DOMAIN_TRANSCODER_VDSC_PW2 power domain in two cases:
 400	 *
 401	 *  - ICL eDP/DSI transcoder
 402	 *  - Display version 12 (except RKL) pipe A
 403	 *
 404	 * For any other pipe, VDSC/joining uses the power well associated with
 405	 * the pipe in use. Hence another reference on the pipe power domain
 406	 * will suffice. (Except no VDSC/joining on ICL pipe A.)
 407	 */
 408	if (DISPLAY_VER(display) == 12 && !display->platform.rocketlake &&
 409	    pipe == PIPE_A)
 410		return POWER_DOMAIN_TRANSCODER_VDSC_PW2;
 411	else if (is_pipe_dsc(crtc, cpu_transcoder))
 412		return POWER_DOMAIN_PIPE(pipe);
 413	else
 414		return POWER_DOMAIN_TRANSCODER_VDSC_PW2;
 415}
 416
 417static int intel_dsc_get_vdsc_per_pipe(const struct intel_crtc_state *crtc_state)
 418{
 419	return crtc_state->dsc.num_streams;
 420}
 421
 422int intel_dsc_get_num_vdsc_instances(const struct intel_crtc_state *crtc_state)
 423{
 424	int num_vdsc_instances = intel_dsc_get_vdsc_per_pipe(crtc_state);
 425	int num_joined_pipes = intel_crtc_num_joined_pipes(crtc_state);
 426
 427	num_vdsc_instances *= num_joined_pipes;
 428
 429	return num_vdsc_instances;
 430}
 431
 432static void intel_dsc_get_pps_reg(const struct intel_crtc_state *crtc_state, int pps,
 433				  i915_reg_t *dsc_reg, int dsc_reg_num)
 434{
 435	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 436	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
 437	enum pipe pipe = crtc->pipe;
 438	bool pipe_dsc;
 439
 440	pipe_dsc = is_pipe_dsc(crtc, cpu_transcoder);
 441
 442	if (dsc_reg_num >= 4)
 443		MISSING_CASE(dsc_reg_num);
 444	if (dsc_reg_num >= 3)
 445		dsc_reg[2] = BMG_DSC2_PPS(pipe, pps);
 446	if (dsc_reg_num >= 2)
 447		dsc_reg[1] = pipe_dsc ? ICL_DSC1_PPS(pipe, pps) : DSCC_PPS(pps);
 448	if (dsc_reg_num >= 1)
 449		dsc_reg[0] = pipe_dsc ? ICL_DSC0_PPS(pipe, pps) : DSCA_PPS(pps);
 450}
 451
 452static void intel_dsc_pps_write(const struct intel_crtc_state *crtc_state,
 453				int pps, u32 pps_val)
 454{
 455	struct intel_display *display = to_intel_display(crtc_state);
 456	i915_reg_t dsc_reg[3];
 457	int i, vdsc_per_pipe, dsc_reg_num;
 458
 459	vdsc_per_pipe = intel_dsc_get_vdsc_per_pipe(crtc_state);
 460	dsc_reg_num = min_t(int, ARRAY_SIZE(dsc_reg), vdsc_per_pipe);
 461
 462	drm_WARN_ON_ONCE(display->drm, dsc_reg_num < vdsc_per_pipe);
 463
 464	intel_dsc_get_pps_reg(crtc_state, pps, dsc_reg, dsc_reg_num);
 465
 466	for (i = 0; i < dsc_reg_num; i++)
 467		intel_de_write(display, dsc_reg[i], pps_val);
 468}
 469
 470static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state)
 471{
 472	struct intel_display *display = to_intel_display(crtc_state);
 473	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 474	const struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
 475	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
 476	enum pipe pipe = crtc->pipe;
 477	u32 pps_val;
 478	u32 rc_buf_thresh_dword[4];
 479	u32 rc_range_params_dword[8];
 480	int i = 0;
 481	int num_vdsc_instances = intel_dsc_get_num_vdsc_instances(crtc_state);
 482	int vdsc_instances_per_pipe = intel_dsc_get_vdsc_per_pipe(crtc_state);
 483
 484	/* PPS 0 */
 485	pps_val = DSC_PPS0_VER_MAJOR(1) |
 486		DSC_PPS0_VER_MINOR(vdsc_cfg->dsc_version_minor) |
 487		DSC_PPS0_BPC(vdsc_cfg->bits_per_component) |
 488		DSC_PPS0_LINE_BUF_DEPTH(vdsc_cfg->line_buf_depth);
 489	if (vdsc_cfg->dsc_version_minor == 2) {
 490		pps_val |= DSC_PPS0_ALT_ICH_SEL;
 491		if (vdsc_cfg->native_420)
 492			pps_val |= DSC_PPS0_NATIVE_420_ENABLE;
 493		if (vdsc_cfg->native_422)
 494			pps_val |= DSC_PPS0_NATIVE_422_ENABLE;
 495	}
 496	if (vdsc_cfg->block_pred_enable)
 497		pps_val |= DSC_PPS0_BLOCK_PREDICTION;
 498	if (vdsc_cfg->convert_rgb)
 499		pps_val |= DSC_PPS0_COLOR_SPACE_CONVERSION;
 500	if (vdsc_cfg->simple_422)
 501		pps_val |= DSC_PPS0_422_ENABLE;
 502	if (vdsc_cfg->vbr_enable)
 503		pps_val |= DSC_PPS0_VBR_ENABLE;
 504	intel_dsc_pps_write(crtc_state, 0, pps_val);
 505
 506	/* PPS 1 */
 507	pps_val = DSC_PPS1_BPP(vdsc_cfg->bits_per_pixel);
 508	intel_dsc_pps_write(crtc_state, 1, pps_val);
 509
 510	/* PPS 2 */
 511	pps_val = DSC_PPS2_PIC_HEIGHT(vdsc_cfg->pic_height) |
 512		DSC_PPS2_PIC_WIDTH(vdsc_cfg->pic_width / num_vdsc_instances);
 513	intel_dsc_pps_write(crtc_state, 2, pps_val);
 514
 515	/* PPS 3 */
 516	pps_val = DSC_PPS3_SLICE_HEIGHT(vdsc_cfg->slice_height) |
 517		DSC_PPS3_SLICE_WIDTH(vdsc_cfg->slice_width);
 518	intel_dsc_pps_write(crtc_state, 3, pps_val);
 519
 520	/* PPS 4 */
 521	pps_val = DSC_PPS4_INITIAL_XMIT_DELAY(vdsc_cfg->initial_xmit_delay) |
 522		DSC_PPS4_INITIAL_DEC_DELAY(vdsc_cfg->initial_dec_delay);
 523	intel_dsc_pps_write(crtc_state, 4, pps_val);
 524
 525	/* PPS 5 */
 526	pps_val = DSC_PPS5_SCALE_INC_INT(vdsc_cfg->scale_increment_interval) |
 527		DSC_PPS5_SCALE_DEC_INT(vdsc_cfg->scale_decrement_interval);
 528	intel_dsc_pps_write(crtc_state, 5, pps_val);
 529
 530	/* PPS 6 */
 531	pps_val = DSC_PPS6_INITIAL_SCALE_VALUE(vdsc_cfg->initial_scale_value) |
 532		DSC_PPS6_FIRST_LINE_BPG_OFFSET(vdsc_cfg->first_line_bpg_offset) |
 533		DSC_PPS6_FLATNESS_MIN_QP(vdsc_cfg->flatness_min_qp) |
 534		DSC_PPS6_FLATNESS_MAX_QP(vdsc_cfg->flatness_max_qp);
 535	intel_dsc_pps_write(crtc_state, 6, pps_val);
 536
 537	/* PPS 7 */
 538	pps_val = DSC_PPS7_SLICE_BPG_OFFSET(vdsc_cfg->slice_bpg_offset) |
 539		DSC_PPS7_NFL_BPG_OFFSET(vdsc_cfg->nfl_bpg_offset);
 540	intel_dsc_pps_write(crtc_state, 7, pps_val);
 541
 542	/* PPS 8 */
 543	pps_val = DSC_PPS8_FINAL_OFFSET(vdsc_cfg->final_offset) |
 544		DSC_PPS8_INITIAL_OFFSET(vdsc_cfg->initial_offset);
 545	intel_dsc_pps_write(crtc_state, 8, pps_val);
 546
 547	/* PPS 9 */
 548	pps_val = DSC_PPS9_RC_MODEL_SIZE(vdsc_cfg->rc_model_size) |
 549		DSC_PPS9_RC_EDGE_FACTOR(DSC_RC_EDGE_FACTOR_CONST);
 550	intel_dsc_pps_write(crtc_state, 9, pps_val);
 551
 552	/* PPS 10 */
 553	pps_val = DSC_PPS10_RC_QUANT_INC_LIMIT0(vdsc_cfg->rc_quant_incr_limit0) |
 554		DSC_PPS10_RC_QUANT_INC_LIMIT1(vdsc_cfg->rc_quant_incr_limit1) |
 555		DSC_PPS10_RC_TARGET_OFF_HIGH(DSC_RC_TGT_OFFSET_HI_CONST) |
 556		DSC_PPS10_RC_TARGET_OFF_LOW(DSC_RC_TGT_OFFSET_LO_CONST);
 557	intel_dsc_pps_write(crtc_state, 10, pps_val);
 558
 559	/* PPS 16 */
 560	pps_val = DSC_PPS16_SLICE_CHUNK_SIZE(vdsc_cfg->slice_chunk_size) |
 561		DSC_PPS16_SLICE_PER_LINE((vdsc_cfg->pic_width / num_vdsc_instances) /
 562					 vdsc_cfg->slice_width) |
 563		DSC_PPS16_SLICE_ROW_PER_FRAME(vdsc_cfg->pic_height /
 564					      vdsc_cfg->slice_height);
 565	intel_dsc_pps_write(crtc_state, 16, pps_val);
 566
 567	if (DISPLAY_VER(display) >= 14) {
 568		/* PPS 17 */
 569		pps_val = DSC_PPS17_SL_BPG_OFFSET(vdsc_cfg->second_line_bpg_offset);
 570		intel_dsc_pps_write(crtc_state, 17, pps_val);
 571
 572		/* PPS 18 */
 573		pps_val = DSC_PPS18_NSL_BPG_OFFSET(vdsc_cfg->nsl_bpg_offset) |
 574			DSC_PPS18_SL_OFFSET_ADJ(vdsc_cfg->second_line_offset_adj);
 575		intel_dsc_pps_write(crtc_state, 18, pps_val);
 576	}
 577
 578	/* Populate the RC_BUF_THRESH registers */
 579	memset(rc_buf_thresh_dword, 0, sizeof(rc_buf_thresh_dword));
 580	for (i = 0; i < DSC_NUM_BUF_RANGES - 1; i++)
 581		rc_buf_thresh_dword[i / 4] |=
 582			(u32)(vdsc_cfg->rc_buf_thresh[i] <<
 583			      BITS_PER_BYTE * (i % 4));
 584	if (!is_pipe_dsc(crtc, cpu_transcoder)) {
 585		intel_de_write(display, DSCA_RC_BUF_THRESH_0,
 586			       rc_buf_thresh_dword[0]);
 587		intel_de_write(display, DSCA_RC_BUF_THRESH_0_UDW,
 588			       rc_buf_thresh_dword[1]);
 589		intel_de_write(display, DSCA_RC_BUF_THRESH_1,
 590			       rc_buf_thresh_dword[2]);
 591		intel_de_write(display, DSCA_RC_BUF_THRESH_1_UDW,
 592			       rc_buf_thresh_dword[3]);
 593		if (vdsc_instances_per_pipe > 1) {
 594			intel_de_write(display, DSCC_RC_BUF_THRESH_0,
 595				       rc_buf_thresh_dword[0]);
 596			intel_de_write(display, DSCC_RC_BUF_THRESH_0_UDW,
 597				       rc_buf_thresh_dword[1]);
 598			intel_de_write(display, DSCC_RC_BUF_THRESH_1,
 599				       rc_buf_thresh_dword[2]);
 600			intel_de_write(display, DSCC_RC_BUF_THRESH_1_UDW,
 601				       rc_buf_thresh_dword[3]);
 602		}
 603	} else {
 604		intel_de_write(display, ICL_DSC0_RC_BUF_THRESH_0(pipe),
 605			       rc_buf_thresh_dword[0]);
 606		intel_de_write(display, ICL_DSC0_RC_BUF_THRESH_0_UDW(pipe),
 607			       rc_buf_thresh_dword[1]);
 608		intel_de_write(display, ICL_DSC0_RC_BUF_THRESH_1(pipe),
 609			       rc_buf_thresh_dword[2]);
 610		intel_de_write(display, ICL_DSC0_RC_BUF_THRESH_1_UDW(pipe),
 611			       rc_buf_thresh_dword[3]);
 612		if (vdsc_instances_per_pipe > 1) {
 613			intel_de_write(display,
 614				       ICL_DSC1_RC_BUF_THRESH_0(pipe),
 615				       rc_buf_thresh_dword[0]);
 616			intel_de_write(display,
 617				       ICL_DSC1_RC_BUF_THRESH_0_UDW(pipe),
 618				       rc_buf_thresh_dword[1]);
 619			intel_de_write(display,
 620				       ICL_DSC1_RC_BUF_THRESH_1(pipe),
 621				       rc_buf_thresh_dword[2]);
 622			intel_de_write(display,
 623				       ICL_DSC1_RC_BUF_THRESH_1_UDW(pipe),
 624				       rc_buf_thresh_dword[3]);
 625		}
 626	}
 627
 628	/* Populate the RC_RANGE_PARAMETERS registers */
 629	memset(rc_range_params_dword, 0, sizeof(rc_range_params_dword));
 630	for (i = 0; i < DSC_NUM_BUF_RANGES; i++)
 631		rc_range_params_dword[i / 2] |=
 632			(u32)(((vdsc_cfg->rc_range_params[i].range_bpg_offset <<
 633				RC_BPG_OFFSET_SHIFT) |
 634			       (vdsc_cfg->rc_range_params[i].range_max_qp <<
 635				RC_MAX_QP_SHIFT) |
 636			       (vdsc_cfg->rc_range_params[i].range_min_qp <<
 637				RC_MIN_QP_SHIFT)) << 16 * (i % 2));
 638	if (!is_pipe_dsc(crtc, cpu_transcoder)) {
 639		intel_de_write(display, DSCA_RC_RANGE_PARAMETERS_0,
 640			       rc_range_params_dword[0]);
 641		intel_de_write(display, DSCA_RC_RANGE_PARAMETERS_0_UDW,
 642			       rc_range_params_dword[1]);
 643		intel_de_write(display, DSCA_RC_RANGE_PARAMETERS_1,
 644			       rc_range_params_dword[2]);
 645		intel_de_write(display, DSCA_RC_RANGE_PARAMETERS_1_UDW,
 646			       rc_range_params_dword[3]);
 647		intel_de_write(display, DSCA_RC_RANGE_PARAMETERS_2,
 648			       rc_range_params_dword[4]);
 649		intel_de_write(display, DSCA_RC_RANGE_PARAMETERS_2_UDW,
 650			       rc_range_params_dword[5]);
 651		intel_de_write(display, DSCA_RC_RANGE_PARAMETERS_3,
 652			       rc_range_params_dword[6]);
 653		intel_de_write(display, DSCA_RC_RANGE_PARAMETERS_3_UDW,
 654			       rc_range_params_dword[7]);
 655		if (vdsc_instances_per_pipe > 1) {
 656			intel_de_write(display, DSCC_RC_RANGE_PARAMETERS_0,
 657				       rc_range_params_dword[0]);
 658			intel_de_write(display,
 659				       DSCC_RC_RANGE_PARAMETERS_0_UDW,
 660				       rc_range_params_dword[1]);
 661			intel_de_write(display, DSCC_RC_RANGE_PARAMETERS_1,
 662				       rc_range_params_dword[2]);
 663			intel_de_write(display,
 664				       DSCC_RC_RANGE_PARAMETERS_1_UDW,
 665				       rc_range_params_dword[3]);
 666			intel_de_write(display, DSCC_RC_RANGE_PARAMETERS_2,
 667				       rc_range_params_dword[4]);
 668			intel_de_write(display,
 669				       DSCC_RC_RANGE_PARAMETERS_2_UDW,
 670				       rc_range_params_dword[5]);
 671			intel_de_write(display, DSCC_RC_RANGE_PARAMETERS_3,
 672				       rc_range_params_dword[6]);
 673			intel_de_write(display,
 674				       DSCC_RC_RANGE_PARAMETERS_3_UDW,
 675				       rc_range_params_dword[7]);
 676		}
 677	} else {
 678		intel_de_write(display, ICL_DSC0_RC_RANGE_PARAMETERS_0(pipe),
 679			       rc_range_params_dword[0]);
 680		intel_de_write(display,
 681			       ICL_DSC0_RC_RANGE_PARAMETERS_0_UDW(pipe),
 682			       rc_range_params_dword[1]);
 683		intel_de_write(display, ICL_DSC0_RC_RANGE_PARAMETERS_1(pipe),
 684			       rc_range_params_dword[2]);
 685		intel_de_write(display,
 686			       ICL_DSC0_RC_RANGE_PARAMETERS_1_UDW(pipe),
 687			       rc_range_params_dword[3]);
 688		intel_de_write(display, ICL_DSC0_RC_RANGE_PARAMETERS_2(pipe),
 689			       rc_range_params_dword[4]);
 690		intel_de_write(display,
 691			       ICL_DSC0_RC_RANGE_PARAMETERS_2_UDW(pipe),
 692			       rc_range_params_dword[5]);
 693		intel_de_write(display, ICL_DSC0_RC_RANGE_PARAMETERS_3(pipe),
 694			       rc_range_params_dword[6]);
 695		intel_de_write(display,
 696			       ICL_DSC0_RC_RANGE_PARAMETERS_3_UDW(pipe),
 697			       rc_range_params_dword[7]);
 698		if (vdsc_instances_per_pipe > 1) {
 699			intel_de_write(display,
 700				       ICL_DSC1_RC_RANGE_PARAMETERS_0(pipe),
 701				       rc_range_params_dword[0]);
 702			intel_de_write(display,
 703				       ICL_DSC1_RC_RANGE_PARAMETERS_0_UDW(pipe),
 704				       rc_range_params_dword[1]);
 705			intel_de_write(display,
 706				       ICL_DSC1_RC_RANGE_PARAMETERS_1(pipe),
 707				       rc_range_params_dword[2]);
 708			intel_de_write(display,
 709				       ICL_DSC1_RC_RANGE_PARAMETERS_1_UDW(pipe),
 710				       rc_range_params_dword[3]);
 711			intel_de_write(display,
 712				       ICL_DSC1_RC_RANGE_PARAMETERS_2(pipe),
 713				       rc_range_params_dword[4]);
 714			intel_de_write(display,
 715				       ICL_DSC1_RC_RANGE_PARAMETERS_2_UDW(pipe),
 716				       rc_range_params_dword[5]);
 717			intel_de_write(display,
 718				       ICL_DSC1_RC_RANGE_PARAMETERS_3(pipe),
 719				       rc_range_params_dword[6]);
 720			intel_de_write(display,
 721				       ICL_DSC1_RC_RANGE_PARAMETERS_3_UDW(pipe),
 722				       rc_range_params_dword[7]);
 723		}
 724	}
 725}
 726
 727void intel_dsc_dsi_pps_write(struct intel_encoder *encoder,
 728			     const struct intel_crtc_state *crtc_state)
 729{
 730	const struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
 731	struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
 732	struct mipi_dsi_device *dsi;
 733	struct drm_dsc_picture_parameter_set pps;
 734	enum port port;
 735
 736	if (!crtc_state->dsc.compression_enable)
 737		return;
 738
 739	drm_dsc_pps_payload_pack(&pps, vdsc_cfg);
 740
 741	for_each_dsi_port(port, intel_dsi->ports) {
 742		dsi = intel_dsi->dsi_hosts[port]->device;
 743
 744		mipi_dsi_picture_parameter_set(dsi, &pps);
 745		mipi_dsi_compression_mode(dsi, true);
 746	}
 747}
 748
 749void intel_dsc_dp_pps_write(struct intel_encoder *encoder,
 750			    const struct intel_crtc_state *crtc_state)
 751{
 752	struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
 753	const struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
 754	struct drm_dsc_pps_infoframe dp_dsc_pps_sdp;
 755
 756	if (!crtc_state->dsc.compression_enable)
 757		return;
 758
 759	/* Prepare DP SDP PPS header as per DP 1.4 spec, Table 2-123 */
 760	drm_dsc_dp_pps_header_init(&dp_dsc_pps_sdp.pps_header);
 761
 762	/* Fill the PPS payload bytes as per DSC spec 1.2 Table 4-1 */
 763	drm_dsc_pps_payload_pack(&dp_dsc_pps_sdp.pps_payload, vdsc_cfg);
 764
 765	dig_port->write_infoframe(encoder, crtc_state,
 766				  DP_SDP_PPS, &dp_dsc_pps_sdp,
 767				  sizeof(dp_dsc_pps_sdp));
 768}
 769
 770void intel_dsc_su_et_parameters_configure(struct intel_dsb *dsb, struct intel_encoder *encoder,
 771					  const struct intel_crtc_state *crtc_state, int su_lines)
 772{
 773	struct intel_display *display = to_intel_display(crtc_state);
 774	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 775	const struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
 776	enum pipe pipe = crtc->pipe;
 777	int vdsc_instances_per_pipe = intel_dsc_get_vdsc_per_pipe(crtc_state);
 778	int slice_row_per_frame = su_lines / vdsc_cfg->slice_height;
 779	u32 val;
 780
 781	drm_WARN_ON_ONCE(display->drm, su_lines % vdsc_cfg->slice_height);
 782	drm_WARN_ON_ONCE(display->drm, vdsc_instances_per_pipe > 2);
 783
 784	val = DSC_SUPS0_SU_SLICE_ROW_PER_FRAME(slice_row_per_frame);
 785	val |= DSC_SUPS0_SU_PIC_HEIGHT(su_lines);
 786
 787	intel_de_write_dsb(display, dsb, LNL_DSC0_SU_PARAMETER_SET_0(pipe), val);
 788
 789	if (vdsc_instances_per_pipe == 2)
 790		intel_de_write_dsb(display, dsb, LNL_DSC1_SU_PARAMETER_SET_0(pipe), val);
 791}
 792
 793static i915_reg_t dss_ctl1_reg(struct intel_crtc *crtc, enum transcoder cpu_transcoder)
 794{
 795	return is_pipe_dsc(crtc, cpu_transcoder) ?
 796		ICL_PIPE_DSS_CTL1(crtc->pipe) : DSS_CTL1;
 797}
 798
 799static i915_reg_t dss_ctl2_reg(struct intel_crtc *crtc, enum transcoder cpu_transcoder)
 800{
 801	return is_pipe_dsc(crtc, cpu_transcoder) ?
 802		ICL_PIPE_DSS_CTL2(crtc->pipe) : DSS_CTL2;
 803}
 804
 805void intel_uncompressed_joiner_enable(const struct intel_crtc_state *crtc_state)
 806{
 807	struct intel_display *display = to_intel_display(crtc_state);
 808	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 809	u32 dss_ctl1_val = 0;
 810
 811	if (crtc_state->joiner_pipes && !crtc_state->dsc.compression_enable) {
 812		if (intel_crtc_is_bigjoiner_secondary(crtc_state))
 813			dss_ctl1_val |= UNCOMPRESSED_JOINER_SECONDARY;
 814		else
 815			dss_ctl1_val |= UNCOMPRESSED_JOINER_PRIMARY;
 816
 817		intel_de_write(display, dss_ctl1_reg(crtc, crtc_state->cpu_transcoder),
 818			       dss_ctl1_val);
 819	}
 820}
 821
 822void intel_dsc_enable(const struct intel_crtc_state *crtc_state)
 823{
 824	struct intel_display *display = to_intel_display(crtc_state);
 825	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 826	u32 dss_ctl1_val = 0;
 827	u32 dss_ctl2_val = 0;
 828	int vdsc_instances_per_pipe = intel_dsc_get_vdsc_per_pipe(crtc_state);
 829
 830	if (!crtc_state->dsc.compression_enable)
 831		return;
 832
 833	intel_dsc_pps_configure(crtc_state);
 834
 835	dss_ctl2_val |= VDSC0_ENABLE;
 836	if (vdsc_instances_per_pipe > 1) {
 837		dss_ctl2_val |= VDSC1_ENABLE;
 838		dss_ctl1_val |= JOINER_ENABLE;
 839	}
 840
 841	if (vdsc_instances_per_pipe > 2) {
 842		dss_ctl2_val |= VDSC2_ENABLE;
 843		dss_ctl2_val |= SMALL_JOINER_CONFIG_3_ENGINES;
 844	}
 845
 846	if (crtc_state->joiner_pipes) {
 847		if (intel_crtc_ultrajoiner_enable_needed(crtc_state))
 848			dss_ctl1_val |= ULTRA_JOINER_ENABLE;
 849
 850		if (intel_crtc_is_ultrajoiner_primary(crtc_state))
 851			dss_ctl1_val |= PRIMARY_ULTRA_JOINER_ENABLE;
 852
 853		dss_ctl1_val |= BIG_JOINER_ENABLE;
 854
 855		if (intel_crtc_is_bigjoiner_primary(crtc_state))
 856			dss_ctl1_val |= PRIMARY_BIG_JOINER_ENABLE;
 857	}
 858	intel_de_write(display, dss_ctl1_reg(crtc, crtc_state->cpu_transcoder), dss_ctl1_val);
 859	intel_de_write(display, dss_ctl2_reg(crtc, crtc_state->cpu_transcoder), dss_ctl2_val);
 860}
 861
 862void intel_dsc_disable(const struct intel_crtc_state *old_crtc_state)
 863{
 864	struct intel_display *display = to_intel_display(old_crtc_state);
 865	struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
 866
 867	/* Disable only if either of them is enabled */
 868	if (old_crtc_state->dsc.compression_enable ||
 869	    old_crtc_state->joiner_pipes) {
 870		intel_de_write(display, dss_ctl1_reg(crtc, old_crtc_state->cpu_transcoder), 0);
 871		intel_de_write(display, dss_ctl2_reg(crtc, old_crtc_state->cpu_transcoder), 0);
 872	}
 873}
 874
 875static u32 intel_dsc_pps_read(struct intel_crtc_state *crtc_state, int pps,
 876			      bool *all_equal)
 877{
 878	struct intel_display *display = to_intel_display(crtc_state);
 879	i915_reg_t dsc_reg[3];
 880	int i, vdsc_per_pipe, dsc_reg_num;
 881	u32 val;
 882
 883	vdsc_per_pipe = intel_dsc_get_vdsc_per_pipe(crtc_state);
 884	dsc_reg_num = min_t(int, ARRAY_SIZE(dsc_reg), vdsc_per_pipe);
 885
 886	drm_WARN_ON_ONCE(display->drm, dsc_reg_num < vdsc_per_pipe);
 887
 888	intel_dsc_get_pps_reg(crtc_state, pps, dsc_reg, dsc_reg_num);
 889
 890	*all_equal = true;
 891
 892	val = intel_de_read(display, dsc_reg[0]);
 893
 894	for (i = 1; i < dsc_reg_num; i++) {
 895		if (intel_de_read(display, dsc_reg[i]) != val) {
 896			*all_equal = false;
 897			break;
 898		}
 899	}
 900
 901	return val;
 902}
 903
 904static u32 intel_dsc_pps_read_and_verify(struct intel_crtc_state *crtc_state, int pps)
 905{
 906	struct intel_display *display = to_intel_display(crtc_state);
 907	u32 val;
 908	bool all_equal;
 909
 910	val = intel_dsc_pps_read(crtc_state, pps, &all_equal);
 911	drm_WARN_ON(display->drm, !all_equal);
 912
 913	return val;
 914}
 915
 916static void intel_dsc_get_pps_config(struct intel_crtc_state *crtc_state)
 917{
 918	struct intel_display *display = to_intel_display(crtc_state);
 919	struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
 920	int num_vdsc_instances = intel_dsc_get_num_vdsc_instances(crtc_state);
 921	u32 pps_temp;
 922
 923	/* PPS 0 */
 924	pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 0);
 925
 926	vdsc_cfg->bits_per_component = REG_FIELD_GET(DSC_PPS0_BPC_MASK, pps_temp);
 927	vdsc_cfg->line_buf_depth = REG_FIELD_GET(DSC_PPS0_LINE_BUF_DEPTH_MASK, pps_temp);
 928	vdsc_cfg->block_pred_enable = pps_temp & DSC_PPS0_BLOCK_PREDICTION;
 929	vdsc_cfg->convert_rgb = pps_temp & DSC_PPS0_COLOR_SPACE_CONVERSION;
 930	vdsc_cfg->simple_422 = pps_temp & DSC_PPS0_422_ENABLE;
 931	vdsc_cfg->native_422 = pps_temp & DSC_PPS0_NATIVE_422_ENABLE;
 932	vdsc_cfg->native_420 = pps_temp & DSC_PPS0_NATIVE_420_ENABLE;
 933	vdsc_cfg->vbr_enable = pps_temp & DSC_PPS0_VBR_ENABLE;
 934
 935	/* PPS 1 */
 936	pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 1);
 937
 938	vdsc_cfg->bits_per_pixel = REG_FIELD_GET(DSC_PPS1_BPP_MASK, pps_temp);
 939
 940	if (vdsc_cfg->native_420)
 941		vdsc_cfg->bits_per_pixel >>= 1;
 942
 943	crtc_state->dsc.compressed_bpp_x16 = vdsc_cfg->bits_per_pixel;
 944
 945	/* PPS 2 */
 946	pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 2);
 947
 948	vdsc_cfg->pic_width = REG_FIELD_GET(DSC_PPS2_PIC_WIDTH_MASK, pps_temp) * num_vdsc_instances;
 949	vdsc_cfg->pic_height = REG_FIELD_GET(DSC_PPS2_PIC_HEIGHT_MASK, pps_temp);
 950
 951	/* PPS 3 */
 952	pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 3);
 953
 954	vdsc_cfg->slice_width = REG_FIELD_GET(DSC_PPS3_SLICE_WIDTH_MASK, pps_temp);
 955	vdsc_cfg->slice_height = REG_FIELD_GET(DSC_PPS3_SLICE_HEIGHT_MASK, pps_temp);
 956
 957	/* PPS 4 */
 958	pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 4);
 959
 960	vdsc_cfg->initial_dec_delay = REG_FIELD_GET(DSC_PPS4_INITIAL_DEC_DELAY_MASK, pps_temp);
 961	vdsc_cfg->initial_xmit_delay = REG_FIELD_GET(DSC_PPS4_INITIAL_XMIT_DELAY_MASK, pps_temp);
 962
 963	/* PPS 5 */
 964	pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 5);
 965
 966	vdsc_cfg->scale_decrement_interval = REG_FIELD_GET(DSC_PPS5_SCALE_DEC_INT_MASK, pps_temp);
 967	vdsc_cfg->scale_increment_interval = REG_FIELD_GET(DSC_PPS5_SCALE_INC_INT_MASK, pps_temp);
 968
 969	/* PPS 6 */
 970	pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 6);
 971
 972	vdsc_cfg->initial_scale_value = REG_FIELD_GET(DSC_PPS6_INITIAL_SCALE_VALUE_MASK, pps_temp);
 973	vdsc_cfg->first_line_bpg_offset = REG_FIELD_GET(DSC_PPS6_FIRST_LINE_BPG_OFFSET_MASK, pps_temp);
 974	vdsc_cfg->flatness_min_qp = REG_FIELD_GET(DSC_PPS6_FLATNESS_MIN_QP_MASK, pps_temp);
 975	vdsc_cfg->flatness_max_qp = REG_FIELD_GET(DSC_PPS6_FLATNESS_MAX_QP_MASK, pps_temp);
 976
 977	/* PPS 7 */
 978	pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 7);
 979
 980	vdsc_cfg->nfl_bpg_offset = REG_FIELD_GET(DSC_PPS7_NFL_BPG_OFFSET_MASK, pps_temp);
 981	vdsc_cfg->slice_bpg_offset = REG_FIELD_GET(DSC_PPS7_SLICE_BPG_OFFSET_MASK, pps_temp);
 982
 983	/* PPS 8 */
 984	pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 8);
 985
 986	vdsc_cfg->initial_offset = REG_FIELD_GET(DSC_PPS8_INITIAL_OFFSET_MASK, pps_temp);
 987	vdsc_cfg->final_offset = REG_FIELD_GET(DSC_PPS8_FINAL_OFFSET_MASK, pps_temp);
 988
 989	/* PPS 9 */
 990	pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 9);
 991
 992	vdsc_cfg->rc_model_size = REG_FIELD_GET(DSC_PPS9_RC_MODEL_SIZE_MASK, pps_temp);
 993
 994	/* PPS 10 */
 995	pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 10);
 996
 997	vdsc_cfg->rc_quant_incr_limit0 = REG_FIELD_GET(DSC_PPS10_RC_QUANT_INC_LIMIT0_MASK, pps_temp);
 998	vdsc_cfg->rc_quant_incr_limit1 = REG_FIELD_GET(DSC_PPS10_RC_QUANT_INC_LIMIT1_MASK, pps_temp);
 999
1000	/* PPS 16 */
1001	pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 16);
1002
1003	vdsc_cfg->slice_chunk_size = REG_FIELD_GET(DSC_PPS16_SLICE_CHUNK_SIZE_MASK, pps_temp);
1004
1005	if (DISPLAY_VER(display) >= 14) {
1006		/* PPS 17 */
1007		pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 17);
1008
1009		vdsc_cfg->second_line_bpg_offset = REG_FIELD_GET(DSC_PPS17_SL_BPG_OFFSET_MASK, pps_temp);
1010
1011		/* PPS 18 */
1012		pps_temp = intel_dsc_pps_read_and_verify(crtc_state, 18);
1013
1014		vdsc_cfg->nsl_bpg_offset = REG_FIELD_GET(DSC_PPS18_NSL_BPG_OFFSET_MASK, pps_temp);
1015		vdsc_cfg->second_line_offset_adj = REG_FIELD_GET(DSC_PPS18_SL_OFFSET_ADJ_MASK, pps_temp);
1016	}
1017}
1018
1019void intel_dsc_get_config(struct intel_crtc_state *crtc_state)
1020{
1021	struct intel_display *display = to_intel_display(crtc_state);
1022	struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1023	enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
1024	enum intel_display_power_domain power_domain;
1025	intel_wakeref_t wakeref;
1026	u32 dss_ctl1, dss_ctl2;
1027
1028	if (!intel_dsc_source_support(crtc_state))
1029		return;
1030
1031	power_domain = intel_dsc_power_domain(crtc, cpu_transcoder);
1032
1033	wakeref = intel_display_power_get_if_enabled(display, power_domain);
1034	if (!wakeref)
1035		return;
1036
1037	dss_ctl1 = intel_de_read(display, dss_ctl1_reg(crtc, cpu_transcoder));
1038	dss_ctl2 = intel_de_read(display, dss_ctl2_reg(crtc, cpu_transcoder));
1039
1040	crtc_state->dsc.compression_enable = dss_ctl2 & VDSC0_ENABLE;
1041	if (!crtc_state->dsc.compression_enable)
1042		goto out;
1043
1044	if (dss_ctl1 & JOINER_ENABLE && dss_ctl2 & (VDSC2_ENABLE | SMALL_JOINER_CONFIG_3_ENGINES))
1045		crtc_state->dsc.num_streams = 3;
1046	else if (dss_ctl1 & JOINER_ENABLE && dss_ctl2 & VDSC1_ENABLE)
1047		crtc_state->dsc.num_streams = 2;
1048	else
1049		crtc_state->dsc.num_streams = 1;
1050
1051	intel_dsc_get_pps_config(crtc_state);
1052out:
1053	intel_display_power_put(display, power_domain, wakeref);
1054}
1055
1056static void intel_vdsc_dump_state(struct drm_printer *p, int indent,
1057				  const struct intel_crtc_state *crtc_state)
1058{
1059	drm_printf_indent(p, indent,
1060			  "dsc-dss: compressed-bpp:" FXP_Q4_FMT ", slice-count: %d, num_streams: %d\n",
1061			  FXP_Q4_ARGS(crtc_state->dsc.compressed_bpp_x16),
1062			  crtc_state->dsc.slice_count,
1063			  crtc_state->dsc.num_streams);
1064}
1065
1066void intel_vdsc_state_dump(struct drm_printer *p, int indent,
1067			   const struct intel_crtc_state *crtc_state)
1068{
1069	if (!crtc_state->dsc.compression_enable)
1070		return;
1071
1072	intel_vdsc_dump_state(p, indent, crtc_state);
1073	drm_dsc_dump_config(p, indent, &crtc_state->dsc.config);
1074}
1075
1076int intel_vdsc_min_cdclk(const struct intel_crtc_state *crtc_state)
1077{
1078	struct intel_display *display = to_intel_display(crtc_state);
1079	int num_vdsc_instances = intel_dsc_get_num_vdsc_instances(crtc_state);
1080	int min_cdclk;
1081
1082	if (!crtc_state->dsc.compression_enable)
1083		return 0;
1084
1085	/*
1086	 * When we decide to use only one VDSC engine, since
1087	 * each VDSC operates with 1 ppc throughput, pixel clock
1088	 * cannot be higher than the VDSC clock (cdclk)
1089	 * If there 2 VDSC engines, then pixel clock can't be higher than
1090	 * VDSC clock(cdclk) * 2 and so on.
1091	 */
1092	min_cdclk = DIV_ROUND_UP(crtc_state->pixel_rate, num_vdsc_instances);
1093
1094	if (crtc_state->joiner_pipes) {
1095		int pixel_clock = intel_dp_mode_to_fec_clock(crtc_state->hw.adjusted_mode.clock);
1096
1097		/*
1098		 * According to Bigjoiner bw check:
1099		 * compressed_bpp <= PPC * CDCLK * Big joiner Interface bits / Pixel clock
1100		 *
1101		 * We have already computed compressed_bpp, so now compute the min CDCLK that
1102		 * is required to support this compressed_bpp.
1103		 *
1104		 * => CDCLK >= compressed_bpp * Pixel clock / (PPC * Bigjoiner Interface bits)
1105		 *
1106		 * Since PPC = 2 with bigjoiner
1107		 * => CDCLK >= compressed_bpp * Pixel clock  / 2 * Bigjoiner Interface bits
1108		 */
1109		int bigjoiner_interface_bits = DISPLAY_VER(display) >= 14 ? 36 : 24;
1110		int min_cdclk_bj =
1111			(fxp_q4_to_int_roundup(crtc_state->dsc.compressed_bpp_x16) *
1112			 pixel_clock) / (2 * bigjoiner_interface_bits);
1113
1114		min_cdclk = max(min_cdclk, min_cdclk_bj);
1115	}
1116
1117	return min_cdclk;
1118}
1119
1120unsigned int intel_vdsc_prefill_lines(const struct intel_crtc_state *crtc_state)
1121{
1122	if (!crtc_state->dsc.compression_enable)
1123		return 0;
1124
1125	return 0x18000; /* 1.5 */
1126}
~/ Read-only file preview.