1 // SPDX-License-Identifier: MIT
3 * Copyright © 2018 Intel Corp
6 * Manasi Navare <manasi.d.navare@intel.com>
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 #include <drm/drm_print.h>
15 #include <drm/drm_dp_helper.h>
16 #include <drm/drm_dsc.h>
21 * VESA specification for DP 1.4 adds a new feature called Display Stream
22 * Compression (DSC) used to compress the pixel bits before sending it on
23 * DP/eDP/MIPI DSI interface. DSC is required to be enabled so that the existing
24 * display interfaces can support high resolutions at higher frames rates uisng
25 * the maximum available link capacity of these interfaces.
27 * These functions contain some common logic and helpers to deal with VESA
28 * Display Stream Compression standard required for DSC on Display Port/eDP or
29 * MIPI display interfaces.
33 * drm_dsc_dp_pps_header_init() - Initializes the PPS Header
34 * for DisplayPort as per the DP 1.4 spec.
35 * @pps_header: Secondary data packet header for DSC Picture
36 * Parameter Set as defined in &struct dp_sdp_header
38 * DP 1.4 spec defines the secondary data packet for sending the
39 * picture parameter infoframes from the source to the sink.
40 * This function populates the SDP header defined in
41 * &struct dp_sdp_header.
43 void drm_dsc_dp_pps_header_init(struct dp_sdp_header
*pps_header
)
45 memset(pps_header
, 0, sizeof(*pps_header
));
47 pps_header
->HB1
= DP_SDP_PPS
;
48 pps_header
->HB2
= DP_SDP_PPS_HEADER_PAYLOAD_BYTES_MINUS_1
;
50 EXPORT_SYMBOL(drm_dsc_dp_pps_header_init
);
53 * drm_dsc_pps_payload_pack() - Populates the DSC PPS
56 * Bitwise struct for DSC Picture Parameter Set. This is defined
57 * by &struct drm_dsc_picture_parameter_set
59 * DSC Configuration data filled by driver as defined by
60 * &struct drm_dsc_config
62 * DSC source device sends a picture parameter set (PPS) containing the
63 * information required by the sink to decode the compressed frame. Driver
64 * populates the DSC PPS struct using the DSC configuration parameters in
65 * the order expected by the DSC Display Sink device. For the DSC, the sink
66 * device expects the PPS payload in big endian format for fields
67 * that span more than 1 byte.
69 void drm_dsc_pps_payload_pack(struct drm_dsc_picture_parameter_set
*pps_payload
,
70 const struct drm_dsc_config
*dsc_cfg
)
74 /* Protect against someone accidently changing struct size */
75 BUILD_BUG_ON(sizeof(*pps_payload
) !=
76 DP_SDP_PPS_HEADER_PAYLOAD_BYTES_MINUS_1
+ 1);
78 memset(pps_payload
, 0, sizeof(*pps_payload
));
81 pps_payload
->dsc_version
=
82 dsc_cfg
->dsc_version_minor
|
83 dsc_cfg
->dsc_version_major
<< DSC_PPS_VERSION_MAJOR_SHIFT
;
89 dsc_cfg
->line_buf_depth
|
90 dsc_cfg
->bits_per_component
<< DSC_PPS_BPC_SHIFT
;
94 ((dsc_cfg
->bits_per_pixel
& DSC_PPS_BPP_HIGH_MASK
) >>
96 dsc_cfg
->vbr_enable
<< DSC_PPS_VBR_EN_SHIFT
|
97 dsc_cfg
->simple_422
<< DSC_PPS_SIMPLE422_SHIFT
|
98 dsc_cfg
->convert_rgb
<< DSC_PPS_CONVERT_RGB_SHIFT
|
99 dsc_cfg
->block_pred_enable
<< DSC_PPS_BLOCK_PRED_EN_SHIFT
;
102 pps_payload
->bits_per_pixel_low
=
103 (dsc_cfg
->bits_per_pixel
& DSC_PPS_LSB_MASK
);
106 * The DSC panel expects the PPS packet to have big endian format
107 * for data spanning 2 bytes. Use a macro cpu_to_be16() to convert
108 * to big endian format. If format is little endian, it will swap
109 * bytes to convert to Big endian else keep it unchanged.
113 pps_payload
->pic_height
= cpu_to_be16(dsc_cfg
->pic_height
);
116 pps_payload
->pic_width
= cpu_to_be16(dsc_cfg
->pic_width
);
119 pps_payload
->slice_height
= cpu_to_be16(dsc_cfg
->slice_height
);
122 pps_payload
->slice_width
= cpu_to_be16(dsc_cfg
->slice_width
);
125 pps_payload
->chunk_size
= cpu_to_be16(dsc_cfg
->slice_chunk_size
);
128 pps_payload
->initial_xmit_delay_high
=
129 ((dsc_cfg
->initial_xmit_delay
&
130 DSC_PPS_INIT_XMIT_DELAY_HIGH_MASK
) >>
134 pps_payload
->initial_xmit_delay_low
=
135 (dsc_cfg
->initial_xmit_delay
& DSC_PPS_LSB_MASK
);
138 pps_payload
->initial_dec_delay
=
139 cpu_to_be16(dsc_cfg
->initial_dec_delay
);
144 pps_payload
->initial_scale_value
=
145 dsc_cfg
->initial_scale_value
;
148 pps_payload
->scale_increment_interval
=
149 cpu_to_be16(dsc_cfg
->scale_increment_interval
);
152 pps_payload
->scale_decrement_interval_high
=
153 ((dsc_cfg
->scale_decrement_interval
&
154 DSC_PPS_SCALE_DEC_INT_HIGH_MASK
) >>
158 pps_payload
->scale_decrement_interval_low
=
159 (dsc_cfg
->scale_decrement_interval
& DSC_PPS_LSB_MASK
);
161 /* PPS 26[7:0], PPS 27[7:5] RESERVED */
164 pps_payload
->first_line_bpg_offset
=
165 dsc_cfg
->first_line_bpg_offset
;
168 pps_payload
->nfl_bpg_offset
=
169 cpu_to_be16(dsc_cfg
->nfl_bpg_offset
);
172 pps_payload
->slice_bpg_offset
=
173 cpu_to_be16(dsc_cfg
->slice_bpg_offset
);
176 pps_payload
->initial_offset
=
177 cpu_to_be16(dsc_cfg
->initial_offset
);
180 pps_payload
->final_offset
= cpu_to_be16(dsc_cfg
->final_offset
);
183 pps_payload
->flatness_min_qp
= dsc_cfg
->flatness_min_qp
;
186 pps_payload
->flatness_max_qp
= dsc_cfg
->flatness_max_qp
;
189 pps_payload
->rc_model_size
=
190 cpu_to_be16(DSC_RC_MODEL_SIZE_CONST
);
193 pps_payload
->rc_edge_factor
= DSC_RC_EDGE_FACTOR_CONST
;
196 pps_payload
->rc_quant_incr_limit0
=
197 dsc_cfg
->rc_quant_incr_limit0
;
200 pps_payload
->rc_quant_incr_limit1
=
201 dsc_cfg
->rc_quant_incr_limit1
;
204 pps_payload
->rc_tgt_offset
= DSC_RC_TGT_OFFSET_LO_CONST
|
205 DSC_RC_TGT_OFFSET_HI_CONST
<< DSC_PPS_RC_TGT_OFFSET_HI_SHIFT
;
208 for (i
= 0; i
< DSC_NUM_BUF_RANGES
- 1; i
++)
209 pps_payload
->rc_buf_thresh
[i
] =
210 dsc_cfg
->rc_buf_thresh
[i
];
214 * For DSC sink programming the RC Range parameter fields
215 * are as follows: Min_qp[15:11], max_qp[10:6], offset[5:0]
217 for (i
= 0; i
< DSC_NUM_BUF_RANGES
; i
++) {
218 pps_payload
->rc_range_parameters
[i
] =
219 cpu_to_be16((dsc_cfg
->rc_range_params
[i
].range_min_qp
<<
220 DSC_PPS_RC_RANGE_MINQP_SHIFT
) |
221 (dsc_cfg
->rc_range_params
[i
].range_max_qp
<<
222 DSC_PPS_RC_RANGE_MAXQP_SHIFT
) |
223 (dsc_cfg
->rc_range_params
[i
].range_bpg_offset
));
227 pps_payload
->native_422_420
= dsc_cfg
->native_422
|
228 dsc_cfg
->native_420
<< DSC_PPS_NATIVE_420_SHIFT
;
231 pps_payload
->second_line_bpg_offset
=
232 dsc_cfg
->second_line_bpg_offset
;
235 pps_payload
->nsl_bpg_offset
=
236 cpu_to_be16(dsc_cfg
->nsl_bpg_offset
);
239 pps_payload
->second_line_offset_adj
=
240 cpu_to_be16(dsc_cfg
->second_line_offset_adj
);
242 /* PPS 94 - 127 are O */
244 EXPORT_SYMBOL(drm_dsc_pps_payload_pack
);
247 * drm_dsc_compute_rc_parameters() - Write rate control
248 * parameters to the dsc configuration defined in
249 * &struct drm_dsc_config in accordance with the DSC 1.2
250 * specification. Some configuration fields must be present
254 * DSC Configuration data partially filled by driver
256 int drm_dsc_compute_rc_parameters(struct drm_dsc_config
*vdsc_cfg
)
258 unsigned long groups_per_line
= 0;
259 unsigned long groups_total
= 0;
260 unsigned long num_extra_mux_bits
= 0;
261 unsigned long slice_bits
= 0;
262 unsigned long hrd_delay
= 0;
263 unsigned long final_scale
= 0;
264 unsigned long rbs_min
= 0;
266 if (vdsc_cfg
->native_420
|| vdsc_cfg
->native_422
) {
267 /* Number of groups used to code each line of a slice */
268 groups_per_line
= DIV_ROUND_UP(vdsc_cfg
->slice_width
/ 2,
269 DSC_RC_PIXELS_PER_GROUP
);
271 /* chunksize in Bytes */
272 vdsc_cfg
->slice_chunk_size
= DIV_ROUND_UP(vdsc_cfg
->slice_width
/ 2 *
273 vdsc_cfg
->bits_per_pixel
,
276 /* Number of groups used to code each line of a slice */
277 groups_per_line
= DIV_ROUND_UP(vdsc_cfg
->slice_width
,
278 DSC_RC_PIXELS_PER_GROUP
);
280 /* chunksize in Bytes */
281 vdsc_cfg
->slice_chunk_size
= DIV_ROUND_UP(vdsc_cfg
->slice_width
*
282 vdsc_cfg
->bits_per_pixel
,
286 if (vdsc_cfg
->convert_rgb
)
287 num_extra_mux_bits
= 3 * (vdsc_cfg
->mux_word_size
+
288 (4 * vdsc_cfg
->bits_per_component
+ 4)
290 else if (vdsc_cfg
->native_422
)
291 num_extra_mux_bits
= 4 * vdsc_cfg
->mux_word_size
+
292 (4 * vdsc_cfg
->bits_per_component
+ 4) +
293 3 * (4 * vdsc_cfg
->bits_per_component
) - 2;
295 num_extra_mux_bits
= 3 * vdsc_cfg
->mux_word_size
+
296 (4 * vdsc_cfg
->bits_per_component
+ 4) +
297 2 * (4 * vdsc_cfg
->bits_per_component
) - 2;
298 /* Number of bits in one Slice */
299 slice_bits
= 8 * vdsc_cfg
->slice_chunk_size
* vdsc_cfg
->slice_height
;
301 while ((num_extra_mux_bits
> 0) &&
302 ((slice_bits
- num_extra_mux_bits
) % vdsc_cfg
->mux_word_size
))
303 num_extra_mux_bits
--;
305 if (groups_per_line
< vdsc_cfg
->initial_scale_value
- 8)
306 vdsc_cfg
->initial_scale_value
= groups_per_line
+ 8;
308 /* scale_decrement_interval calculation according to DSC spec 1.11 */
309 if (vdsc_cfg
->initial_scale_value
> 8)
310 vdsc_cfg
->scale_decrement_interval
= groups_per_line
/
311 (vdsc_cfg
->initial_scale_value
- 8);
313 vdsc_cfg
->scale_decrement_interval
= DSC_SCALE_DECREMENT_INTERVAL_MAX
;
315 vdsc_cfg
->final_offset
= vdsc_cfg
->rc_model_size
-
316 (vdsc_cfg
->initial_xmit_delay
*
317 vdsc_cfg
->bits_per_pixel
+ 8) / 16 + num_extra_mux_bits
;
319 if (vdsc_cfg
->final_offset
>= vdsc_cfg
->rc_model_size
) {
320 DRM_DEBUG_KMS("FinalOfs < RcModelSze for this InitialXmitDelay\n");
324 final_scale
= (vdsc_cfg
->rc_model_size
* 8) /
325 (vdsc_cfg
->rc_model_size
- vdsc_cfg
->final_offset
);
326 if (vdsc_cfg
->slice_height
> 1)
328 * NflBpgOffset is 16 bit value with 11 fractional bits
329 * hence we multiply by 2^11 for preserving the
332 vdsc_cfg
->nfl_bpg_offset
= DIV_ROUND_UP((vdsc_cfg
->first_line_bpg_offset
<< 11),
333 (vdsc_cfg
->slice_height
- 1));
335 vdsc_cfg
->nfl_bpg_offset
= 0;
337 /* Number of groups used to code the entire slice */
338 groups_total
= groups_per_line
* vdsc_cfg
->slice_height
;
340 /* slice_bpg_offset is 16 bit value with 11 fractional bits */
341 vdsc_cfg
->slice_bpg_offset
= DIV_ROUND_UP(((vdsc_cfg
->rc_model_size
-
342 vdsc_cfg
->initial_offset
+
343 num_extra_mux_bits
) << 11),
346 if (final_scale
> 9) {
348 * ScaleIncrementInterval =
349 * finaloffset/((NflBpgOffset + SliceBpgOffset)*8(finalscale - 1.125))
350 * as (NflBpgOffset + SliceBpgOffset) has 11 bit fractional value,
351 * we need divide by 2^11 from pstDscCfg values
353 vdsc_cfg
->scale_increment_interval
=
354 (vdsc_cfg
->final_offset
* (1 << 11)) /
355 ((vdsc_cfg
->nfl_bpg_offset
+
356 vdsc_cfg
->slice_bpg_offset
) *
360 * If finalScaleValue is less than or equal to 9, a value of 0 should
361 * be used to disable the scale increment at the end of the slice
363 vdsc_cfg
->scale_increment_interval
= 0;
367 * DSC spec mentions that bits_per_pixel specifies the target
368 * bits/pixel (bpp) rate that is used by the encoder,
369 * in steps of 1/16 of a bit per pixel
371 rbs_min
= vdsc_cfg
->rc_model_size
- vdsc_cfg
->initial_offset
+
372 DIV_ROUND_UP(vdsc_cfg
->initial_xmit_delay
*
373 vdsc_cfg
->bits_per_pixel
, 16) +
374 groups_per_line
* vdsc_cfg
->first_line_bpg_offset
;
376 hrd_delay
= DIV_ROUND_UP((rbs_min
* 16), vdsc_cfg
->bits_per_pixel
);
377 vdsc_cfg
->rc_bits
= (hrd_delay
* vdsc_cfg
->bits_per_pixel
) / 16;
378 vdsc_cfg
->initial_dec_delay
= hrd_delay
- vdsc_cfg
->initial_xmit_delay
;
382 EXPORT_SYMBOL(drm_dsc_compute_rc_parameters
);