Commit a71e1310 authored by Relja Vojvodic's avatar Relja Vojvodic Committed by Alex Deucher

drm/amd/display: Add more mechanisms for tests

[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: default avatarDaniel Wheeler <daniel.wheeler@amd.com>
Acked-by: default avatarRodrigo Siqueira <rodrigo.siqueira@amd.com>
Reviewed-by: default avatarAlvin Lee <alvin.lee2@amd.com>
Signed-off-by: default avatarRelja Vojvodic <relja.vojvodic@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent ade13d3f
......@@ -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);
}
}
......
......@@ -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;
......
......@@ -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)
......
......@@ -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);
......
......@@ -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*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment