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.

Revert "drm/amd/display: Refactor DC update checks"

Revert commit c24bb00cc6cf ("drm/amd/display: Refactor DC update checks")

[WHY]
Causing issues with PSR/Replay, reverting until those can be fixed.

Reviewed-by: Martin Leung <Martin.Leung@amd.com>
Signed-off-by: Dillon Varone <Dillon.Varone@amd.com>
Signed-off-by: Chuanyu Tseng <chuanyu.tseng@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Dillon Varone and committed by
Alex Deucher
4e91f432 60c741a1

+308 -204
+3 -3
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
··· 9890 9890 } 9891 9891 9892 9892 /* Decrement skip count when SR is enabled and we're doing fast updates. */ 9893 - if (acrtc_state->update_type <= UPDATE_TYPE_FAST && 9893 + if (acrtc_state->update_type == UPDATE_TYPE_FAST && 9894 9894 (psr->psr_feature_enabled || pr->config.replay_supported)) { 9895 9895 if (aconn->sr_skip_count > 0) 9896 9896 aconn->sr_skip_count--; ··· 10100 10100 * fast updates. 10101 10101 */ 10102 10102 if (crtc->state->async_flip && 10103 - (acrtc_state->update_type > UPDATE_TYPE_FAST || 10103 + (acrtc_state->update_type != UPDATE_TYPE_FAST || 10104 10104 get_mem_type(old_plane_state->fb) != get_mem_type(fb))) 10105 10105 drm_warn_once(state->dev, 10106 10106 "[PLANE:%d:%s] async flip with non-fast update\n", ··· 10108 10108 10109 10109 bundle->flip_addrs[planes_count].flip_immediate = 10110 10110 crtc->state->async_flip && 10111 - acrtc_state->update_type <= UPDATE_TYPE_FAST && 10111 + acrtc_state->update_type == UPDATE_TYPE_FAST && 10112 10112 get_mem_type(old_plane_state->fb) == get_mem_type(fb); 10113 10113 10114 10114 timestamp_ns = ktime_get_ns();
+1 -1
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c
··· 685 685 * pitch, the DCC state, rotation, etc. 686 686 */ 687 687 if (crtc_state->async_flip && 688 - dm_crtc_state->update_type > UPDATE_TYPE_FAST) { 688 + dm_crtc_state->update_type != UPDATE_TYPE_FAST) { 689 689 drm_dbg_atomic(crtc->dev, 690 690 "[CRTC:%d:%s] async flips are only supported for fast updates\n", 691 691 crtc->base.id, crtc->name);
+284 -198
drivers/gpu/drm/amd/display/dc/core/dc.c
··· 2761 2761 static struct surface_update_descriptor get_plane_info_update_type(const struct dc_surface_update *u) 2762 2762 { 2763 2763 union surface_update_flags *update_flags = &u->surface->update_flags; 2764 - struct surface_update_descriptor update_type = { UPDATE_TYPE_ADDR_ONLY, LOCK_DESCRIPTOR_NONE }; 2764 + struct surface_update_descriptor update_type = { UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_NONE }; 2765 2765 2766 2766 if (!u->plane_info) 2767 2767 return update_type; ··· 2853 2853 const struct dc_surface_update *u) 2854 2854 { 2855 2855 union surface_update_flags *update_flags = &u->surface->update_flags; 2856 - struct surface_update_descriptor update_type = { UPDATE_TYPE_ADDR_ONLY, LOCK_DESCRIPTOR_NONE }; 2856 + struct surface_update_descriptor update_type = { UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_NONE }; 2857 2857 2858 2858 if (!u->scaling_info) 2859 2859 return update_type; ··· 2904 2904 return update_type; 2905 2905 } 2906 2906 2907 - static struct surface_update_descriptor check_update_surface( 2907 + static struct surface_update_descriptor det_surface_update( 2908 2908 const struct dc_check_config *check_config, 2909 2909 struct dc_surface_update *u) 2910 2910 { 2911 - struct surface_update_descriptor overall_type = { UPDATE_TYPE_ADDR_ONLY, LOCK_DESCRIPTOR_NONE }; 2911 + struct surface_update_descriptor overall_type = { UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_NONE }; 2912 2912 union surface_update_flags *update_flags = &u->surface->update_flags; 2913 2913 2914 2914 if (u->surface->force_full_update) { ··· 2928 2928 2929 2929 if (u->flip_addr) { 2930 2930 update_flags->bits.addr_update = 1; 2931 - elevate_update_type(&overall_type, UPDATE_TYPE_ADDR_ONLY, LOCK_DESCRIPTOR_STREAM); 2931 + elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM); 2932 2932 2933 2933 if (u->flip_addr->address.tmz_surface != u->surface->address.tmz_surface) { 2934 2934 update_flags->bits.tmz_changed = 1; ··· 2942 2942 2943 2943 if (u->input_csc_color_matrix) { 2944 2944 update_flags->bits.input_csc_change = 1; 2945 - elevate_update_type(&overall_type, 2946 - check_config->enable_legacy_fast_update ? UPDATE_TYPE_MED : UPDATE_TYPE_FAST, 2947 - LOCK_DESCRIPTOR_STREAM); 2948 - } 2949 - 2950 - if (u->cursor_csc_color_matrix) { 2951 - elevate_update_type(&overall_type, 2952 - check_config->enable_legacy_fast_update ? UPDATE_TYPE_MED : UPDATE_TYPE_FAST, 2953 - LOCK_DESCRIPTOR_STREAM); 2945 + elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM); 2954 2946 } 2955 2947 2956 2948 if (u->coeff_reduction_factor) { 2957 2949 update_flags->bits.coeff_reduction_change = 1; 2958 - elevate_update_type(&overall_type, 2959 - check_config->enable_legacy_fast_update ? UPDATE_TYPE_MED : UPDATE_TYPE_FAST, 2960 - LOCK_DESCRIPTOR_STREAM); 2950 + elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM); 2961 2951 } 2962 2952 2963 2953 if (u->gamut_remap_matrix) { 2964 2954 update_flags->bits.gamut_remap_change = 1; 2965 - elevate_update_type(&overall_type, 2966 - check_config->enable_legacy_fast_update ? UPDATE_TYPE_MED : UPDATE_TYPE_FAST, 2967 - LOCK_DESCRIPTOR_STREAM); 2955 + elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM); 2968 2956 } 2969 2957 2970 2958 if (u->cm || (u->gamma && dce_use_lut(u->plane_info ? u->plane_info->format : u->surface->format))) { 2971 2959 update_flags->bits.gamma_change = 1; 2972 - elevate_update_type(&overall_type, 2973 - check_config->enable_legacy_fast_update ? UPDATE_TYPE_MED : UPDATE_TYPE_FAST, 2974 - LOCK_DESCRIPTOR_STREAM); 2960 + elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM); 2975 2961 } 2976 2962 2977 2963 if (u->cm && (u->cm->flags.bits.lut3d_enable || u->surface->cm.flags.bits.lut3d_enable)) { 2978 2964 update_flags->bits.lut_3d = 1; 2979 - elevate_update_type(&overall_type, 2980 - check_config->enable_legacy_fast_update ? UPDATE_TYPE_MED : UPDATE_TYPE_FAST, 2981 - LOCK_DESCRIPTOR_STREAM); 2965 + elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM); 2982 2966 } 2983 2967 2984 2968 if (u->cm && u->cm->flags.bits.lut3d_dma_enable != u->surface->cm.flags.bits.lut3d_dma_enable && ··· 2978 2994 2979 2995 if (u->hdr_mult.value) 2980 2996 if (u->hdr_mult.value != u->surface->hdr_mult.value) { 2997 + // TODO: Should be fast? 2981 2998 update_flags->bits.hdr_mult = 1; 2982 - elevate_update_type(&overall_type, 2983 - check_config->enable_legacy_fast_update ? UPDATE_TYPE_MED : UPDATE_TYPE_FAST, 2984 - LOCK_DESCRIPTOR_STREAM); 2999 + elevate_update_type(&overall_type, UPDATE_TYPE_MED, LOCK_DESCRIPTOR_STREAM); 2985 3000 } 2986 3001 2987 3002 if (u->sdr_white_level_nits) ··· 3034 3051 int surface_count, 3035 3052 struct dc_stream_update *stream_update) 3036 3053 { 3037 - struct surface_update_descriptor overall_type = { UPDATE_TYPE_ADDR_ONLY, LOCK_DESCRIPTOR_NONE }; 3054 + struct surface_update_descriptor overall_type = { UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_NONE }; 3038 3055 3039 3056 /* When countdown finishes, promote this flip to full to trigger deferred final transition */ 3040 3057 if (check_config->deferred_transition_state && !check_config->transition_countdown_to_steady_state) { ··· 3101 3118 if (su_flags->raw) 3102 3119 elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL); 3103 3120 3104 - /* Non-global cases */ 3105 - if (stream_update->hdr_static_metadata || 3106 - stream_update->vrr_infopacket || 3107 - stream_update->vsc_infopacket || 3108 - stream_update->vsp_infopacket || 3109 - stream_update->hfvsif_infopacket || 3110 - stream_update->adaptive_sync_infopacket || 3111 - stream_update->vtem_infopacket || 3112 - stream_update->avi_infopacket) { 3113 - elevate_update_type(&overall_type, UPDATE_TYPE_MED, LOCK_DESCRIPTOR_STREAM); 3114 - } 3115 - 3121 + // Non-global cases 3116 3122 if (stream_update->output_csc_transform) { 3117 3123 su_flags->bits.out_csc = 1; 3118 3124 elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM); ··· 3111 3139 su_flags->bits.out_tf = 1; 3112 3140 elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM); 3113 3141 } 3114 - 3115 - if (stream_update->periodic_interrupt) { 3116 - elevate_update_type(&overall_type, UPDATE_TYPE_MED, LOCK_DESCRIPTOR_STREAM); 3117 - } 3118 - 3119 - if (stream_update->dither_option) { 3120 - elevate_update_type(&overall_type, UPDATE_TYPE_MED, LOCK_DESCRIPTOR_STREAM); 3121 - } 3122 - 3123 - if (stream_update->cursor_position || stream_update->cursor_attributes) { 3124 - elevate_update_type(&overall_type, UPDATE_TYPE_MED, LOCK_DESCRIPTOR_STREAM); 3125 - } 3126 - 3127 - /* TODO - cleanup post blend CM */ 3128 - if (stream_update->func_shaper || stream_update->lut3d_func) { 3129 - elevate_update_type(&overall_type, UPDATE_TYPE_FAST, LOCK_DESCRIPTOR_STREAM); 3130 - } 3131 - 3132 - if (stream_update->pending_test_pattern) { 3133 - elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL); 3134 - } 3135 3142 } 3136 3143 3137 3144 for (int i = 0 ; i < surface_count; i++) { 3138 3145 struct surface_update_descriptor inner_type = 3139 - check_update_surface(check_config, &updates[i]); 3146 + det_surface_update(check_config, &updates[i]); 3140 3147 3141 3148 elevate_update_type(&overall_type, inner_type.update_type, inner_type.lock_descriptor); 3142 3149 } ··· 3140 3189 updates[i].surface->update_flags.raw = 0; 3141 3190 3142 3191 return check_update_surfaces_for_stream(check_config, updates, surface_count, stream_update); 3143 - } 3144 - 3145 - /* 3146 - * check_update_state_and_surfaces_for_stream() - Determine update type (fast, med, or full) 3147 - * 3148 - * This function performs checks on the DC global state, and is therefore not re-entrant. It 3149 - * should not be called from DM. 3150 - * 3151 - * See :c:type:`enum surface_update_type <surface_update_type>` for explanation of update types 3152 - */ 3153 - static struct surface_update_descriptor check_update_state_and_surfaces_for_stream( 3154 - const struct dc *dc, 3155 - const struct dc_check_config *check_config, 3156 - const struct dc_stream_state *stream, 3157 - const struct dc_surface_update *updates, 3158 - const int surface_count, 3159 - const struct dc_stream_update *stream_update) 3160 - { 3161 - (void)check_config; 3162 - (void)stream_update; 3163 - 3164 - const struct dc_state *context = dc->current_state; 3165 - 3166 - struct surface_update_descriptor overall_type = { UPDATE_TYPE_ADDR_ONLY, LOCK_DESCRIPTOR_NONE}; 3167 - 3168 - if (updates) 3169 - for (int i = 0; i < surface_count; i++) 3170 - if (!is_surface_in_context(context, updates[i].surface)) 3171 - elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL); 3172 - 3173 - if (stream) { 3174 - const struct dc_stream_status *stream_status = dc_stream_get_status_const(stream); 3175 - if (stream_status == NULL || stream_status->plane_count != surface_count) 3176 - elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL); 3177 - } 3178 - if (dc->idle_optimizations_allowed) 3179 - elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL); 3180 - 3181 - if (dc_can_clear_cursor_limit(dc)) 3182 - elevate_update_type(&overall_type, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL); 3183 - 3184 - return overall_type; 3185 - } 3186 - 3187 - /* 3188 - * dc_check_update_state_and_surfaces_for_stream() - Determine update type (fast, med, or full) 3189 - * 3190 - * This function performs checks on the DC global state, stream and surface update, and is 3191 - * therefore not re-entrant. It should not be called from DM. 3192 - * 3193 - * See :c:type:`enum surface_update_type <surface_update_type>` for explanation of update types 3194 - */ 3195 - static struct surface_update_descriptor dc_check_update_state_and_surfaces_for_stream( 3196 - const struct dc *dc, 3197 - const struct dc_check_config *check_config, 3198 - struct dc_stream_state *stream, 3199 - struct dc_surface_update *updates, 3200 - int surface_count, 3201 - struct dc_stream_update *stream_update) 3202 - { 3203 - /* check updates against the entire DC state (global) first */ 3204 - struct surface_update_descriptor overall_update_type = check_update_state_and_surfaces_for_stream( 3205 - dc, 3206 - check_config, 3207 - stream, 3208 - updates, 3209 - surface_count, 3210 - stream_update); 3211 - 3212 - /* check updates for stream and plane */ 3213 - struct surface_update_descriptor stream_update_type = dc_check_update_surfaces_for_stream( 3214 - check_config, 3215 - updates, 3216 - surface_count, 3217 - stream_update); 3218 - elevate_update_type(&overall_update_type, stream_update_type.update_type, stream_update_type.lock_descriptor); 3219 - 3220 - return overall_update_type; 3221 3192 } 3222 3193 3223 3194 static struct dc_stream_status *stream_get_status( ··· 3498 3625 } 3499 3626 } 3500 3627 3628 + static bool full_update_required_weak( 3629 + const struct dc *dc, 3630 + const struct dc_surface_update *srf_updates, 3631 + int surface_count, 3632 + const struct dc_stream_update *stream_update, 3633 + const struct dc_stream_state *stream); 3634 + 3501 3635 struct pipe_split_policy_backup { 3502 3636 bool dynamic_odm_policy; 3503 3637 bool subvp_policy; ··· 3575 3695 struct dc_surface_update *srf_updates, int surface_count, 3576 3696 struct dc_stream_state *stream, 3577 3697 struct dc_stream_update *stream_update, 3578 - struct surface_update_descriptor *update_descriptor, 3698 + enum surface_update_type *new_update_type, 3579 3699 struct dc_state **new_context) 3580 3700 { 3581 3701 struct dc_state *context; 3582 3702 int i, j; 3703 + enum surface_update_type update_type; 3583 3704 const struct dc_stream_status *stream_status; 3584 3705 struct dc_context *dc_ctx = dc->ctx; 3585 3706 ··· 3594 3713 } 3595 3714 3596 3715 context = dc->current_state; 3597 - *update_descriptor = dc_check_update_state_and_surfaces_for_stream( 3598 - dc, 3599 - &dc->check_config, 3600 - stream, 3601 - srf_updates, 3602 - surface_count, 3603 - stream_update); 3716 + update_type = dc_check_update_surfaces_for_stream( 3717 + &dc->check_config, srf_updates, surface_count, stream_update).update_type; 3718 + if (full_update_required_weak(dc, srf_updates, surface_count, stream_update, stream)) 3719 + update_type = UPDATE_TYPE_FULL; 3604 3720 3605 3721 /* It is possible to receive a flip for one plane while there are multiple flip_immediate planes in the same stream. 3606 3722 * E.g. Desktop and MPO plane are flip_immediate but only the MPO plane received a flip 3607 3723 * Force the other flip_immediate planes to flip so GSL doesn't wait for a flip that won't come. 3608 3724 */ 3609 3725 force_immediate_gsl_plane_flip(dc, srf_updates, surface_count); 3610 - if (update_descriptor->update_type == UPDATE_TYPE_FULL) 3726 + if (update_type == UPDATE_TYPE_FULL) 3611 3727 backup_planes_and_stream_state(&dc->scratch.current_state, stream); 3612 3728 3613 3729 /* update current stream with the new updates */ ··· 3630 3752 } 3631 3753 } 3632 3754 3633 - if (update_descriptor->update_type == UPDATE_TYPE_FULL) { 3755 + if (update_type == UPDATE_TYPE_FULL) { 3634 3756 if (stream_update) { 3635 3757 uint32_t dsc_changed = stream_update->stream->update_flags.bits.dsc_changed; 3636 3758 stream_update->stream->update_flags.raw = 0xFFFFFFFF; ··· 3640 3762 srf_updates[i].surface->update_flags.raw = 0xFFFFFFFF; 3641 3763 } 3642 3764 3643 - if (update_descriptor->update_type >= update_surface_trace_level) 3765 + if (update_type >= update_surface_trace_level) 3644 3766 update_surface_trace(dc, srf_updates, surface_count); 3645 3767 3646 3768 for (i = 0; i < surface_count; i++) 3647 3769 copy_surface_update_to_plane(srf_updates[i].surface, &srf_updates[i]); 3648 3770 3649 - if (update_descriptor->update_type >= UPDATE_TYPE_FULL) { 3771 + if (update_type >= UPDATE_TYPE_FULL) { 3650 3772 struct dc_plane_state *new_planes[MAX_SURFACES] = {0}; 3651 3773 3652 3774 for (i = 0; i < surface_count; i++) ··· 3684 3806 for (i = 0; i < surface_count; i++) { 3685 3807 struct dc_plane_state *surface = srf_updates[i].surface; 3686 3808 3687 - if (update_descriptor->update_type != UPDATE_TYPE_MED) 3809 + if (update_type != UPDATE_TYPE_MED) 3688 3810 continue; 3689 3811 if (surface->update_flags.bits.position_change) { 3690 3812 for (j = 0; j < dc->res_pool->pipe_count; j++) { ··· 3698 3820 } 3699 3821 } 3700 3822 3701 - if (update_descriptor->update_type == UPDATE_TYPE_FULL) { 3823 + if (update_type == UPDATE_TYPE_FULL) { 3702 3824 struct pipe_split_policy_backup policy; 3703 3825 bool minimize = false; 3704 3826 ··· 3727 3849 update_seamless_boot_flags(dc, context, surface_count, stream); 3728 3850 3729 3851 *new_context = context; 3730 - if (update_descriptor->update_type == UPDATE_TYPE_FULL) 3852 + *new_update_type = update_type; 3853 + if (update_type == UPDATE_TYPE_FULL) 3731 3854 backup_planes_and_stream_state(&dc->scratch.new_state, stream); 3732 3855 3733 3856 return true; ··· 3808 3929 program_cursor_position(dc, stream); 3809 3930 3810 3931 /* Full fe update*/ 3811 - if (update_type <= UPDATE_TYPE_FAST) 3932 + if (update_type == UPDATE_TYPE_FAST) 3812 3933 continue; 3813 3934 3814 3935 if (stream_update->dsc_config) ··· 4117 4238 struct pipe_ctx *top_pipe_to_program = NULL; 4118 4239 struct dc_stream_status *stream_status = NULL; 4119 4240 bool should_offload_fams2_flip = false; 4120 - bool should_lock_all_pipes = (update_type > UPDATE_TYPE_FAST); 4241 + bool should_lock_all_pipes = (update_type != UPDATE_TYPE_FAST); 4121 4242 4122 4243 if (should_lock_all_pipes) 4123 4244 determine_pipe_unlock_order(dc, context); ··· 4177 4298 continue; 4178 4299 4179 4300 pipe_ctx->plane_state->triplebuffer_flips = false; 4180 - if (update_type <= UPDATE_TYPE_FAST && 4301 + if (update_type == UPDATE_TYPE_FAST && 4181 4302 dc->hwss.program_triplebuffer != NULL && 4182 4303 !pipe_ctx->plane_state->flip_immediate && dc->debug.enable_tri_buf) { 4183 4304 /*triple buffer for VUpdate only*/ ··· 4234 4355 { 4235 4356 int i, j; 4236 4357 struct pipe_ctx *top_pipe_to_program = NULL; 4237 - bool should_lock_all_pipes = (update_type > UPDATE_TYPE_FAST); 4358 + bool should_lock_all_pipes = (update_type != UPDATE_TYPE_FAST); 4238 4359 bool subvp_prev_use = false; 4239 4360 bool subvp_curr_use = false; 4240 4361 uint8_t current_stream_mask = 0; ··· 4251 4372 if (update_type == UPDATE_TYPE_FULL && dc->optimized_required) 4252 4373 hwss_process_outstanding_hw_updates(dc, dc->current_state); 4253 4374 4254 - if (update_type > UPDATE_TYPE_FAST && dc->res_pool->funcs->prepare_mcache_programming) 4375 + if (update_type != UPDATE_TYPE_FAST && dc->res_pool->funcs->prepare_mcache_programming) 4255 4376 dc->res_pool->funcs->prepare_mcache_programming(dc, context); 4256 4377 4257 4378 for (i = 0; i < dc->res_pool->pipe_count; i++) { ··· 4313 4434 odm_pipe->ttu_regs.min_ttu_vblank = MAX_TTU; 4314 4435 } 4315 4436 4316 - if ((update_type > UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed) 4437 + if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed) 4317 4438 if (top_pipe_to_program && 4318 4439 top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) { 4319 4440 if (should_use_dmub_inbox1_lock(dc, stream->link)) { ··· 4384 4505 } 4385 4506 dc->hwss.post_unlock_program_front_end(dc, context); 4386 4507 4387 - if (update_type > UPDATE_TYPE_FAST) 4508 + if (update_type != UPDATE_TYPE_FAST) 4388 4509 if (dc->hwss.commit_subvp_config) 4389 4510 dc->hwss.commit_subvp_config(dc, context); 4390 4511 ··· 4400 4521 return; 4401 4522 } 4402 4523 4403 - if (update_type > UPDATE_TYPE_FAST) { 4524 + if (update_type != UPDATE_TYPE_FAST) { 4404 4525 for (j = 0; j < dc->res_pool->pipe_count; j++) { 4405 4526 struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[j]; 4406 4527 ··· 4428 4549 if (!should_update_pipe_for_plane(context, pipe_ctx, plane_state)) 4429 4550 continue; 4430 4551 pipe_ctx->plane_state->triplebuffer_flips = false; 4431 - if (update_type <= UPDATE_TYPE_FAST && 4552 + if (update_type == UPDATE_TYPE_FAST && 4432 4553 dc->hwss.program_triplebuffer != NULL && 4433 4554 !pipe_ctx->plane_state->flip_immediate && dc->debug.enable_tri_buf) { 4434 4555 /*triple buffer for VUpdate only*/ ··· 4455 4576 continue; 4456 4577 4457 4578 /* Full fe update*/ 4458 - if (update_type <= UPDATE_TYPE_FAST) 4579 + if (update_type == UPDATE_TYPE_FAST) 4459 4580 continue; 4460 4581 4461 4582 stream_status = ··· 4474 4595 continue; 4475 4596 4476 4597 /* Full fe update*/ 4477 - if (update_type <= UPDATE_TYPE_FAST) 4598 + if (update_type == UPDATE_TYPE_FAST) 4478 4599 continue; 4479 4600 4480 4601 ASSERT(!pipe_ctx->plane_state->triplebuffer_flips); ··· 4485 4606 } 4486 4607 } 4487 4608 4488 - if (dc->hwss.program_front_end_for_ctx && update_type > UPDATE_TYPE_FAST) { 4609 + if (dc->hwss.program_front_end_for_ctx && update_type != UPDATE_TYPE_FAST) { 4489 4610 dc->hwss.program_front_end_for_ctx(dc, context); 4490 4611 4491 4612 //Pipe busy until some frame and line # ··· 4513 4634 } 4514 4635 4515 4636 // Update Type FAST, Surface updates 4516 - if (update_type <= UPDATE_TYPE_FAST) { 4637 + if (update_type == UPDATE_TYPE_FAST) { 4517 4638 if (dc->hwss.set_flip_control_gsl) 4518 4639 for (i = 0; i < surface_count; i++) { 4519 4640 struct dc_plane_state *plane_state = srf_updates[i].surface; ··· 4570 4691 dc->hwss.pipe_control_lock(dc, top_pipe_to_program, false); 4571 4692 } 4572 4693 4573 - if ((update_type > UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed) 4694 + if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed) 4574 4695 if (top_pipe_to_program && 4575 4696 top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) { 4576 4697 top_pipe_to_program->stream_res.tg->funcs->wait_for_state( ··· 4603 4724 /* If enabling subvp or transitioning from subvp->subvp, enable the 4604 4725 * phantom streams before we program front end for the phantom pipes. 4605 4726 */ 4606 - if (update_type > UPDATE_TYPE_FAST) { 4727 + if (update_type != UPDATE_TYPE_FAST) { 4607 4728 if (dc->hwss.enable_phantom_streams) 4608 4729 dc->hwss.enable_phantom_streams(dc, context); 4609 4730 } 4610 4731 } 4611 4732 4612 - if (update_type > UPDATE_TYPE_FAST) 4733 + if (update_type != UPDATE_TYPE_FAST) 4613 4734 dc->hwss.post_unlock_program_front_end(dc, context); 4614 4735 4615 4736 if (subvp_prev_use && !subvp_curr_use) { ··· 4622 4743 dc->hwss.disable_phantom_streams(dc, context); 4623 4744 } 4624 4745 4625 - if (update_type > UPDATE_TYPE_FAST) 4746 + if (update_type != UPDATE_TYPE_FAST) 4626 4747 if (dc->hwss.commit_subvp_config) 4627 4748 dc->hwss.commit_subvp_config(dc, context); 4628 4749 /* Since phantom pipe programming is moved to post_unlock_program_front_end, ··· 5094 5215 return true; 5095 5216 } 5096 5217 5218 + void populate_fast_updates(struct dc_fast_update *fast_update, 5219 + struct dc_surface_update *srf_updates, 5220 + int surface_count, 5221 + struct dc_stream_update *stream_update) 5222 + { 5223 + int i = 0; 5224 + 5225 + if (stream_update) { 5226 + fast_update[0].out_transfer_func = stream_update->out_transfer_func; 5227 + fast_update[0].output_csc_transform = stream_update->output_csc_transform; 5228 + } else { 5229 + fast_update[0].out_transfer_func = NULL; 5230 + fast_update[0].output_csc_transform = NULL; 5231 + } 5232 + 5233 + for (i = 0; i < surface_count; i++) { 5234 + fast_update[i].flip_addr = srf_updates[i].flip_addr; 5235 + fast_update[i].gamma = srf_updates[i].gamma; 5236 + fast_update[i].gamut_remap_matrix = srf_updates[i].gamut_remap_matrix; 5237 + fast_update[i].input_csc_color_matrix = srf_updates[i].input_csc_color_matrix; 5238 + fast_update[i].coeff_reduction_factor = srf_updates[i].coeff_reduction_factor; 5239 + fast_update[i].cursor_csc_color_matrix = srf_updates[i].cursor_csc_color_matrix; 5240 + #if defined(CONFIG_DRM_AMD_DC_DCN4_2) 5241 + fast_update[i].cm_hist_control = srf_updates[i].cm_hist_control; 5242 + #endif 5243 + } 5244 + } 5245 + 5246 + static bool fast_updates_exist(const struct dc_fast_update *fast_update, int surface_count) 5247 + { 5248 + int i; 5249 + 5250 + if (fast_update[0].out_transfer_func || 5251 + fast_update[0].output_csc_transform) 5252 + return true; 5253 + 5254 + for (i = 0; i < surface_count; i++) { 5255 + if (fast_update[i].flip_addr || 5256 + fast_update[i].gamma || 5257 + fast_update[i].gamut_remap_matrix || 5258 + fast_update[i].input_csc_color_matrix || 5259 + fast_update[i].cursor_csc_color_matrix || 5260 + #if defined(CONFIG_DRM_AMD_DC_DCN4_2) 5261 + fast_update[i].cm_hist_control || 5262 + #endif 5263 + fast_update[i].coeff_reduction_factor) 5264 + return true; 5265 + } 5266 + 5267 + return false; 5268 + } 5269 + 5270 + bool fast_nonaddr_updates_exist(struct dc_fast_update *fast_update, int surface_count) 5271 + { 5272 + int i; 5273 + 5274 + if (fast_update[0].out_transfer_func || 5275 + fast_update[0].output_csc_transform) 5276 + return true; 5277 + 5278 + for (i = 0; i < surface_count; i++) { 5279 + if (fast_update[i].input_csc_color_matrix || 5280 + fast_update[i].gamma || 5281 + fast_update[i].gamut_remap_matrix || 5282 + fast_update[i].coeff_reduction_factor || 5283 + #if defined(CONFIG_DRM_AMD_DC_DCN4_2) 5284 + fast_update[i].cm_hist_control || 5285 + #endif 5286 + fast_update[i].cursor_csc_color_matrix) 5287 + return true; 5288 + } 5289 + 5290 + return false; 5291 + } 5292 + 5293 + static bool full_update_required_weak( 5294 + const struct dc *dc, 5295 + const struct dc_surface_update *srf_updates, 5296 + int surface_count, 5297 + const struct dc_stream_update *stream_update, 5298 + const struct dc_stream_state *stream) 5299 + { 5300 + (void)stream_update; 5301 + const struct dc_state *context = dc->current_state; 5302 + if (srf_updates) 5303 + for (int i = 0; i < surface_count; i++) 5304 + if (!is_surface_in_context(context, srf_updates[i].surface)) 5305 + return true; 5306 + 5307 + if (stream) { 5308 + const struct dc_stream_status *stream_status = dc_stream_get_status_const(stream); 5309 + if (stream_status == NULL || stream_status->plane_count != surface_count) 5310 + return true; 5311 + } 5312 + if (dc->idle_optimizations_allowed) 5313 + return true; 5314 + 5315 + if (dc_can_clear_cursor_limit(dc)) 5316 + return true; 5317 + 5318 + return false; 5319 + } 5320 + 5321 + static bool full_update_required( 5322 + const struct dc *dc, 5323 + const struct dc_surface_update *srf_updates, 5324 + int surface_count, 5325 + const struct dc_stream_update *stream_update, 5326 + const struct dc_stream_state *stream) 5327 + { 5328 + const union dc_plane_cm_flags blend_only_flags = { 5329 + .bits = { 5330 + .blend_enable = 1, 5331 + } 5332 + }; 5333 + 5334 + if (full_update_required_weak(dc, srf_updates, surface_count, stream_update, stream)) 5335 + return true; 5336 + 5337 + for (int i = 0; i < surface_count; i++) { 5338 + if (srf_updates && 5339 + (srf_updates[i].plane_info || 5340 + srf_updates[i].scaling_info || 5341 + (srf_updates[i].hdr_mult.value && 5342 + srf_updates[i].hdr_mult.value != srf_updates->surface->hdr_mult.value) || 5343 + (srf_updates[i].sdr_white_level_nits && 5344 + srf_updates[i].sdr_white_level_nits != srf_updates->surface->sdr_white_level_nits) || 5345 + srf_updates[i].in_transfer_func || 5346 + srf_updates[i].surface->force_full_update || 5347 + (srf_updates[i].flip_addr && 5348 + srf_updates[i].flip_addr->address.tmz_surface != srf_updates[i].surface->address.tmz_surface) || 5349 + (srf_updates[i].cm && 5350 + ((srf_updates[i].cm->flags.all != blend_only_flags.all && srf_updates[i].cm->flags.all != 0) || 5351 + (srf_updates[i].surface->cm.flags.all != blend_only_flags.all && srf_updates[i].surface->cm.flags.all != 0))))) 5352 + return true; 5353 + } 5354 + 5355 + if (stream_update && 5356 + (((stream_update->src.height != 0 && stream_update->src.width != 0) || 5357 + (stream_update->dst.height != 0 && stream_update->dst.width != 0) || 5358 + stream_update->integer_scaling_update) || 5359 + stream_update->hdr_static_metadata || 5360 + stream_update->abm_level || 5361 + stream_update->periodic_interrupt || 5362 + stream_update->vrr_infopacket || 5363 + stream_update->vsc_infopacket || 5364 + stream_update->vsp_infopacket || 5365 + stream_update->hfvsif_infopacket || 5366 + stream_update->vtem_infopacket || 5367 + stream_update->adaptive_sync_infopacket || 5368 + stream_update->avi_infopacket || 5369 + stream_update->dpms_off || 5370 + stream_update->allow_freesync || 5371 + stream_update->vrr_active_variable || 5372 + stream_update->vrr_active_fixed || 5373 + stream_update->gamut_remap || 5374 + stream_update->output_color_space || 5375 + stream_update->dither_option || 5376 + stream_update->wb_update || 5377 + stream_update->dsc_config || 5378 + stream_update->mst_bw_update || 5379 + stream_update->func_shaper || 5380 + stream_update->lut3d_func || 5381 + stream_update->pending_test_pattern || 5382 + stream_update->crtc_timing_adjust || 5383 + stream_update->scaler_sharpener_update || 5384 + stream_update->hw_cursor_req)) 5385 + return true; 5386 + 5387 + return false; 5388 + } 5389 + 5390 + static bool fast_update_only( 5391 + const struct dc *dc, 5392 + const struct dc_fast_update *fast_update, 5393 + const struct dc_surface_update *srf_updates, 5394 + int surface_count, 5395 + const struct dc_stream_update *stream_update, 5396 + const struct dc_stream_state *stream) 5397 + { 5398 + return fast_updates_exist(fast_update, surface_count) 5399 + && !full_update_required(dc, srf_updates, surface_count, stream_update, stream); 5400 + } 5401 + 5097 5402 static bool update_planes_and_stream_v2(struct dc *dc, 5098 5403 struct dc_surface_update *srf_updates, int surface_count, 5099 5404 struct dc_stream_state *stream, 5100 5405 struct dc_stream_update *stream_update) 5101 5406 { 5102 5407 struct dc_state *context; 5408 + enum surface_update_type update_type; 5409 + struct dc_fast_update fast_update[MAX_SURFACES] = {0}; 5103 5410 5104 5411 /* In cases where MPO and split or ODM are used transitions can 5105 5412 * cause underflow. Apply stream configuration with minimal pipe ··· 5293 5228 */ 5294 5229 bool force_minimal_pipe_splitting = 0; 5295 5230 bool is_plane_addition = 0; 5231 + bool is_fast_update_only; 5296 5232 5297 - struct surface_update_descriptor update_descriptor = {0}; 5298 - 5233 + populate_fast_updates(fast_update, srf_updates, surface_count, stream_update); 5234 + is_fast_update_only = fast_update_only(dc, fast_update, srf_updates, 5235 + surface_count, stream_update, stream); 5299 5236 force_minimal_pipe_splitting = could_mpcc_tree_change_for_active_pipes( 5300 5237 dc, 5301 5238 stream, ··· 5316 5249 surface_count, 5317 5250 stream, 5318 5251 stream_update, 5319 - &update_descriptor, 5252 + &update_type, 5320 5253 &context)) 5321 5254 return false; 5322 5255 ··· 5326 5259 dc_state_release(context); 5327 5260 return false; 5328 5261 } 5329 - elevate_update_type(&update_descriptor, UPDATE_TYPE_FULL, LOCK_DESCRIPTOR_GLOBAL); 5262 + update_type = UPDATE_TYPE_FULL; 5330 5263 } 5331 5264 5332 5265 if (dc->hwss.is_pipe_topology_transition_seamless && ··· 5335 5268 commit_minimal_transition_state_in_dc_update(dc, context, stream, 5336 5269 srf_updates, surface_count); 5337 5270 5338 - if (update_descriptor.update_type <= UPDATE_TYPE_FAST) { 5271 + if (is_fast_update_only && !dc->check_config.enable_legacy_fast_update) { 5339 5272 commit_planes_for_stream_fast(dc, 5340 5273 srf_updates, 5341 5274 surface_count, 5342 5275 stream, 5343 5276 stream_update, 5344 - update_descriptor.update_type, 5277 + update_type, 5345 5278 context); 5346 5279 } else { 5347 5280 if (!stream_update && ··· 5357 5290 surface_count, 5358 5291 stream, 5359 5292 stream_update, 5360 - update_descriptor.update_type, 5293 + update_type, 5361 5294 context); 5362 5295 } 5363 5296 if (dc->current_state != context) ··· 5371 5304 struct dc_stream_update *stream_update, 5372 5305 enum surface_update_type update_type) 5373 5306 { 5307 + struct dc_fast_update fast_update[MAX_SURFACES] = {0}; 5308 + 5374 5309 ASSERT(update_type < UPDATE_TYPE_FULL); 5375 - if (update_type <= UPDATE_TYPE_FAST) 5310 + populate_fast_updates(fast_update, srf_updates, surface_count, 5311 + stream_update); 5312 + if (fast_update_only(dc, fast_update, srf_updates, surface_count, 5313 + stream_update, stream) && 5314 + !dc->check_config.enable_legacy_fast_update) 5376 5315 commit_planes_for_stream_fast(dc, 5377 5316 srf_updates, 5378 5317 surface_count, ··· 5469 5396 struct dc_stream_update *stream_update) 5470 5397 { 5471 5398 struct dc_state *new_context; 5472 - struct surface_update_descriptor update_descriptor = {0}; 5399 + enum surface_update_type update_type; 5473 5400 5474 5401 /* 5475 5402 * When this function returns true and new_context is not equal to ··· 5481 5408 * replaced by a newer context. Refer to the use of 5482 5409 * swap_and_free_current_context below. 5483 5410 */ 5484 - if (!update_planes_and_stream_state(dc, 5485 - srf_updates, 5486 - surface_count, 5487 - stream, 5488 - stream_update, 5489 - &update_descriptor, 5411 + if (!update_planes_and_stream_state(dc, srf_updates, surface_count, 5412 + stream, stream_update, &update_type, 5490 5413 &new_context)) 5491 5414 return false; 5492 5415 5493 5416 if (new_context == dc->current_state) { 5494 5417 commit_planes_and_stream_update_on_current_context(dc, 5495 5418 srf_updates, surface_count, stream, 5496 - stream_update, update_descriptor.update_type); 5419 + stream_update, update_type); 5497 5420 5498 5421 if (dc->check_config.transition_countdown_to_steady_state) 5499 5422 dc->check_config.transition_countdown_to_steady_state--; 5500 5423 } else { 5501 5424 commit_planes_and_stream_update_with_new_context(dc, 5502 5425 srf_updates, surface_count, stream, 5503 - stream_update, update_descriptor.update_type, new_context); 5426 + stream_update, update_type, new_context); 5504 5427 } 5505 5428 5506 5429 return true; ··· 7268 7199 struct dc_stream_update *stream_update; 7269 7200 bool update_v3; 7270 7201 bool do_clear_update_flags; 7271 - struct surface_update_descriptor update_descriptor; 7202 + enum surface_update_type update_type; 7272 7203 struct dc_state *new_context; 7273 7204 enum update_v3_flow flow; 7274 7205 struct dc_state *backup_context; ··· 7351 7282 ASSERT(scratch->flow == UPDATE_V3_FLOW_INVALID); 7352 7283 dc_exit_ips_for_hw_access(scratch->dc); 7353 7284 7285 + /* HWSS path determination needs to be done prior to updating the surface and stream states. */ 7286 + struct dc_fast_update fast_update[MAX_SURFACES] = { 0 }; 7287 + 7288 + populate_fast_updates(fast_update, 7289 + scratch->surface_updates, 7290 + scratch->surface_count, 7291 + scratch->stream_update); 7292 + 7293 + const bool is_hwss_fast_path_only = 7294 + fast_update_only(scratch->dc, 7295 + fast_update, 7296 + scratch->surface_updates, 7297 + scratch->surface_count, 7298 + scratch->stream_update, 7299 + scratch->stream) && 7300 + !scratch->dc->check_config.enable_legacy_fast_update; 7301 + 7354 7302 if (!update_planes_and_stream_state( 7355 7303 scratch->dc, 7356 7304 scratch->surface_updates, 7357 7305 scratch->surface_count, 7358 7306 scratch->stream, 7359 7307 scratch->stream_update, 7360 - &scratch->update_descriptor, 7308 + &scratch->update_type, 7361 7309 &scratch->new_context 7362 7310 )) { 7363 7311 return false; 7364 7312 } 7365 7313 7366 7314 if (scratch->new_context == scratch->dc->current_state) { 7367 - ASSERT(scratch->update_descriptor.update_type < UPDATE_TYPE_FULL); 7315 + ASSERT(scratch->update_type < UPDATE_TYPE_FULL); 7368 7316 7369 - scratch->flow = scratch->update_descriptor.update_type <= UPDATE_TYPE_FAST 7317 + scratch->flow = is_hwss_fast_path_only 7370 7318 ? UPDATE_V3_FLOW_NO_NEW_CONTEXT_CONTEXT_FAST 7371 7319 : UPDATE_V3_FLOW_NO_NEW_CONTEXT_CONTEXT_FULL; 7372 7320 return true; 7373 7321 } 7374 7322 7375 - ASSERT(scratch->update_descriptor.update_type >= UPDATE_TYPE_FULL); 7323 + ASSERT(scratch->update_type >= UPDATE_TYPE_FULL); 7376 7324 7377 7325 const bool seamless = scratch->dc->hwss.is_pipe_topology_transition_seamless( 7378 7326 scratch->dc, ··· 7462 7376 intermediate_update ? scratch->intermediate_count : scratch->surface_count, 7463 7377 scratch->stream, 7464 7378 use_stream_update ? scratch->stream_update : NULL, 7465 - intermediate_context ? UPDATE_TYPE_FULL : scratch->update_descriptor.update_type, 7379 + intermediate_context ? UPDATE_TYPE_FULL : scratch->update_type, 7466 7380 // `dc->current_state` only used in `NO_NEW_CONTEXT`, where it is equal to `new_context` 7467 7381 intermediate_context ? scratch->intermediate_context : scratch->new_context 7468 7382 ); ··· 7480 7394 scratch->surface_count, 7481 7395 scratch->stream, 7482 7396 scratch->stream_update, 7483 - scratch->update_descriptor.update_type, 7397 + scratch->update_type, 7484 7398 scratch->new_context 7485 7399 ); 7486 7400 break;
+20 -2
drivers/gpu/drm/amd/display/dc/dc.h
··· 467 467 */ 468 468 469 469 enum surface_update_type { 470 - UPDATE_TYPE_ADDR_ONLY, /* only surface address is being updated, no other programming needed */ 471 470 UPDATE_TYPE_FAST, /* super fast, safe to execute in isr */ 472 471 UPDATE_TYPE_MED, /* ISR safe, most of programming needed, no bw/clk change*/ 473 472 UPDATE_TYPE_FULL, /* may need to shuffle resources */ ··· 1880 1881 struct scaling_taps scaling_quality; 1881 1882 }; 1882 1883 1884 + struct dc_fast_update { 1885 + const struct dc_flip_addrs *flip_addr; 1886 + const struct dc_gamma *gamma; 1887 + const struct colorspace_transform *gamut_remap_matrix; 1888 + const struct dc_csc_transform *input_csc_color_matrix; 1889 + const struct fixed31_32 *coeff_reduction_factor; 1890 + struct dc_transfer_func *out_transfer_func; 1891 + struct dc_csc_transform *output_csc_transform; 1892 + const struct dc_csc_transform *cursor_csc_color_matrix; 1893 + #if defined(CONFIG_DRM_AMD_DC_DCN4_2) 1894 + struct cm_hist_control *cm_hist_control; 1895 + #endif 1896 + }; 1897 + 1883 1898 struct dc_surface_update { 1884 1899 struct dc_plane_state *surface; 1885 1900 ··· 2032 2019 void get_audio_check(struct audio_info *aud_modes, 2033 2020 struct audio_check *aud_chk); 2034 2021 2035 - /* 2022 + bool fast_nonaddr_updates_exist(struct dc_fast_update *fast_update, int surface_count); 2023 + void populate_fast_updates(struct dc_fast_update *fast_update, 2024 + struct dc_surface_update *srf_updates, 2025 + int surface_count, 2026 + struct dc_stream_update *stream_update); 2027 + /* 2036 2028 * Set up streams and links associated to drive sinks 2037 2029 * The streams parameter is an absolute set of all active streams. 2038 2030 *