1 /* 2 * Copyright 2015 Advanced Micro Devices, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20 * OTHER DEALINGS IN THE SOFTWARE. 21 * 22 * Authors: AMD 23 * 24 */ 25 26 #include "dm_services.h" 27 #include "core_types.h" 28 #include "timing_generator.h" 29 #include "hw_sequencer.h" 30 #include "hw_sequencer_private.h" 31 #include "basics/dc_common.h" 32 33 #define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0])) 34 35 /* used as index in array of black_color_format */ 36 enum black_color_format { 37 BLACK_COLOR_FORMAT_RGB_FULLRANGE = 0, 38 BLACK_COLOR_FORMAT_RGB_LIMITED, 39 BLACK_COLOR_FORMAT_YUV_TV, 40 BLACK_COLOR_FORMAT_YUV_CV, 41 BLACK_COLOR_FORMAT_YUV_SUPER_AA, 42 BLACK_COLOR_FORMAT_DEBUG, 43 }; 44 45 enum dc_color_space_type { 46 COLOR_SPACE_RGB_TYPE, 47 COLOR_SPACE_RGB_LIMITED_TYPE, 48 COLOR_SPACE_YCBCR601_TYPE, 49 COLOR_SPACE_YCBCR709_TYPE, 50 COLOR_SPACE_YCBCR2020_TYPE, 51 COLOR_SPACE_YCBCR601_LIMITED_TYPE, 52 COLOR_SPACE_YCBCR709_LIMITED_TYPE, 53 COLOR_SPACE_YCBCR709_BLACK_TYPE, 54 }; 55 56 static const struct tg_color black_color_format[] = { 57 /* BlackColorFormat_RGB_FullRange */ 58 {0, 0, 0}, 59 /* BlackColorFormat_RGB_Limited */ 60 {0x40, 0x40, 0x40}, 61 /* BlackColorFormat_YUV_TV */ 62 {0x200, 0x40, 0x200}, 63 /* BlackColorFormat_YUV_CV */ 64 {0x1f4, 0x40, 0x1f4}, 65 /* BlackColorFormat_YUV_SuperAA */ 66 {0x1a2, 0x20, 0x1a2}, 67 /* visual confirm debug */ 68 {0xff, 0xff, 0}, 69 }; 70 71 struct out_csc_color_matrix_type { 72 enum dc_color_space_type color_space_type; 73 uint16_t regval[12]; 74 }; 75 76 static const struct out_csc_color_matrix_type output_csc_matrix[] = { 77 { COLOR_SPACE_RGB_TYPE, 78 { 0x2000, 0, 0, 0, 79 0, 0x2000, 0, 0, 80 0, 0, 0x2000, 0} }, 81 { COLOR_SPACE_RGB_LIMITED_TYPE, 82 { 0x1B67, 0, 0, 0x201, 83 0, 0x1B67, 0, 0x201, 84 0, 0, 0x1B67, 0x201} }, 85 { COLOR_SPACE_YCBCR601_TYPE, 86 { 0xE04, 0xF444, 0xFDB9, 0x1004, 87 0x831, 0x1016, 0x320, 0x201, 88 0xFB45, 0xF6B7, 0xE04, 0x1004} }, 89 { COLOR_SPACE_YCBCR709_TYPE, 90 { 0xE04, 0xF345, 0xFEB7, 0x1004, 91 0x5D3, 0x1399, 0x1FA, 0x201, 92 0xFCCA, 0xF533, 0xE04, 0x1004} }, 93 /* TODO: correct values below */ 94 { COLOR_SPACE_YCBCR601_LIMITED_TYPE, 95 { 0xE00, 0xF447, 0xFDB9, 0x1000, 96 0x991, 0x12C9, 0x3A6, 0x200, 97 0xFB47, 0xF6B9, 0xE00, 0x1000} }, 98 { COLOR_SPACE_YCBCR709_LIMITED_TYPE, 99 { 0xE00, 0xF349, 0xFEB7, 0x1000, 100 0x6CE, 0x16E3, 0x24F, 0x200, 101 0xFCCB, 0xF535, 0xE00, 0x1000} }, 102 { COLOR_SPACE_YCBCR2020_TYPE, 103 { 0x1000, 0xF149, 0xFEB7, 0x1004, 104 0x0868, 0x15B2, 0x01E6, 0x201, 105 0xFB88, 0xF478, 0x1000, 0x1004} }, 106 { COLOR_SPACE_YCBCR709_BLACK_TYPE, 107 { 0x0000, 0x0000, 0x0000, 0x1000, 108 0x0000, 0x0000, 0x0000, 0x0200, 109 0x0000, 0x0000, 0x0000, 0x1000} }, 110 }; 111 112 static bool is_rgb_type( 113 enum dc_color_space color_space) 114 { 115 bool ret = false; 116 117 if (color_space == COLOR_SPACE_SRGB || 118 color_space == COLOR_SPACE_XR_RGB || 119 color_space == COLOR_SPACE_MSREF_SCRGB || 120 color_space == COLOR_SPACE_2020_RGB_FULLRANGE || 121 color_space == COLOR_SPACE_ADOBERGB || 122 color_space == COLOR_SPACE_DCIP3 || 123 color_space == COLOR_SPACE_DOLBYVISION) 124 ret = true; 125 return ret; 126 } 127 128 static bool is_rgb_limited_type( 129 enum dc_color_space color_space) 130 { 131 bool ret = false; 132 133 if (color_space == COLOR_SPACE_SRGB_LIMITED || 134 color_space == COLOR_SPACE_2020_RGB_LIMITEDRANGE) 135 ret = true; 136 return ret; 137 } 138 139 static bool is_ycbcr601_type( 140 enum dc_color_space color_space) 141 { 142 bool ret = false; 143 144 if (color_space == COLOR_SPACE_YCBCR601 || 145 color_space == COLOR_SPACE_XV_YCC_601) 146 ret = true; 147 return ret; 148 } 149 150 static bool is_ycbcr601_limited_type( 151 enum dc_color_space color_space) 152 { 153 bool ret = false; 154 155 if (color_space == COLOR_SPACE_YCBCR601_LIMITED) 156 ret = true; 157 return ret; 158 } 159 160 static bool is_ycbcr709_type( 161 enum dc_color_space color_space) 162 { 163 bool ret = false; 164 165 if (color_space == COLOR_SPACE_YCBCR709 || 166 color_space == COLOR_SPACE_XV_YCC_709) 167 ret = true; 168 return ret; 169 } 170 171 static bool is_ycbcr2020_type( 172 enum dc_color_space color_space) 173 { 174 bool ret = false; 175 176 if (color_space == COLOR_SPACE_2020_YCBCR) 177 ret = true; 178 return ret; 179 } 180 181 static bool is_ycbcr709_limited_type( 182 enum dc_color_space color_space) 183 { 184 bool ret = false; 185 186 if (color_space == COLOR_SPACE_YCBCR709_LIMITED) 187 ret = true; 188 return ret; 189 } 190 191 static enum dc_color_space_type get_color_space_type(enum dc_color_space color_space) 192 { 193 enum dc_color_space_type type = COLOR_SPACE_RGB_TYPE; 194 195 if (is_rgb_type(color_space)) 196 type = COLOR_SPACE_RGB_TYPE; 197 else if (is_rgb_limited_type(color_space)) 198 type = COLOR_SPACE_RGB_LIMITED_TYPE; 199 else if (is_ycbcr601_type(color_space)) 200 type = COLOR_SPACE_YCBCR601_TYPE; 201 else if (is_ycbcr709_type(color_space)) 202 type = COLOR_SPACE_YCBCR709_TYPE; 203 else if (is_ycbcr601_limited_type(color_space)) 204 type = COLOR_SPACE_YCBCR601_LIMITED_TYPE; 205 else if (is_ycbcr709_limited_type(color_space)) 206 type = COLOR_SPACE_YCBCR709_LIMITED_TYPE; 207 else if (is_ycbcr2020_type(color_space)) 208 type = COLOR_SPACE_YCBCR2020_TYPE; 209 else if (color_space == COLOR_SPACE_YCBCR709) 210 type = COLOR_SPACE_YCBCR709_BLACK_TYPE; 211 else if (color_space == COLOR_SPACE_YCBCR709_BLACK) 212 type = COLOR_SPACE_YCBCR709_BLACK_TYPE; 213 return type; 214 } 215 216 const uint16_t *find_color_matrix(enum dc_color_space color_space, 217 uint32_t *array_size) 218 { 219 int i; 220 enum dc_color_space_type type; 221 const uint16_t *val = NULL; 222 int arr_size = NUM_ELEMENTS(output_csc_matrix); 223 224 type = get_color_space_type(color_space); 225 for (i = 0; i < arr_size; i++) 226 if (output_csc_matrix[i].color_space_type == type) { 227 val = output_csc_matrix[i].regval; 228 *array_size = 12; 229 break; 230 } 231 232 return val; 233 } 234 235 236 void color_space_to_black_color( 237 const struct dc *dc, 238 enum dc_color_space colorspace, 239 struct tg_color *black_color) 240 { 241 switch (colorspace) { 242 case COLOR_SPACE_YCBCR601: 243 case COLOR_SPACE_YCBCR709: 244 case COLOR_SPACE_YCBCR709_BLACK: 245 case COLOR_SPACE_YCBCR601_LIMITED: 246 case COLOR_SPACE_YCBCR709_LIMITED: 247 case COLOR_SPACE_2020_YCBCR: 248 *black_color = black_color_format[BLACK_COLOR_FORMAT_YUV_CV]; 249 break; 250 251 case COLOR_SPACE_SRGB_LIMITED: 252 *black_color = 253 black_color_format[BLACK_COLOR_FORMAT_RGB_LIMITED]; 254 break; 255 256 /** 257 * Remove default and add case for all color space 258 * so when we forget to add new color space 259 * compiler will give a warning 260 */ 261 case COLOR_SPACE_UNKNOWN: 262 case COLOR_SPACE_SRGB: 263 case COLOR_SPACE_XR_RGB: 264 case COLOR_SPACE_MSREF_SCRGB: 265 case COLOR_SPACE_XV_YCC_709: 266 case COLOR_SPACE_XV_YCC_601: 267 case COLOR_SPACE_2020_RGB_FULLRANGE: 268 case COLOR_SPACE_2020_RGB_LIMITEDRANGE: 269 case COLOR_SPACE_ADOBERGB: 270 case COLOR_SPACE_DCIP3: 271 case COLOR_SPACE_DISPLAYNATIVE: 272 case COLOR_SPACE_DOLBYVISION: 273 case COLOR_SPACE_APPCTRL: 274 case COLOR_SPACE_CUSTOMPOINTS: 275 /* fefault is sRGB black (full range). */ 276 *black_color = 277 black_color_format[BLACK_COLOR_FORMAT_RGB_FULLRANGE]; 278 /* default is sRGB black 0. */ 279 break; 280 } 281 } 282 283 bool hwss_wait_for_blank_complete( 284 struct timing_generator *tg) 285 { 286 int counter; 287 288 /* Not applicable if the pipe is not primary, save 300ms of boot time */ 289 if (!tg->funcs->is_blanked) 290 return true; 291 for (counter = 0; counter < 100; counter++) { 292 if (tg->funcs->is_blanked(tg)) 293 break; 294 295 msleep(1); 296 } 297 298 if (counter == 100) { 299 dm_error("DC: failed to blank crtc!\n"); 300 return false; 301 } 302 303 return true; 304 } 305 306 void get_mpctree_visual_confirm_color( 307 struct pipe_ctx *pipe_ctx, 308 struct tg_color *color) 309 { 310 const struct tg_color pipe_colors[6] = { 311 {MAX_TG_COLOR_VALUE, 0, 0}, /* red */ 312 {MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE / 4, 0}, /* orange */ 313 {MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE, 0}, /* yellow */ 314 {0, MAX_TG_COLOR_VALUE, 0}, /* green */ 315 {0, 0, MAX_TG_COLOR_VALUE}, /* blue */ 316 {MAX_TG_COLOR_VALUE / 2, 0, MAX_TG_COLOR_VALUE / 2}, /* purple */ 317 }; 318 319 struct pipe_ctx *top_pipe = pipe_ctx; 320 321 while (top_pipe->top_pipe) 322 top_pipe = top_pipe->top_pipe; 323 324 *color = pipe_colors[top_pipe->pipe_idx]; 325 } 326 327 void get_surface_visual_confirm_color( 328 const struct pipe_ctx *pipe_ctx, 329 struct tg_color *color) 330 { 331 uint32_t color_value = MAX_TG_COLOR_VALUE; 332 333 switch (pipe_ctx->plane_res.scl_data.format) { 334 case PIXEL_FORMAT_ARGB8888: 335 /* set border color to red */ 336 color->color_r_cr = color_value; 337 if (pipe_ctx->plane_state->layer_index > 0) { 338 /* set border color to pink */ 339 color->color_b_cb = color_value; 340 color->color_g_y = color_value * 0.5; 341 } 342 break; 343 344 case PIXEL_FORMAT_ARGB2101010: 345 /* set border color to blue */ 346 color->color_b_cb = color_value; 347 if (pipe_ctx->plane_state->layer_index > 0) { 348 /* set border color to cyan */ 349 color->color_g_y = color_value; 350 } 351 break; 352 case PIXEL_FORMAT_420BPP8: 353 /* set border color to green */ 354 color->color_g_y = color_value; 355 break; 356 case PIXEL_FORMAT_420BPP10: 357 /* set border color to yellow */ 358 color->color_g_y = color_value; 359 color->color_r_cr = color_value; 360 break; 361 case PIXEL_FORMAT_FP16: 362 /* set border color to white */ 363 color->color_r_cr = color_value; 364 color->color_b_cb = color_value; 365 color->color_g_y = color_value; 366 if (pipe_ctx->plane_state->layer_index > 0) { 367 /* set border color to orange */ 368 color->color_g_y = 0.22 * color_value; 369 color->color_b_cb = 0; 370 } 371 break; 372 default: 373 break; 374 } 375 } 376 377 void get_hdr_visual_confirm_color( 378 struct pipe_ctx *pipe_ctx, 379 struct tg_color *color) 380 { 381 uint32_t color_value = MAX_TG_COLOR_VALUE; 382 bool is_sdr = false; 383 384 /* Determine the overscan color based on the top-most (desktop) plane's context */ 385 struct pipe_ctx *top_pipe_ctx = pipe_ctx; 386 387 while (top_pipe_ctx->top_pipe != NULL) 388 top_pipe_ctx = top_pipe_ctx->top_pipe; 389 390 switch (top_pipe_ctx->plane_res.scl_data.format) { 391 case PIXEL_FORMAT_ARGB2101010: 392 if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_PQ) { 393 /* HDR10, ARGB2101010 - set border color to red */ 394 color->color_r_cr = color_value; 395 } else if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_GAMMA22) { 396 /* FreeSync 2 ARGB2101010 - set border color to pink */ 397 color->color_r_cr = color_value; 398 color->color_b_cb = color_value; 399 } else 400 is_sdr = true; 401 break; 402 case PIXEL_FORMAT_FP16: 403 if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_PQ) { 404 /* HDR10, FP16 - set border color to blue */ 405 color->color_b_cb = color_value; 406 } else if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_GAMMA22) { 407 /* FreeSync 2 HDR - set border color to green */ 408 color->color_g_y = color_value; 409 } else 410 is_sdr = true; 411 break; 412 default: 413 is_sdr = true; 414 break; 415 } 416 417 if (is_sdr) { 418 /* SDR - set border color to Gray */ 419 color->color_r_cr = color_value/2; 420 color->color_b_cb = color_value/2; 421 color->color_g_y = color_value/2; 422 } 423 } 424 425 void get_subvp_visual_confirm_color( 426 struct dc *dc, 427 struct dc_state *context, 428 struct pipe_ctx *pipe_ctx, 429 struct tg_color *color) 430 { 431 uint32_t color_value = MAX_TG_COLOR_VALUE; 432 bool enable_subvp = false; 433 int i; 434 435 if (!dc->ctx || !dc->ctx->dmub_srv || !pipe_ctx || !context) 436 return; 437 438 for (i = 0; i < dc->res_pool->pipe_count; i++) { 439 struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; 440 441 if (pipe->stream && pipe->stream->mall_stream_config.paired_stream && 442 pipe->stream->mall_stream_config.type == SUBVP_MAIN) { 443 /* SubVP enable - red */ 444 color->color_g_y = 0; 445 color->color_b_cb = 0; 446 color->color_r_cr = color_value; 447 enable_subvp = true; 448 449 if (pipe_ctx->stream == pipe->stream) 450 return; 451 break; 452 } 453 } 454 455 if (enable_subvp && pipe_ctx->stream->mall_stream_config.type == SUBVP_NONE) { 456 color->color_r_cr = 0; 457 if (pipe_ctx->stream->allow_freesync == 1) { 458 /* SubVP enable and DRR on - green */ 459 color->color_b_cb = 0; 460 color->color_g_y = color_value; 461 } else { 462 /* SubVP enable and No DRR - blue */ 463 color->color_g_y = 0; 464 color->color_b_cb = color_value; 465 } 466 } 467 } 468 469 void hwss_build_fast_sequence(struct dc *dc, 470 struct dc_dmub_cmd *dc_dmub_cmd, 471 unsigned int dmub_cmd_count, 472 struct block_sequence block_sequence[], 473 int *num_steps, 474 struct pipe_ctx *pipe_ctx) 475 { 476 struct dc_plane_state *plane = pipe_ctx->plane_state; 477 struct dc_stream_state *stream = pipe_ctx->stream; 478 struct dce_hwseq *hws = dc->hwseq; 479 struct pipe_ctx *current_pipe = NULL; 480 struct pipe_ctx *current_mpc_pipe = NULL; 481 unsigned int i = 0; 482 483 *num_steps = 0; // Initialize to 0 484 485 if (!plane || !stream) 486 return; 487 488 if (dc->hwss.subvp_pipe_control_lock_fast) { 489 block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.dc = dc; 490 block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.lock = true; 491 block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.pipe_ctx = pipe_ctx; 492 block_sequence[*num_steps].func = DMUB_SUBVP_PIPE_CONTROL_LOCK_FAST; 493 (*num_steps)++; 494 } 495 if (dc->hwss.pipe_control_lock) { 496 block_sequence[*num_steps].params.pipe_control_lock_params.dc = dc; 497 block_sequence[*num_steps].params.pipe_control_lock_params.lock = true; 498 block_sequence[*num_steps].params.pipe_control_lock_params.pipe_ctx = pipe_ctx; 499 block_sequence[*num_steps].func = OPTC_PIPE_CONTROL_LOCK; 500 (*num_steps)++; 501 } 502 503 for (i = 0; i < dmub_cmd_count; i++) { 504 block_sequence[*num_steps].params.send_dmcub_cmd_params.ctx = dc->ctx; 505 block_sequence[*num_steps].params.send_dmcub_cmd_params.cmd = &(dc_dmub_cmd[i].dmub_cmd); 506 block_sequence[*num_steps].params.send_dmcub_cmd_params.wait_type = dc_dmub_cmd[i].wait_type; 507 block_sequence[*num_steps].func = DMUB_SEND_DMCUB_CMD; 508 (*num_steps)++; 509 } 510 511 current_pipe = pipe_ctx; 512 while (current_pipe) { 513 current_mpc_pipe = current_pipe; 514 while (current_mpc_pipe) { 515 if (dc->hwss.set_flip_control_gsl && current_mpc_pipe->plane_state && current_mpc_pipe->plane_state->update_flags.raw) { 516 block_sequence[*num_steps].params.set_flip_control_gsl_params.pipe_ctx = current_mpc_pipe; 517 block_sequence[*num_steps].params.set_flip_control_gsl_params.flip_immediate = current_mpc_pipe->plane_state->flip_immediate; 518 block_sequence[*num_steps].func = HUBP_SET_FLIP_CONTROL_GSL; 519 (*num_steps)++; 520 } 521 if (dc->hwss.program_triplebuffer && dc->debug.enable_tri_buf && current_mpc_pipe->plane_state->update_flags.raw) { 522 block_sequence[*num_steps].params.program_triplebuffer_params.dc = dc; 523 block_sequence[*num_steps].params.program_triplebuffer_params.pipe_ctx = current_mpc_pipe; 524 block_sequence[*num_steps].params.program_triplebuffer_params.enableTripleBuffer = current_mpc_pipe->plane_state->triplebuffer_flips; 525 block_sequence[*num_steps].func = HUBP_PROGRAM_TRIPLEBUFFER; 526 (*num_steps)++; 527 } 528 if (dc->hwss.update_plane_addr && current_mpc_pipe->plane_state->update_flags.bits.addr_update) { 529 block_sequence[*num_steps].params.update_plane_addr_params.dc = dc; 530 block_sequence[*num_steps].params.update_plane_addr_params.pipe_ctx = current_mpc_pipe; 531 block_sequence[*num_steps].func = HUBP_UPDATE_PLANE_ADDR; 532 (*num_steps)++; 533 } 534 535 if (hws->funcs.set_input_transfer_func && current_mpc_pipe->plane_state->update_flags.bits.gamma_change) { 536 block_sequence[*num_steps].params.set_input_transfer_func_params.dc = dc; 537 block_sequence[*num_steps].params.set_input_transfer_func_params.pipe_ctx = current_mpc_pipe; 538 block_sequence[*num_steps].params.set_input_transfer_func_params.plane_state = current_mpc_pipe->plane_state; 539 block_sequence[*num_steps].func = DPP_SET_INPUT_TRANSFER_FUNC; 540 (*num_steps)++; 541 } 542 543 if (dc->hwss.program_gamut_remap && current_mpc_pipe->plane_state->update_flags.bits.gamut_remap_change) { 544 block_sequence[*num_steps].params.program_gamut_remap_params.pipe_ctx = current_mpc_pipe; 545 block_sequence[*num_steps].func = DPP_PROGRAM_GAMUT_REMAP; 546 (*num_steps)++; 547 } 548 if (current_mpc_pipe->plane_state->update_flags.bits.input_csc_change) { 549 block_sequence[*num_steps].params.setup_dpp_params.pipe_ctx = current_mpc_pipe; 550 block_sequence[*num_steps].func = DPP_SETUP_DPP; 551 (*num_steps)++; 552 } 553 if (current_mpc_pipe->plane_state->update_flags.bits.coeff_reduction_change) { 554 block_sequence[*num_steps].params.program_bias_and_scale_params.pipe_ctx = current_mpc_pipe; 555 block_sequence[*num_steps].func = DPP_PROGRAM_BIAS_AND_SCALE; 556 (*num_steps)++; 557 } 558 if (hws->funcs.set_output_transfer_func && current_mpc_pipe->stream->update_flags.bits.out_tf) { 559 block_sequence[*num_steps].params.set_output_transfer_func_params.dc = dc; 560 block_sequence[*num_steps].params.set_output_transfer_func_params.pipe_ctx = current_mpc_pipe; 561 block_sequence[*num_steps].params.set_output_transfer_func_params.stream = current_mpc_pipe->stream; 562 block_sequence[*num_steps].func = DPP_SET_OUTPUT_TRANSFER_FUNC; 563 (*num_steps)++; 564 } 565 566 if (current_mpc_pipe->stream->update_flags.bits.out_csc) { 567 block_sequence[*num_steps].params.power_on_mpc_mem_pwr_params.mpc = dc->res_pool->mpc; 568 block_sequence[*num_steps].params.power_on_mpc_mem_pwr_params.mpcc_id = current_mpc_pipe->plane_res.hubp->inst; 569 block_sequence[*num_steps].params.power_on_mpc_mem_pwr_params.power_on = true; 570 block_sequence[*num_steps].func = MPC_POWER_ON_MPC_MEM_PWR; 571 (*num_steps)++; 572 573 if (current_mpc_pipe->stream->csc_color_matrix.enable_adjustment == true) { 574 block_sequence[*num_steps].params.set_output_csc_params.mpc = dc->res_pool->mpc; 575 block_sequence[*num_steps].params.set_output_csc_params.opp_id = current_mpc_pipe->stream_res.opp->inst; 576 block_sequence[*num_steps].params.set_output_csc_params.regval = current_mpc_pipe->stream->csc_color_matrix.matrix; 577 block_sequence[*num_steps].params.set_output_csc_params.ocsc_mode = MPC_OUTPUT_CSC_COEF_A; 578 block_sequence[*num_steps].func = MPC_SET_OUTPUT_CSC; 579 (*num_steps)++; 580 } else { 581 block_sequence[*num_steps].params.set_ocsc_default_params.mpc = dc->res_pool->mpc; 582 block_sequence[*num_steps].params.set_ocsc_default_params.opp_id = current_mpc_pipe->stream_res.opp->inst; 583 block_sequence[*num_steps].params.set_ocsc_default_params.color_space = current_mpc_pipe->stream->output_color_space; 584 block_sequence[*num_steps].params.set_ocsc_default_params.ocsc_mode = MPC_OUTPUT_CSC_COEF_A; 585 block_sequence[*num_steps].func = MPC_SET_OCSC_DEFAULT; 586 (*num_steps)++; 587 } 588 } 589 current_mpc_pipe = current_mpc_pipe->bottom_pipe; 590 } 591 current_pipe = current_pipe->next_odm_pipe; 592 } 593 594 if (dc->hwss.pipe_control_lock) { 595 block_sequence[*num_steps].params.pipe_control_lock_params.dc = dc; 596 block_sequence[*num_steps].params.pipe_control_lock_params.lock = false; 597 block_sequence[*num_steps].params.pipe_control_lock_params.pipe_ctx = pipe_ctx; 598 block_sequence[*num_steps].func = OPTC_PIPE_CONTROL_LOCK; 599 (*num_steps)++; 600 } 601 if (dc->hwss.subvp_pipe_control_lock_fast) { 602 block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.dc = dc; 603 block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.lock = false; 604 block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.pipe_ctx = pipe_ctx; 605 block_sequence[*num_steps].func = DMUB_SUBVP_PIPE_CONTROL_LOCK_FAST; 606 (*num_steps)++; 607 } 608 609 current_pipe = pipe_ctx; 610 while (current_pipe) { 611 current_mpc_pipe = current_pipe; 612 613 while (current_mpc_pipe) { 614 if (!current_mpc_pipe->bottom_pipe && !current_mpc_pipe->next_odm_pipe && 615 current_mpc_pipe->stream && current_mpc_pipe->plane_state && 616 current_mpc_pipe->plane_state->update_flags.bits.addr_update && 617 !current_mpc_pipe->plane_state->skip_manual_trigger) { 618 block_sequence[*num_steps].params.program_manual_trigger_params.pipe_ctx = current_mpc_pipe; 619 block_sequence[*num_steps].func = OPTC_PROGRAM_MANUAL_TRIGGER; 620 (*num_steps)++; 621 } 622 current_mpc_pipe = current_mpc_pipe->bottom_pipe; 623 } 624 current_pipe = current_pipe->next_odm_pipe; 625 } 626 } 627 628 void hwss_execute_sequence(struct dc *dc, 629 struct block_sequence block_sequence[], 630 int num_steps) 631 { 632 unsigned int i; 633 union block_sequence_params *params; 634 struct dce_hwseq *hws = dc->hwseq; 635 636 for (i = 0; i < num_steps; i++) { 637 params = &(block_sequence[i].params); 638 switch (block_sequence[i].func) { 639 640 case DMUB_SUBVP_PIPE_CONTROL_LOCK_FAST: 641 dc->hwss.subvp_pipe_control_lock_fast(params); 642 break; 643 case OPTC_PIPE_CONTROL_LOCK: 644 dc->hwss.pipe_control_lock(params->pipe_control_lock_params.dc, 645 params->pipe_control_lock_params.pipe_ctx, 646 params->pipe_control_lock_params.lock); 647 break; 648 case HUBP_SET_FLIP_CONTROL_GSL: 649 dc->hwss.set_flip_control_gsl(params->set_flip_control_gsl_params.pipe_ctx, 650 params->set_flip_control_gsl_params.flip_immediate); 651 break; 652 case HUBP_PROGRAM_TRIPLEBUFFER: 653 dc->hwss.program_triplebuffer(params->program_triplebuffer_params.dc, 654 params->program_triplebuffer_params.pipe_ctx, 655 params->program_triplebuffer_params.enableTripleBuffer); 656 break; 657 case HUBP_UPDATE_PLANE_ADDR: 658 dc->hwss.update_plane_addr(params->update_plane_addr_params.dc, 659 params->update_plane_addr_params.pipe_ctx); 660 break; 661 case DPP_SET_INPUT_TRANSFER_FUNC: 662 hws->funcs.set_input_transfer_func(params->set_input_transfer_func_params.dc, 663 params->set_input_transfer_func_params.pipe_ctx, 664 params->set_input_transfer_func_params.plane_state); 665 break; 666 case DPP_PROGRAM_GAMUT_REMAP: 667 dc->hwss.program_gamut_remap(params->program_gamut_remap_params.pipe_ctx); 668 break; 669 case DPP_SETUP_DPP: 670 hwss_setup_dpp(params); 671 break; 672 case DPP_PROGRAM_BIAS_AND_SCALE: 673 hwss_program_bias_and_scale(params); 674 break; 675 case OPTC_PROGRAM_MANUAL_TRIGGER: 676 hwss_program_manual_trigger(params); 677 break; 678 case DPP_SET_OUTPUT_TRANSFER_FUNC: 679 hws->funcs.set_output_transfer_func(params->set_output_transfer_func_params.dc, 680 params->set_output_transfer_func_params.pipe_ctx, 681 params->set_output_transfer_func_params.stream); 682 break; 683 case MPC_UPDATE_VISUAL_CONFIRM: 684 dc->hwss.update_visual_confirm_color(params->update_visual_confirm_params.dc, 685 params->update_visual_confirm_params.pipe_ctx, 686 params->update_visual_confirm_params.mpcc_id); 687 break; 688 case MPC_POWER_ON_MPC_MEM_PWR: 689 hwss_power_on_mpc_mem_pwr(params); 690 break; 691 case MPC_SET_OUTPUT_CSC: 692 hwss_set_output_csc(params); 693 break; 694 case MPC_SET_OCSC_DEFAULT: 695 hwss_set_ocsc_default(params); 696 break; 697 case DMUB_SEND_DMCUB_CMD: 698 hwss_send_dmcub_cmd(params); 699 break; 700 default: 701 ASSERT(false); 702 break; 703 } 704 } 705 } 706 707 void hwss_send_dmcub_cmd(union block_sequence_params *params) 708 { 709 struct dc_context *ctx = params->send_dmcub_cmd_params.ctx; 710 union dmub_rb_cmd *cmd = params->send_dmcub_cmd_params.cmd; 711 enum dm_dmub_wait_type wait_type = params->send_dmcub_cmd_params.wait_type; 712 713 dm_execute_dmub_cmd(ctx, cmd, wait_type); 714 } 715 716 void hwss_program_manual_trigger(union block_sequence_params *params) 717 { 718 struct pipe_ctx *pipe_ctx = params->program_manual_trigger_params.pipe_ctx; 719 720 if (pipe_ctx->stream_res.tg->funcs->program_manual_trigger) 721 pipe_ctx->stream_res.tg->funcs->program_manual_trigger(pipe_ctx->stream_res.tg); 722 } 723 724 void hwss_setup_dpp(union block_sequence_params *params) 725 { 726 struct pipe_ctx *pipe_ctx = params->setup_dpp_params.pipe_ctx; 727 struct dpp *dpp = pipe_ctx->plane_res.dpp; 728 struct dc_plane_state *plane_state = pipe_ctx->plane_state; 729 730 if (dpp && dpp->funcs->dpp_setup) { 731 // program the input csc 732 dpp->funcs->dpp_setup(dpp, 733 plane_state->format, 734 EXPANSION_MODE_ZERO, 735 plane_state->input_csc_color_matrix, 736 plane_state->color_space, 737 NULL); 738 } 739 } 740 741 void hwss_program_bias_and_scale(union block_sequence_params *params) 742 { 743 struct pipe_ctx *pipe_ctx = params->program_bias_and_scale_params.pipe_ctx; 744 struct dpp *dpp = pipe_ctx->plane_res.dpp; 745 struct dc_plane_state *plane_state = pipe_ctx->plane_state; 746 struct dc_bias_and_scale bns_params = {0}; 747 748 //TODO :for CNVC set scale and bias registers if necessary 749 build_prescale_params(&bns_params, plane_state); 750 if (dpp->funcs->dpp_program_bias_and_scale) 751 dpp->funcs->dpp_program_bias_and_scale(dpp, &bns_params); 752 } 753 754 void hwss_power_on_mpc_mem_pwr(union block_sequence_params *params) 755 { 756 struct mpc *mpc = params->power_on_mpc_mem_pwr_params.mpc; 757 int mpcc_id = params->power_on_mpc_mem_pwr_params.mpcc_id; 758 bool power_on = params->power_on_mpc_mem_pwr_params.power_on; 759 760 if (mpc->funcs->power_on_mpc_mem_pwr) 761 mpc->funcs->power_on_mpc_mem_pwr(mpc, mpcc_id, power_on); 762 } 763 764 void hwss_set_output_csc(union block_sequence_params *params) 765 { 766 struct mpc *mpc = params->set_output_csc_params.mpc; 767 int opp_id = params->set_output_csc_params.opp_id; 768 const uint16_t *matrix = params->set_output_csc_params.regval; 769 enum mpc_output_csc_mode ocsc_mode = params->set_output_csc_params.ocsc_mode; 770 771 if (mpc->funcs->set_output_csc != NULL) 772 mpc->funcs->set_output_csc(mpc, 773 opp_id, 774 matrix, 775 ocsc_mode); 776 } 777 778 void hwss_set_ocsc_default(union block_sequence_params *params) 779 { 780 struct mpc *mpc = params->set_ocsc_default_params.mpc; 781 int opp_id = params->set_ocsc_default_params.opp_id; 782 enum dc_color_space colorspace = params->set_ocsc_default_params.color_space; 783 enum mpc_output_csc_mode ocsc_mode = params->set_ocsc_default_params.ocsc_mode; 784 785 if (mpc->funcs->set_ocsc_default != NULL) 786 mpc->funcs->set_ocsc_default(mpc, 787 opp_id, 788 colorspace, 789 ocsc_mode); 790 } 791 792 void get_mclk_switch_visual_confirm_color( 793 struct dc *dc, 794 struct dc_state *context, 795 struct pipe_ctx *pipe_ctx, 796 struct tg_color *color) 797 { 798 uint32_t color_value = MAX_TG_COLOR_VALUE; 799 struct vba_vars_st *vba = &context->bw_ctx.dml.vba; 800 801 if (!dc->ctx || !dc->ctx->dmub_srv || !pipe_ctx || !vba || !context) 802 return; 803 804 if (vba->DRAMClockChangeSupport[vba->VoltageLevel][vba->maxMpcComb] != 805 dm_dram_clock_change_unsupported) { 806 /* MCLK switching is supported */ 807 if (!pipe_ctx->has_vactive_margin) { 808 /* In Vblank - yellow */ 809 color->color_r_cr = color_value; 810 color->color_g_y = color_value; 811 812 if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) { 813 /* FPO + Vblank - cyan */ 814 color->color_r_cr = 0; 815 color->color_g_y = color_value; 816 color->color_b_cb = color_value; 817 } 818 } else { 819 /* In Vactive - pink */ 820 color->color_r_cr = color_value; 821 color->color_b_cb = color_value; 822 } 823 /* SubVP */ 824 get_subvp_visual_confirm_color(dc, context, pipe_ctx, color); 825 } 826 } 827 828 void get_surface_tile_visual_confirm_color( 829 struct pipe_ctx *pipe_ctx, 830 struct tg_color *color) 831 { 832 uint32_t color_value = MAX_TG_COLOR_VALUE; 833 /* Determine the overscan color based on the bottom-most plane's context */ 834 struct pipe_ctx *bottom_pipe_ctx = pipe_ctx; 835 836 while (bottom_pipe_ctx->bottom_pipe != NULL) 837 bottom_pipe_ctx = bottom_pipe_ctx->bottom_pipe; 838 839 switch (bottom_pipe_ctx->plane_state->tiling_info.gfx9.swizzle) { 840 case DC_SW_LINEAR: 841 /* LINEAR Surface - set border color to red */ 842 color->color_r_cr = color_value; 843 break; 844 default: 845 break; 846 } 847 } 848