Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/amd/display: Refactor fast update to use new HWSS build sequence

[Description]
- Refactor HW sequencer to use a build / execute sequence
- Also move gamma updates to become fast

v2: squash in build fix ("drm/amd/display: Fix guarding of 'if (dc->debug.visual_confirm)'")

Acked-by: Stylon Wang <stylon.wang@amd.com>
Signed-off-by: Alvin Lee <alvin.lee2@amd.com>
Reviewed-by: Jun Lei <jun.lei@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Alvin Lee and committed by
Alex Deucher
0baae624 49f26218

+693 -30
+244 -30
drivers/gpu/drm/amd/display/dc/core/dc.c
··· 2589 2589 elevate_update_type(&overall_type, type); 2590 2590 } 2591 2591 2592 - if (update_flags->bits.input_csc_change 2593 - || update_flags->bits.coeff_reduction_change 2594 - || update_flags->bits.lut_3d 2595 - || update_flags->bits.gamma_change 2596 - || update_flags->bits.gamut_remap_change) { 2592 + if (update_flags->bits.lut_3d) { 2597 2593 type = UPDATE_TYPE_FULL; 2598 2594 elevate_update_type(&overall_type, type); 2599 2595 } 2600 2596 2597 + if (dc->debug.enable_legacy_fast_update && 2598 + (update_flags->bits.gamma_change || 2599 + update_flags->bits.gamut_remap_change || 2600 + update_flags->bits.input_csc_change || 2601 + update_flags->bits.coeff_reduction_change)) { 2602 + type = UPDATE_TYPE_FULL; 2603 + elevate_update_type(&overall_type, type); 2604 + } 2601 2605 return overall_type; 2602 2606 } 2603 2607 ··· 2634 2630 stream_update->integer_scaling_update) 2635 2631 su_flags->bits.scaling = 1; 2636 2632 2637 - if (stream_update->out_transfer_func) 2633 + if (dc->debug.enable_legacy_fast_update && stream_update->out_transfer_func) 2638 2634 su_flags->bits.out_tf = 1; 2639 2635 2640 2636 if (stream_update->abm_level) ··· 2665 2661 2666 2662 if (stream_update->output_csc_transform || stream_update->output_color_space) 2667 2663 su_flags->bits.out_csc = 1; 2664 + 2665 + /* Output transfer function changes do not require bandwidth recalculation, 2666 + * so don't trigger a full update 2667 + */ 2668 + if (!dc->debug.enable_legacy_fast_update && stream_update->out_transfer_func) 2669 + su_flags->bits.out_tf = 1; 2668 2670 } 2669 2671 2670 2672 for (i = 0 ; i < surface_count; i++) { ··· 3422 3412 } 3423 3413 } 3424 3414 3415 + static void build_dmub_update_dirty_rect( 3416 + struct dc *dc, 3417 + int surface_count, 3418 + struct dc_stream_state *stream, 3419 + struct dc_surface_update *srf_updates, 3420 + struct dc_state *context, 3421 + struct dc_dmub_cmd dc_dmub_cmd[], 3422 + unsigned int *dmub_cmd_count) 3423 + { 3424 + union dmub_rb_cmd cmd; 3425 + struct dmub_cmd_update_dirty_rect_data *update_dirty_rect; 3426 + unsigned int i, j; 3427 + unsigned int panel_inst = 0; 3428 + 3429 + if (!dc_dmub_should_send_dirty_rect_cmd(dc, stream)) 3430 + return; 3431 + 3432 + if (!dc_get_edp_link_panel_inst(dc, stream->link, &panel_inst)) 3433 + return; 3434 + 3435 + memset(&cmd, 0x0, sizeof(cmd)); 3436 + cmd.update_dirty_rect.header.type = DMUB_CMD__UPDATE_DIRTY_RECT; 3437 + cmd.update_dirty_rect.header.sub_type = 0; 3438 + cmd.update_dirty_rect.header.payload_bytes = 3439 + sizeof(cmd.update_dirty_rect) - 3440 + sizeof(cmd.update_dirty_rect.header); 3441 + update_dirty_rect = &cmd.update_dirty_rect.update_dirty_rect_data; 3442 + for (i = 0; i < surface_count; i++) { 3443 + struct dc_plane_state *plane_state = srf_updates[i].surface; 3444 + const struct dc_flip_addrs *flip_addr = srf_updates[i].flip_addr; 3445 + 3446 + if (!srf_updates[i].surface || !flip_addr) 3447 + continue; 3448 + /* Do not send in immediate flip mode */ 3449 + if (srf_updates[i].surface->flip_immediate) 3450 + continue; 3451 + update_dirty_rect->cmd_version = DMUB_CMD_PSR_CONTROL_VERSION_1; 3452 + update_dirty_rect->dirty_rect_count = flip_addr->dirty_rect_count; 3453 + memcpy(update_dirty_rect->src_dirty_rects, flip_addr->dirty_rects, 3454 + sizeof(flip_addr->dirty_rects)); 3455 + for (j = 0; j < dc->res_pool->pipe_count; j++) { 3456 + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; 3457 + 3458 + if (pipe_ctx->stream != stream) 3459 + continue; 3460 + if (pipe_ctx->plane_state != plane_state) 3461 + continue; 3462 + update_dirty_rect->panel_inst = panel_inst; 3463 + update_dirty_rect->pipe_idx = j; 3464 + dc_dmub_cmd[*dmub_cmd_count].dmub_cmd = cmd; 3465 + dc_dmub_cmd[*dmub_cmd_count].wait_type = DM_DMUB_WAIT_TYPE_NO_WAIT; 3466 + (*dmub_cmd_count)++; 3467 + } 3468 + } 3469 + } 3470 + 3471 + 3472 + /** 3473 + * ************************************************************************************************ 3474 + * build_dmub_cmd_list: Build an array of DMCUB commands to be sent to DMCUB 3475 + * 3476 + * @param [in]: dc: Current DC state 3477 + * @param [in]: srf_updates: Array of surface updates 3478 + * @param [in]: surface_count: Number of surfaces that have an updated 3479 + * @param [in]: stream: Correponding stream to be updated in the current flip 3480 + * @param [in]: context: New DC state to be programmed 3481 + * 3482 + * @param [out]: dc_dmub_cmd: Array of DMCUB commands to be sent to DMCUB 3483 + * @param [out]: dmub_cmd_count: Count indicating the number of DMCUB commands in dc_dmub_cmd array 3484 + * 3485 + * This function builds an array of DMCUB commands to be sent to DMCUB. This function is required 3486 + * to build an array of commands and have them sent while the OTG lock is acquired. 3487 + * 3488 + * @return: void 3489 + * ************************************************************************************************ 3490 + */ 3491 + static void build_dmub_cmd_list(struct dc *dc, 3492 + struct dc_surface_update *srf_updates, 3493 + int surface_count, 3494 + struct dc_stream_state *stream, 3495 + struct dc_state *context, 3496 + struct dc_dmub_cmd dc_dmub_cmd[], 3497 + unsigned int *dmub_cmd_count) 3498 + { 3499 + // Initialize cmd count to 0 3500 + *dmub_cmd_count = 0; 3501 + build_dmub_update_dirty_rect(dc, surface_count, stream, srf_updates, context, dc_dmub_cmd, dmub_cmd_count); 3502 + } 3503 + 3504 + static void commit_planes_for_stream_fast(struct dc *dc, 3505 + struct dc_surface_update *srf_updates, 3506 + int surface_count, 3507 + struct dc_stream_state *stream, 3508 + struct dc_stream_update *stream_update, 3509 + enum surface_update_type update_type, 3510 + struct dc_state *context) 3511 + { 3512 + int i, j; 3513 + struct pipe_ctx *top_pipe_to_program = NULL; 3514 + bool should_lock_all_pipes = (update_type != UPDATE_TYPE_FAST); 3515 + dc_z10_restore(dc); 3516 + 3517 + for (j = 0; j < dc->res_pool->pipe_count; j++) { 3518 + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; 3519 + 3520 + if (!pipe_ctx->top_pipe && 3521 + !pipe_ctx->prev_odm_pipe && 3522 + pipe_ctx->stream && 3523 + pipe_ctx->stream == stream) { 3524 + top_pipe_to_program = pipe_ctx; 3525 + } 3526 + } 3527 + 3528 + if (dc->debug.visual_confirm) { 3529 + for (i = 0; i < dc->res_pool->pipe_count; i++) { 3530 + struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; 3531 + 3532 + if (pipe->stream && pipe->plane_state) 3533 + dc_update_viusal_confirm_color(dc, context, pipe); 3534 + } 3535 + } 3536 + 3537 + for (i = 0; i < surface_count; i++) { 3538 + struct dc_plane_state *plane_state = srf_updates[i].surface; 3539 + /*set logical flag for lock/unlock use*/ 3540 + for (j = 0; j < dc->res_pool->pipe_count; j++) { 3541 + struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; 3542 + 3543 + if (!pipe_ctx->plane_state) 3544 + continue; 3545 + if (should_update_pipe_for_plane(context, pipe_ctx, plane_state)) 3546 + continue; 3547 + pipe_ctx->plane_state->triplebuffer_flips = false; 3548 + if (update_type == UPDATE_TYPE_FAST && 3549 + dc->hwss.program_triplebuffer && 3550 + !pipe_ctx->plane_state->flip_immediate && dc->debug.enable_tri_buf) { 3551 + /*triple buffer for VUpdate only*/ 3552 + pipe_ctx->plane_state->triplebuffer_flips = true; 3553 + } 3554 + } 3555 + } 3556 + 3557 + build_dmub_cmd_list(dc, 3558 + srf_updates, 3559 + surface_count, 3560 + stream, 3561 + context, 3562 + context->dc_dmub_cmd, 3563 + &(context->dmub_cmd_count)); 3564 + hwss_build_fast_sequence(dc, 3565 + context->dc_dmub_cmd, 3566 + context->dmub_cmd_count, 3567 + context->block_sequence, 3568 + &(context->block_sequence_steps), 3569 + top_pipe_to_program); 3570 + hwss_execute_sequence(dc, 3571 + context->block_sequence, 3572 + context->block_sequence_steps); 3573 + } 3574 + 3425 3575 static void commit_planes_for_stream(struct dc *dc, 3426 3576 struct dc_surface_update *srf_updates, 3427 3577 int surface_count, ··· 3616 3446 3617 3447 if (pipe_ctx->stream_res.tg->funcs->wait_drr_doublebuffer_pending_clear) 3618 3448 pipe_ctx->stream_res.tg->funcs->wait_drr_doublebuffer_pending_clear(pipe_ctx->stream_res.tg); 3619 - } 3620 - } 3621 - 3622 - if (get_seamless_boot_stream_count(context) > 0 && surface_count > 0) { 3623 - /* Optimize seamless boot flag keeps clocks and watermarks high until 3624 - * first flip. After first flip, optimization is required to lower 3625 - * bandwidth. Important to note that it is expected UEFI will 3626 - * only light up a single display on POST, therefore we only expect 3627 - * one stream with seamless boot flag set. 3628 - */ 3629 - if (stream->apply_seamless_boot_optimization) { 3630 - stream->apply_seamless_boot_optimization = false; 3631 - 3632 - if (get_seamless_boot_stream_count(context) == 0) 3633 - dc->optimized_required = true; 3634 3449 } 3635 3450 } 3636 3451 ··· 4201 4046 return true; 4202 4047 } 4203 4048 4049 + /** 4050 + * ******************************************************************************* 4051 + * update_seamless_boot_flags: Helper function for updating seamless boot flags 4052 + * 4053 + * @param [in]: dc: Current DC state 4054 + * @param [in]: context: New DC state to be programmed 4055 + * @param [in]: surface_count: Number of surfaces that have an updated 4056 + * @param [in]: stream: Correponding stream to be updated in the current flip 4057 + * 4058 + * Updating seamless boot flags do not need to be part of the commit sequence. This 4059 + * helper function will update the seamless boot flags on each flip (if required) 4060 + * outside of the HW commit sequence (fast or slow). 4061 + * 4062 + * @return: void 4063 + * ******************************************************************************* 4064 + */ 4065 + static void update_seamless_boot_flags(struct dc *dc, 4066 + struct dc_state *context, 4067 + int surface_count, 4068 + struct dc_stream_state *stream) 4069 + { 4070 + if (get_seamless_boot_stream_count(context) > 0 && surface_count > 0) { 4071 + /* Optimize seamless boot flag keeps clocks and watermarks high until 4072 + * first flip. After first flip, optimization is required to lower 4073 + * bandwidth. Important to note that it is expected UEFI will 4074 + * only light up a single display on POST, therefore we only expect 4075 + * one stream with seamless boot flag set. 4076 + */ 4077 + if (stream->apply_seamless_boot_optimization) { 4078 + stream->apply_seamless_boot_optimization = false; 4079 + 4080 + if (get_seamless_boot_stream_count(context) == 0) 4081 + dc->optimized_required = true; 4082 + } 4083 + } 4084 + } 4085 + 4204 4086 bool dc_update_planes_and_stream(struct dc *dc, 4205 4087 struct dc_surface_update *srf_updates, int surface_count, 4206 4088 struct dc_stream_state *stream, ··· 4304 4112 update_type = UPDATE_TYPE_FULL; 4305 4113 } 4306 4114 4307 - commit_planes_for_stream( 4308 - dc, 4309 - srf_updates, 4310 - surface_count, 4311 - stream, 4312 - stream_update, 4313 - update_type, 4314 - context); 4115 + update_seamless_boot_flags(dc, context, surface_count, stream); 4116 + if (!dc->debug.enable_legacy_fast_update && update_type == UPDATE_TYPE_FAST) { 4117 + commit_planes_for_stream_fast(dc, 4118 + srf_updates, 4119 + surface_count, 4120 + stream, 4121 + stream_update, 4122 + update_type, 4123 + context); 4124 + } else { 4125 + commit_planes_for_stream( 4126 + dc, 4127 + srf_updates, 4128 + surface_count, 4129 + stream, 4130 + stream_update, 4131 + update_type, 4132 + context); 4133 + } 4315 4134 4316 4135 if (dc->current_state != context) { 4317 4136 ··· 4447 4244 4448 4245 TRACE_DC_PIPE_STATE(pipe_ctx, i, MAX_PIPES); 4449 4246 4450 - commit_planes_for_stream( 4247 + update_seamless_boot_flags(dc, context, surface_count, stream); 4248 + if (!dc->debug.enable_legacy_fast_update && update_type == UPDATE_TYPE_FAST) { 4249 + commit_planes_for_stream_fast(dc, 4250 + srf_updates, 4251 + surface_count, 4252 + stream, 4253 + stream_update, 4254 + update_type, 4255 + context); 4256 + } else { 4257 + commit_planes_for_stream( 4451 4258 dc, 4452 4259 srf_updates, 4453 4260 surface_count, ··· 4465 4252 stream_update, 4466 4253 update_type, 4467 4254 context); 4255 + } 4468 4256 /*update current_State*/ 4469 4257 if (dc->current_state != context) { 4470 4258
+255
drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
··· 27 27 #include "core_types.h" 28 28 #include "timing_generator.h" 29 29 #include "hw_sequencer.h" 30 + #include "hw_sequencer_private.h" 31 + #include "basics/dc_common.h" 30 32 31 33 #define NUM_ELEMENTS(a) (sizeof(a) / sizeof((a)[0])) 32 34 ··· 463 461 color->color_b_cb = color_value; 464 462 } 465 463 } 464 + } 465 + 466 + void hwss_build_fast_sequence(struct dc *dc, 467 + struct dc_dmub_cmd *dc_dmub_cmd, 468 + unsigned int dmub_cmd_count, 469 + struct block_sequence block_sequence[], 470 + int *num_steps, 471 + struct pipe_ctx *pipe_ctx) 472 + { 473 + struct dc_plane_state *plane = pipe_ctx->plane_state; 474 + struct dc_stream_state *stream = pipe_ctx->stream; 475 + struct dce_hwseq *hws = dc->hwseq; 476 + struct pipe_ctx *current_pipe = NULL; 477 + struct pipe_ctx *current_mpc_pipe = NULL; 478 + unsigned int i = 0; 479 + 480 + *num_steps = 0; // Initialize to 0 481 + 482 + if (!plane || !stream) 483 + return; 484 + 485 + if (dc->hwss.subvp_pipe_control_lock_fast) { 486 + block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.dc = dc; 487 + block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.lock = true; 488 + block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.pipe_ctx = pipe_ctx; 489 + block_sequence[*num_steps].func = DMUB_SUBVP_PIPE_CONTROL_LOCK_FAST; 490 + (*num_steps)++; 491 + } 492 + if (dc->hwss.pipe_control_lock) { 493 + block_sequence[*num_steps].params.pipe_control_lock_params.dc = dc; 494 + block_sequence[*num_steps].params.pipe_control_lock_params.lock = true; 495 + block_sequence[*num_steps].params.pipe_control_lock_params.pipe_ctx = pipe_ctx; 496 + block_sequence[*num_steps].func = OPTC_PIPE_CONTROL_LOCK; 497 + (*num_steps)++; 498 + } 499 + 500 + for (i = 0; i < dmub_cmd_count; i++) { 501 + block_sequence[*num_steps].params.send_dmcub_cmd_params.ctx = dc->ctx; 502 + block_sequence[*num_steps].params.send_dmcub_cmd_params.cmd = &(dc_dmub_cmd[i].dmub_cmd); 503 + block_sequence[*num_steps].params.send_dmcub_cmd_params.wait_type = dc_dmub_cmd[i].wait_type; 504 + block_sequence[*num_steps].func = DMUB_SEND_DMCUB_CMD; 505 + (*num_steps)++; 506 + } 507 + 508 + current_pipe = pipe_ctx; 509 + while (current_pipe) { 510 + current_mpc_pipe = current_pipe; 511 + while (current_mpc_pipe) { 512 + if (dc->hwss.set_flip_control_gsl && current_mpc_pipe->plane_state && current_mpc_pipe->plane_state->update_flags.raw) { 513 + block_sequence[*num_steps].params.set_flip_control_gsl_params.pipe_ctx = current_mpc_pipe; 514 + block_sequence[*num_steps].params.set_flip_control_gsl_params.flip_immediate = current_mpc_pipe->plane_state->flip_immediate; 515 + block_sequence[*num_steps].func = HUBP_SET_FLIP_CONTROL_GSL; 516 + (*num_steps)++; 517 + } 518 + if (dc->hwss.program_triplebuffer && dc->debug.enable_tri_buf && current_mpc_pipe->plane_state->update_flags.raw) { 519 + block_sequence[*num_steps].params.program_triplebuffer_params.dc = dc; 520 + block_sequence[*num_steps].params.program_triplebuffer_params.pipe_ctx = current_mpc_pipe; 521 + block_sequence[*num_steps].params.program_triplebuffer_params.enableTripleBuffer = current_mpc_pipe->plane_state->triplebuffer_flips; 522 + block_sequence[*num_steps].func = HUBP_PROGRAM_TRIPLEBUFFER; 523 + (*num_steps)++; 524 + } 525 + if (dc->hwss.update_plane_addr && current_mpc_pipe->plane_state->update_flags.bits.addr_update) { 526 + block_sequence[*num_steps].params.update_plane_addr_params.dc = dc; 527 + block_sequence[*num_steps].params.update_plane_addr_params.pipe_ctx = current_mpc_pipe; 528 + block_sequence[*num_steps].func = HUBP_UPDATE_PLANE_ADDR; 529 + (*num_steps)++; 530 + } 531 + 532 + if (hws->funcs.set_input_transfer_func && current_mpc_pipe->plane_state->update_flags.bits.gamma_change) { 533 + block_sequence[*num_steps].params.set_input_transfer_func_params.dc = dc; 534 + block_sequence[*num_steps].params.set_input_transfer_func_params.pipe_ctx = current_mpc_pipe; 535 + block_sequence[*num_steps].params.set_input_transfer_func_params.plane_state = current_mpc_pipe->plane_state; 536 + block_sequence[*num_steps].func = DPP_SET_INPUT_TRANSFER_FUNC; 537 + (*num_steps)++; 538 + } 539 + 540 + if (dc->hwss.program_gamut_remap && current_mpc_pipe->plane_state->update_flags.bits.gamut_remap_change) { 541 + block_sequence[*num_steps].params.program_gamut_remap_params.pipe_ctx = current_mpc_pipe; 542 + block_sequence[*num_steps].func = DPP_PROGRAM_GAMUT_REMAP; 543 + (*num_steps)++; 544 + } 545 + if (current_mpc_pipe->plane_state->update_flags.bits.input_csc_change) { 546 + block_sequence[*num_steps].params.setup_dpp_params.pipe_ctx = current_mpc_pipe; 547 + block_sequence[*num_steps].func = DPP_SETUP_DPP; 548 + (*num_steps)++; 549 + } 550 + if (current_mpc_pipe->plane_state->update_flags.bits.coeff_reduction_change) { 551 + block_sequence[*num_steps].params.program_bias_and_scale_params.pipe_ctx = current_mpc_pipe; 552 + block_sequence[*num_steps].func = DPP_PROGRAM_BIAS_AND_SCALE; 553 + (*num_steps)++; 554 + } 555 + if (hws->funcs.set_output_transfer_func && current_mpc_pipe->stream->update_flags.bits.out_tf) { 556 + block_sequence[*num_steps].params.set_output_transfer_func_params.dc = dc; 557 + block_sequence[*num_steps].params.set_output_transfer_func_params.pipe_ctx = current_mpc_pipe; 558 + block_sequence[*num_steps].params.set_output_transfer_func_params.stream = current_mpc_pipe->stream; 559 + block_sequence[*num_steps].func = DPP_SET_OUTPUT_TRANSFER_FUNC; 560 + (*num_steps)++; 561 + } 562 + 563 + current_mpc_pipe = current_mpc_pipe->bottom_pipe; 564 + } 565 + current_pipe = current_pipe->next_odm_pipe; 566 + } 567 + 568 + if (dc->hwss.pipe_control_lock) { 569 + block_sequence[*num_steps].params.pipe_control_lock_params.dc = dc; 570 + block_sequence[*num_steps].params.pipe_control_lock_params.lock = false; 571 + block_sequence[*num_steps].params.pipe_control_lock_params.pipe_ctx = pipe_ctx; 572 + block_sequence[*num_steps].func = OPTC_PIPE_CONTROL_LOCK; 573 + (*num_steps)++; 574 + } 575 + if (dc->hwss.subvp_pipe_control_lock_fast) { 576 + block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.dc = dc; 577 + block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.lock = false; 578 + block_sequence[*num_steps].params.subvp_pipe_control_lock_fast_params.pipe_ctx = pipe_ctx; 579 + block_sequence[*num_steps].func = DMUB_SUBVP_PIPE_CONTROL_LOCK_FAST; 580 + (*num_steps)++; 581 + } 582 + 583 + current_pipe = pipe_ctx; 584 + while (current_pipe) { 585 + current_mpc_pipe = current_pipe; 586 + 587 + while (current_mpc_pipe) { 588 + if (!current_mpc_pipe->bottom_pipe && !pipe_ctx->next_odm_pipe && 589 + current_mpc_pipe->stream && current_mpc_pipe->plane_state && 590 + current_mpc_pipe->plane_state->update_flags.bits.addr_update && 591 + !current_mpc_pipe->plane_state->skip_manual_trigger) { 592 + block_sequence[*num_steps].params.program_manual_trigger_params.pipe_ctx = current_mpc_pipe; 593 + block_sequence[*num_steps].func = OPTC_PROGRAM_MANUAL_TRIGGER; 594 + (*num_steps)++; 595 + } 596 + current_mpc_pipe = current_mpc_pipe->bottom_pipe; 597 + } 598 + current_pipe = current_pipe->next_odm_pipe; 599 + } 600 + } 601 + 602 + void hwss_execute_sequence(struct dc *dc, 603 + struct block_sequence block_sequence[], 604 + int num_steps) 605 + { 606 + unsigned int i; 607 + union block_sequence_params *params; 608 + struct dce_hwseq *hws = dc->hwseq; 609 + 610 + for (i = 0; i < num_steps; i++) { 611 + params = &(block_sequence[i].params); 612 + switch (block_sequence[i].func) { 613 + 614 + case DMUB_SUBVP_PIPE_CONTROL_LOCK_FAST: 615 + dc->hwss.subvp_pipe_control_lock_fast(params); 616 + break; 617 + case OPTC_PIPE_CONTROL_LOCK: 618 + dc->hwss.pipe_control_lock(params->pipe_control_lock_params.dc, 619 + params->pipe_control_lock_params.pipe_ctx, 620 + params->pipe_control_lock_params.lock); 621 + break; 622 + case HUBP_SET_FLIP_CONTROL_GSL: 623 + dc->hwss.set_flip_control_gsl(params->set_flip_control_gsl_params.pipe_ctx, 624 + params->set_flip_control_gsl_params.flip_immediate); 625 + break; 626 + case HUBP_PROGRAM_TRIPLEBUFFER: 627 + dc->hwss.program_triplebuffer(params->program_triplebuffer_params.dc, 628 + params->program_triplebuffer_params.pipe_ctx, 629 + params->program_triplebuffer_params.enableTripleBuffer); 630 + break; 631 + case HUBP_UPDATE_PLANE_ADDR: 632 + dc->hwss.update_plane_addr(params->update_plane_addr_params.dc, 633 + params->update_plane_addr_params.pipe_ctx); 634 + break; 635 + case DPP_SET_INPUT_TRANSFER_FUNC: 636 + hws->funcs.set_input_transfer_func(params->set_input_transfer_func_params.dc, 637 + params->set_input_transfer_func_params.pipe_ctx, 638 + params->set_input_transfer_func_params.plane_state); 639 + break; 640 + case DPP_PROGRAM_GAMUT_REMAP: 641 + dc->hwss.program_gamut_remap(params->program_gamut_remap_params.pipe_ctx); 642 + break; 643 + case DPP_SETUP_DPP: 644 + hwss_setup_dpp(params); 645 + break; 646 + case DPP_PROGRAM_BIAS_AND_SCALE: 647 + hwss_program_bias_and_scale(params); 648 + break; 649 + case OPTC_PROGRAM_MANUAL_TRIGGER: 650 + hwss_program_manual_trigger(params); 651 + break; 652 + case DPP_SET_OUTPUT_TRANSFER_FUNC: 653 + hws->funcs.set_output_transfer_func(params->set_output_transfer_func_params.dc, 654 + params->set_output_transfer_func_params.pipe_ctx, 655 + params->set_output_transfer_func_params.stream); 656 + break; 657 + case MPC_UPDATE_VISUAL_CONFIRM: 658 + dc->hwss.update_visual_confirm_color(params->update_visual_confirm_params.dc, 659 + params->update_visual_confirm_params.pipe_ctx, 660 + params->update_visual_confirm_params.mpcc_id); 661 + break; 662 + case DMUB_SEND_DMCUB_CMD: 663 + hwss_send_dmcub_cmd(params); 664 + break; 665 + default: 666 + ASSERT(false); 667 + break; 668 + } 669 + } 670 + } 671 + 672 + void hwss_send_dmcub_cmd(union block_sequence_params *params) 673 + { 674 + struct dc_context *ctx = params->send_dmcub_cmd_params.ctx; 675 + union dmub_rb_cmd *cmd = params->send_dmcub_cmd_params.cmd; 676 + enum dm_dmub_wait_type wait_type = params->send_dmcub_cmd_params.wait_type; 677 + 678 + dm_execute_dmub_cmd(ctx, cmd, wait_type); 679 + } 680 + 681 + void hwss_program_manual_trigger(union block_sequence_params *params) 682 + { 683 + struct pipe_ctx *pipe_ctx = params->program_manual_trigger_params.pipe_ctx; 684 + 685 + if (pipe_ctx->stream_res.tg->funcs->program_manual_trigger) 686 + pipe_ctx->stream_res.tg->funcs->program_manual_trigger(pipe_ctx->stream_res.tg); 687 + } 688 + 689 + void hwss_setup_dpp(union block_sequence_params *params) 690 + { 691 + struct pipe_ctx *pipe_ctx = params->setup_dpp_params.pipe_ctx; 692 + struct dpp *dpp = pipe_ctx->plane_res.dpp; 693 + struct dc_plane_state *plane_state = pipe_ctx->plane_state; 694 + 695 + if (dpp && dpp->funcs->dpp_setup) { 696 + // program the input csc 697 + dpp->funcs->dpp_setup(dpp, 698 + plane_state->format, 699 + EXPANSION_MODE_ZERO, 700 + plane_state->input_csc_color_matrix, 701 + plane_state->color_space, 702 + NULL); 703 + } 704 + } 705 + 706 + void hwss_program_bias_and_scale(union block_sequence_params *params) 707 + { 708 + struct pipe_ctx *pipe_ctx = params->program_bias_and_scale_params.pipe_ctx; 709 + struct dpp *dpp = pipe_ctx->plane_res.dpp; 710 + struct dc_plane_state *plane_state = pipe_ctx->plane_state; 711 + struct dc_bias_and_scale bns_params = {0}; 712 + 713 + //TODO :for CNVC set scale and bias registers if necessary 714 + build_prescale_params(&bns_params, plane_state); 715 + if (dpp->funcs->dpp_program_bias_and_scale) 716 + dpp->funcs->dpp_program_bias_and_scale(dpp, &bns_params); 466 717 } 467 718 468 719 void get_mclk_switch_visual_confirm_color(
+1
drivers/gpu/drm/amd/display/dc/dc.h
··· 896 896 bool disable_dp_plus_plus_wa; 897 897 uint32_t fpo_vactive_min_active_margin_us; 898 898 uint32_t fpo_vactive_max_blank_us; 899 + bool enable_legacy_fast_update; 899 900 }; 900 901 901 902 struct gpu_info_soc_bounding_box_v1_0;
+5
drivers/gpu/drm/amd/display/dc/dce100/dce100_resource.c
··· 401 401 } 402 402 }; 403 403 404 + static const struct dc_debug_options debug_defaults = { 405 + .enable_legacy_fast_update = true, 406 + }; 407 + 404 408 #define CTX ctx 405 409 #define REG(reg) mm ## reg 406 410 ··· 1075 1071 dc->caps.dual_link_dvi = true; 1076 1072 dc->caps.disable_dp_clk_share = true; 1077 1073 dc->caps.extended_aux_timeout_support = false; 1074 + dc->debug = debug_defaults; 1078 1075 1079 1076 for (i = 0; i < pool->base.pipe_count; i++) { 1080 1077 pool->base.timing_generators[i] =
+5
drivers/gpu/drm/amd/display/dc/dce110/dce110_resource.c
··· 424 424 64 425 425 }; 426 426 427 + static const struct dc_debug_options debug_defaults = { 428 + .enable_legacy_fast_update = true, 429 + }; 430 + 427 431 static const struct dc_plane_cap underlay_plane_cap = { 428 432 .type = DC_PLANE_TYPE_DCE_UNDERLAY, 429 433 .per_pixel_alpha = 1, ··· 1372 1368 dc->caps.min_horizontal_blanking_period = 80; 1373 1369 dc->caps.is_apu = true; 1374 1370 dc->caps.extended_aux_timeout_support = false; 1371 + dc->debug = debug_defaults; 1375 1372 1376 1373 /************************************************* 1377 1374 * Create resources *
+5
drivers/gpu/drm/amd/display/dc/dce112/dce112_resource.c
··· 429 429 64 430 430 }; 431 431 432 + static const struct dc_debug_options debug_defaults = { 433 + .enable_legacy_fast_update = true, 434 + }; 435 + 432 436 #define CTX ctx 433 437 #define REG(reg) mm ## reg 434 438 ··· 1243 1239 dc->caps.min_horizontal_blanking_period = 80; 1244 1240 dc->caps.dual_link_dvi = true; 1245 1241 dc->caps.extended_aux_timeout_support = false; 1242 + dc->debug = debug_defaults; 1246 1243 1247 1244 /************************************************* 1248 1245 * Create resources *
+1
drivers/gpu/drm/amd/display/dc/dce120/dce120_resource.c
··· 526 526 527 527 static const struct dc_debug_options debug_defaults = { 528 528 .disable_clock_gate = true, 529 + .enable_legacy_fast_update = true, 529 530 }; 530 531 531 532 static struct clock_source *dce120_clock_source_create(
+6
drivers/gpu/drm/amd/display/dc/dce80/dce80_resource.c
··· 418 418 } 419 419 }; 420 420 421 + static const struct dc_debug_options debug_defaults = { 422 + .enable_legacy_fast_update = true, 423 + }; 424 + 421 425 static const struct dce_dmcu_registers dmcu_regs = { 422 426 DMCU_DCE80_REG_LIST() 423 427 }; ··· 973 969 dc->caps.min_horizontal_blanking_period = 80; 974 970 dc->caps.dual_link_dvi = true; 975 971 dc->caps.extended_aux_timeout_support = false; 972 + dc->debug = debug_defaults; 976 973 977 974 /************************************************* 978 975 * Create resources * ··· 1374 1369 dc->caps.max_cursor_size = 128; 1375 1370 dc->caps.min_horizontal_blanking_period = 80; 1376 1371 dc->caps.is_apu = true; 1372 + dc->debug = debug_defaults; 1377 1373 1378 1374 /************************************************* 1379 1375 * Create resources *
+1
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
··· 553 553 .recovery_enabled = false, /*enable this by default after testing.*/ 554 554 .max_downscale_src_width = 3840, 555 555 .underflow_assert_delay_us = 0xFFFFFFFF, 556 + .enable_legacy_fast_update = true, 556 557 }; 557 558 558 559 static const struct dc_debug_options debug_defaults_diags = {
+1
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_resource.c
··· 722 722 .scl_reset_length10 = true, 723 723 .sanity_checks = false, 724 724 .underflow_assert_delay_us = 0xFFFFFFFF, 725 + .enable_legacy_fast_update = true, 725 726 }; 726 727 727 728 void dcn20_dpp_destroy(struct dpp **dpp)
+1
drivers/gpu/drm/amd/display/dc/dcn201/dcn201_resource.c
··· 613 613 .sanity_checks = false, 614 614 .underflow_assert_delay_us = 0xFFFFFFFF, 615 615 .enable_tri_buf = false, 616 + .enable_legacy_fast_update = true, 616 617 }; 617 618 618 619 static void dcn201_dpp_destroy(struct dpp **dpp)
+1
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
··· 653 653 .usbc_combo_phy_reset_wa = true, 654 654 .dmub_command_table = true, 655 655 .use_max_lb = true, 656 + .enable_legacy_fast_update = true, 656 657 }; 657 658 658 659 static const struct dc_panel_config panel_config_defaults = {
+1
drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c
··· 887 887 } 888 888 }, 889 889 .disable_z10 = true, 890 + .enable_legacy_fast_update = true, 890 891 .enable_z9_disable_interface = true, /* Allow support for the PMFW interface for disable Z9*/ 891 892 .dml_hostvm_override = DML_HOSTVM_OVERRIDE_FALSE, 892 893 };
+1
drivers/gpu/drm/amd/display/dc/dcn315/dcn315_resource.c
··· 887 887 .afmt = true, 888 888 } 889 889 }, 890 + .enable_legacy_fast_update = true, 890 891 .psr_power_use_phy_fsm = 0, 891 892 }; 892 893
+1
drivers/gpu/drm/amd/display/dc/dcn316/dcn316_resource.c
··· 884 884 .afmt = true, 885 885 } 886 886 }, 887 + .enable_legacy_fast_update = true, 887 888 }; 888 889 889 890 static const struct dc_panel_config panel_config_defaults = {
+24
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c
··· 409 409 } 410 410 } 411 411 412 + void dcn32_subvp_pipe_control_lock_fast(union block_sequence_params *params) 413 + { 414 + struct dc *dc = params->subvp_pipe_control_lock_fast_params.dc; 415 + bool lock = params->subvp_pipe_control_lock_fast_params.lock; 416 + struct pipe_ctx *pipe_ctx = params->subvp_pipe_control_lock_fast_params.pipe_ctx; 417 + bool subvp_immediate_flip = false; 418 + 419 + if (pipe_ctx && pipe_ctx->stream && pipe_ctx->plane_state) { 420 + if (pipe_ctx->stream->mall_stream_config.type == SUBVP_MAIN && 421 + pipe_ctx->plane_state->flip_immediate) 422 + subvp_immediate_flip = true; 423 + } 424 + 425 + // Don't need to lock for DRR VSYNC flips -- FW will wait for DRR pending update cleared. 426 + if (subvp_immediate_flip) { 427 + union dmub_inbox0_cmd_lock_hw hw_lock_cmd = { 0 }; 428 + 429 + hw_lock_cmd.bits.command_code = DMUB_INBOX0_CMD__HW_LOCK; 430 + hw_lock_cmd.bits.hw_lock_client = HW_LOCK_CLIENT_DRIVER; 431 + hw_lock_cmd.bits.lock = lock; 432 + hw_lock_cmd.bits.should_release = !lock; 433 + dmub_hw_lock_mgr_inbox0_cmd(dc->ctx->dmub_srv, hw_lock_cmd); 434 + } 435 + } 412 436 413 437 bool dcn32_set_mpc_shaper_3dlut( 414 438 struct pipe_ctx *pipe_ctx, const struct dc_stream_state *stream)
+2
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.h
··· 84 84 struct pipe_ctx *top_pipe_to_program, 85 85 bool subvp_prev_use); 86 86 87 + void dcn32_subvp_pipe_control_lock_fast(union block_sequence_params *params); 88 + 87 89 void dcn32_unblank_stream(struct pipe_ctx *pipe_ctx, 88 90 struct dc_link_settings *link_settings); 89 91
+1
drivers/gpu/drm/amd/display/dc/dcn32/dcn32_init.c
··· 110 110 .enable_phantom_streams = dcn32_enable_phantom_streams, 111 111 .subvp_pipe_control_lock = dcn32_subvp_pipe_control_lock, 112 112 .update_visual_confirm_color = dcn10_update_visual_confirm_color, 113 + .subvp_pipe_control_lock_fast = dcn32_subvp_pipe_control_lock_fast, 113 114 .update_phantom_vp_position = dcn32_update_phantom_vp_position, 114 115 .update_dsc_pg = dcn32_update_dsc_pg, 115 116 .apply_update_flags_for_phantom = dcn32_apply_update_flags_for_phantom,
+11
drivers/gpu/drm/amd/display/dc/inc/core_types.h
··· 37 37 #include "dwb.h" 38 38 #include "mcif_wb.h" 39 39 #include "panel_cntl.h" 40 + #include "dmub/inc/dmub_cmd.h" 40 41 41 42 #define MAX_CLOCK_SOURCES 7 42 43 #define MAX_SVP_PHANTOM_STREAMS 2 ··· 500 499 struct display_mode_lib dml; 501 500 }; 502 501 502 + struct dc_dmub_cmd { 503 + union dmub_rb_cmd dmub_cmd; 504 + enum dm_dmub_wait_type wait_type; 505 + }; 506 + 503 507 /** 504 508 * struct dc_state - The full description of a state requested by users 505 509 */ ··· 552 546 * initially copied into every context. 553 547 */ 554 548 struct bw_context bw_ctx; 549 + 550 + struct block_sequence block_sequence[50]; 551 + unsigned int block_sequence_steps; 552 + struct dc_dmub_cmd dc_dmub_cmd[10]; 553 + unsigned int dmub_cmd_count; 555 554 556 555 /** 557 556 * @refcount: refcount reference
+126
drivers/gpu/drm/amd/display/dc/inc/hw_sequencer.h
··· 44 44 struct dpp; 45 45 struct dce_hwseq; 46 46 struct link_resource; 47 + struct dc_dmub_cmd; 48 + 49 + struct subvp_pipe_control_lock_fast_params { 50 + struct dc *dc; 51 + bool lock; 52 + struct pipe_ctx *pipe_ctx; 53 + }; 54 + 55 + struct pipe_control_lock_params { 56 + struct dc *dc; 57 + struct pipe_ctx *pipe_ctx; 58 + bool lock; 59 + }; 60 + 61 + struct set_flip_control_gsl_params { 62 + struct pipe_ctx *pipe_ctx; 63 + bool flip_immediate; 64 + }; 65 + 66 + struct program_triplebuffer_params { 67 + const struct dc *dc; 68 + struct pipe_ctx *pipe_ctx; 69 + bool enableTripleBuffer; 70 + }; 71 + 72 + struct update_plane_addr_params { 73 + struct dc *dc; 74 + struct pipe_ctx *pipe_ctx; 75 + }; 76 + 77 + struct set_input_transfer_func_params { 78 + struct dc *dc; 79 + struct pipe_ctx *pipe_ctx; 80 + struct dc_plane_state *plane_state; 81 + }; 82 + 83 + struct program_gamut_remap_params { 84 + struct pipe_ctx *pipe_ctx; 85 + }; 86 + 87 + struct program_manual_trigger_params { 88 + struct pipe_ctx *pipe_ctx; 89 + }; 90 + 91 + struct send_dmcub_cmd_params { 92 + struct dc_context *ctx; 93 + union dmub_rb_cmd *cmd; 94 + enum dm_dmub_wait_type wait_type; 95 + }; 96 + 97 + struct setup_dpp_params { 98 + struct pipe_ctx *pipe_ctx; 99 + }; 100 + 101 + struct program_bias_and_scale_params { 102 + struct pipe_ctx *pipe_ctx; 103 + }; 104 + 105 + struct set_output_transfer_func_params { 106 + struct dc *dc; 107 + struct pipe_ctx *pipe_ctx; 108 + const struct dc_stream_state *stream; 109 + }; 110 + 111 + struct update_visual_confirm_params { 112 + struct dc *dc; 113 + struct pipe_ctx *pipe_ctx; 114 + int mpcc_id; 115 + }; 116 + 117 + union block_sequence_params { 118 + struct update_plane_addr_params update_plane_addr_params; 119 + struct subvp_pipe_control_lock_fast_params subvp_pipe_control_lock_fast_params; 120 + struct pipe_control_lock_params pipe_control_lock_params; 121 + struct set_flip_control_gsl_params set_flip_control_gsl_params; 122 + struct program_triplebuffer_params program_triplebuffer_params; 123 + struct set_input_transfer_func_params set_input_transfer_func_params; 124 + struct program_gamut_remap_params program_gamut_remap_params; 125 + struct program_manual_trigger_params program_manual_trigger_params; 126 + struct send_dmcub_cmd_params send_dmcub_cmd_params; 127 + struct setup_dpp_params setup_dpp_params; 128 + struct program_bias_and_scale_params program_bias_and_scale_params; 129 + struct set_output_transfer_func_params set_output_transfer_func_params; 130 + struct update_visual_confirm_params update_visual_confirm_params; 131 + }; 132 + 133 + enum block_sequence_func { 134 + DMUB_SUBVP_PIPE_CONTROL_LOCK_FAST = 0, 135 + OPTC_PIPE_CONTROL_LOCK, 136 + HUBP_SET_FLIP_CONTROL_GSL, 137 + HUBP_PROGRAM_TRIPLEBUFFER, 138 + HUBP_UPDATE_PLANE_ADDR, 139 + DPP_SET_INPUT_TRANSFER_FUNC, 140 + DPP_PROGRAM_GAMUT_REMAP, 141 + OPTC_PROGRAM_MANUAL_TRIGGER, 142 + DMUB_SEND_DMCUB_CMD, 143 + DPP_SETUP_DPP, 144 + DPP_PROGRAM_BIAS_AND_SCALE, 145 + DPP_SET_OUTPUT_TRANSFER_FUNC, 146 + MPC_UPDATE_VISUAL_CONFIRM, 147 + }; 148 + 149 + struct block_sequence { 150 + union block_sequence_params params; 151 + enum block_sequence_func func; 152 + }; 47 153 48 154 struct hw_sequencer_funcs { 49 155 void (*hardware_release)(struct dc *dc); ··· 358 252 const struct tg_color *solid_color, 359 253 int width, int height, int offset); 360 254 255 + void (*subvp_pipe_control_lock_fast)(union block_sequence_params *params); 361 256 void (*z10_restore)(const struct dc *dc); 362 257 void (*z10_save_init)(struct dc *dc); 363 258 ··· 419 312 struct dc_state *context, 420 313 struct pipe_ctx *pipe_ctx, 421 314 struct tg_color *color); 315 + 316 + void hwss_execute_sequence(struct dc *dc, 317 + struct block_sequence block_sequence[], 318 + int num_steps); 319 + 320 + void hwss_build_fast_sequence(struct dc *dc, 321 + struct dc_dmub_cmd *dc_dmub_cmd, 322 + unsigned int dmub_cmd_count, 323 + struct block_sequence block_sequence[], 324 + int *num_steps, 325 + struct pipe_ctx *pipe_ctx); 326 + 327 + void hwss_send_dmcub_cmd(union block_sequence_params *params); 328 + 329 + void hwss_program_manual_trigger(union block_sequence_params *params); 330 + 331 + void hwss_setup_dpp(union block_sequence_params *params); 332 + 333 + void hwss_program_bias_and_scale(union block_sequence_params *params); 422 334 423 335 #endif /* __DC_HW_SEQUENCER_H__ */