]> git.dujemihanovic.xyz Git - linux.git/commitdiff
drm/amd/display: update extended blank for dcn314 onwards
authorGabe Teeger <gabe.teeger@amd.com>
Thu, 6 Apr 2023 21:03:06 +0000 (17:03 -0400)
committerAlex Deucher <alexander.deucher@amd.com>
Mon, 24 Apr 2023 22:36:46 +0000 (18:36 -0400)
[Why]
Flickering and underflow was observed when testing extended
blank on dcn314.

[What]
Vstartup is contrainted by vblank_nom, so adjusting it to include
non-adjusted vtotal in its calculation during freesync video
means that Vstartup is not changed when vtotal changes.
This fixed the flickering + underflow.

dc_extended_blank_supported function was removed
because extended blank is only relevant to when
zstate is supported. The increased vtotal during
freesync can be passed to dml regardless of whether
extended blank is supported or not, so this function is
not needed.

Updates were made recently in dml to the calculation of
min_dst_y_next_start. Dml input for dcn314 will now
always use the newer calculation for min_dst_y_next_start.
Dml input for older dcn versions remains untouched.

The variable optimized_min_dst_y_next_start
is replaced everywhere with min_dst_y_next_start,
and the updated dml allows min_dst_y_next_start to
increase to an optimized value during freesync video,
then return to default when freesync is disengaged.

Also removed registry key for controlling
extended blank feature.

Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Reviewed-by: Nicholas Kazlauskas <Nicholas.Kazlauskas@amd.com>
Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
Signed-off-by: Gabe Teeger <gabe.teeger@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c
drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c
drivers/gpu/drm/amd/display/dc/dml/dcn31/display_rq_dlg_calc_31.c
drivers/gpu/drm/amd/display/dc/dml/dcn314/dcn314_fpu.c
drivers/gpu/drm/amd/display/dc/dml/dcn314/display_rq_dlg_calc_314.c
drivers/gpu/drm/amd/display/dc/dml/display_mode_structs.h

index c10243ef93b6be569f570ece08cd55dd8cd38661..89a245e3c9ac9d6a3710bd48155b709a67efe0a8 100644 (file)
@@ -2607,9 +2607,6 @@ static enum surface_update_type check_update_surfaces_for_stream(
                                stream_update->vrr_active_variable))
                        su_flags->bits.fams_changed = 1;
 
-               if (stream_update->crtc_timing_adjust && dc_extended_blank_supported(dc))
-                       su_flags->bits.crtc_timing_adjust = 1;
-
                if (su_flags->raw != 0)
                        overall_type = UPDATE_TYPE_FULL;
 
@@ -4849,21 +4846,3 @@ void dc_notify_vsync_int_state(struct dc *dc, struct dc_stream_state *stream, bo
        if (pipe->stream_res.abm && pipe->stream_res.abm->funcs->set_abm_pause)
                pipe->stream_res.abm->funcs->set_abm_pause(pipe->stream_res.abm, !enable, i, pipe->stream_res.tg->inst);
 }
-
-/**
- * dc_extended_blank_supported - Decide whether extended blank is supported
- *
- * @dc: [in] Current DC state
- *
- * Extended blank is a freesync optimization feature to be enabled in the
- * future.  During the extra vblank period gained from freesync, we have the
- * ability to enter z9/z10.
- *
- * Return:
- * Indicate whether extended blank is supported (%true or %false)
- */
-bool dc_extended_blank_supported(struct dc *dc)
-{
-       return dc->debug.extended_blank_optimization && !dc->debug.disable_z10
-               && dc->caps.zstate_support && dc->caps.is_apu;
-}
index dc0a61ca99d019a6b4ec2dff30b13e95ebf9b97c..5268d98b96dc4ca8113a9b4b9dcf163a5fdf6b3a 100644 (file)
@@ -2128,8 +2128,6 @@ struct dc_sink_init_data {
        bool converter_disable_audio;
 };
 
-bool dc_extended_blank_supported(struct dc *dc);
-
 struct dc_sink *dc_sink_create(const struct dc_sink_init_data *init_params);
 
 /* Newer interfaces  */
index 5800acf6aae11f9886282f41e5a40f1e47748c7d..f49c1c0d627478db9a104a5aaf837c19e858ab9f 100644 (file)
@@ -2130,7 +2130,7 @@ void dcn20_optimize_bandwidth(
                        dc->clk_mgr,
                        context,
                        true);
-       if (dc_extended_blank_supported(dc) && context->bw_ctx.bw.dcn.clk.zstate_support == DCN_ZSTATE_SUPPORT_ALLOW) {
+       if (context->bw_ctx.bw.dcn.clk.zstate_support == DCN_ZSTATE_SUPPORT_ALLOW) {
                for (i = 0; i < dc->res_pool->pipe_count; ++i) {
                        struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
 
@@ -2138,7 +2138,7 @@ void dcn20_optimize_bandwidth(
                                && pipe_ctx->stream->adjust.v_total_min == pipe_ctx->stream->adjust.v_total_max
                                && pipe_ctx->stream->adjust.v_total_max > pipe_ctx->stream->timing.v_total)
                                        pipe_ctx->plane_res.hubp->funcs->program_extended_blank(pipe_ctx->plane_res.hubp,
-                                               pipe_ctx->dlg_regs.optimized_min_dst_y_next_start);
+                                               pipe_ctx->dlg_regs.min_dst_y_next_start);
                }
        }
 }
index f1c1a4b5fcac33532b8eb0911d344a2b13051d10..7661f8946aa31c938ffa7ee3e93f0c1bc0b03135 100644 (file)
@@ -948,10 +948,10 @@ static enum dcn_zstate_support_state  decide_zstate_support(struct dc *dc, struc
 {
        int plane_count;
        int i;
-       unsigned int optimized_min_dst_y_next_start_us;
+       unsigned int min_dst_y_next_start_us;
 
        plane_count = 0;
-       optimized_min_dst_y_next_start_us = 0;
+       min_dst_y_next_start_us = 0;
        for (i = 0; i < dc->res_pool->pipe_count; i++) {
                if (context->res_ctx.pipe_ctx[i].plane_state)
                        plane_count++;
@@ -973,19 +973,18 @@ static enum dcn_zstate_support_state  decide_zstate_support(struct dc *dc, struc
        else if (context->stream_count == 1 &&  context->streams[0]->signal == SIGNAL_TYPE_EDP) {
                struct dc_link *link = context->streams[0]->sink->link;
                struct dc_stream_status *stream_status = &context->stream_status[0];
+               struct dc_stream_state *current_stream = context->streams[0];
                int minmum_z8_residency = dc->debug.minimum_z8_residency_time > 0 ? dc->debug.minimum_z8_residency_time : 1000;
                bool allow_z8 = context->bw_ctx.dml.vba.StutterPeriod > (double)minmum_z8_residency;
                bool is_pwrseq0 = link->link_index == 0;
+               bool isFreesyncVideo;
 
-               if (dc_extended_blank_supported(dc)) {
-                       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-                               if (context->res_ctx.pipe_ctx[i].stream == context->streams[0]
-                                       && context->res_ctx.pipe_ctx[i].stream->adjust.v_total_min == context->res_ctx.pipe_ctx[i].stream->adjust.v_total_max
-                                       && context->res_ctx.pipe_ctx[i].stream->adjust.v_total_min > context->res_ctx.pipe_ctx[i].stream->timing.v_total) {
-                                               optimized_min_dst_y_next_start_us =
-                                                       context->res_ctx.pipe_ctx[i].dlg_regs.optimized_min_dst_y_next_start_us;
-                                               break;
-                               }
+               isFreesyncVideo = current_stream->adjust.v_total_min == current_stream->adjust.v_total_max;
+               isFreesyncVideo = isFreesyncVideo && current_stream->timing.v_total < current_stream->adjust.v_total_min;
+               for (i = 0; i < dc->res_pool->pipe_count; i++) {
+                       if (context->res_ctx.pipe_ctx[i].stream == current_stream && isFreesyncVideo) {
+                               min_dst_y_next_start_us = context->res_ctx.pipe_ctx[i].dlg_regs.min_dst_y_next_start_us;
+                               break;
                        }
                }
 
@@ -993,7 +992,7 @@ static enum dcn_zstate_support_state  decide_zstate_support(struct dc *dc, struc
                if (stream_status->plane_count > 1)
                        return DCN_ZSTATE_SUPPORT_DISALLOW;
 
-               if (is_pwrseq0 && (context->bw_ctx.dml.vba.StutterPeriod > 5000.0 || optimized_min_dst_y_next_start_us > 5000))
+               if (is_pwrseq0 && (context->bw_ctx.dml.vba.StutterPeriod > 5000.0 || min_dst_y_next_start_us > 5000))
                        return DCN_ZSTATE_SUPPORT_ALLOW;
                else if (is_pwrseq0 && link->psr_settings.psr_version == DC_PSR_VERSION_1 && !link->panel_config.psr.disable_psr)
                        return allow_z8 ? DCN_ZSTATE_SUPPORT_ALLOW_Z8_Z10_ONLY : DCN_ZSTATE_SUPPORT_ALLOW_Z10_ONLY;
index 2244e4fb8c96da195ce1c1b1d3771c13de5dc576..fcde8f21b8be0ac91cb2873ab06464266020eee3 100644 (file)
@@ -987,8 +987,7 @@ static void dml_rq_dlg_get_dlg_params(
 
        dlg_vblank_start = interlaced ? (vblank_start / 2) : vblank_start;
        disp_dlg_regs->min_dst_y_next_start = (unsigned int) (((double) dlg_vblank_start) * dml_pow(2, 2));
-       disp_dlg_regs->optimized_min_dst_y_next_start_us = 0;
-       disp_dlg_regs->optimized_min_dst_y_next_start = disp_dlg_regs->min_dst_y_next_start;
+       disp_dlg_regs->min_dst_y_next_start_us = 0;
        ASSERT(disp_dlg_regs->min_dst_y_next_start < (unsigned int)dml_pow(2, 18));
 
        dml_print("DML_DLG: %s: min_ttu_vblank (us)         = %3.2f\n", __func__, min_ttu_vblank);
index 44082f65de1fa233f6056e0871a476f60d0642b5..19370b872a91d51c12c2ef471cb8cddacdc9aa29 100644 (file)
@@ -286,6 +286,7 @@ int dcn314_populate_dml_pipes_from_context_fpu(struct dc *dc, struct dc_state *c
        struct resource_context *res_ctx = &context->res_ctx;
        struct pipe_ctx *pipe;
        bool upscaled = false;
+       bool isFreesyncVideo = false;
 
        dc_assert_fp_enabled();
 
@@ -299,9 +300,16 @@ int dcn314_populate_dml_pipes_from_context_fpu(struct dc *dc, struct dc_state *c
                pipe = &res_ctx->pipe_ctx[i];
                timing = &pipe->stream->timing;
 
-               if (dc_extended_blank_supported(dc) && pipe->stream->adjust.v_total_max == pipe->stream->adjust.v_total_min
-                       && pipe->stream->adjust.v_total_min > timing->v_total)
+               isFreesyncVideo = pipe->stream->adjust.v_total_max == pipe->stream->adjust.v_total_min;
+               isFreesyncVideo = isFreesyncVideo && pipe->stream->adjust.v_total_min > timing->v_total;
+
+               if (!isFreesyncVideo) {
+                       pipes[pipe_cnt].pipe.dest.vblank_nom =
+                               dcn3_14_ip.VBlankNomDefaultUS / (timing->h_total / (timing->pix_clk_100hz / 10000.0));
+               } else {
                        pipes[pipe_cnt].pipe.dest.vtotal = pipe->stream->adjust.v_total_min;
+                       pipes[pipe_cnt].pipe.dest.vblank_nom = timing->v_total - pipes[pipe_cnt].pipe.dest.vactive;
+               }
 
                if (pipe->plane_state &&
                                (pipe->plane_state->src_rect.height < pipe->plane_state->dst_rect.height ||
@@ -323,8 +331,6 @@ int dcn314_populate_dml_pipes_from_context_fpu(struct dc *dc, struct dc_state *c
                pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_luma = 0;
                pipes[pipe_cnt].pipe.src.dcc_fraction_of_zs_req_chroma = 0;
                pipes[pipe_cnt].pipe.dest.vfront_porch = timing->v_front_porch;
-               pipes[pipe_cnt].pipe.dest.vblank_nom =
-                               dcn3_14_ip.VBlankNomDefaultUS / (timing->h_total / (timing->pix_clk_100hz / 10000.0));
                pipes[pipe_cnt].pipe.src.dcc_rate = 3;
                pipes[pipe_cnt].dout.dsc_input_bpc = 0;
 
index ea4eb66066c42bc00767f27bf7e7a692e04c0de7..4f945458b2b7ede84f8a13565ccb08e661096071 100644 (file)
@@ -1051,7 +1051,6 @@ static void dml_rq_dlg_get_dlg_params(
 
        float vba__refcyc_per_req_delivery_pre_l = get_refcyc_per_req_delivery_pre_l_in_us(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz;  // From VBA
        float vba__refcyc_per_req_delivery_l = get_refcyc_per_req_delivery_l_in_us(mode_lib, e2e_pipe_param, num_pipes, pipe_idx) * refclk_freq_in_mhz;  // From VBA
-       int blank_lines = 0;
 
        memset(disp_dlg_regs, 0, sizeof(*disp_dlg_regs));
        memset(disp_ttu_regs, 0, sizeof(*disp_ttu_regs));
@@ -1075,17 +1074,10 @@ static void dml_rq_dlg_get_dlg_params(
        min_ttu_vblank = get_min_ttu_vblank_in_us(mode_lib, e2e_pipe_param, num_pipes, pipe_idx);       // From VBA
 
        dlg_vblank_start = interlaced ? (vblank_start / 2) : vblank_start;
-       disp_dlg_regs->optimized_min_dst_y_next_start = disp_dlg_regs->min_dst_y_next_start;
-       disp_dlg_regs->optimized_min_dst_y_next_start_us = 0;
-       disp_dlg_regs->min_dst_y_next_start = (unsigned int) (((double) dlg_vblank_start) * dml_pow(2, 2));
-       blank_lines = (dst->vblank_end + dst->vtotal_min - dst->vblank_start - dst->vstartup_start - 1);
-       if (blank_lines < 0)
-               blank_lines = 0;
-       if (blank_lines != 0) {
-               disp_dlg_regs->optimized_min_dst_y_next_start = vba__min_dst_y_next_start;
-               disp_dlg_regs->optimized_min_dst_y_next_start_us = (disp_dlg_regs->optimized_min_dst_y_next_start * dst->hactive) / (unsigned int) dst->pixel_rate_mhz;
-               disp_dlg_regs->min_dst_y_next_start = disp_dlg_regs->optimized_min_dst_y_next_start;
-       }
+       disp_dlg_regs->min_dst_y_next_start_us =
+               (vba__min_dst_y_next_start * dst->hactive) / (unsigned int) dst->pixel_rate_mhz;
+       disp_dlg_regs->min_dst_y_next_start = vba__min_dst_y_next_start * dml_pow(2, 2);
+
        ASSERT(disp_dlg_regs->min_dst_y_next_start < (unsigned int)dml_pow(2, 18));
 
        dml_print("DML_DLG: %s: min_ttu_vblank (us)         = %3.2f\n", __func__, min_ttu_vblank);
index 3c077164f36203400f38d9910058e4004cca12bc..ff0246a9458fdc895ef443766cbce0f156237fe7 100644 (file)
@@ -619,8 +619,7 @@ struct _vcs_dpi_display_dlg_regs_st {
        unsigned int refcyc_h_blank_end;
        unsigned int dlg_vblank_end;
        unsigned int min_dst_y_next_start;
-       unsigned int optimized_min_dst_y_next_start;
-       unsigned int optimized_min_dst_y_next_start_us;
+       unsigned int min_dst_y_next_start_us;
        unsigned int refcyc_per_htotal;
        unsigned int refcyc_x_after_scaler;
        unsigned int dst_y_after_scaler;