0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/kernel.h>
0010 #include <linux/module.h>
0011 #include <linux/init.h>
0012 #include <linux/errno.h>
0013 #include <linux/byteorder/generic.h>
0014
0015 #include <drm/display/drm_dp_helper.h>
0016 #include <drm/display/drm_dsc_helper.h>
0017 #include <drm/drm_print.h>
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 void drm_dsc_dp_pps_header_init(struct dp_sdp_header *pps_header)
0045 {
0046 memset(pps_header, 0, sizeof(*pps_header));
0047
0048 pps_header->HB1 = DP_SDP_PPS;
0049 pps_header->HB2 = DP_SDP_PPS_HEADER_PAYLOAD_BYTES_MINUS_1;
0050 }
0051 EXPORT_SYMBOL(drm_dsc_dp_pps_header_init);
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061 int drm_dsc_dp_rc_buffer_size(u8 rc_buffer_block_size, u8 rc_buffer_size)
0062 {
0063 int size = 1024 * (rc_buffer_size + 1);
0064
0065 switch (rc_buffer_block_size) {
0066 case DP_DSC_RC_BUF_BLK_SIZE_1:
0067 return 1 * size;
0068 case DP_DSC_RC_BUF_BLK_SIZE_4:
0069 return 4 * size;
0070 case DP_DSC_RC_BUF_BLK_SIZE_16:
0071 return 16 * size;
0072 case DP_DSC_RC_BUF_BLK_SIZE_64:
0073 return 64 * size;
0074 default:
0075 return 0;
0076 }
0077 }
0078 EXPORT_SYMBOL(drm_dsc_dp_rc_buffer_size);
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093
0094
0095
0096
0097 void drm_dsc_pps_payload_pack(struct drm_dsc_picture_parameter_set *pps_payload,
0098 const struct drm_dsc_config *dsc_cfg)
0099 {
0100 int i;
0101
0102
0103 BUILD_BUG_ON(sizeof(*pps_payload) !=
0104 DP_SDP_PPS_HEADER_PAYLOAD_BYTES_MINUS_1 + 1);
0105
0106 memset(pps_payload, 0, sizeof(*pps_payload));
0107
0108
0109 pps_payload->dsc_version =
0110 dsc_cfg->dsc_version_minor |
0111 dsc_cfg->dsc_version_major << DSC_PPS_VERSION_MAJOR_SHIFT;
0112
0113
0114
0115
0116 pps_payload->pps_3 =
0117 dsc_cfg->line_buf_depth |
0118 dsc_cfg->bits_per_component << DSC_PPS_BPC_SHIFT;
0119
0120
0121 pps_payload->pps_4 =
0122 ((dsc_cfg->bits_per_pixel & DSC_PPS_BPP_HIGH_MASK) >>
0123 DSC_PPS_MSB_SHIFT) |
0124 dsc_cfg->vbr_enable << DSC_PPS_VBR_EN_SHIFT |
0125 dsc_cfg->simple_422 << DSC_PPS_SIMPLE422_SHIFT |
0126 dsc_cfg->convert_rgb << DSC_PPS_CONVERT_RGB_SHIFT |
0127 dsc_cfg->block_pred_enable << DSC_PPS_BLOCK_PRED_EN_SHIFT;
0128
0129
0130 pps_payload->bits_per_pixel_low =
0131 (dsc_cfg->bits_per_pixel & DSC_PPS_LSB_MASK);
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141 pps_payload->pic_height = cpu_to_be16(dsc_cfg->pic_height);
0142
0143
0144 pps_payload->pic_width = cpu_to_be16(dsc_cfg->pic_width);
0145
0146
0147 pps_payload->slice_height = cpu_to_be16(dsc_cfg->slice_height);
0148
0149
0150 pps_payload->slice_width = cpu_to_be16(dsc_cfg->slice_width);
0151
0152
0153 pps_payload->chunk_size = cpu_to_be16(dsc_cfg->slice_chunk_size);
0154
0155
0156 pps_payload->initial_xmit_delay_high =
0157 ((dsc_cfg->initial_xmit_delay &
0158 DSC_PPS_INIT_XMIT_DELAY_HIGH_MASK) >>
0159 DSC_PPS_MSB_SHIFT);
0160
0161
0162 pps_payload->initial_xmit_delay_low =
0163 (dsc_cfg->initial_xmit_delay & DSC_PPS_LSB_MASK);
0164
0165
0166 pps_payload->initial_dec_delay =
0167 cpu_to_be16(dsc_cfg->initial_dec_delay);
0168
0169
0170
0171
0172 pps_payload->initial_scale_value =
0173 dsc_cfg->initial_scale_value;
0174
0175
0176 pps_payload->scale_increment_interval =
0177 cpu_to_be16(dsc_cfg->scale_increment_interval);
0178
0179
0180 pps_payload->scale_decrement_interval_high =
0181 ((dsc_cfg->scale_decrement_interval &
0182 DSC_PPS_SCALE_DEC_INT_HIGH_MASK) >>
0183 DSC_PPS_MSB_SHIFT);
0184
0185
0186 pps_payload->scale_decrement_interval_low =
0187 (dsc_cfg->scale_decrement_interval & DSC_PPS_LSB_MASK);
0188
0189
0190
0191
0192 pps_payload->first_line_bpg_offset =
0193 dsc_cfg->first_line_bpg_offset;
0194
0195
0196 pps_payload->nfl_bpg_offset =
0197 cpu_to_be16(dsc_cfg->nfl_bpg_offset);
0198
0199
0200 pps_payload->slice_bpg_offset =
0201 cpu_to_be16(dsc_cfg->slice_bpg_offset);
0202
0203
0204 pps_payload->initial_offset =
0205 cpu_to_be16(dsc_cfg->initial_offset);
0206
0207
0208 pps_payload->final_offset = cpu_to_be16(dsc_cfg->final_offset);
0209
0210
0211 pps_payload->flatness_min_qp = dsc_cfg->flatness_min_qp;
0212
0213
0214 pps_payload->flatness_max_qp = dsc_cfg->flatness_max_qp;
0215
0216
0217 pps_payload->rc_model_size = cpu_to_be16(dsc_cfg->rc_model_size);
0218
0219
0220 pps_payload->rc_edge_factor = DSC_RC_EDGE_FACTOR_CONST;
0221
0222
0223 pps_payload->rc_quant_incr_limit0 =
0224 dsc_cfg->rc_quant_incr_limit0;
0225
0226
0227 pps_payload->rc_quant_incr_limit1 =
0228 dsc_cfg->rc_quant_incr_limit1;
0229
0230
0231 pps_payload->rc_tgt_offset = DSC_RC_TGT_OFFSET_LO_CONST |
0232 DSC_RC_TGT_OFFSET_HI_CONST << DSC_PPS_RC_TGT_OFFSET_HI_SHIFT;
0233
0234
0235 for (i = 0; i < DSC_NUM_BUF_RANGES - 1; i++)
0236 pps_payload->rc_buf_thresh[i] =
0237 dsc_cfg->rc_buf_thresh[i];
0238
0239
0240
0241
0242
0243
0244 for (i = 0; i < DSC_NUM_BUF_RANGES; i++) {
0245 pps_payload->rc_range_parameters[i] =
0246 cpu_to_be16((dsc_cfg->rc_range_params[i].range_min_qp <<
0247 DSC_PPS_RC_RANGE_MINQP_SHIFT) |
0248 (dsc_cfg->rc_range_params[i].range_max_qp <<
0249 DSC_PPS_RC_RANGE_MAXQP_SHIFT) |
0250 (dsc_cfg->rc_range_params[i].range_bpg_offset));
0251 }
0252
0253
0254 pps_payload->native_422_420 = dsc_cfg->native_422 |
0255 dsc_cfg->native_420 << DSC_PPS_NATIVE_420_SHIFT;
0256
0257
0258 pps_payload->second_line_bpg_offset =
0259 dsc_cfg->second_line_bpg_offset;
0260
0261
0262 pps_payload->nsl_bpg_offset =
0263 cpu_to_be16(dsc_cfg->nsl_bpg_offset);
0264
0265
0266 pps_payload->second_line_offset_adj =
0267 cpu_to_be16(dsc_cfg->second_line_offset_adj);
0268
0269
0270 }
0271 EXPORT_SYMBOL(drm_dsc_pps_payload_pack);
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283 int drm_dsc_compute_rc_parameters(struct drm_dsc_config *vdsc_cfg)
0284 {
0285 unsigned long groups_per_line = 0;
0286 unsigned long groups_total = 0;
0287 unsigned long num_extra_mux_bits = 0;
0288 unsigned long slice_bits = 0;
0289 unsigned long hrd_delay = 0;
0290 unsigned long final_scale = 0;
0291 unsigned long rbs_min = 0;
0292
0293 if (vdsc_cfg->native_420 || vdsc_cfg->native_422) {
0294
0295 groups_per_line = DIV_ROUND_UP(vdsc_cfg->slice_width / 2,
0296 DSC_RC_PIXELS_PER_GROUP);
0297
0298
0299 vdsc_cfg->slice_chunk_size = DIV_ROUND_UP(vdsc_cfg->slice_width / 2 *
0300 vdsc_cfg->bits_per_pixel,
0301 (8 * 16));
0302 } else {
0303
0304 groups_per_line = DIV_ROUND_UP(vdsc_cfg->slice_width,
0305 DSC_RC_PIXELS_PER_GROUP);
0306
0307
0308 vdsc_cfg->slice_chunk_size = DIV_ROUND_UP(vdsc_cfg->slice_width *
0309 vdsc_cfg->bits_per_pixel,
0310 (8 * 16));
0311 }
0312
0313 if (vdsc_cfg->convert_rgb)
0314 num_extra_mux_bits = 3 * (vdsc_cfg->mux_word_size +
0315 (4 * vdsc_cfg->bits_per_component + 4)
0316 - 2);
0317 else if (vdsc_cfg->native_422)
0318 num_extra_mux_bits = 4 * vdsc_cfg->mux_word_size +
0319 (4 * vdsc_cfg->bits_per_component + 4) +
0320 3 * (4 * vdsc_cfg->bits_per_component) - 2;
0321 else
0322 num_extra_mux_bits = 3 * vdsc_cfg->mux_word_size +
0323 (4 * vdsc_cfg->bits_per_component + 4) +
0324 2 * (4 * vdsc_cfg->bits_per_component) - 2;
0325
0326 slice_bits = 8 * vdsc_cfg->slice_chunk_size * vdsc_cfg->slice_height;
0327
0328 while ((num_extra_mux_bits > 0) &&
0329 ((slice_bits - num_extra_mux_bits) % vdsc_cfg->mux_word_size))
0330 num_extra_mux_bits--;
0331
0332 if (groups_per_line < vdsc_cfg->initial_scale_value - 8)
0333 vdsc_cfg->initial_scale_value = groups_per_line + 8;
0334
0335
0336 if (vdsc_cfg->initial_scale_value > 8)
0337 vdsc_cfg->scale_decrement_interval = groups_per_line /
0338 (vdsc_cfg->initial_scale_value - 8);
0339 else
0340 vdsc_cfg->scale_decrement_interval = DSC_SCALE_DECREMENT_INTERVAL_MAX;
0341
0342 vdsc_cfg->final_offset = vdsc_cfg->rc_model_size -
0343 (vdsc_cfg->initial_xmit_delay *
0344 vdsc_cfg->bits_per_pixel + 8) / 16 + num_extra_mux_bits;
0345
0346 if (vdsc_cfg->final_offset >= vdsc_cfg->rc_model_size) {
0347 DRM_DEBUG_KMS("FinalOfs < RcModelSze for this InitialXmitDelay\n");
0348 return -ERANGE;
0349 }
0350
0351 final_scale = (vdsc_cfg->rc_model_size * 8) /
0352 (vdsc_cfg->rc_model_size - vdsc_cfg->final_offset);
0353 if (vdsc_cfg->slice_height > 1)
0354
0355
0356
0357
0358
0359 vdsc_cfg->nfl_bpg_offset = DIV_ROUND_UP((vdsc_cfg->first_line_bpg_offset << 11),
0360 (vdsc_cfg->slice_height - 1));
0361 else
0362 vdsc_cfg->nfl_bpg_offset = 0;
0363
0364
0365 groups_total = groups_per_line * vdsc_cfg->slice_height;
0366
0367
0368 vdsc_cfg->slice_bpg_offset = DIV_ROUND_UP(((vdsc_cfg->rc_model_size -
0369 vdsc_cfg->initial_offset +
0370 num_extra_mux_bits) << 11),
0371 groups_total);
0372
0373 if (final_scale > 9) {
0374
0375
0376
0377
0378
0379
0380 vdsc_cfg->scale_increment_interval =
0381 (vdsc_cfg->final_offset * (1 << 11)) /
0382 ((vdsc_cfg->nfl_bpg_offset +
0383 vdsc_cfg->slice_bpg_offset) *
0384 (final_scale - 9));
0385 } else {
0386
0387
0388
0389
0390 vdsc_cfg->scale_increment_interval = 0;
0391 }
0392
0393
0394
0395
0396
0397
0398 rbs_min = vdsc_cfg->rc_model_size - vdsc_cfg->initial_offset +
0399 DIV_ROUND_UP(vdsc_cfg->initial_xmit_delay *
0400 vdsc_cfg->bits_per_pixel, 16) +
0401 groups_per_line * vdsc_cfg->first_line_bpg_offset;
0402
0403 hrd_delay = DIV_ROUND_UP((rbs_min * 16), vdsc_cfg->bits_per_pixel);
0404 vdsc_cfg->rc_bits = (hrd_delay * vdsc_cfg->bits_per_pixel) / 16;
0405 vdsc_cfg->initial_dec_delay = hrd_delay - vdsc_cfg->initial_xmit_delay;
0406
0407 return 0;
0408 }
0409 EXPORT_SYMBOL(drm_dsc_compute_rc_parameters);