1 // SPDX-License-Identifier: MIT 2 // 3 // Copyright 2025 Advanced Micro Devices, Inc. 4 5 #include "dm_services.h" 6 #include "core_types.h" 7 #include "reg_helper.h" 8 #include "basics/conversion.h" 9 #include "dcn60/dcn60_dpp.h" 10 11 #define REG(reg)\ 12 dpp->tf_regs->reg 13 14 #define CTX \ 15 dpp->base.ctx 16 17 #undef FN 18 #define FN(reg_name, field_name) \ 19 dpp->tf_shift->field_name, dpp->tf_mask->field_name 20 21 void dpp60_dpp_setup( 22 struct dpp *dpp_base, 23 enum surface_pixel_format format, 24 enum expansion_mode mode, 25 struct dc_csc_transform input_csc_color_matrix, 26 enum dc_color_space input_color_space, 27 struct cnv_alpha_2bit_lut *alpha_2bit_lut) 28 { 29 struct dcn60_dpp *dpp = TO_DCN60_DPP(dpp_base); 30 uint32_t pixel_format = 8; 31 uint32_t alpha_en = 1; 32 enum dc_color_space color_space = COLOR_SPACE_SRGB; 33 enum dcn10_input_csc_select select = INPUT_CSC_SELECT_BYPASS; 34 uint32_t is_2bit = 0; 35 uint32_t dealpha_en = 0, dealpha_ablnd_en = 0; 36 uint32_t realpha_en = 0, realpha_ablnd_en = 0; 37 struct out_csc_color_matrix tbl_entry; 38 int i; 39 40 REG_SET_2(FORMAT_CONTROL, 0, 41 CNVC_BYPASS, 0, 42 FORMAT_EXPANSION_MODE, mode); 43 44 REG_UPDATE(FORMAT_CONTROL, FORMAT_CNV16, 0); 45 REG_UPDATE(FORMAT_CONTROL, CNVC_BYPASS_MSB_ALIGN, 0); 46 REG_UPDATE(FORMAT_CONTROL, CLAMP_POSITIVE, 0); 47 REG_UPDATE(FORMAT_CONTROL, CLAMP_POSITIVE_C, 0); 48 49 REG_UPDATE(FORMAT_CONTROL, FORMAT_CROSSBAR_R, 0); 50 REG_UPDATE(FORMAT_CONTROL, FORMAT_CROSSBAR_G, 1); 51 REG_UPDATE(FORMAT_CONTROL, FORMAT_CROSSBAR_B, 2); 52 53 switch (format) { 54 case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555: 55 pixel_format = 1; 56 break; 57 case SURFACE_PIXEL_FORMAT_GRPH_RGB565: 58 pixel_format = 3; 59 alpha_en = 0; 60 break; 61 case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: 62 case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888: 63 pixel_format = 8; 64 break; 65 case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: 66 case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: 67 pixel_format = 10; 68 is_2bit = 1; 69 break; 70 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb: 71 case SURFACE_PIXEL_FORMAT_VIDEO_422_CrCb_P208: 72 pixel_format = 64; 73 color_space = COLOR_SPACE_YCBCR709; 74 select = INPUT_CSC_SELECT_ICSC; 75 break; 76 case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr: 77 case SURFACE_PIXEL_FORMAT_VIDEO_422_CbCr_P208: 78 pixel_format = 65; 79 color_space = COLOR_SPACE_YCBCR709; 80 select = INPUT_CSC_SELECT_ICSC; 81 break; 82 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb: 83 case SURFACE_PIXEL_FORMAT_VIDEO_422_CrCb_P210: 84 pixel_format = 66; 85 color_space = COLOR_SPACE_YCBCR709; 86 select = INPUT_CSC_SELECT_ICSC; 87 break; 88 case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr: 89 case SURFACE_PIXEL_FORMAT_VIDEO_422_CbCr_P210: 90 pixel_format = 67; 91 color_space = COLOR_SPACE_YCBCR709; 92 select = INPUT_CSC_SELECT_ICSC; 93 break; 94 case SURFACE_PIXEL_FORMAT_VIDEO_422_CrCb_P212: 95 pixel_format = 68; 96 color_space = COLOR_SPACE_YCBCR709; 97 select = INPUT_CSC_SELECT_ICSC; 98 break; 99 case SURFACE_PIXEL_FORMAT_VIDEO_422_CbCr_P212: 100 pixel_format = 69; 101 color_space = COLOR_SPACE_YCBCR709; 102 select = INPUT_CSC_SELECT_ICSC; 103 break; 104 /* Packed 422 formats*/ 105 case SURFACE_PIXEL_FORMAT_VIDEO_422_YCrYCb: 106 pixel_format = 72; 107 color_space = COLOR_SPACE_YCBCR709; 108 select = INPUT_CSC_SELECT_ICSC; 109 // color space and select subjected to change 110 break; 111 case SURFACE_PIXEL_FORMAT_VIDEO_422_YCbYCr: 112 pixel_format = 73; 113 color_space = COLOR_SPACE_YCBCR709; 114 select = INPUT_CSC_SELECT_ICSC; 115 // color space and select subjected to change 116 break; 117 case SURFACE_PIXEL_FORMAT_VIDEO_422_CrYCbY: 118 pixel_format = 74; 119 color_space = COLOR_SPACE_YCBCR709; 120 select = INPUT_CSC_SELECT_ICSC; 121 // color space and select subjected to change 122 break; 123 case SURFACE_PIXEL_FORMAT_VIDEO_422_CbYCrY: 124 pixel_format = 75; 125 color_space = COLOR_SPACE_YCBCR709; 126 select = INPUT_CSC_SELECT_ICSC; 127 // color space and select subjected to change 128 break; 129 case SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCrYCb: 130 pixel_format = 76; 131 color_space = COLOR_SPACE_YCBCR709; 132 select = INPUT_CSC_SELECT_ICSC; 133 // color space and select subjected to change 134 break; 135 case SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_YCbYCr: 136 pixel_format = 77; 137 color_space = COLOR_SPACE_YCBCR709; 138 select = INPUT_CSC_SELECT_ICSC; 139 // color space and select subjected to change 140 break; 141 case SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CrYCbY: 142 pixel_format = 78; 143 color_space = COLOR_SPACE_YCBCR709; 144 select = INPUT_CSC_SELECT_ICSC; 145 // color space and select subjected to change 146 break; 147 case SURFACE_PIXEL_FORMAT_VIDEO_422_10bpc_CbYCrY: 148 pixel_format = 79; 149 color_space = COLOR_SPACE_YCBCR709; 150 select = INPUT_CSC_SELECT_ICSC; 151 // color space and select subjected to change 152 break; 153 case SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCrYCb: 154 pixel_format = 80; 155 color_space = COLOR_SPACE_YCBCR709; 156 select = INPUT_CSC_SELECT_ICSC; 157 // color space and select subjected to change 158 break; 159 case SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_YCbYCr: 160 pixel_format = 81; 161 color_space = COLOR_SPACE_YCBCR709; 162 select = INPUT_CSC_SELECT_ICSC; 163 // color space and select subjected to change 164 break; 165 case SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CrYCbY: 166 pixel_format = 82; 167 color_space = COLOR_SPACE_YCBCR709; 168 select = INPUT_CSC_SELECT_ICSC; 169 // color space and select subjected to change 170 break; 171 case SURFACE_PIXEL_FORMAT_VIDEO_422_12bpc_CbYCrY: 172 pixel_format = 83; 173 color_space = COLOR_SPACE_YCBCR709; 174 select = INPUT_CSC_SELECT_ICSC; 175 // color space and select subjected to change 176 break; 177 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: 178 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616: 179 pixel_format = 26; /* ARGB16161616_UNORM */ 180 break; 181 case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: 182 pixel_format = 24; 183 break; 184 case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: 185 pixel_format = 25; 186 break; 187 case SURFACE_PIXEL_FORMAT_VIDEO_AYCrCb8888: 188 pixel_format = 12; 189 color_space = COLOR_SPACE_YCBCR709; 190 select = INPUT_CSC_SELECT_ICSC; 191 break; 192 case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FIX: 193 pixel_format = 112; 194 alpha_en = 0; 195 break; 196 case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FIX: 197 pixel_format = 113; 198 alpha_en = 0; 199 break; 200 case SURFACE_PIXEL_FORMAT_VIDEO_ACrYCb2101010: 201 pixel_format = 114; 202 color_space = COLOR_SPACE_YCBCR709; 203 select = INPUT_CSC_SELECT_ICSC; 204 is_2bit = 1; 205 break; 206 case SURFACE_PIXEL_FORMAT_VIDEO_CrYCbA1010102: 207 pixel_format = 115; 208 color_space = COLOR_SPACE_YCBCR709; 209 select = INPUT_CSC_SELECT_ICSC; 210 is_2bit = 1; 211 break; 212 case SURFACE_PIXEL_FORMAT_GRPH_RGBE: 213 pixel_format = 116; 214 break; 215 case SURFACE_PIXEL_FORMAT_GRPH_RGBE_ALPHA: 216 pixel_format = 116; 217 break; 218 case SURFACE_PIXEL_FORMAT_GRPH_RGB111110_FLOAT: 219 pixel_format = 118; 220 alpha_en = 0; 221 break; 222 case SURFACE_PIXEL_FORMAT_GRPH_BGR101111_FLOAT: 223 pixel_format = 119; 224 alpha_en = 0; 225 break; 226 default: 227 break; 228 } 229 230 /* Set default color space based on format if none is given. */ 231 color_space = input_color_space ? input_color_space : color_space; 232 233 if (is_2bit == 1 && alpha_2bit_lut != NULL) { 234 REG_UPDATE(ALPHA_2BIT_LUT01, ALPHA_2BIT_LUT0, alpha_2bit_lut->lut0); 235 REG_UPDATE(ALPHA_2BIT_LUT01, ALPHA_2BIT_LUT1, alpha_2bit_lut->lut1); 236 REG_UPDATE(ALPHA_2BIT_LUT23, ALPHA_2BIT_LUT2, alpha_2bit_lut->lut2); 237 REG_UPDATE(ALPHA_2BIT_LUT23, ALPHA_2BIT_LUT3, alpha_2bit_lut->lut3); 238 } 239 240 REG_SET(CNVC_SURFACE_PIXEL_FORMAT, 0, 241 CNVC_SURFACE_PIXEL_FORMAT, pixel_format); 242 243 REG_UPDATE(FORMAT_CONTROL, FORMAT_CONTROL__ALPHA_EN, alpha_en); 244 245 REG_SET_2(PRE_DEALPHA, 0, 246 PRE_DEALPHA_EN, dealpha_en, 247 PRE_DEALPHA_ABLND_EN, dealpha_ablnd_en); 248 REG_SET_2(PRE_REALPHA, 0, 249 PRE_REALPHA_EN, realpha_en, 250 PRE_REALPHA_ABLND_EN, realpha_ablnd_en); 251 252 if (format < SURFACE_PIXEL_FORMAT_VIDEO_BEGIN || 253 format >= SURFACE_PIXEL_FORMAT_SUBSAMPLE_END || 254 color_space != COLOR_SPACE_SRGB) { 255 /* If input adjustment exists, program the ICSC with those values. */ 256 if (input_csc_color_matrix.enable_adjustment == true) { 257 for (i = 0; i < 12; i++) 258 tbl_entry.regval[i] = input_csc_color_matrix.matrix[i]; 259 260 tbl_entry.color_space = input_color_space; 261 262 if (dpp3_should_bypass_post_csc_for_colorspace(color_space)) 263 select = INPUT_CSC_SELECT_BYPASS; 264 else 265 select = INPUT_CSC_SELECT_ICSC; 266 267 dpp3_program_post_csc(dpp_base, color_space, select, 268 &tbl_entry); 269 } else { 270 dpp3_program_post_csc(dpp_base, color_space, select, NULL); 271 } 272 } 273 } 274 275 void dpp60_full_bypass(struct dpp *dpp_base) 276 { 277 struct dcn60_dpp *dpp = TO_DCN60_DPP(dpp_base); 278 279 /* Input pixel format: ARGB8888 */ 280 REG_SET(CNVC_SURFACE_PIXEL_FORMAT, 0, 281 CNVC_SURFACE_PIXEL_FORMAT, 0x8); 282 283 /* Zero expansion */ 284 REG_SET_3(FORMAT_CONTROL, 0, 285 CNVC_BYPASS, 0, 286 FORMAT_CONTROL__ALPHA_EN, 0, 287 FORMAT_EXPANSION_MODE, 0); 288 289 /* COLOR_KEYER_CONTROL.COLOR_KEYER_EN = 0 this should be default */ 290 if (dpp->tf_mask->CM_BYPASS_EN) 291 REG_SET(CM_CONTROL, 0, CM_BYPASS_EN, 1); 292 else 293 REG_SET(CM_CONTROL, 0, CM_BYPASS, 1); 294 } 295 296 static struct dpp_funcs dcn60_dpp_funcs = { 297 .dpp_program_gamcor_lut = dpp3_program_gamcor_lut, 298 .dpp_read_state = dpp401_read_state, 299 .dpp_reset = dpp_reset, 300 .dpp_set_scaler = dpp60_dscl_set_scaler_manual_scale, 301 .dpp_get_optimal_number_of_taps = dpp3_get_optimal_number_of_taps, 302 .dpp_set_pre_degam = NULL, 303 .dpp_full_bypass = dpp60_full_bypass, 304 .dpp_setup = dpp60_dpp_setup, 305 .dpp_program_cm_dealpha = dpp3_program_cm_dealpha, 306 .dpp_program_cm_bias = dpp3_program_cm_bias, 307 .dpp_program_bias_and_scale = dpp35_program_bias_and_scale_fcnv, 308 .dpp_cnv_set_alpha_keyer = dpp2_cnv_set_alpha_keyer, 309 .set_cursor_attributes = dpp401_set_cursor_attributes, 310 .set_cursor_position = dpp401_set_cursor_position, 311 .set_optional_cursor_attributes = dpp401_set_optional_cursor_attributes, 312 .dpp_dppclk_control = dpp1_dppclk_control, 313 .dpp_set_hdr_multiplier = dpp3_set_hdr_multiplier, 314 .set_cursor_matrix = dpp401_set_cursor_matrix, 315 .dpp_cm_hist_control = dpp42_dpp_cm_hist_control, 316 .dpp_cm_hist_read = dpp42_dpp_cm_hist_read, 317 .dpp_read_reg_state = dpp30_read_reg_state, 318 .dpp_set_pregam_state = dpp50_set_pregam_state, 319 }; 320 321 static struct dpp_caps dcn60_dpp_cap = { 322 .dscl_data_proc_format = DSCL_DATA_PRCESSING_FLOAT_FORMAT, 323 .max_lb_partitions = 63, 324 .dscl_calc_lb_num_partitions = dscl401_calc_lb_num_partitions, 325 }; 326 327 bool dpp60_construct( 328 struct dcn60_dpp *dpp, 329 struct dc_context *ctx, 330 uint32_t inst, 331 const struct dcn60_dpp_registers *tf_regs, 332 const struct dcn60_dpp_shift *tf_shift, 333 const struct dcn60_dpp_mask *tf_mask) 334 { 335 dpp->base.ctx = ctx; 336 337 dpp->base.inst = inst; 338 dpp->base.funcs = &dcn60_dpp_funcs; 339 dpp->base.caps = &dcn60_dpp_cap; 340 341 dpp->tf_regs = tf_regs; 342 dpp->tf_shift = tf_shift; 343 dpp->tf_mask = tf_mask; 344 345 return true; 346 } 347