drm/amd/display: Add more mechanisms for tests
authorRelja Vojvodic <relja.vojvodic@amd.com>
Mon, 11 Dec 2023 23:00:14 +0000 (18:00 -0500)
committerAlex Deucher <alexander.deucher@amd.com>
Wed, 3 Jan 2024 15:31:22 +0000 (10:31 -0500)
[Why]
More information is desired for the test tools.

[How]
Refactored get_subvp_visual_confirm_color and
get_mclk_switch_visual_confirm_color to support the new method of
storing the p_state type, which was changed so that it could also be
saved and output by the DPM log. Ensured that the p_state type is kept
updated by looping through the pipes within commit_planes_for_stream.

Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Acked-by: Rodrigo Siqueira <rodrigo.siqueira@amd.com>
Reviewed-by: Alvin Lee <alvin.lee2@amd.com>
Signed-off-by: Relja Vojvodic <relja.vojvodic@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
drivers/gpu/drm/amd/display/dc/clk_mgr/dcn32/dcn32_clk_mgr.c
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/core/dc_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/hwss/hw_sequencer.h
drivers/gpu/drm/amd/display/dc/inc/core_types.h

index 95c0b49b531a082e550ab6ac39e6a3b19fc35332..51adb13b3b800f467c25edf08fa4d484bc59587f 100644 (file)
@@ -25,7 +25,6 @@
 
 #include "dccg.h"
 #include "clk_mgr_internal.h"
-
 #include "dcn32/dcn32_clk_mgr_smu_msg.h"
 #include "dcn20/dcn20_clk_mgr.h"
 #include "dce100/dce_clk_mgr.h"
@@ -34,7 +33,7 @@
 #include "core_types.h"
 #include "dm_helpers.h"
 #include "link.h"
-
+#include "dc_state_priv.h"
 #include "atomfirmware.h"
 #include "smu13_driver_if.h"
 
@@ -458,13 +457,43 @@ static int dcn32_get_dispclk_from_dentist(struct clk_mgr *clk_mgr_base)
        return 0;
 }
 
-static void dcn32_auto_dpm_test_log(struct dc_clocks *new_clocks, struct clk_mgr_internal *clk_mgr)
+static bool dcn32_check_native_scaling(struct pipe_ctx *pipe)
+{
+       bool is_native_scaling = false;
+       int width = pipe->plane_state->src_rect.width;
+       int height = pipe->plane_state->src_rect.height;
+
+       if (pipe->stream->timing.h_addressable == width &&
+                       pipe->stream->timing.v_addressable == height &&
+                       pipe->plane_state->dst_rect.width == width &&
+                       pipe->plane_state->dst_rect.height == height)
+               is_native_scaling = true;
+
+       return is_native_scaling;
+}
+
+static void dcn32_auto_dpm_test_log(
+               struct dc_clocks *new_clocks,
+               struct clk_mgr_internal *clk_mgr,
+               struct dc_state *context)
 {
        unsigned int dispclk_khz_reg, dppclk_khz_reg, dprefclk_khz_reg, dcfclk_khz_reg, dtbclk_khz_reg,
-                                fclk_khz_reg;
+                                fclk_khz_reg, mall_ss_size_bytes;
        int dramclk_khz_override, fclk_khz_override, num_fclk_levels;
 
-       msleep(5);
+       struct pipe_ctx *pipe_ctx_list[MAX_PIPES];
+       int active_pipe_count = 0;
+
+       for (int i = 0; i < MAX_PIPES; i++) {
+               struct pipe_ctx *pipe_ctx = &context->res_ctx.pipe_ctx[i];
+
+               if (pipe_ctx->stream && dc_state_get_pipe_subvp_type(context, pipe_ctx) != SUBVP_PHANTOM) {
+                       pipe_ctx_list[active_pipe_count] = pipe_ctx;
+                       active_pipe_count++;
+               }
+       }
+
+       mall_ss_size_bytes = context->bw_ctx.bw.dcn.mall_ss_size_bytes;
 
     dispclk_khz_reg    = REG_READ(CLK1_CLK0_CURRENT_CNT); // DISPCLK
     dppclk_khz_reg     = REG_READ(CLK1_CLK1_CURRENT_CNT); // DPPCLK
@@ -494,16 +523,49 @@ static void dcn32_auto_dpm_test_log(struct dc_clocks *new_clocks, struct clk_mgr
        //
        //                              AutoDPMTest: clk1:%d - clk2:%d - clk3:%d - clk4:%d\n"
        ////////////////////////////////////////////////////////////////////////////
-       if (new_clocks &&
+       if (new_clocks && active_pipe_count > 0 &&
                new_clocks->dramclk_khz > 0 &&
                new_clocks->fclk_khz > 0 &&
                new_clocks->dcfclk_khz > 0 &&
                new_clocks->dppclk_khz > 0) {
 
+               uint32_t pix_clk_list[MAX_PIPES] = {0};
+               int p_state_list[MAX_PIPES] = {0};
+               int disp_src_width_list[MAX_PIPES] = {0};
+               int disp_src_height_list[MAX_PIPES] = {0};
+               uint64_t disp_src_refresh_list[MAX_PIPES] = {0};
+               bool is_scaled_list[MAX_PIPES] = {0};
+
+               for (int i = 0; i < active_pipe_count; i++) {
+                       struct pipe_ctx *curr_pipe_ctx = pipe_ctx_list[i];
+                       uint64_t refresh_rate;
+
+                       pix_clk_list[i] = curr_pipe_ctx->stream->timing.pix_clk_100hz;
+                       p_state_list[i] = curr_pipe_ctx->p_state_type;
+
+                       refresh_rate = (curr_pipe_ctx->stream->timing.pix_clk_100hz * (uint64_t)100 +
+                               curr_pipe_ctx->stream->timing.v_total * curr_pipe_ctx->stream->timing.h_total - (uint64_t)1);
+                       refresh_rate = div_u64(refresh_rate, curr_pipe_ctx->stream->timing.v_total);
+                       refresh_rate = div_u64(refresh_rate, curr_pipe_ctx->stream->timing.h_total);
+                       disp_src_refresh_list[i] = refresh_rate;
+
+                       if (curr_pipe_ctx->plane_state) {
+                               is_scaled_list[i] = !(dcn32_check_native_scaling(curr_pipe_ctx));
+                               disp_src_width_list[i] = curr_pipe_ctx->plane_state->src_rect.width;
+                               disp_src_height_list[i] = curr_pipe_ctx->plane_state->src_rect.height;
+                       }
+               }
+
                DC_LOG_AUTO_DPM_TEST("AutoDPMTest: dramclk:%d - fclk:%d - "
                        "dcfclk:%d - dppclk:%d - dispclk_hw:%d - "
                        "dppclk_hw:%d - dprefclk_hw:%d - dcfclk_hw:%d - "
-                       "dtbclk_hw:%d - fclk_hw:%d\n",
+                       "dtbclk_hw:%d - fclk_hw:%d - pix_clk_0:%d - pix_clk_1:%d - "
+                       "pix_clk_2:%d - pix_clk_3:%d - mall_ss_size:%d - p_state_type_0:%d - "
+                       "p_state_type_1:%d - p_state_type_2:%d - p_state_type_3:%d - "
+                       "pix_width_0:%d - pix_height_0:%d - refresh_rate_0:%lld - is_scaled_0:%d - "
+                       "pix_width_1:%d - pix_height_1:%d - refresh_rate_1:%lld - is_scaled_1:%d - "
+                       "pix_width_2:%d - pix_height_2:%d - refresh_rate_2:%lld - is_scaled_2:%d - "
+                       "pix_width_3:%d - pix_height_3:%d - refresh_rate_3:%lld - is_scaled_3:%d\n",
                        dramclk_khz_override,
                        fclk_khz_override,
                        new_clocks->dcfclk_khz,
@@ -513,7 +575,14 @@ static void dcn32_auto_dpm_test_log(struct dc_clocks *new_clocks, struct clk_mgr
                        dprefclk_khz_reg,
                        dcfclk_khz_reg,
                        dtbclk_khz_reg,
-                       fclk_khz_reg);
+                       fclk_khz_reg,
+                       pix_clk_list[0], pix_clk_list[1], pix_clk_list[3], pix_clk_list[2],
+                       mall_ss_size_bytes,
+                       p_state_list[0], p_state_list[1], p_state_list[2], p_state_list[3],
+                       disp_src_width_list[0], disp_src_height_list[0], disp_src_refresh_list[0], is_scaled_list[0],
+                       disp_src_width_list[1], disp_src_height_list[1], disp_src_refresh_list[1], is_scaled_list[1],
+                       disp_src_width_list[2], disp_src_height_list[2], disp_src_refresh_list[2], is_scaled_list[2],
+                       disp_src_width_list[3], disp_src_height_list[3], disp_src_refresh_list[3], is_scaled_list[3]);
        }
 }
 
@@ -686,6 +755,7 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base,
                /* DCCG requires KHz precision for DTBCLK */
                clk_mgr_base->clks.ref_dtbclk_khz =
                                dcn32_smu_set_hard_min_by_freq(clk_mgr, PPCLK_DTBCLK, khz_to_mhz_ceil(new_clocks->ref_dtbclk_khz));
+
                dcn32_update_clocks_update_dtb_dto(clk_mgr, context, clk_mgr_base->clks.ref_dtbclk_khz);
        }
 
@@ -713,8 +783,8 @@ static void dcn32_update_clocks(struct clk_mgr *clk_mgr_base,
                dmcu->funcs->set_psr_wait_loop(dmcu,
                                clk_mgr_base->clks.dispclk_khz / 1000 / 7);
 
-       if (dc->config.enable_auto_dpm_test_logs && safe_to_lower) {
-           dcn32_auto_dpm_test_log(new_clocks, clk_mgr);
+       if (dc->config.enable_auto_dpm_test_logs) {
+           dcn32_auto_dpm_test_log(new_clocks, clk_mgr, context);
        }
 }
 
index 043913d65b16292db9786754b02e83823624eff6..d55de3f5115df4a2a8a30414b48b4328f6a5ccd9 100644 (file)
@@ -1088,7 +1088,7 @@ static void apply_ctx_interdependent_lock(struct dc *dc,
        }
 }
 
-static void dc_update_viusal_confirm_color(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx)
+static void dc_update_visual_confirm_color(struct dc *dc, struct dc_state *context, struct pipe_ctx *pipe_ctx)
 {
        if (dc->ctx->dce_version >= DCN_VERSION_1_0) {
                memset(&pipe_ctx->visual_confirm_color, 0, sizeof(struct tg_color));
@@ -1108,9 +1108,9 @@ static void dc_update_viusal_confirm_color(struct dc *dc, struct dc_state *conte
                        if (dc->debug.visual_confirm == VISUAL_CONFIRM_MPCTREE)
                                get_mpctree_visual_confirm_color(pipe_ctx, &(pipe_ctx->visual_confirm_color));
                        else if (dc->debug.visual_confirm == VISUAL_CONFIRM_SUBVP)
-                               get_subvp_visual_confirm_color(dc, context, pipe_ctx, &(pipe_ctx->visual_confirm_color));
+                               get_subvp_visual_confirm_color(pipe_ctx, &(pipe_ctx->visual_confirm_color));
                        else if (dc->debug.visual_confirm == VISUAL_CONFIRM_MCLK_SWITCH)
-                               get_mclk_switch_visual_confirm_color(dc, context, pipe_ctx, &(pipe_ctx->visual_confirm_color));
+                               get_mclk_switch_visual_confirm_color(pipe_ctx, &(pipe_ctx->visual_confirm_color));
                }
        }
 }
@@ -1190,8 +1190,10 @@ static void disable_dangling_plane(struct dc *dc, struct dc_state *context)
                                dc_state_rem_all_planes_for_stream(dc, old_stream, dangling_context);
                        disable_all_writeback_pipes_for_stream(dc, old_stream, dangling_context);
 
-                       if (pipe->stream && pipe->plane_state)
-                               dc_update_viusal_confirm_color(dc, context, pipe);
+                       if (pipe->stream && pipe->plane_state) {
+                               set_p_state_switch_method(dc, context, pipe);
+                               dc_update_visual_confirm_color(dc, context, pipe);
+                       }
 
                        if (dc->hwss.apply_ctx_for_surface) {
                                apply_ctx_interdependent_lock(dc, dc->current_state, old_stream, true);
@@ -3377,12 +3379,14 @@ static void commit_planes_for_stream_fast(struct dc *dc,
                        &context->res_ctx,
                        stream);
 
-       if (dc->debug.visual_confirm) {
-               for (i = 0; i < dc->res_pool->pipe_count; i++) {
-                       struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+
+               if (pipe->stream && pipe->plane_state) {
+                       set_p_state_switch_method(dc, context, pipe);
 
-                       if (pipe->stream && pipe->plane_state)
-                               dc_update_viusal_confirm_color(dc, context, pipe);
+                       if (dc->debug.visual_confirm)
+                               dc_update_visual_confirm_color(dc, context, pipe);
                }
        }
 
@@ -3531,13 +3535,16 @@ static void commit_planes_for_stream(struct dc *dc,
                }
        }
 
-       if (dc->debug.visual_confirm)
-               for (i = 0; i < dc->res_pool->pipe_count; i++) {
-                       struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+       for (i = 0; i < dc->res_pool->pipe_count; i++) {
+               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
 
-                       if (pipe->stream && pipe->plane_state)
-                               dc_update_viusal_confirm_color(dc, context, pipe);
+               if (pipe->stream && pipe->plane_state) {
+                       set_p_state_switch_method(dc, context, pipe);
+
+                       if (dc->debug.visual_confirm)
+                               dc_update_visual_confirm_color(dc, context, pipe);
                }
+       }
 
        if (stream->test_pattern.type != DP_TEST_PATTERN_VIDEO_MODE) {
                struct pipe_ctx *mpcc_pipe;
index 48fdfacc413aa3549ebfe2b885f7f4971e63a1d8..9c05b1a07142fe70df4184299fe1f18a2411ce6b 100644 (file)
@@ -426,44 +426,130 @@ void get_hdr_visual_confirm_color(
 }
 
 void get_subvp_visual_confirm_color(
-               struct dc *dc,
-               struct dc_state *context,
                struct pipe_ctx *pipe_ctx,
                struct tg_color *color)
 {
        uint32_t color_value = MAX_TG_COLOR_VALUE;
-       bool enable_subvp = false;
-       int i;
-
-       if (!dc->ctx || !dc->ctx->dmub_srv || !pipe_ctx || !context)
-               return;
+       if (pipe_ctx) {
+               switch (pipe_ctx->p_state_type) {
+               case P_STATE_SUB_VP:
+                       color->color_r_cr = color_value;
+                       color->color_g_y  = 0;
+                       color->color_b_cb = 0;
+                       break;
+               case P_STATE_DRR_SUB_VP:
+                       color->color_r_cr = 0;
+                       color->color_g_y  = color_value;
+                       color->color_b_cb = 0;
+                       break;
+               case P_STATE_V_BLANK_SUB_VP:
+                       color->color_r_cr = 0;
+                       color->color_g_y  = 0;
+                       color->color_b_cb = color_value;
+                       break;
+               default:
+                       break;
+               }
+       }
+}
 
-       for (i = 0; i < dc->res_pool->pipe_count; i++) {
-               struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+void get_mclk_switch_visual_confirm_color(
+               struct pipe_ctx *pipe_ctx,
+               struct tg_color *color)
+{
+       uint32_t color_value = MAX_TG_COLOR_VALUE;
 
-               if (dc_state_get_pipe_subvp_type(context, pipe) == SUBVP_MAIN) {
-                       /* SubVP enable - red */
-                       color->color_g_y = 0;
+       if (pipe_ctx) {
+               switch (pipe_ctx->p_state_type) {
+               case P_STATE_V_BLANK:
+                       color->color_r_cr = color_value;
+                       color->color_g_y = color_value;
                        color->color_b_cb = 0;
+                       break;
+               case P_STATE_FPO:
+                       color->color_r_cr = 0;
+                       color->color_g_y  = color_value;
+                       color->color_b_cb = color_value;
+                       break;
+               case P_STATE_V_ACTIVE:
                        color->color_r_cr = color_value;
-                       enable_subvp = true;
-
-                       if (pipe_ctx->stream == pipe->stream)
-                               return;
+                       color->color_g_y  = 0;
+                       color->color_b_cb = color_value;
+                       break;
+               case P_STATE_SUB_VP:
+                       color->color_r_cr = color_value;
+                       color->color_g_y  = 0;
+                       color->color_b_cb = 0;
+                       break;
+               case P_STATE_DRR_SUB_VP:
+                       color->color_r_cr = 0;
+                       color->color_g_y  = color_value;
+                       color->color_b_cb = 0;
+                       break;
+               case P_STATE_V_BLANK_SUB_VP:
+                       color->color_r_cr = 0;
+                       color->color_g_y  = 0;
+                       color->color_b_cb = color_value;
+                       break;
+               default:
                        break;
                }
        }
+}
 
-       if (enable_subvp && dc_state_get_pipe_subvp_type(context, pipe_ctx) == SUBVP_NONE) {
-               color->color_r_cr = 0;
-               if (pipe_ctx->stream->allow_freesync == 1) {
-                       /* SubVP enable and DRR on - green */
-                       color->color_b_cb = 0;
-                       color->color_g_y = color_value;
+void set_p_state_switch_method(
+               struct dc *dc,
+               struct dc_state *context,
+               struct pipe_ctx *pipe_ctx)
+{
+       struct vba_vars_st *vba = &context->bw_ctx.dml.vba;
+       bool enable_subvp;
+
+       if (!dc->ctx || !dc->ctx->dmub_srv || !pipe_ctx || !vba || !context)
+               return;
+
+       if (vba->DRAMClockChangeSupport[vba->VoltageLevel][vba->maxMpcComb] !=
+                       dm_dram_clock_change_unsupported) {
+               /* MCLK switching is supported */
+               if (!pipe_ctx->has_vactive_margin) {
+                       /* In Vblank - yellow */
+                       pipe_ctx->p_state_type = P_STATE_V_BLANK;
+
+                       if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) {
+                               /* FPO + Vblank - cyan */
+                               pipe_ctx->p_state_type = P_STATE_FPO;
+                       }
                } else {
-                       /* SubVP enable and No DRR - blue */
-                       color->color_g_y = 0;
-                       color->color_b_cb = color_value;
+                       /* In Vactive - pink */
+                       pipe_ctx->p_state_type = P_STATE_V_ACTIVE;
+               }
+
+               /* SubVP */
+               enable_subvp = false;
+
+               for (int i = 0; i < dc->res_pool->pipe_count; i++) {
+                       struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i];
+
+                       if (pipe->stream && dc_state_get_paired_subvp_stream(context, pipe->stream) &&
+                                       dc_state_get_pipe_subvp_type(context, pipe) == SUBVP_MAIN) {
+                               /* SubVP enable - red */
+                               pipe_ctx->p_state_type = P_STATE_SUB_VP;
+                               enable_subvp = true;
+
+                               if (pipe_ctx->stream == pipe->stream)
+                                       return;
+                               break;
+                       }
+               }
+
+               if (enable_subvp && dc_state_get_pipe_subvp_type(context, pipe_ctx) == SUBVP_NONE) {
+                       if (pipe_ctx->stream->allow_freesync == 1) {
+                               /* SubVP enable and DRR on - green */
+                               pipe_ctx->p_state_type = P_STATE_DRR_SUB_VP;
+                       } else {
+                               /* SubVP enable and No DRR - blue */
+                               pipe_ctx->p_state_type = P_STATE_V_BLANK_SUB_VP;
+                       }
                }
        }
 }
@@ -815,42 +901,6 @@ void hwss_subvp_save_surf_addr(union block_sequence_params *params)
        dc_dmub_srv_subvp_save_surf_addr(dc_dmub_srv, addr, subvp_index);
 }
 
-void get_mclk_switch_visual_confirm_color(
-               struct dc *dc,
-               struct dc_state *context,
-               struct pipe_ctx *pipe_ctx,
-               struct tg_color *color)
-{
-       uint32_t color_value = MAX_TG_COLOR_VALUE;
-       struct vba_vars_st *vba = &context->bw_ctx.dml.vba;
-
-       if (!dc->ctx || !dc->ctx->dmub_srv || !pipe_ctx || !vba || !context)
-               return;
-
-       if (vba->DRAMClockChangeSupport[vba->VoltageLevel][vba->maxMpcComb] !=
-                       dm_dram_clock_change_unsupported) {
-               /* MCLK switching is supported */
-               if (!pipe_ctx->has_vactive_margin) {
-                       /* In Vblank - yellow */
-                       color->color_r_cr = color_value;
-                       color->color_g_y = color_value;
-
-                       if (context->bw_ctx.bw.dcn.clk.fw_based_mclk_switching) {
-                               /* FPO + Vblank - cyan */
-                               color->color_r_cr = 0;
-                               color->color_g_y  = color_value;
-                               color->color_b_cb = color_value;
-                       }
-               } else {
-                       /* In Vactive - pink */
-                       color->color_r_cr = color_value;
-                       color->color_b_cb = color_value;
-               }
-               /* SubVP */
-               get_subvp_visual_confirm_color(dc, context, pipe_ctx, color);
-       }
-}
-
 void get_surface_tile_visual_confirm_color(
                struct pipe_ctx *pipe_ctx,
                struct tg_color *color)
index 6ca8c5488d507aadafcd11a9589effd187fcf277..a54399383318145b8bc72fc85e646bf546588609 100644 (file)
@@ -455,17 +455,18 @@ void get_mpctree_visual_confirm_color(
                struct tg_color *color);
 
 void get_subvp_visual_confirm_color(
-       struct dc *dc,
-       struct dc_state *context,
        struct pipe_ctx *pipe_ctx,
        struct tg_color *color);
 
 void get_mclk_switch_visual_confirm_color(
-               struct dc *dc,
-               struct dc_state *context,
                struct pipe_ctx *pipe_ctx,
                struct tg_color *color);
 
+void set_p_state_switch_method(
+               struct dc *dc,
+               struct dc_state *context,
+               struct pipe_ctx *pipe_ctx);
+
 void hwss_execute_sequence(struct dc *dc,
                struct block_sequence block_sequence[],
                int num_steps);
index c3b973abb89a73ea4139af0318840af37b608245..f74ae0d41d3c49cf215d615f336339b773cbbcbc 100644 (file)
@@ -381,6 +381,16 @@ union pipe_update_flags {
        uint32_t raw;
 };
 
+enum p_state_switch_method {
+       P_STATE_UNKNOWN                                         = 0,
+       P_STATE_V_BLANK                                         = 1,
+       P_STATE_FPO,
+       P_STATE_V_ACTIVE,
+       P_STATE_SUB_VP,
+       P_STATE_DRR_SUB_VP,
+       P_STATE_V_BLANK_SUB_VP
+};
+
 struct pipe_ctx {
        struct dc_plane_state *plane_state;
        struct dc_stream_state *stream;
@@ -429,6 +439,7 @@ struct pipe_ctx {
        struct dwbc *dwbc;
        struct mcif_wb *mcif_wb;
        union pipe_update_flags update_flags;
+       enum p_state_switch_method p_state_type;
        struct tg_color visual_confirm_color;
        bool has_vactive_margin;
        /* subvp_index: only valid if the pipe is a SUBVP_MAIN*/