Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: MIT
0002 /*
0003  * Copyright © 2018 Intel Corporation
0004  *
0005  * Author: Gaurav K Singh <gaurav.k.singh@intel.com>
0006  *         Manasi Navare <manasi.d.navare@intel.com>
0007  */
0008 #include <linux/limits.h>
0009 
0010 #include <drm/display/drm_dsc_helper.h>
0011 
0012 #include "i915_drv.h"
0013 #include "intel_crtc.h"
0014 #include "intel_de.h"
0015 #include "intel_display_types.h"
0016 #include "intel_dsi.h"
0017 #include "intel_qp_tables.h"
0018 #include "intel_vdsc.h"
0019 
0020 enum ROW_INDEX_BPP {
0021     ROW_INDEX_6BPP = 0,
0022     ROW_INDEX_8BPP,
0023     ROW_INDEX_10BPP,
0024     ROW_INDEX_12BPP,
0025     ROW_INDEX_15BPP,
0026     MAX_ROW_INDEX
0027 };
0028 
0029 enum COLUMN_INDEX_BPC {
0030     COLUMN_INDEX_8BPC = 0,
0031     COLUMN_INDEX_10BPC,
0032     COLUMN_INDEX_12BPC,
0033     COLUMN_INDEX_14BPC,
0034     COLUMN_INDEX_16BPC,
0035     MAX_COLUMN_INDEX
0036 };
0037 
0038 /* From DSC_v1.11 spec, rc_parameter_Set syntax element typically constant */
0039 static const u16 rc_buf_thresh[] = {
0040     896, 1792, 2688, 3584, 4480, 5376, 6272, 6720, 7168, 7616,
0041     7744, 7872, 8000, 8064
0042 };
0043 
0044 struct rc_parameters {
0045     u16 initial_xmit_delay;
0046     u8 first_line_bpg_offset;
0047     u16 initial_offset;
0048     u8 flatness_min_qp;
0049     u8 flatness_max_qp;
0050     u8 rc_quant_incr_limit0;
0051     u8 rc_quant_incr_limit1;
0052     struct drm_dsc_rc_range_parameters rc_range_params[DSC_NUM_BUF_RANGES];
0053 };
0054 
0055 /*
0056  * Selected Rate Control Related Parameter Recommended Values
0057  * from DSC_v1.11 spec & C Model release: DSC_model_20161212
0058  */
0059 static const struct rc_parameters rc_parameters[][MAX_COLUMN_INDEX] = {
0060 {
0061     /* 6BPP/8BPC */
0062     { 768, 15, 6144, 3, 13, 11, 11, {
0063         { 0, 4, 0 }, { 1, 6, -2 }, { 3, 8, -2 }, { 4, 8, -4 },
0064         { 5, 9, -6 }, { 5, 9, -6 }, { 6, 9, -6 }, { 6, 10, -8 },
0065         { 7, 11, -8 }, { 8, 12, -10 }, { 9, 12, -10 }, { 10, 12, -12 },
0066         { 10, 12, -12 }, { 11, 12, -12 }, { 13, 14, -12 }
0067         }
0068     },
0069     /* 6BPP/10BPC */
0070     { 768, 15, 6144, 7, 17, 15, 15, {
0071         { 0, 8, 0 }, { 3, 10, -2 }, { 7, 12, -2 }, { 8, 12, -4 },
0072         { 9, 13, -6 }, { 9, 13, -6 }, { 10, 13, -6 }, { 10, 14, -8 },
0073         { 11, 15, -8 }, { 12, 16, -10 }, { 13, 16, -10 },
0074         { 14, 16, -12 }, { 14, 16, -12 }, { 15, 16, -12 },
0075         { 17, 18, -12 }
0076         }
0077     },
0078     /* 6BPP/12BPC */
0079     { 768, 15, 6144, 11, 21, 19, 19, {
0080         { 0, 12, 0 }, { 5, 14, -2 }, { 11, 16, -2 }, { 12, 16, -4 },
0081         { 13, 17, -6 }, { 13, 17, -6 }, { 14, 17, -6 }, { 14, 18, -8 },
0082         { 15, 19, -8 }, { 16, 20, -10 }, { 17, 20, -10 },
0083         { 18, 20, -12 }, { 18, 20, -12 }, { 19, 20, -12 },
0084         { 21, 22, -12 }
0085         }
0086     },
0087     /* 6BPP/14BPC */
0088     { 768, 15, 6144, 15, 25, 23, 27, {
0089         { 0, 16, 0 }, { 7, 18, -2 }, { 15, 20, -2 }, { 16, 20, -4 },
0090         { 17, 21, -6 }, { 17, 21, -6 }, { 18, 21, -6 }, { 18, 22, -8 },
0091         { 19, 23, -8 }, { 20, 24, -10 }, { 21, 24, -10 },
0092         { 22, 24, -12 }, { 22, 24, -12 }, { 23, 24, -12 },
0093         { 25, 26, -12 }
0094         }
0095     },
0096     /* 6BPP/16BPC */
0097     { 768, 15, 6144, 19, 29, 27, 27, {
0098         { 0, 20, 0 }, { 9, 22, -2 }, { 19, 24, -2 }, { 20, 24, -4 },
0099         { 21, 25, -6 }, { 21, 25, -6 }, { 22, 25, -6 }, { 22, 26, -8 },
0100         { 23, 27, -8 }, { 24, 28, -10 }, { 25, 28, -10 },
0101         { 26, 28, -12 }, { 26, 28, -12 }, { 27, 28, -12 },
0102         { 29, 30, -12 }
0103         }
0104     },
0105 },
0106 {
0107     /* 8BPP/8BPC */
0108     { 512, 12, 6144, 3, 12, 11, 11, {
0109         { 0, 4, 2 }, { 0, 4, 0 }, { 1, 5, 0 }, { 1, 6, -2 },
0110         { 3, 7, -4 }, { 3, 7, -6 }, { 3, 7, -8 }, { 3, 8, -8 },
0111         { 3, 9, -8 }, { 3, 10, -10 }, { 5, 11, -10 }, { 5, 12, -12 },
0112         { 5, 13, -12 }, { 7, 13, -12 }, { 13, 15, -12 }
0113         }
0114     },
0115     /* 8BPP/10BPC */
0116     { 512, 12, 6144, 7, 16, 15, 15, {
0117         { 0, 4, 2 }, { 4, 8, 0 }, { 5, 9, 0 }, { 5, 10, -2 },
0118         { 7, 11, -4 }, { 7, 11, -6 }, { 7, 11, -8 }, { 7, 12, -8 },
0119         { 7, 13, -8 }, { 7, 14, -10 }, { 9, 15, -10 }, { 9, 16, -12 },
0120         { 9, 17, -12 }, { 11, 17, -12 }, { 17, 19, -12 }
0121         }
0122     },
0123     /* 8BPP/12BPC */
0124     { 512, 12, 6144, 11, 20, 19, 19, {
0125         { 0, 12, 2 }, { 4, 12, 0 }, { 9, 13, 0 }, { 9, 14, -2 },
0126         { 11, 15, -4 }, { 11, 15, -6 }, { 11, 15, -8 }, { 11, 16, -8 },
0127         { 11, 17, -8 }, { 11, 18, -10 }, { 13, 19, -10 },
0128         { 13, 20, -12 }, { 13, 21, -12 }, { 15, 21, -12 },
0129         { 21, 23, -12 }
0130         }
0131     },
0132     /* 8BPP/14BPC */
0133     { 512, 12, 6144, 15, 24, 23, 23, {
0134         { 0, 12, 0 }, { 5, 13, 0 }, { 11, 15, 0 }, { 12, 17, -2 },
0135         { 15, 19, -4 }, { 15, 19, -6 }, { 15, 19, -8 }, { 15, 20, -8 },
0136         { 15, 21, -8 }, { 15, 22, -10 }, { 17, 22, -10 },
0137         { 17, 23, -12 }, { 17, 23, -12 }, { 21, 24, -12 },
0138         { 24, 25, -12 }
0139         }
0140     },
0141     /* 8BPP/16BPC */
0142     { 512, 12, 6144, 19, 28, 27, 27, {
0143         { 0, 12, 2 }, { 6, 14, 0 }, { 13, 17, 0 }, { 15, 20, -2 },
0144         { 19, 23, -4 }, { 19, 23, -6 }, { 19, 23, -8 }, { 19, 24, -8 },
0145         { 19, 25, -8 }, { 19, 26, -10 }, { 21, 26, -10 },
0146         { 21, 27, -12 }, { 21, 27, -12 }, { 25, 28, -12 },
0147         { 28, 29, -12 }
0148         }
0149     },
0150 },
0151 {
0152     /* 10BPP/8BPC */
0153     { 410, 15, 5632, 3, 12, 11, 11, {
0154         { 0, 3, 2 }, { 0, 4, 0 }, { 1, 5, 0 }, { 2, 6, -2 },
0155         { 3, 7, -4 }, { 3, 7, -6 }, { 3, 7, -8 }, { 3, 8, -8 },
0156         { 3, 9, -8 }, { 3, 9, -10 }, { 5, 10, -10 }, { 5, 10, -10 },
0157         { 5, 11, -12 }, { 7, 11, -12 }, { 11, 12, -12 }
0158         }
0159     },
0160     /* 10BPP/10BPC */
0161     { 410, 15, 5632, 7, 16, 15, 15, {
0162         { 0, 7, 2 }, { 4, 8, 0 }, { 5, 9, 0 }, { 6, 10, -2 },
0163         { 7, 11, -4 }, { 7, 11, -6 }, { 7, 11, -8 }, { 7, 12, -8 },
0164         { 7, 13, -8 }, { 7, 13, -10 }, { 9, 14, -10 }, { 9, 14, -10 },
0165         { 9, 15, -12 }, { 11, 15, -12 }, { 15, 16, -12 }
0166         }
0167     },
0168     /* 10BPP/12BPC */
0169     { 410, 15, 5632, 11, 20, 19, 19, {
0170         { 0, 11, 2 }, { 4, 12, 0 }, { 9, 13, 0 }, { 10, 14, -2 },
0171         { 11, 15, -4 }, { 11, 15, -6 }, { 11, 15, -8 }, { 11, 16, -8 },
0172         { 11, 17, -8 }, { 11, 17, -10 }, { 13, 18, -10 },
0173         { 13, 18, -10 }, { 13, 19, -12 }, { 15, 19, -12 },
0174         { 19, 20, -12 }
0175         }
0176     },
0177     /* 10BPP/14BPC */
0178     { 410, 15, 5632, 15, 24, 23, 23, {
0179         { 0, 11, 2 }, { 5, 13, 0 }, { 11, 15, 0 }, { 13, 18, -2 },
0180         { 15, 19, -4 }, { 15, 19, -6 }, { 15, 19, -8 }, { 15, 20, -8 },
0181         { 15, 21, -8 }, { 15, 21, -10 }, { 17, 22, -10 },
0182         { 17, 22, -10 }, { 17, 23, -12 }, { 19, 23, -12 },
0183         { 23, 24, -12 }
0184         }
0185     },
0186     /* 10BPP/16BPC */
0187     { 410, 15, 5632, 19, 28, 27, 27, {
0188         { 0, 11, 2 }, { 6, 14, 0 }, { 13, 17, 0 }, { 16, 20, -2 },
0189         { 19, 23, -4 }, { 19, 23, -6 }, { 19, 23, -8 }, { 19, 24, -8 },
0190         { 19, 25, -8 }, { 19, 25, -10 }, { 21, 26, -10 },
0191         { 21, 26, -10 }, { 21, 27, -12 }, { 23, 27, -12 },
0192         { 27, 28, -12 }
0193         }
0194     },
0195 },
0196 {
0197     /* 12BPP/8BPC */
0198     { 341, 15, 2048, 3, 12, 11, 11, {
0199         { 0, 2, 2 }, { 0, 4, 0 }, { 1, 5, 0 }, { 1, 6, -2 },
0200         { 3, 7, -4 }, { 3, 7, -6 }, { 3, 7, -8 }, { 3, 8, -8 },
0201         { 3, 9, -8 }, { 3, 10, -10 }, { 5, 11, -10 },
0202         { 5, 12, -12 }, { 5, 13, -12 }, { 7, 13, -12 }, { 13, 15, -12 }
0203         }
0204     },
0205     /* 12BPP/10BPC */
0206     { 341, 15, 2048, 7, 16, 15, 15, {
0207         { 0, 2, 2 }, { 2, 5, 0 }, { 3, 7, 0 }, { 4, 8, -2 },
0208         { 6, 9, -4 }, { 7, 10, -6 }, { 7, 11, -8 }, { 7, 12, -8 },
0209         { 7, 13, -8 }, { 7, 14, -10 }, { 9, 15, -10 }, { 9, 16, -12 },
0210         { 9, 17, -12 }, { 11, 17, -12 }, { 17, 19, -12 }
0211         }
0212     },
0213     /* 12BPP/12BPC */
0214     { 341, 15, 2048, 11, 20, 19, 19, {
0215         { 0, 6, 2 }, { 4, 9, 0 }, { 7, 11, 0 }, { 8, 12, -2 },
0216         { 10, 13, -4 }, { 11, 14, -6 }, { 11, 15, -8 }, { 11, 16, -8 },
0217         { 11, 17, -8 }, { 11, 18, -10 }, { 13, 19, -10 },
0218         { 13, 20, -12 }, { 13, 21, -12 }, { 15, 21, -12 },
0219         { 21, 23, -12 }
0220         }
0221     },
0222     /* 12BPP/14BPC */
0223     { 341, 15, 2048, 15, 24, 23, 23, {
0224         { 0, 6, 2 }, { 7, 10, 0 }, { 9, 13, 0 }, { 11, 16, -2 },
0225         { 14, 17, -4 }, { 15, 18, -6 }, { 15, 19, -8 }, { 15, 20, -8 },
0226         { 15, 20, -8 }, { 15, 21, -10 }, { 17, 21, -10 },
0227         { 17, 21, -12 }, { 17, 21, -12 }, { 19, 22, -12 },
0228         { 22, 23, -12 }
0229         }
0230     },
0231     /* 12BPP/16BPC */
0232     { 341, 15, 2048, 19, 28, 27, 27, {
0233         { 0, 6, 2 }, { 6, 11, 0 }, { 11, 15, 0 }, { 14, 18, -2 },
0234         { 18, 21, -4 }, { 19, 22, -6 }, { 19, 23, -8 }, { 19, 24, -8 },
0235         { 19, 24, -8 }, { 19, 25, -10 }, { 21, 25, -10 },
0236         { 21, 25, -12 }, { 21, 25, -12 }, { 23, 26, -12 },
0237         { 26, 27, -12 }
0238         }
0239     },
0240 },
0241 {
0242     /* 15BPP/8BPC */
0243     { 273, 15, 2048, 3, 12, 11, 11, {
0244         { 0, 0, 10 }, { 0, 1, 8 }, { 0, 1, 6 }, { 0, 2, 4 },
0245         { 1, 2, 2 }, { 1, 3, 0 }, { 1, 3, -2 }, { 2, 4, -4 },
0246         { 2, 5, -6 }, { 3, 5, -8 }, { 4, 6, -10 }, { 4, 7, -10 },
0247         { 5, 7, -12 }, { 7, 8, -12 }, { 8, 9, -12 }
0248         }
0249     },
0250     /* 15BPP/10BPC */
0251     { 273, 15, 2048, 7, 16, 15, 15, {
0252         { 0, 2, 10 }, { 2, 5, 8 }, { 3, 5, 6 }, { 4, 6, 4 },
0253         { 5, 6, 2 }, { 5, 7, 0 }, { 5, 7, -2 }, { 6, 8, -4 },
0254         { 6, 9, -6 }, { 7, 9, -8 }, { 8, 10, -10 }, { 8, 11, -10 },
0255         { 9, 11, -12 }, { 11, 12, -12 }, { 12, 13, -12 }
0256         }
0257     },
0258     /* 15BPP/12BPC */
0259     { 273, 15, 2048, 11, 20, 19, 19, {
0260         { 0, 4, 10 }, { 2, 7, 8 }, { 4, 9, 6 }, { 6, 11, 4 },
0261         { 9, 11, 2 }, { 9, 11, 0 }, { 9, 12, -2 }, { 10, 12, -4 },
0262         { 11, 13, -6 }, { 11, 13, -8 }, { 12, 14, -10 },
0263         { 13, 15, -10 }, { 13, 15, -12 }, { 15, 16, -12 },
0264         { 16, 17, -12 }
0265         }
0266     },
0267     /* 15BPP/14BPC */
0268     { 273, 15, 2048, 15, 24, 23, 23, {
0269         { 0, 4, 10 }, { 3, 8, 8 }, { 6, 11, 6 }, { 9, 14, 4 },
0270         { 13, 15, 2 }, { 13, 15, 0 }, { 13, 16, -2 }, { 14, 16, -4 },
0271         { 15, 17, -6 }, { 15, 17, -8 }, { 16, 18, -10 },
0272         { 17, 19, -10 }, { 17, 19, -12 }, { 19, 20, -12 },
0273         { 20, 21, -12 }
0274         }
0275     },
0276     /* 15BPP/16BPC */
0277     { 273, 15, 2048, 19, 28, 27, 27, {
0278         { 0, 4, 10 }, { 4, 9, 8 }, { 8, 13, 6 }, { 12, 17, 4 },
0279         { 17, 19, 2 }, { 17, 20, 0 }, { 17, 20, -2 }, { 18, 20, -4 },
0280         { 19, 21, -6 }, { 19, 21, -8 }, { 20, 22, -10 },
0281         { 21, 23, -10 }, { 21, 23, -12 }, { 23, 24, -12 },
0282         { 24, 25, -12 }
0283         }
0284     }
0285 }
0286 
0287 };
0288 
0289 static int get_row_index_for_rc_params(u16 compressed_bpp)
0290 {
0291     switch (compressed_bpp) {
0292     case 6:
0293         return ROW_INDEX_6BPP;
0294     case 8:
0295         return ROW_INDEX_8BPP;
0296     case 10:
0297         return ROW_INDEX_10BPP;
0298     case 12:
0299         return ROW_INDEX_12BPP;
0300     case 15:
0301         return ROW_INDEX_15BPP;
0302     default:
0303         return -EINVAL;
0304     }
0305 }
0306 
0307 static int get_column_index_for_rc_params(u8 bits_per_component)
0308 {
0309     switch (bits_per_component) {
0310     case 8:
0311         return COLUMN_INDEX_8BPC;
0312     case 10:
0313         return COLUMN_INDEX_10BPC;
0314     case 12:
0315         return COLUMN_INDEX_12BPC;
0316     case 14:
0317         return COLUMN_INDEX_14BPC;
0318     case 16:
0319         return COLUMN_INDEX_16BPC;
0320     default:
0321         return -EINVAL;
0322     }
0323 }
0324 
0325 static const struct rc_parameters *get_rc_params(u16 compressed_bpp,
0326                          u8 bits_per_component)
0327 {
0328     int row_index, column_index;
0329 
0330     row_index = get_row_index_for_rc_params(compressed_bpp);
0331     if (row_index < 0)
0332         return NULL;
0333 
0334     column_index = get_column_index_for_rc_params(bits_per_component);
0335     if (column_index < 0)
0336         return NULL;
0337 
0338     return &rc_parameters[row_index][column_index];
0339 }
0340 
0341 bool intel_dsc_source_support(const struct intel_crtc_state *crtc_state)
0342 {
0343     const struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
0344     struct drm_i915_private *i915 = to_i915(crtc->base.dev);
0345     enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
0346 
0347     if (!INTEL_INFO(i915)->display.has_dsc)
0348         return false;
0349 
0350     if (DISPLAY_VER(i915) >= 12)
0351         return true;
0352 
0353     if (DISPLAY_VER(i915) >= 11 && cpu_transcoder != TRANSCODER_A)
0354         return true;
0355 
0356     return false;
0357 }
0358 
0359 static bool is_pipe_dsc(struct intel_crtc *crtc, enum transcoder cpu_transcoder)
0360 {
0361     struct drm_i915_private *i915 = to_i915(crtc->base.dev);
0362 
0363     if (DISPLAY_VER(i915) >= 12)
0364         return true;
0365 
0366     if (cpu_transcoder == TRANSCODER_EDP ||
0367         cpu_transcoder == TRANSCODER_DSI_0 ||
0368         cpu_transcoder == TRANSCODER_DSI_1)
0369         return false;
0370 
0371     /* There's no pipe A DSC engine on ICL */
0372     drm_WARN_ON(&i915->drm, crtc->pipe == PIPE_A);
0373 
0374     return true;
0375 }
0376 
0377 static void
0378 calculate_rc_params(struct rc_parameters *rc,
0379             struct drm_dsc_config *vdsc_cfg)
0380 {
0381     int bpc = vdsc_cfg->bits_per_component;
0382     int bpp = vdsc_cfg->bits_per_pixel >> 4;
0383     static const s8 ofs_und6[] = {
0384         0, -2, -2, -4, -6, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12
0385     };
0386     static const s8 ofs_und8[] = {
0387         2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -10, -12, -12, -12
0388     };
0389     static const s8 ofs_und12[] = {
0390         2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -10, -12, -12, -12
0391     };
0392     static const s8 ofs_und15[] = {
0393         10, 8, 6, 4, 2, 0, -2, -4, -6, -8, -10, -10, -12, -12, -12
0394     };
0395     int qp_bpc_modifier = (bpc - 8) * 2;
0396     u32 res, buf_i, bpp_i;
0397 
0398     if (vdsc_cfg->slice_height >= 8)
0399         rc->first_line_bpg_offset =
0400             12 + DIV_ROUND_UP((9 * min(34, vdsc_cfg->slice_height - 8)), 100);
0401     else
0402         rc->first_line_bpg_offset = 2 * (vdsc_cfg->slice_height - 1);
0403 
0404     /* Our hw supports only 444 modes as of today */
0405     if (bpp >= 12)
0406         rc->initial_offset = 2048;
0407     else if (bpp >= 10)
0408         rc->initial_offset = 5632 - DIV_ROUND_UP(((bpp - 10) * 3584), 2);
0409     else if (bpp >= 8)
0410         rc->initial_offset = 6144 - DIV_ROUND_UP(((bpp - 8) * 512), 2);
0411     else
0412         rc->initial_offset = 6144;
0413 
0414     /* initial_xmit_delay = rc_model_size/2/compression_bpp */
0415     rc->initial_xmit_delay = DIV_ROUND_UP(DSC_RC_MODEL_SIZE_CONST, 2 * bpp);
0416 
0417     rc->flatness_min_qp = 3 + qp_bpc_modifier;
0418     rc->flatness_max_qp = 12 + qp_bpc_modifier;
0419 
0420     rc->rc_quant_incr_limit0 = 11 + qp_bpc_modifier;
0421     rc->rc_quant_incr_limit1 = 11 + qp_bpc_modifier;
0422 
0423     bpp_i  = (2 * (bpp - 6));
0424     for (buf_i = 0; buf_i < DSC_NUM_BUF_RANGES; buf_i++) {
0425         /* Read range_minqp and range_max_qp from qp tables */
0426         rc->rc_range_params[buf_i].range_min_qp =
0427             intel_lookup_range_min_qp(bpc, buf_i, bpp_i);
0428         rc->rc_range_params[buf_i].range_max_qp =
0429             intel_lookup_range_max_qp(bpc, buf_i, bpp_i);
0430 
0431         /* Calculate range_bgp_offset */
0432         if (bpp <= 6) {
0433             rc->rc_range_params[buf_i].range_bpg_offset = ofs_und6[buf_i];
0434         } else if (bpp <= 8) {
0435             res = DIV_ROUND_UP(((bpp - 6) * (ofs_und8[buf_i] - ofs_und6[buf_i])), 2);
0436             rc->rc_range_params[buf_i].range_bpg_offset =
0437                                 ofs_und6[buf_i] + res;
0438         } else if (bpp <= 12) {
0439             rc->rc_range_params[buf_i].range_bpg_offset =
0440                                 ofs_und8[buf_i];
0441         } else if (bpp <= 15) {
0442             res = DIV_ROUND_UP(((bpp - 12) * (ofs_und15[buf_i] - ofs_und12[buf_i])), 3);
0443             rc->rc_range_params[buf_i].range_bpg_offset =
0444                                 ofs_und12[buf_i] + res;
0445         } else {
0446             rc->rc_range_params[buf_i].range_bpg_offset =
0447                                 ofs_und15[buf_i];
0448         }
0449     }
0450 }
0451 
0452 int intel_dsc_compute_params(struct intel_crtc_state *pipe_config)
0453 {
0454     struct intel_crtc *crtc = to_intel_crtc(pipe_config->uapi.crtc);
0455     struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
0456     struct drm_dsc_config *vdsc_cfg = &pipe_config->dsc.config;
0457     u16 compressed_bpp = pipe_config->dsc.compressed_bpp;
0458     const struct rc_parameters *rc_params;
0459     struct rc_parameters *rc = NULL;
0460     u8 i = 0;
0461 
0462     vdsc_cfg->pic_width = pipe_config->hw.adjusted_mode.crtc_hdisplay;
0463     vdsc_cfg->slice_width = DIV_ROUND_UP(vdsc_cfg->pic_width,
0464                          pipe_config->dsc.slice_count);
0465 
0466     /* Gen 11 does not support YCbCr */
0467     vdsc_cfg->simple_422 = false;
0468     /* Gen 11 does not support VBR */
0469     vdsc_cfg->vbr_enable = false;
0470 
0471     /* Gen 11 only supports integral values of bpp */
0472     vdsc_cfg->bits_per_pixel = compressed_bpp << 4;
0473     vdsc_cfg->bits_per_component = pipe_config->pipe_bpp / 3;
0474 
0475     for (i = 0; i < DSC_NUM_BUF_RANGES - 1; i++) {
0476         /*
0477          * six 0s are appended to the lsb of each threshold value
0478          * internally in h/w.
0479          * Only 8 bits are allowed for programming RcBufThreshold
0480          */
0481         vdsc_cfg->rc_buf_thresh[i] = rc_buf_thresh[i] >> 6;
0482     }
0483 
0484     /*
0485      * For 6bpp, RC Buffer threshold 12 and 13 need a different value
0486      * as per C Model
0487      */
0488     if (compressed_bpp == 6) {
0489         vdsc_cfg->rc_buf_thresh[12] = 0x7C;
0490         vdsc_cfg->rc_buf_thresh[13] = 0x7D;
0491     }
0492 
0493     /*
0494      * From XE_LPD onwards we supports compression bpps in steps of 1
0495      * upto uncompressed bpp-1, hence add calculations for all the rc
0496      * parameters
0497      */
0498     if (DISPLAY_VER(dev_priv) >= 13) {
0499         rc = kmalloc(sizeof(*rc), GFP_KERNEL);
0500         if (!rc)
0501             return -ENOMEM;
0502 
0503         calculate_rc_params(rc, vdsc_cfg);
0504         rc_params = rc;
0505     } else {
0506         rc_params = get_rc_params(compressed_bpp,
0507                       vdsc_cfg->bits_per_component);
0508         if (!rc_params)
0509             return -EINVAL;
0510     }
0511 
0512     vdsc_cfg->first_line_bpg_offset = rc_params->first_line_bpg_offset;
0513     vdsc_cfg->initial_xmit_delay = rc_params->initial_xmit_delay;
0514     vdsc_cfg->initial_offset = rc_params->initial_offset;
0515     vdsc_cfg->flatness_min_qp = rc_params->flatness_min_qp;
0516     vdsc_cfg->flatness_max_qp = rc_params->flatness_max_qp;
0517     vdsc_cfg->rc_quant_incr_limit0 = rc_params->rc_quant_incr_limit0;
0518     vdsc_cfg->rc_quant_incr_limit1 = rc_params->rc_quant_incr_limit1;
0519 
0520     for (i = 0; i < DSC_NUM_BUF_RANGES; i++) {
0521         vdsc_cfg->rc_range_params[i].range_min_qp =
0522             rc_params->rc_range_params[i].range_min_qp;
0523         vdsc_cfg->rc_range_params[i].range_max_qp =
0524             rc_params->rc_range_params[i].range_max_qp;
0525         /*
0526          * Range BPG Offset uses 2's complement and is only a 6 bits. So
0527          * mask it to get only 6 bits.
0528          */
0529         vdsc_cfg->rc_range_params[i].range_bpg_offset =
0530             rc_params->rc_range_params[i].range_bpg_offset &
0531             DSC_RANGE_BPG_OFFSET_MASK;
0532     }
0533 
0534     /*
0535      * BitsPerComponent value determines mux_word_size:
0536      * When BitsPerComponent is less than or 10bpc, muxWordSize will be equal to
0537      * 48 bits otherwise 64
0538      */
0539     if (vdsc_cfg->bits_per_component <= 10)
0540         vdsc_cfg->mux_word_size = DSC_MUX_WORD_SIZE_8_10_BPC;
0541     else
0542         vdsc_cfg->mux_word_size = DSC_MUX_WORD_SIZE_12_BPC;
0543 
0544     /* InitialScaleValue is a 6 bit value with 3 fractional bits (U3.3) */
0545     vdsc_cfg->initial_scale_value = (vdsc_cfg->rc_model_size << 3) /
0546         (vdsc_cfg->rc_model_size - vdsc_cfg->initial_offset);
0547 
0548     kfree(rc);
0549 
0550     return 0;
0551 }
0552 
0553 enum intel_display_power_domain
0554 intel_dsc_power_domain(struct intel_crtc *crtc, enum transcoder cpu_transcoder)
0555 {
0556     struct drm_i915_private *i915 = to_i915(crtc->base.dev);
0557     enum pipe pipe = crtc->pipe;
0558 
0559     /*
0560      * VDSC/joining uses a separate power well, PW2, and requires
0561      * POWER_DOMAIN_TRANSCODER_VDSC_PW2 power domain in two cases:
0562      *
0563      *  - ICL eDP/DSI transcoder
0564      *  - Display version 12 (except RKL) pipe A
0565      *
0566      * For any other pipe, VDSC/joining uses the power well associated with
0567      * the pipe in use. Hence another reference on the pipe power domain
0568      * will suffice. (Except no VDSC/joining on ICL pipe A.)
0569      */
0570     if (DISPLAY_VER(i915) == 12 && !IS_ROCKETLAKE(i915) && pipe == PIPE_A)
0571         return POWER_DOMAIN_TRANSCODER_VDSC_PW2;
0572     else if (is_pipe_dsc(crtc, cpu_transcoder))
0573         return POWER_DOMAIN_PIPE(pipe);
0574     else
0575         return POWER_DOMAIN_TRANSCODER_VDSC_PW2;
0576 }
0577 
0578 static void intel_dsc_pps_configure(const struct intel_crtc_state *crtc_state)
0579 {
0580     struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
0581     struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
0582     const struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
0583     enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
0584     enum pipe pipe = crtc->pipe;
0585     u32 pps_val = 0;
0586     u32 rc_buf_thresh_dword[4];
0587     u32 rc_range_params_dword[8];
0588     u8 num_vdsc_instances = (crtc_state->dsc.dsc_split) ? 2 : 1;
0589     int i = 0;
0590 
0591     if (crtc_state->bigjoiner_pipes)
0592         num_vdsc_instances *= 2;
0593 
0594     /* Populate PICTURE_PARAMETER_SET_0 registers */
0595     pps_val = DSC_VER_MAJ | vdsc_cfg->dsc_version_minor <<
0596         DSC_VER_MIN_SHIFT |
0597         vdsc_cfg->bits_per_component << DSC_BPC_SHIFT |
0598         vdsc_cfg->line_buf_depth << DSC_LINE_BUF_DEPTH_SHIFT;
0599     if (vdsc_cfg->block_pred_enable)
0600         pps_val |= DSC_BLOCK_PREDICTION;
0601     if (vdsc_cfg->convert_rgb)
0602         pps_val |= DSC_COLOR_SPACE_CONVERSION;
0603     if (vdsc_cfg->simple_422)
0604         pps_val |= DSC_422_ENABLE;
0605     if (vdsc_cfg->vbr_enable)
0606         pps_val |= DSC_VBR_ENABLE;
0607     drm_dbg_kms(&dev_priv->drm, "PPS0 = 0x%08x\n", pps_val);
0608     if (!is_pipe_dsc(crtc, cpu_transcoder)) {
0609         intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_0,
0610                    pps_val);
0611         /*
0612          * If 2 VDSC instances are needed, configure PPS for second
0613          * VDSC
0614          */
0615         if (crtc_state->dsc.dsc_split)
0616             intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_0,
0617                        pps_val);
0618     } else {
0619         intel_de_write(dev_priv,
0620                    ICL_DSC0_PICTURE_PARAMETER_SET_0(pipe),
0621                    pps_val);
0622         if (crtc_state->dsc.dsc_split)
0623             intel_de_write(dev_priv,
0624                        ICL_DSC1_PICTURE_PARAMETER_SET_0(pipe),
0625                        pps_val);
0626     }
0627 
0628     /* Populate PICTURE_PARAMETER_SET_1 registers */
0629     pps_val = 0;
0630     pps_val |= DSC_BPP(vdsc_cfg->bits_per_pixel);
0631     drm_dbg_kms(&dev_priv->drm, "PPS1 = 0x%08x\n", pps_val);
0632     if (!is_pipe_dsc(crtc, cpu_transcoder)) {
0633         intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_1,
0634                    pps_val);
0635         /*
0636          * If 2 VDSC instances are needed, configure PPS for second
0637          * VDSC
0638          */
0639         if (crtc_state->dsc.dsc_split)
0640             intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_1,
0641                        pps_val);
0642     } else {
0643         intel_de_write(dev_priv,
0644                    ICL_DSC0_PICTURE_PARAMETER_SET_1(pipe),
0645                    pps_val);
0646         if (crtc_state->dsc.dsc_split)
0647             intel_de_write(dev_priv,
0648                        ICL_DSC1_PICTURE_PARAMETER_SET_1(pipe),
0649                        pps_val);
0650     }
0651 
0652     /* Populate PICTURE_PARAMETER_SET_2 registers */
0653     pps_val = 0;
0654     pps_val |= DSC_PIC_HEIGHT(vdsc_cfg->pic_height) |
0655         DSC_PIC_WIDTH(vdsc_cfg->pic_width / num_vdsc_instances);
0656     drm_dbg_kms(&dev_priv->drm, "PPS2 = 0x%08x\n", pps_val);
0657     if (!is_pipe_dsc(crtc, cpu_transcoder)) {
0658         intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_2,
0659                    pps_val);
0660         /*
0661          * If 2 VDSC instances are needed, configure PPS for second
0662          * VDSC
0663          */
0664         if (crtc_state->dsc.dsc_split)
0665             intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_2,
0666                        pps_val);
0667     } else {
0668         intel_de_write(dev_priv,
0669                    ICL_DSC0_PICTURE_PARAMETER_SET_2(pipe),
0670                    pps_val);
0671         if (crtc_state->dsc.dsc_split)
0672             intel_de_write(dev_priv,
0673                        ICL_DSC1_PICTURE_PARAMETER_SET_2(pipe),
0674                        pps_val);
0675     }
0676 
0677     /* Populate PICTURE_PARAMETER_SET_3 registers */
0678     pps_val = 0;
0679     pps_val |= DSC_SLICE_HEIGHT(vdsc_cfg->slice_height) |
0680         DSC_SLICE_WIDTH(vdsc_cfg->slice_width);
0681     drm_dbg_kms(&dev_priv->drm, "PPS3 = 0x%08x\n", pps_val);
0682     if (!is_pipe_dsc(crtc, cpu_transcoder)) {
0683         intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_3,
0684                    pps_val);
0685         /*
0686          * If 2 VDSC instances are needed, configure PPS for second
0687          * VDSC
0688          */
0689         if (crtc_state->dsc.dsc_split)
0690             intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_3,
0691                        pps_val);
0692     } else {
0693         intel_de_write(dev_priv,
0694                    ICL_DSC0_PICTURE_PARAMETER_SET_3(pipe),
0695                    pps_val);
0696         if (crtc_state->dsc.dsc_split)
0697             intel_de_write(dev_priv,
0698                        ICL_DSC1_PICTURE_PARAMETER_SET_3(pipe),
0699                        pps_val);
0700     }
0701 
0702     /* Populate PICTURE_PARAMETER_SET_4 registers */
0703     pps_val = 0;
0704     pps_val |= DSC_INITIAL_XMIT_DELAY(vdsc_cfg->initial_xmit_delay) |
0705         DSC_INITIAL_DEC_DELAY(vdsc_cfg->initial_dec_delay);
0706     drm_dbg_kms(&dev_priv->drm, "PPS4 = 0x%08x\n", pps_val);
0707     if (!is_pipe_dsc(crtc, cpu_transcoder)) {
0708         intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_4,
0709                    pps_val);
0710         /*
0711          * If 2 VDSC instances are needed, configure PPS for second
0712          * VDSC
0713          */
0714         if (crtc_state->dsc.dsc_split)
0715             intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_4,
0716                        pps_val);
0717     } else {
0718         intel_de_write(dev_priv,
0719                    ICL_DSC0_PICTURE_PARAMETER_SET_4(pipe),
0720                    pps_val);
0721         if (crtc_state->dsc.dsc_split)
0722             intel_de_write(dev_priv,
0723                        ICL_DSC1_PICTURE_PARAMETER_SET_4(pipe),
0724                        pps_val);
0725     }
0726 
0727     /* Populate PICTURE_PARAMETER_SET_5 registers */
0728     pps_val = 0;
0729     pps_val |= DSC_SCALE_INC_INT(vdsc_cfg->scale_increment_interval) |
0730         DSC_SCALE_DEC_INT(vdsc_cfg->scale_decrement_interval);
0731     drm_dbg_kms(&dev_priv->drm, "PPS5 = 0x%08x\n", pps_val);
0732     if (!is_pipe_dsc(crtc, cpu_transcoder)) {
0733         intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_5,
0734                    pps_val);
0735         /*
0736          * If 2 VDSC instances are needed, configure PPS for second
0737          * VDSC
0738          */
0739         if (crtc_state->dsc.dsc_split)
0740             intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_5,
0741                        pps_val);
0742     } else {
0743         intel_de_write(dev_priv,
0744                    ICL_DSC0_PICTURE_PARAMETER_SET_5(pipe),
0745                    pps_val);
0746         if (crtc_state->dsc.dsc_split)
0747             intel_de_write(dev_priv,
0748                        ICL_DSC1_PICTURE_PARAMETER_SET_5(pipe),
0749                        pps_val);
0750     }
0751 
0752     /* Populate PICTURE_PARAMETER_SET_6 registers */
0753     pps_val = 0;
0754     pps_val |= DSC_INITIAL_SCALE_VALUE(vdsc_cfg->initial_scale_value) |
0755         DSC_FIRST_LINE_BPG_OFFSET(vdsc_cfg->first_line_bpg_offset) |
0756         DSC_FLATNESS_MIN_QP(vdsc_cfg->flatness_min_qp) |
0757         DSC_FLATNESS_MAX_QP(vdsc_cfg->flatness_max_qp);
0758     drm_dbg_kms(&dev_priv->drm, "PPS6 = 0x%08x\n", pps_val);
0759     if (!is_pipe_dsc(crtc, cpu_transcoder)) {
0760         intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_6,
0761                    pps_val);
0762         /*
0763          * If 2 VDSC instances are needed, configure PPS for second
0764          * VDSC
0765          */
0766         if (crtc_state->dsc.dsc_split)
0767             intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_6,
0768                        pps_val);
0769     } else {
0770         intel_de_write(dev_priv,
0771                    ICL_DSC0_PICTURE_PARAMETER_SET_6(pipe),
0772                    pps_val);
0773         if (crtc_state->dsc.dsc_split)
0774             intel_de_write(dev_priv,
0775                        ICL_DSC1_PICTURE_PARAMETER_SET_6(pipe),
0776                        pps_val);
0777     }
0778 
0779     /* Populate PICTURE_PARAMETER_SET_7 registers */
0780     pps_val = 0;
0781     pps_val |= DSC_SLICE_BPG_OFFSET(vdsc_cfg->slice_bpg_offset) |
0782         DSC_NFL_BPG_OFFSET(vdsc_cfg->nfl_bpg_offset);
0783     drm_dbg_kms(&dev_priv->drm, "PPS7 = 0x%08x\n", pps_val);
0784     if (!is_pipe_dsc(crtc, cpu_transcoder)) {
0785         intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_7,
0786                    pps_val);
0787         /*
0788          * If 2 VDSC instances are needed, configure PPS for second
0789          * VDSC
0790          */
0791         if (crtc_state->dsc.dsc_split)
0792             intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_7,
0793                        pps_val);
0794     } else {
0795         intel_de_write(dev_priv,
0796                    ICL_DSC0_PICTURE_PARAMETER_SET_7(pipe),
0797                    pps_val);
0798         if (crtc_state->dsc.dsc_split)
0799             intel_de_write(dev_priv,
0800                        ICL_DSC1_PICTURE_PARAMETER_SET_7(pipe),
0801                        pps_val);
0802     }
0803 
0804     /* Populate PICTURE_PARAMETER_SET_8 registers */
0805     pps_val = 0;
0806     pps_val |= DSC_FINAL_OFFSET(vdsc_cfg->final_offset) |
0807         DSC_INITIAL_OFFSET(vdsc_cfg->initial_offset);
0808     drm_dbg_kms(&dev_priv->drm, "PPS8 = 0x%08x\n", pps_val);
0809     if (!is_pipe_dsc(crtc, cpu_transcoder)) {
0810         intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_8,
0811                    pps_val);
0812         /*
0813          * If 2 VDSC instances are needed, configure PPS for second
0814          * VDSC
0815          */
0816         if (crtc_state->dsc.dsc_split)
0817             intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_8,
0818                        pps_val);
0819     } else {
0820         intel_de_write(dev_priv,
0821                    ICL_DSC0_PICTURE_PARAMETER_SET_8(pipe),
0822                    pps_val);
0823         if (crtc_state->dsc.dsc_split)
0824             intel_de_write(dev_priv,
0825                        ICL_DSC1_PICTURE_PARAMETER_SET_8(pipe),
0826                        pps_val);
0827     }
0828 
0829     /* Populate PICTURE_PARAMETER_SET_9 registers */
0830     pps_val = 0;
0831     pps_val |= DSC_RC_MODEL_SIZE(vdsc_cfg->rc_model_size) |
0832         DSC_RC_EDGE_FACTOR(DSC_RC_EDGE_FACTOR_CONST);
0833     drm_dbg_kms(&dev_priv->drm, "PPS9 = 0x%08x\n", pps_val);
0834     if (!is_pipe_dsc(crtc, cpu_transcoder)) {
0835         intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_9,
0836                    pps_val);
0837         /*
0838          * If 2 VDSC instances are needed, configure PPS for second
0839          * VDSC
0840          */
0841         if (crtc_state->dsc.dsc_split)
0842             intel_de_write(dev_priv, DSCC_PICTURE_PARAMETER_SET_9,
0843                        pps_val);
0844     } else {
0845         intel_de_write(dev_priv,
0846                    ICL_DSC0_PICTURE_PARAMETER_SET_9(pipe),
0847                    pps_val);
0848         if (crtc_state->dsc.dsc_split)
0849             intel_de_write(dev_priv,
0850                        ICL_DSC1_PICTURE_PARAMETER_SET_9(pipe),
0851                        pps_val);
0852     }
0853 
0854     /* Populate PICTURE_PARAMETER_SET_10 registers */
0855     pps_val = 0;
0856     pps_val |= DSC_RC_QUANT_INC_LIMIT0(vdsc_cfg->rc_quant_incr_limit0) |
0857         DSC_RC_QUANT_INC_LIMIT1(vdsc_cfg->rc_quant_incr_limit1) |
0858         DSC_RC_TARGET_OFF_HIGH(DSC_RC_TGT_OFFSET_HI_CONST) |
0859         DSC_RC_TARGET_OFF_LOW(DSC_RC_TGT_OFFSET_LO_CONST);
0860     drm_dbg_kms(&dev_priv->drm, "PPS10 = 0x%08x\n", pps_val);
0861     if (!is_pipe_dsc(crtc, cpu_transcoder)) {
0862         intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_10,
0863                    pps_val);
0864         /*
0865          * If 2 VDSC instances are needed, configure PPS for second
0866          * VDSC
0867          */
0868         if (crtc_state->dsc.dsc_split)
0869             intel_de_write(dev_priv,
0870                        DSCC_PICTURE_PARAMETER_SET_10, pps_val);
0871     } else {
0872         intel_de_write(dev_priv,
0873                    ICL_DSC0_PICTURE_PARAMETER_SET_10(pipe),
0874                    pps_val);
0875         if (crtc_state->dsc.dsc_split)
0876             intel_de_write(dev_priv,
0877                        ICL_DSC1_PICTURE_PARAMETER_SET_10(pipe),
0878                        pps_val);
0879     }
0880 
0881     /* Populate Picture parameter set 16 */
0882     pps_val = 0;
0883     pps_val |= DSC_SLICE_CHUNK_SIZE(vdsc_cfg->slice_chunk_size) |
0884         DSC_SLICE_PER_LINE((vdsc_cfg->pic_width / num_vdsc_instances) /
0885                    vdsc_cfg->slice_width) |
0886         DSC_SLICE_ROW_PER_FRAME(vdsc_cfg->pic_height /
0887                     vdsc_cfg->slice_height);
0888     drm_dbg_kms(&dev_priv->drm, "PPS16 = 0x%08x\n", pps_val);
0889     if (!is_pipe_dsc(crtc, cpu_transcoder)) {
0890         intel_de_write(dev_priv, DSCA_PICTURE_PARAMETER_SET_16,
0891                    pps_val);
0892         /*
0893          * If 2 VDSC instances are needed, configure PPS for second
0894          * VDSC
0895          */
0896         if (crtc_state->dsc.dsc_split)
0897             intel_de_write(dev_priv,
0898                        DSCC_PICTURE_PARAMETER_SET_16, pps_val);
0899     } else {
0900         intel_de_write(dev_priv,
0901                    ICL_DSC0_PICTURE_PARAMETER_SET_16(pipe),
0902                    pps_val);
0903         if (crtc_state->dsc.dsc_split)
0904             intel_de_write(dev_priv,
0905                        ICL_DSC1_PICTURE_PARAMETER_SET_16(pipe),
0906                        pps_val);
0907     }
0908 
0909     /* Populate the RC_BUF_THRESH registers */
0910     memset(rc_buf_thresh_dword, 0, sizeof(rc_buf_thresh_dword));
0911     for (i = 0; i < DSC_NUM_BUF_RANGES - 1; i++) {
0912         rc_buf_thresh_dword[i / 4] |=
0913             (u32)(vdsc_cfg->rc_buf_thresh[i] <<
0914                   BITS_PER_BYTE * (i % 4));
0915         drm_dbg_kms(&dev_priv->drm, "RC_BUF_THRESH_%d = 0x%08x\n", i,
0916                 rc_buf_thresh_dword[i / 4]);
0917     }
0918     if (!is_pipe_dsc(crtc, cpu_transcoder)) {
0919         intel_de_write(dev_priv, DSCA_RC_BUF_THRESH_0,
0920                    rc_buf_thresh_dword[0]);
0921         intel_de_write(dev_priv, DSCA_RC_BUF_THRESH_0_UDW,
0922                    rc_buf_thresh_dword[1]);
0923         intel_de_write(dev_priv, DSCA_RC_BUF_THRESH_1,
0924                    rc_buf_thresh_dword[2]);
0925         intel_de_write(dev_priv, DSCA_RC_BUF_THRESH_1_UDW,
0926                    rc_buf_thresh_dword[3]);
0927         if (crtc_state->dsc.dsc_split) {
0928             intel_de_write(dev_priv, DSCC_RC_BUF_THRESH_0,
0929                        rc_buf_thresh_dword[0]);
0930             intel_de_write(dev_priv, DSCC_RC_BUF_THRESH_0_UDW,
0931                        rc_buf_thresh_dword[1]);
0932             intel_de_write(dev_priv, DSCC_RC_BUF_THRESH_1,
0933                        rc_buf_thresh_dword[2]);
0934             intel_de_write(dev_priv, DSCC_RC_BUF_THRESH_1_UDW,
0935                        rc_buf_thresh_dword[3]);
0936         }
0937     } else {
0938         intel_de_write(dev_priv, ICL_DSC0_RC_BUF_THRESH_0(pipe),
0939                    rc_buf_thresh_dword[0]);
0940         intel_de_write(dev_priv, ICL_DSC0_RC_BUF_THRESH_0_UDW(pipe),
0941                    rc_buf_thresh_dword[1]);
0942         intel_de_write(dev_priv, ICL_DSC0_RC_BUF_THRESH_1(pipe),
0943                    rc_buf_thresh_dword[2]);
0944         intel_de_write(dev_priv, ICL_DSC0_RC_BUF_THRESH_1_UDW(pipe),
0945                    rc_buf_thresh_dword[3]);
0946         if (crtc_state->dsc.dsc_split) {
0947             intel_de_write(dev_priv,
0948                        ICL_DSC1_RC_BUF_THRESH_0(pipe),
0949                        rc_buf_thresh_dword[0]);
0950             intel_de_write(dev_priv,
0951                        ICL_DSC1_RC_BUF_THRESH_0_UDW(pipe),
0952                        rc_buf_thresh_dword[1]);
0953             intel_de_write(dev_priv,
0954                        ICL_DSC1_RC_BUF_THRESH_1(pipe),
0955                        rc_buf_thresh_dword[2]);
0956             intel_de_write(dev_priv,
0957                        ICL_DSC1_RC_BUF_THRESH_1_UDW(pipe),
0958                        rc_buf_thresh_dword[3]);
0959         }
0960     }
0961 
0962     /* Populate the RC_RANGE_PARAMETERS registers */
0963     memset(rc_range_params_dword, 0, sizeof(rc_range_params_dword));
0964     for (i = 0; i < DSC_NUM_BUF_RANGES; i++) {
0965         rc_range_params_dword[i / 2] |=
0966             (u32)(((vdsc_cfg->rc_range_params[i].range_bpg_offset <<
0967                 RC_BPG_OFFSET_SHIFT) |
0968                    (vdsc_cfg->rc_range_params[i].range_max_qp <<
0969                 RC_MAX_QP_SHIFT) |
0970                    (vdsc_cfg->rc_range_params[i].range_min_qp <<
0971                 RC_MIN_QP_SHIFT)) << 16 * (i % 2));
0972         drm_dbg_kms(&dev_priv->drm, "RC_RANGE_PARAM_%d = 0x%08x\n", i,
0973                 rc_range_params_dword[i / 2]);
0974     }
0975     if (!is_pipe_dsc(crtc, cpu_transcoder)) {
0976         intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_0,
0977                    rc_range_params_dword[0]);
0978         intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_0_UDW,
0979                    rc_range_params_dword[1]);
0980         intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_1,
0981                    rc_range_params_dword[2]);
0982         intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_1_UDW,
0983                    rc_range_params_dword[3]);
0984         intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_2,
0985                    rc_range_params_dword[4]);
0986         intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_2_UDW,
0987                    rc_range_params_dword[5]);
0988         intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_3,
0989                    rc_range_params_dword[6]);
0990         intel_de_write(dev_priv, DSCA_RC_RANGE_PARAMETERS_3_UDW,
0991                    rc_range_params_dword[7]);
0992         if (crtc_state->dsc.dsc_split) {
0993             intel_de_write(dev_priv, DSCC_RC_RANGE_PARAMETERS_0,
0994                        rc_range_params_dword[0]);
0995             intel_de_write(dev_priv,
0996                        DSCC_RC_RANGE_PARAMETERS_0_UDW,
0997                        rc_range_params_dword[1]);
0998             intel_de_write(dev_priv, DSCC_RC_RANGE_PARAMETERS_1,
0999                        rc_range_params_dword[2]);
1000             intel_de_write(dev_priv,
1001                        DSCC_RC_RANGE_PARAMETERS_1_UDW,
1002                        rc_range_params_dword[3]);
1003             intel_de_write(dev_priv, DSCC_RC_RANGE_PARAMETERS_2,
1004                        rc_range_params_dword[4]);
1005             intel_de_write(dev_priv,
1006                        DSCC_RC_RANGE_PARAMETERS_2_UDW,
1007                        rc_range_params_dword[5]);
1008             intel_de_write(dev_priv, DSCC_RC_RANGE_PARAMETERS_3,
1009                        rc_range_params_dword[6]);
1010             intel_de_write(dev_priv,
1011                        DSCC_RC_RANGE_PARAMETERS_3_UDW,
1012                        rc_range_params_dword[7]);
1013         }
1014     } else {
1015         intel_de_write(dev_priv, ICL_DSC0_RC_RANGE_PARAMETERS_0(pipe),
1016                    rc_range_params_dword[0]);
1017         intel_de_write(dev_priv,
1018                    ICL_DSC0_RC_RANGE_PARAMETERS_0_UDW(pipe),
1019                    rc_range_params_dword[1]);
1020         intel_de_write(dev_priv, ICL_DSC0_RC_RANGE_PARAMETERS_1(pipe),
1021                    rc_range_params_dword[2]);
1022         intel_de_write(dev_priv,
1023                    ICL_DSC0_RC_RANGE_PARAMETERS_1_UDW(pipe),
1024                    rc_range_params_dword[3]);
1025         intel_de_write(dev_priv, ICL_DSC0_RC_RANGE_PARAMETERS_2(pipe),
1026                    rc_range_params_dword[4]);
1027         intel_de_write(dev_priv,
1028                    ICL_DSC0_RC_RANGE_PARAMETERS_2_UDW(pipe),
1029                    rc_range_params_dword[5]);
1030         intel_de_write(dev_priv, ICL_DSC0_RC_RANGE_PARAMETERS_3(pipe),
1031                    rc_range_params_dword[6]);
1032         intel_de_write(dev_priv,
1033                    ICL_DSC0_RC_RANGE_PARAMETERS_3_UDW(pipe),
1034                    rc_range_params_dword[7]);
1035         if (crtc_state->dsc.dsc_split) {
1036             intel_de_write(dev_priv,
1037                        ICL_DSC1_RC_RANGE_PARAMETERS_0(pipe),
1038                        rc_range_params_dword[0]);
1039             intel_de_write(dev_priv,
1040                        ICL_DSC1_RC_RANGE_PARAMETERS_0_UDW(pipe),
1041                        rc_range_params_dword[1]);
1042             intel_de_write(dev_priv,
1043                        ICL_DSC1_RC_RANGE_PARAMETERS_1(pipe),
1044                        rc_range_params_dword[2]);
1045             intel_de_write(dev_priv,
1046                        ICL_DSC1_RC_RANGE_PARAMETERS_1_UDW(pipe),
1047                        rc_range_params_dword[3]);
1048             intel_de_write(dev_priv,
1049                        ICL_DSC1_RC_RANGE_PARAMETERS_2(pipe),
1050                        rc_range_params_dword[4]);
1051             intel_de_write(dev_priv,
1052                        ICL_DSC1_RC_RANGE_PARAMETERS_2_UDW(pipe),
1053                        rc_range_params_dword[5]);
1054             intel_de_write(dev_priv,
1055                        ICL_DSC1_RC_RANGE_PARAMETERS_3(pipe),
1056                        rc_range_params_dword[6]);
1057             intel_de_write(dev_priv,
1058                        ICL_DSC1_RC_RANGE_PARAMETERS_3_UDW(pipe),
1059                        rc_range_params_dword[7]);
1060         }
1061     }
1062 }
1063 
1064 void intel_dsc_dsi_pps_write(struct intel_encoder *encoder,
1065                  const struct intel_crtc_state *crtc_state)
1066 {
1067     const struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
1068     struct intel_dsi *intel_dsi = enc_to_intel_dsi(encoder);
1069     struct mipi_dsi_device *dsi;
1070     struct drm_dsc_picture_parameter_set pps;
1071     enum port port;
1072 
1073     if (!crtc_state->dsc.compression_enable)
1074         return;
1075 
1076     drm_dsc_pps_payload_pack(&pps, vdsc_cfg);
1077 
1078     for_each_dsi_port(port, intel_dsi->ports) {
1079         dsi = intel_dsi->dsi_hosts[port]->device;
1080 
1081         mipi_dsi_picture_parameter_set(dsi, &pps);
1082         mipi_dsi_compression_mode(dsi, true);
1083     }
1084 }
1085 
1086 void intel_dsc_dp_pps_write(struct intel_encoder *encoder,
1087                 const struct intel_crtc_state *crtc_state)
1088 {
1089     struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
1090     const struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
1091     struct drm_dsc_pps_infoframe dp_dsc_pps_sdp;
1092 
1093     if (!crtc_state->dsc.compression_enable)
1094         return;
1095 
1096     /* Prepare DP SDP PPS header as per DP 1.4 spec, Table 2-123 */
1097     drm_dsc_dp_pps_header_init(&dp_dsc_pps_sdp.pps_header);
1098 
1099     /* Fill the PPS payload bytes as per DSC spec 1.2 Table 4-1 */
1100     drm_dsc_pps_payload_pack(&dp_dsc_pps_sdp.pps_payload, vdsc_cfg);
1101 
1102     dig_port->write_infoframe(encoder, crtc_state,
1103                   DP_SDP_PPS, &dp_dsc_pps_sdp,
1104                   sizeof(dp_dsc_pps_sdp));
1105 }
1106 
1107 static i915_reg_t dss_ctl1_reg(struct intel_crtc *crtc, enum transcoder cpu_transcoder)
1108 {
1109     return is_pipe_dsc(crtc, cpu_transcoder) ?
1110         ICL_PIPE_DSS_CTL1(crtc->pipe) : DSS_CTL1;
1111 }
1112 
1113 static i915_reg_t dss_ctl2_reg(struct intel_crtc *crtc, enum transcoder cpu_transcoder)
1114 {
1115     return is_pipe_dsc(crtc, cpu_transcoder) ?
1116         ICL_PIPE_DSS_CTL2(crtc->pipe) : DSS_CTL2;
1117 }
1118 
1119 void intel_uncompressed_joiner_enable(const struct intel_crtc_state *crtc_state)
1120 {
1121     struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1122     struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1123     u32 dss_ctl1_val = 0;
1124 
1125     if (crtc_state->bigjoiner_pipes && !crtc_state->dsc.compression_enable) {
1126         if (intel_crtc_is_bigjoiner_slave(crtc_state))
1127             dss_ctl1_val |= UNCOMPRESSED_JOINER_SLAVE;
1128         else
1129             dss_ctl1_val |= UNCOMPRESSED_JOINER_MASTER;
1130 
1131         intel_de_write(dev_priv, dss_ctl1_reg(crtc, crtc_state->cpu_transcoder), dss_ctl1_val);
1132     }
1133 }
1134 
1135 void intel_dsc_enable(const struct intel_crtc_state *crtc_state)
1136 {
1137     struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1138     struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1139     u32 dss_ctl1_val = 0;
1140     u32 dss_ctl2_val = 0;
1141 
1142     if (!crtc_state->dsc.compression_enable)
1143         return;
1144 
1145     intel_dsc_pps_configure(crtc_state);
1146 
1147     dss_ctl2_val |= LEFT_BRANCH_VDSC_ENABLE;
1148     if (crtc_state->dsc.dsc_split) {
1149         dss_ctl2_val |= RIGHT_BRANCH_VDSC_ENABLE;
1150         dss_ctl1_val |= JOINER_ENABLE;
1151     }
1152     if (crtc_state->bigjoiner_pipes) {
1153         dss_ctl1_val |= BIG_JOINER_ENABLE;
1154         if (!intel_crtc_is_bigjoiner_slave(crtc_state))
1155             dss_ctl1_val |= MASTER_BIG_JOINER_ENABLE;
1156     }
1157     intel_de_write(dev_priv, dss_ctl1_reg(crtc, crtc_state->cpu_transcoder), dss_ctl1_val);
1158     intel_de_write(dev_priv, dss_ctl2_reg(crtc, crtc_state->cpu_transcoder), dss_ctl2_val);
1159 }
1160 
1161 void intel_dsc_disable(const struct intel_crtc_state *old_crtc_state)
1162 {
1163     struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->uapi.crtc);
1164     struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1165 
1166     /* Disable only if either of them is enabled */
1167     if (old_crtc_state->dsc.compression_enable ||
1168         old_crtc_state->bigjoiner_pipes) {
1169         intel_de_write(dev_priv, dss_ctl1_reg(crtc, old_crtc_state->cpu_transcoder), 0);
1170         intel_de_write(dev_priv, dss_ctl2_reg(crtc, old_crtc_state->cpu_transcoder), 0);
1171     }
1172 }
1173 
1174 void intel_dsc_get_config(struct intel_crtc_state *crtc_state)
1175 {
1176     struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
1177     struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1178     struct drm_dsc_config *vdsc_cfg = &crtc_state->dsc.config;
1179     enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
1180     enum pipe pipe = crtc->pipe;
1181     enum intel_display_power_domain power_domain;
1182     intel_wakeref_t wakeref;
1183     u32 dss_ctl1, dss_ctl2, val;
1184 
1185     if (!intel_dsc_source_support(crtc_state))
1186         return;
1187 
1188     power_domain = intel_dsc_power_domain(crtc, cpu_transcoder);
1189 
1190     wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
1191     if (!wakeref)
1192         return;
1193 
1194     dss_ctl1 = intel_de_read(dev_priv, dss_ctl1_reg(crtc, cpu_transcoder));
1195     dss_ctl2 = intel_de_read(dev_priv, dss_ctl2_reg(crtc, cpu_transcoder));
1196 
1197     crtc_state->dsc.compression_enable = dss_ctl2 & LEFT_BRANCH_VDSC_ENABLE;
1198     if (!crtc_state->dsc.compression_enable)
1199         goto out;
1200 
1201     crtc_state->dsc.dsc_split = (dss_ctl2 & RIGHT_BRANCH_VDSC_ENABLE) &&
1202         (dss_ctl1 & JOINER_ENABLE);
1203 
1204     /* FIXME: add more state readout as needed */
1205 
1206     /* PPS1 */
1207     if (!is_pipe_dsc(crtc, cpu_transcoder))
1208         val = intel_de_read(dev_priv, DSCA_PICTURE_PARAMETER_SET_1);
1209     else
1210         val = intel_de_read(dev_priv,
1211                     ICL_DSC0_PICTURE_PARAMETER_SET_1(pipe));
1212     vdsc_cfg->bits_per_pixel = val;
1213     crtc_state->dsc.compressed_bpp = vdsc_cfg->bits_per_pixel >> 4;
1214 out:
1215     intel_display_power_put(dev_priv, power_domain, wakeref);
1216 }