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 static enum dc_color_space_type get_color_space_type(enum dc_color_space color_space) 191 { 192 enum dc_color_space_type type = COLOR_SPACE_RGB_TYPE; 193 194 if (is_rgb_type(color_space)) 195 type = COLOR_SPACE_RGB_TYPE; 196 else if (is_rgb_limited_type(color_space)) 197 type = COLOR_SPACE_RGB_LIMITED_TYPE; 198 else if (is_ycbcr601_type(color_space)) 199 type = COLOR_SPACE_YCBCR601_TYPE; 200 else if (is_ycbcr709_type(color_space)) 201 type = COLOR_SPACE_YCBCR709_TYPE; 202 else if (is_ycbcr601_limited_type(color_space)) 203 type = COLOR_SPACE_YCBCR601_LIMITED_TYPE; 204 else if (is_ycbcr709_limited_type(color_space)) 205 type = COLOR_SPACE_YCBCR709_LIMITED_TYPE; 206 else if (is_ycbcr2020_type(color_space)) 207 type = COLOR_SPACE_YCBCR2020_TYPE; 208 else if (color_space == COLOR_SPACE_YCBCR709) 209 type = COLOR_SPACE_YCBCR709_BLACK_TYPE; 210 else if (color_space == COLOR_SPACE_YCBCR709_BLACK) 211 type = COLOR_SPACE_YCBCR709_BLACK_TYPE; 212 return type; 213 } 214 215 const uint16_t *find_color_matrix(enum dc_color_space color_space, 216 uint32_t *array_size) 217 { 218 int i; 219 enum dc_color_space_type type; 220 const uint16_t *val = NULL; 221 int arr_size = NUM_ELEMENTS(output_csc_matrix); 222 223 type = get_color_space_type(color_space); 224 for (i = 0; i < arr_size; i++) 225 if (output_csc_matrix[i].color_space_type == type) { 226 val = output_csc_matrix[i].regval; 227 *array_size = 12; 228 break; 229 } 230 231 return val; 232 } 233 234 235 void color_space_to_black_color( 236 const struct dc *dc, 237 enum dc_color_space colorspace, 238 struct tg_color *black_color) 239 { 240 switch (colorspace) { 241 case COLOR_SPACE_YCBCR601: 242 case COLOR_SPACE_YCBCR709: 243 case COLOR_SPACE_YCBCR709_BLACK: 244 case COLOR_SPACE_YCBCR601_LIMITED: 245 case COLOR_SPACE_YCBCR709_LIMITED: 246 case COLOR_SPACE_2020_YCBCR: 247 *black_color = black_color_format[BLACK_COLOR_FORMAT_YUV_CV]; 248 break; 249 250 case COLOR_SPACE_SRGB_LIMITED: 251 *black_color = 252 black_color_format[BLACK_COLOR_FORMAT_RGB_LIMITED]; 253 break; 254 255 /** 256 * Remove default and add case for all color space 257 * so when we forget to add new color space 258 * compiler will give a warning 259 */ 260 case COLOR_SPACE_UNKNOWN: 261 case COLOR_SPACE_SRGB: 262 case COLOR_SPACE_XR_RGB: 263 case COLOR_SPACE_MSREF_SCRGB: 264 case COLOR_SPACE_XV_YCC_709: 265 case COLOR_SPACE_XV_YCC_601: 266 case COLOR_SPACE_2020_RGB_FULLRANGE: 267 case COLOR_SPACE_2020_RGB_LIMITEDRANGE: 268 case COLOR_SPACE_ADOBERGB: 269 case COLOR_SPACE_DCIP3: 270 case COLOR_SPACE_DISPLAYNATIVE: 271 case COLOR_SPACE_DOLBYVISION: 272 case COLOR_SPACE_APPCTRL: 273 case COLOR_SPACE_CUSTOMPOINTS: 274 /* fefault is sRGB black (full range). */ 275 *black_color = 276 black_color_format[BLACK_COLOR_FORMAT_RGB_FULLRANGE]; 277 /* default is sRGB black 0. */ 278 break; 279 } 280 } 281 282 bool hwss_wait_for_blank_complete( 283 struct timing_generator *tg) 284 { 285 int counter; 286 287 /* Not applicable if the pipe is not primary, save 300ms of boot time */ 288 if (!tg->funcs->is_blanked) 289 return true; 290 for (counter = 0; counter < 100; counter++) { 291 if (tg->funcs->is_blanked(tg)) 292 break; 293 294 msleep(1); 295 } 296 297 if (counter == 100) { 298 dm_error("DC: failed to blank crtc!\n"); 299 return false; 300 } 301 302 return true; 303 } 304 305 void get_mpctree_visual_confirm_color( 306 struct pipe_ctx *pipe_ctx, 307 struct tg_color *color) 308 { 309 const struct tg_color pipe_colors[6] = { 310 {MAX_TG_COLOR_VALUE, 0, 0}, /* red */ 311 {MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE / 4, 0}, /* orange */ 312 {MAX_TG_COLOR_VALUE, MAX_TG_COLOR_VALUE, 0}, /* yellow */ 313 {0, MAX_TG_COLOR_VALUE, 0}, /* green */ 314 {0, 0, MAX_TG_COLOR_VALUE}, /* blue */ 315 {MAX_TG_COLOR_VALUE / 2, 0, MAX_TG_COLOR_VALUE / 2}, /* purple */ 316 }; 317 318 struct pipe_ctx *top_pipe = pipe_ctx; 319 320 while (top_pipe->top_pipe) 321 top_pipe = top_pipe->top_pipe; 322 323 *color = pipe_colors[top_pipe->pipe_idx]; 324 } 325 326 void get_surface_visual_confirm_color( 327 const struct pipe_ctx *pipe_ctx, 328 struct tg_color *color) 329 { 330 uint32_t color_value = MAX_TG_COLOR_VALUE; 331 332 switch (pipe_ctx->plane_res.scl_data.format) { 333 case PIXEL_FORMAT_ARGB8888: 334 /* set border color to red */ 335 color->color_r_cr = color_value; 336 if (pipe_ctx->plane_state->layer_index > 0) { 337 /* set border color to pink */ 338 color->color_b_cb = color_value; 339 color->color_g_y = color_value * 0.5; 340 } 341 break; 342 343 case PIXEL_FORMAT_ARGB2101010: 344 /* set border color to blue */ 345 color->color_b_cb = color_value; 346 if (pipe_ctx->plane_state->layer_index > 0) { 347 /* set border color to cyan */ 348 color->color_g_y = color_value; 349 } 350 break; 351 case PIXEL_FORMAT_420BPP8: 352 /* set border color to green */ 353 color->color_g_y = color_value; 354 break; 355 case PIXEL_FORMAT_420BPP10: 356 /* set border color to yellow */ 357 color->color_g_y = color_value; 358 color->color_r_cr = color_value; 359 break; 360 case PIXEL_FORMAT_FP16: 361 /* set border color to white */ 362 color->color_r_cr = color_value; 363 color->color_b_cb = color_value; 364 color->color_g_y = color_value; 365 if (pipe_ctx->plane_state->layer_index > 0) { 366 /* set border color to orange */ 367 color->color_g_y = 0.22 * color_value; 368 color->color_b_cb = 0; 369 } 370 break; 371 default: 372 break; 373 } 374 } 375 376 void get_hdr_visual_confirm_color( 377 struct pipe_ctx *pipe_ctx, 378 struct tg_color *color) 379 { 380 uint32_t color_value = MAX_TG_COLOR_VALUE; 381 bool is_sdr = false; 382 383 /* Determine the overscan color based on the top-most (desktop) plane's context */ 384 struct pipe_ctx *top_pipe_ctx = pipe_ctx; 385 386 while (top_pipe_ctx->top_pipe != NULL) 387 top_pipe_ctx = top_pipe_ctx->top_pipe; 388 389 switch (top_pipe_ctx->plane_res.scl_data.format) { 390 case PIXEL_FORMAT_ARGB2101010: 391 if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_PQ) { 392 /* HDR10, ARGB2101010 - set border color to red */ 393 color->color_r_cr = color_value; 394 } else if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_GAMMA22) { 395 /* FreeSync 2 ARGB2101010 - set border color to pink */ 396 color->color_r_cr = color_value; 397 color->color_b_cb = color_value; 398 } else 399 is_sdr = true; 400 break; 401 case PIXEL_FORMAT_FP16: 402 if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_PQ) { 403 /* HDR10, FP16 - set border color to blue */ 404 color->color_b_cb = color_value; 405 } else if (top_pipe_ctx->stream->out_transfer_func->tf == TRANSFER_FUNCTION_GAMMA22) { 406 /* FreeSync 2 HDR - set border color to green */ 407 color->color_g_y = color_value; 408 } else 409 is_sdr = true; 410 break; 411 default: 412 is_sdr = true; 413 break; 414 } 415 416 if (is_sdr) { 417 /* SDR - set border color to Gray */ 418 color->color_r_cr = color_value/2; 419 color->color_b_cb = color_value/2; 420 color->color_g_y = color_value/2; 421 } 422 } 423 424 void get_subvp_visual_confirm_color( 425 struct dc *dc, 426 struct dc_state *context, 427 struct pipe_ctx *pipe_ctx, 428 struct tg_color *color) 429 { 430 uint32_t color_value = MAX_TG_COLOR_VALUE; 431 bool enable_subvp = false; 432 int i; 433 434 if (!dc->ctx || !dc->ctx->dmub_srv || !pipe_ctx || !context) 435 return; 436 437 for (i = 0; i < dc->res_pool->pipe_count; i++) { 438 struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; 439 440 if (pipe->stream && pipe->stream->mall_stream_config.paired_stream && 441 pipe->stream->mall_stream_config.type == SUBVP_MAIN) { 442 /* SubVP enable - red */ 443 color->color_g_y = 0; 444 color->color_b_cb = 0; 445 color->color_r_cr = color_value; 446 enable_subvp = true; 447 448 if (pipe_ctx->stream == pipe->stream) 449 return; 450 break; 451 } 452 } 453 454 if (enable_subvp && pipe_ctx->stream->mall_stream_config.type == SUBVP_NONE) { 455 color->color_r_cr = 0; 456 if (pipe_ctx->stream->allow_freesync == 1) { 457 /* SubVP enable and DRR on - green */ 458 color->color_b_cb = 0; 459 color->color_g_y = color_value; 460 } else { 461 /* SubVP enable and No DRR - blue */ 462 color->color_g_y = 0; 463 color->color_b_cb = color_value; 464 } 465 } 466 } 467 468 void hwss_build_fast_sequence(struct dc *dc, 469 struct dc_dmub_cmd *dc_dmub_cmd, 470 unsigned int dmub_cmd_count, 471 struct block_sequence block_sequence[], 472 int *num_steps, 473 struct pipe_ctx *pipe_ctx) 474 { 475 struct dc_plane_state *plane = pipe_ctx->plane_state; 476 struct dc_stream_state *stream = pipe_ctx->stream; 477 struct dce_hwseq *hws = dc->hwseq; 478 struct pipe_ctx *current_pipe = NULL; 479 struct pipe_ctx *current_mpc_pipe = NULL; 480 unsigned int i = 0; 481 482 *num_steps = 0; // Initialize to 0 483 484 if (!plane || !stream) 485 return; 486 487 if (dc->hwss.subvp_pipe_control_lock_fast) { 488 block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.dc = dc; 489 block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.lock = true; 490 block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.pipe_ctx = pipe_ctx; 491 block_sequence[*num_steps].func = DMUB_SUBVP_PIPE_CONTROL_LOCK_FAST; 492 (*num_steps)++; 493 } 494 if (dc->hwss.pipe_control_lock) { 495 block_sequence[*num_steps].params.pipe_control_lock_params.dc = dc; 496 block_sequence[*num_steps].params.pipe_control_lock_params.lock = true; 497 block_sequence[*num_steps].params.pipe_control_lock_params.pipe_ctx = pipe_ctx; 498 block_sequence[*num_steps].func = OPTC_PIPE_CONTROL_LOCK; 499 (*num_steps)++; 500 } 501 502 for (i = 0; i < dmub_cmd_count; i++) { 503 block_sequence[*num_steps].params.send_dmcub_cmd_params.ctx = dc->ctx; 504 block_sequence[*num_steps].params.send_dmcub_cmd_params.cmd = &(dc_dmub_cmd[i].dmub_cmd); 505 block_sequence[*num_steps].params.send_dmcub_cmd_params.wait_type = dc_dmub_cmd[i].wait_type; 506 block_sequence[*num_steps].func = DMUB_SEND_DMCUB_CMD; 507 (*num_steps)++; 508 } 509 510 current_pipe = pipe_ctx; 511 while (current_pipe) { 512 current_mpc_pipe = current_pipe; 513 while (current_mpc_pipe) { 514 if (dc->hwss.set_flip_control_gsl && current_mpc_pipe->plane_state && current_mpc_pipe->plane_state->update_flags.raw) { 515 block_sequence[*num_steps].params.set_flip_control_gsl_params.pipe_ctx = current_mpc_pipe; 516 block_sequence[*num_steps].params.set_flip_control_gsl_params.flip_immediate = current_mpc_pipe->plane_state->flip_immediate; 517 block_sequence[*num_steps].func = HUBP_SET_FLIP_CONTROL_GSL; 518 (*num_steps)++; 519 } 520 if (dc->hwss.program_triplebuffer && dc->debug.enable_tri_buf && current_mpc_pipe->plane_state->update_flags.raw) { 521 block_sequence[*num_steps].params.program_triplebuffer_params.dc = dc; 522 block_sequence[*num_steps].params.program_triplebuffer_params.pipe_ctx = current_mpc_pipe; 523 block_sequence[*num_steps].params.program_triplebuffer_params.enableTripleBuffer = current_mpc_pipe->plane_state->triplebuffer_flips; 524 block_sequence[*num_steps].func = HUBP_PROGRAM_TRIPLEBUFFER; 525 (*num_steps)++; 526 } 527 if (dc->hwss.update_plane_addr && current_mpc_pipe->plane_state->update_flags.bits.addr_update) { 528 block_sequence[*num_steps].params.update_plane_addr_params.dc = dc; 529 block_sequence[*num_steps].params.update_plane_addr_params.pipe_ctx = current_mpc_pipe; 530 block_sequence[*num_steps].func = HUBP_UPDATE_PLANE_ADDR; 531 (*num_steps)++; 532 } 533 534 if (hws->funcs.set_input_transfer_func && current_mpc_pipe->plane_state->update_flags.bits.gamma_change) { 535 block_sequence[*num_steps].params.set_input_transfer_func_params.dc = dc; 536 block_sequence[*num_steps].params.set_input_transfer_func_params.pipe_ctx = current_mpc_pipe; 537 block_sequence[*num_steps].params.set_input_transfer_func_params.plane_state = current_mpc_pipe->plane_state; 538 block_sequence[*num_steps].func = DPP_SET_INPUT_TRANSFER_FUNC; 539 (*num_steps)++; 540 } 541 542 if (dc->hwss.program_gamut_remap && current_mpc_pipe->plane_state->update_flags.bits.gamut_remap_change) { 543 block_sequence[*num_steps].params.program_gamut_remap_params.pipe_ctx = current_mpc_pipe; 544 block_sequence[*num_steps].func = DPP_PROGRAM_GAMUT_REMAP; 545 (*num_steps)++; 546 } 547 if (current_mpc_pipe->plane_state->update_flags.bits.input_csc_change) { 548 block_sequence[*num_steps].params.setup_dpp_params.pipe_ctx = current_mpc_pipe; 549 block_sequence[*num_steps].func = DPP_SETUP_DPP; 550 (*num_steps)++; 551 } 552 if (current_mpc_pipe->plane_state->update_flags.bits.coeff_reduction_change) { 553 block_sequence[*num_steps].params.program_bias_and_scale_params.pipe_ctx = current_mpc_pipe; 554 block_sequence[*num_steps].func = DPP_PROGRAM_BIAS_AND_SCALE; 555 (*num_steps)++; 556 } 557 if (hws->funcs.set_output_transfer_func && current_mpc_pipe->stream->update_flags.bits.out_tf) { 558 block_sequence[*num_steps].params.set_output_transfer_func_params.dc = dc; 559 block_sequence[*num_steps].params.set_output_transfer_func_params.pipe_ctx = current_mpc_pipe; 560 block_sequence[*num_steps].params.set_output_transfer_func_params.stream = current_mpc_pipe->stream; 561 block_sequence[*num_steps].func = DPP_SET_OUTPUT_TRANSFER_FUNC; 562 (*num_steps)++; 563 } 564 565 if (current_mpc_pipe->stream->update_flags.bits.out_csc) { 566 block_sequence[*num_steps].params.power_on_mpc_mem_pwr_params.mpc = dc->res_pool->mpc; 567 block_sequence[*num_steps].params.power_on_mpc_mem_pwr_params.mpcc_id = current_mpc_pipe->plane_res.hubp->inst; 568 block_sequence[*num_steps].params.power_on_mpc_mem_pwr_params.power_on = true; 569 block_sequence[*num_steps].func = MPC_POWER_ON_MPC_MEM_PWR; 570 (*num_steps)++; 571 572 if (current_mpc_pipe->stream->csc_color_matrix.enable_adjustment == true) { 573 block_sequence[*num_steps].params.set_output_csc_params.mpc = dc->res_pool->mpc; 574 block_sequence[*num_steps].params.set_output_csc_params.opp_id = current_mpc_pipe->stream_res.opp->inst; 575 block_sequence[*num_steps].params.set_output_csc_params.regval = current_mpc_pipe->stream->csc_color_matrix.matrix; 576 block_sequence[*num_steps].params.set_output_csc_params.ocsc_mode = MPC_OUTPUT_CSC_COEF_A; 577 block_sequence[*num_steps].func = MPC_SET_OUTPUT_CSC; 578 (*num_steps)++; 579 } else { 580 block_sequence[*num_steps].params.set_ocsc_default_params.mpc = dc->res_pool->mpc; 581 block_sequence[*num_steps].params.set_ocsc_default_params.opp_id = current_mpc_pipe->stream_res.opp->inst; 582 block_sequence[*num_steps].params.set_ocsc_default_params.color_space = current_mpc_pipe->stream->output_color_space; 583 block_sequence[*num_steps].params.set_ocsc_default_params.ocsc_mode = MPC_OUTPUT_CSC_COEF_A; 584 block_sequence[*num_steps].func = MPC_SET_OCSC_DEFAULT; 585 (*num_steps)++; 586 } 587 } 588 current_mpc_pipe = current_mpc_pipe->bottom_pipe; 589 } 590 current_pipe = current_pipe->next_odm_pipe; 591 } 592 593 if (dc->hwss.pipe_control_lock) { 594 block_sequence[*num_steps].params.pipe_control_lock_params.dc = dc; 595 block_sequence[*num_steps].params.pipe_control_lock_params.lock = false; 596 block_sequence[*num_steps].params.pipe_control_lock_params.pipe_ctx = pipe_ctx; 597 block_sequence[*num_steps].func = OPTC_PIPE_CONTROL_LOCK; 598 (*num_steps)++; 599 } 600 if (dc->hwss.subvp_pipe_control_lock_fast) { 601 block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.dc = dc; 602 block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.lock = false; 603 block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.pipe_ctx = pipe_ctx; 604 block_sequence[*num_steps].func = DMUB_SUBVP_PIPE_CONTROL_LOCK_FAST; 605 (*num_steps)++; 606 } 607 608 current_pipe = pipe_ctx; 609 while (current_pipe) { 610 current_mpc_pipe = current_pipe; 611 612 while (current_mpc_pipe) { 613 if (!current_mpc_pipe->bottom_pipe && !current_mpc_pipe->next_odm_pipe && 614 current_mpc_pipe->stream && current_mpc_pipe->plane_state && 615 current_mpc_pipe->plane_state->update_flags.bits.addr_update && 616 !current_mpc_pipe->plane_state->skip_manual_trigger) { 617 block_sequence[*num_steps].params.program_manual_trigger_params.pipe_ctx = current_mpc_pipe; 618 block_sequence[*num_steps].func = OPTC_PROGRAM_MANUAL_TRIGGER; 619 (*num_steps)++; 620 } 621 current_mpc_pipe = current_mpc_pipe->bottom_pipe; 622 } 623 current_pipe = current_pipe->next_odm_pipe; 624 } 625 } 626 627 void hwss_execute_sequence(struct dc *dc, 628 struct block_sequence block_sequence[], 629 int num_steps) 630 { 631 unsigned int i; 632 union block_sequence_params *params; 633 struct dce_hwseq *hws = dc->hwseq; 634 635 for (i = 0; i < num_steps; i++) { 636 params = &(block_sequence[i].params); 637 switch (block_sequence[i].func) { 638 639 case DMUB_SUBVP_PIPE_CONTROL_LOCK_FAST: 640 dc->hwss.subvp_pipe_control_lock_fast(params); 641 break; 642 case OPTC_PIPE_CONTROL_LOCK: 643 dc->hwss.pipe_control_lock(params->pipe_control_lock_params.dc, 644 params->pipe_control_lock_params.pipe_ctx, 645 params->pipe_control_lock_params.lock); 646 break; 647 case HUBP_SET_FLIP_CONTROL_GSL: 648 dc->hwss.set_flip_control_gsl(params->set_flip_control_gsl_params.pipe_ctx, 649 params->set_flip_control_gsl_params.flip_immediate); 650 break; 651 case HUBP_PROGRAM_TRIPLEBUFFER: 652 dc->hwss.program_triplebuffer(params->program_triplebuffer_params.dc, 653 params->program_triplebuffer_params.pipe_ctx, 654 params->program_triplebuffer_params.enableTripleBuffer); 655 break; 656 case HUBP_UPDATE_PLANE_ADDR: 657 dc->hwss.update_plane_addr(params->update_plane_addr_params.dc, 658 params->update_plane_addr_params.pipe_ctx); 659 break; 660 case DPP_SET_INPUT_TRANSFER_FUNC: 661 hws->funcs.set_input_transfer_func(params->set_input_transfer_func_params.dc, 662 params->set_input_transfer_func_params.pipe_ctx, 663 params->set_input_transfer_func_params.plane_state); 664 break; 665 case DPP_PROGRAM_GAMUT_REMAP: 666 dc->hwss.program_gamut_remap(params->program_gamut_remap_params.pipe_ctx); 667 break; 668 case DPP_SETUP_DPP: 669 hwss_setup_dpp(params); 670 break; 671 case DPP_PROGRAM_BIAS_AND_SCALE: 672 hwss_program_bias_and_scale(params); 673 break; 674 case OPTC_PROGRAM_MANUAL_TRIGGER: 675 hwss_program_manual_trigger(params); 676 break; 677 case DPP_SET_OUTPUT_TRANSFER_FUNC: 678 hws->funcs.set_output_transfer_func(params->set_output_transfer_func_params.dc, 679 params->set_output_transfer_func_params.pipe_ctx, 680 params->set_output_transfer_func_params.stream); 681 break; 682 case MPC_UPDATE_VISUAL_CONFIRM: 683 dc->hwss.update_visual_confirm_color(params->update_visual_confirm_params.dc, 684 params->update_visual_confirm_params.pipe_ctx, 685 params->update_visual_confirm_params.mpcc_id); 686 break; 687 case MPC_POWER_ON_MPC_MEM_PWR: 688 hwss_power_on_mpc_mem_pwr(params); 689 break; 690 case MPC_SET_OUTPUT_CSC: 691 hwss_set_output_csc(params); 692 break; 693 case MPC_SET_OCSC_DEFAULT: 694 hwss_set_ocsc_default(params); 695 break; 696 case DMUB_SEND_DMCUB_CMD: 697 hwss_send_dmcub_cmd(params); 698 break; 699 default: 700 ASSERT(false); 701 break; 702 } 703 } 704 } 705 706 void hwss_send_dmcub_cmd(union block_sequence_params *params) 707 { 708 struct dc_context *ctx = params->send_dmcub_cmd_params.ctx; 709 union dmub_rb_cmd *cmd = params->send_dmcub_cmd_params.cmd; 710 enum dm_dmub_wait_type wait_type = params->send_dmcub_cmd_params.wait_type; 711 712 dm_execute_dmub_cmd(ctx, cmd, wait_type); 713 } 714 715 void hwss_program_manual_trigger(union block_sequence_params *params) 716 { 717 struct pipe_ctx *pipe_ctx = params->program_manual_trigger_params.pipe_ctx; 718 719 if (pipe_ctx->stream_res.tg->funcs->program_manual_trigger) 720 pipe_ctx->stream_res.tg->funcs->program_manual_trigger(pipe_ctx->stream_res.tg); 721 } 722 723 void hwss_setup_dpp(union block_sequence_params *params) 724 { 725 struct pipe_ctx *pipe_ctx = params->setup_dpp_params.pipe_ctx; 726 struct dpp *dpp = pipe_ctx->plane_res.dpp; 727 struct dc_plane_state *plane_state = pipe_ctx->plane_state; 728 729 if (dpp && dpp->funcs->dpp_setup) { 730 // program the input csc 731 dpp->funcs->dpp_setup(dpp, 732 plane_state->format, 733 EXPANSION_MODE_ZERO, 734 plane_state->input_csc_color_matrix, 735 plane_state->color_space, 736 NULL); 737 } 738 } 739 740 void hwss_program_bias_and_scale(union block_sequence_params *params) 741 { 742 struct pipe_ctx *pipe_ctx = params->program_bias_and_scale_params.pipe_ctx; 743 struct dpp *dpp = pipe_ctx->plane_res.dpp; 744 struct dc_plane_state *plane_state = pipe_ctx->plane_state; 745 struct dc_bias_and_scale bns_params = {0}; 746 747 //TODO :for CNVC set scale and bias registers if necessary 748 build_prescale_params(&bns_params, plane_state); 749 if (dpp->funcs->dpp_program_bias_and_scale) 750 dpp->funcs->dpp_program_bias_and_scale(dpp, &bns_params); 751 } 752 753 void hwss_power_on_mpc_mem_pwr(union block_sequence_params *params) 754 { 755 struct mpc *mpc = params->power_on_mpc_mem_pwr_params.mpc; 756 int mpcc_id = params->power_on_mpc_mem_pwr_params.mpcc_id; 757 bool power_on = params->power_on_mpc_mem_pwr_params.power_on; 758 759 if (mpc->funcs->power_on_mpc_mem_pwr) 760 mpc->funcs->power_on_mpc_mem_pwr(mpc, mpcc_id, power_on); 761 } 762 763 void hwss_set_output_csc(union block_sequence_params *params) 764 { 765 struct mpc *mpc = params->set_output_csc_params.mpc; 766 int opp_id = params->set_output_csc_params.opp_id; 767 const uint16_t *matrix = params->set_output_csc_params.regval; 768 enum mpc_output_csc_mode ocsc_mode = params->set_output_csc_params.ocsc_mode; 769 770 if (mpc->funcs->set_output_csc != NULL) 771 mpc->funcs->set_output_csc(mpc, 772 opp_id, 773 matrix, 774 ocsc_mode); 775 } 776 777 void hwss_set_ocsc_default(union block_sequence_params *params) 778 { 779 struct mpc *mpc = params->set_ocsc_default_params.mpc; 780 int opp_id = params->set_ocsc_default_params.opp_id; 781 enum dc_color_space colorspace = params->set_ocsc_default_params.color_space; 782 enum mpc_output_csc_mode ocsc_mode = params->set_ocsc_default_params.ocsc_mode; 783 784 if (mpc->funcs->set_ocsc_default != NULL) 785 mpc->funcs->set_ocsc_default(mpc, 786 opp_id, 787 colorspace, 788 ocsc_mode); 789 } 790 791 void get_mclk_switch_visual_confirm_color( 792 struct dc *dc, 793 struct dc_state *context, 794 struct pipe_ctx *pipe_ctx, 795 struct tg_color *color) 796 { 797 uint32_t color_value = MAX_TG_COLOR_VALUE; 798 struct vba_vars_st *vba = &context->bw_ctx.dml.vba; 799 800 if (!dc->ctx || !dc->ctx->dmub_srv || !pipe_ctx || !vba || !context) 801 return; 802 803 if (vba->DRAMClockChangeSupport[vba->VoltageLevel][vba->maxMpcComb] != 804 dm_dram_clock_change_unsupported) { 805 /* MCLK switching is supported */ 806 if (!pipe_ctx->has_vactive_margin) { 807 /* In Vblank - yellow */ 808 color->color_r_cr = color_value; 809 color->color_g_y = color_value; 810 811 if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) { 812 /* FPO + Vblank - cyan */ 813 color->color_r_cr = 0; 814 color->color_g_y = color_value; 815 color->color_b_cb = color_value; 816 } 817 } else { 818 /* In Vactive - pink */ 819 color->color_r_cr = color_value; 820 color->color_b_cb = color_value; 821 } 822 /* SubVP */ 823 get_subvp_visual_confirm_color(dc, context, pipe_ctx, color); 824 } 825 } 826 827 void get_surface_tile_visual_confirm_color( 828 struct pipe_ctx *pipe_ctx, 829 struct tg_color *color) 830 { 831 uint32_t color_value = MAX_TG_COLOR_VALUE; 832 /* Determine the overscan color based on the bottom-most plane's context */ 833 struct pipe_ctx *bottom_pipe_ctx = pipe_ctx; 834 835 while (bottom_pipe_ctx->bottom_pipe != NULL) 836 bottom_pipe_ctx = bottom_pipe_ctx->bottom_pipe; 837 838 switch (bottom_pipe_ctx->plane_state->tiling_info.gfx9.swizzle) { 839 case DC_SW_LINEAR: 840 /* LINEAR Surface - set border color to red */ 841 color->color_r_cr = color_value; 842 break; 843 default: 844 break; 845 } 846 } 847