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: Remove dc state from check_update

[Why]
dc_check_update_surfaces_for_stream should not have access to entire
DC, especially not a mutable one. Concurrent checks should be able
to run independently of one another, without risk of changing state.

[How]
* Remove access to dc state other than debug and capacity.
* Move some checks from DC to DM caller.

Reviewed-by: Nicholas Kazlauskas <nicholas.kazlauskas@amd.com>
Signed-off-by: Dominik Kaszewski <dominik.kaszewski@amd.com>
Signed-off-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Dominik Kaszewski and committed by
Alex Deucher
03a593b1 c04812cb

+41 -40
+41 -40
drivers/gpu/drm/amd/display/dc/core/dc.c
··· 2725 2725 elevate_update_type(&update_type, UPDATE_TYPE_MED); 2726 2726 } 2727 2727 2728 + const struct dc_tiling_info *tiling = &u->plane_info->tiling_info; 2728 2729 2729 - if (memcmp(&u->plane_info->tiling_info, &u->surface->tiling_info, 2730 - sizeof(struct dc_tiling_info)) != 0) { 2730 + if (memcmp(tiling, &u->surface->tiling_info, sizeof(*tiling)) != 0) { 2731 2731 update_flags->bits.swizzle_change = 1; 2732 2732 elevate_update_type(&update_type, UPDATE_TYPE_MED); 2733 2733 2734 - /* todo: below are HW dependent, we should add a hook to 2735 - * DCE/N resource and validated there. 2736 - */ 2737 - if (!dc->debug.skip_full_updated_if_possible) { 2738 - /* swizzled mode requires RQ to be setup properly, 2739 - * thus need to run DML to calculate RQ settings 2740 - */ 2741 - update_flags->bits.bandwidth_change = 1; 2742 - elevate_update_type(&update_type, UPDATE_TYPE_FULL); 2734 + switch (tiling->gfxversion) { 2735 + case DcGfxVersion9: 2736 + case DcGfxVersion10: 2737 + case DcGfxVersion11: 2738 + if (tiling->gfx9.swizzle != DC_SW_LINEAR) { 2739 + elevate_update_type(&update_type, UPDATE_TYPE_FULL); 2740 + update_flags->bits.bandwidth_change = 1; 2741 + } 2742 + break; 2743 + case DcGfxAddr3: 2744 + if (tiling->gfx_addr3.swizzle != DC_ADDR3_SW_LINEAR) { 2745 + elevate_update_type(&update_type, UPDATE_TYPE_FULL); 2746 + update_flags->bits.bandwidth_change = 1; 2747 + } 2748 + break; 2749 + case DcGfxVersion7: 2750 + case DcGfxVersion8: 2751 + case DcGfxVersionUnknown: 2752 + default: 2753 + break; 2743 2754 } 2744 2755 } 2745 2756 ··· 2819 2808 static enum surface_update_type det_surface_update(const struct dc *dc, 2820 2809 const struct dc_surface_update *u) 2821 2810 { 2822 - const struct dc_state *context = dc->current_state; 2823 2811 enum surface_update_type type; 2824 2812 enum surface_update_type overall_type = UPDATE_TYPE_FAST; 2825 2813 union surface_update_flags *update_flags = &u->surface->update_flags; 2826 2814 2827 - if (!is_surface_in_context(context, u->surface) || u->surface->force_full_update) { 2815 + if (u->surface->force_full_update) { 2828 2816 update_flags->raw = 0xFFFFFFFF; 2829 2817 return UPDATE_TYPE_FULL; 2830 2818 } ··· 2954 2944 int i; 2955 2945 enum surface_update_type overall_type = UPDATE_TYPE_FAST; 2956 2946 2957 - if (dc->idle_optimizations_allowed || dc_can_clear_cursor_limit(dc)) 2958 - overall_type = UPDATE_TYPE_FULL; 2959 - 2960 - if (stream_status == NULL || stream_status->plane_count != surface_count) 2961 - overall_type = UPDATE_TYPE_FULL; 2962 - 2963 2947 if (stream_update && stream_update->pending_test_pattern) { 2964 2948 overall_type = UPDATE_TYPE_FULL; 2965 2949 } ··· 3050 3046 updates[i].surface->update_flags.raw = 0; 3051 3047 3052 3048 type = check_update_surfaces_for_stream(dc, updates, surface_count, stream_update, stream_status); 3053 - if (type == UPDATE_TYPE_FULL) { 3054 - if (stream_update) { 3055 - uint32_t dsc_changed = stream_update->stream->update_flags.bits.dsc_changed; 3056 - stream_update->stream->update_flags.raw = 0xFFFFFFFF; 3057 - stream_update->stream->update_flags.bits.dsc_changed = dsc_changed; 3058 - } 3059 - for (i = 0; i < surface_count; i++) 3060 - updates[i].surface->update_flags.raw = 0xFFFFFFFF; 3061 - } 3062 - 3063 - if (type == UPDATE_TYPE_FAST) { 3064 - // If there's an available clock comparator, we use that. 3065 - if (dc->clk_mgr->funcs->are_clock_states_equal) { 3066 - if (!dc->clk_mgr->funcs->are_clock_states_equal(&dc->clk_mgr->clks, &dc->current_state->bw_ctx.bw.dcn.clk)) 3067 - dc->optimized_required = true; 3068 - // Else we fallback to mem compare. 3069 - } else if (memcmp(&dc->current_state->bw_ctx.bw.dcn.clk, &dc->clk_mgr->clks, offsetof(struct dc_clocks, prev_p_state_change_support)) != 0) { 3070 - dc->optimized_required = true; 3071 - } 3072 - } 3073 - 3074 3049 return type; 3075 3050 } 3076 3051 ··· 3419 3436 } 3420 3437 } 3421 3438 3439 + static bool full_update_required(struct dc *dc, 3440 + struct dc_surface_update *srf_updates, 3441 + int surface_count, 3442 + struct dc_stream_update *stream_update, 3443 + struct dc_stream_state *stream); 3444 + 3422 3445 /** 3423 3446 * update_planes_and_stream_state() - The function takes planes and stream 3424 3447 * updates as inputs and determines the appropriate update type. If update type ··· 3472 3483 context = dc->current_state; 3473 3484 update_type = dc_check_update_surfaces_for_stream( 3474 3485 dc, srf_updates, surface_count, stream_update, stream_status); 3486 + if (full_update_required(dc, srf_updates, surface_count, stream_update, stream)) 3487 + update_type = UPDATE_TYPE_FULL; 3475 3488 /* It is possible to receive a flip for one plane while there are multiple flip_immediate planes in the same stream. 3476 3489 * E.g. Desktop and MPO plane are flip_immediate but only the MPO plane received a flip 3477 3490 * Force the other flip_immediate planes to flip so GSL doesn't wait for a flip that won't come. ··· 3503 3512 return false; 3504 3513 } 3505 3514 } 3515 + } 3516 + 3517 + if (update_type == UPDATE_TYPE_FULL) { 3518 + if (stream_update) { 3519 + uint32_t dsc_changed = stream_update->stream->update_flags.bits.dsc_changed; 3520 + stream_update->stream->update_flags.raw = 0xFFFFFFFF; 3521 + stream_update->stream->update_flags.bits.dsc_changed = dsc_changed; 3522 + } 3523 + for (i = 0; i < surface_count; i++) 3524 + srf_updates[i].surface->update_flags.raw = 0xFFFFFFFF; 3506 3525 } 3507 3526 3508 3527 if (update_type >= update_surface_trace_level)