[PATCH 17/28] drm/amd/display: Implement stats logging

Harry Wentland harry.wentland at amd.com
Wed Mar 7 00:51:57 UTC 2018


From: Anthony Koo <Anthony.Koo at amd.com>

Stats will be used for debug purposes

Signed-off-by: Anthony Koo <Anthony.Koo at amd.com>
Reviewed-by: Tony Cheng <Tony.Cheng at amd.com>
Acked-by: Harry Wentland <harry.wentland at amd.com>
---
 drivers/gpu/drm/amd/display/dc/basics/logger.c     |   3 +-
 drivers/gpu/drm/amd/display/include/logger_types.h |   1 +
 .../drm/amd/display/modules/freesync/freesync.c    | 129 ++++++--
 .../gpu/drm/amd/display/modules/inc/mod_freesync.h |   9 +
 .../gpu/drm/amd/display/modules/inc/mod_stats.h    |  65 ++++
 drivers/gpu/drm/amd/display/modules/stats/stats.c  | 334 +++++++++++++++++++++
 6 files changed, 510 insertions(+), 31 deletions(-)
 create mode 100644 drivers/gpu/drm/amd/display/modules/inc/mod_stats.h
 create mode 100644 drivers/gpu/drm/amd/display/modules/stats/stats.c

diff --git a/drivers/gpu/drm/amd/display/dc/basics/logger.c b/drivers/gpu/drm/amd/display/dc/basics/logger.c
index 180a9d69d351..31bee054f43a 100644
--- a/drivers/gpu/drm/amd/display/dc/basics/logger.c
+++ b/drivers/gpu/drm/amd/display/dc/basics/logger.c
@@ -60,7 +60,8 @@ static const struct dc_log_type_info log_type_info_tbl[] = {
 		{LOG_EVENT_LINK_LOSS,       "LinkLoss"},
 		{LOG_EVENT_UNDERFLOW,       "Underflow"},
 		{LOG_IF_TRACE,              "InterfaceTrace"},
-		{LOG_DTN,                   "DTN"}
+		{LOG_DTN,                   "DTN"},
+		{LOG_PROFILING,             "Profiling"}
 };
 
 
diff --git a/drivers/gpu/drm/amd/display/include/logger_types.h b/drivers/gpu/drm/amd/display/include/logger_types.h
index b727f5eeb3a9..427796bdc14a 100644
--- a/drivers/gpu/drm/amd/display/include/logger_types.h
+++ b/drivers/gpu/drm/amd/display/include/logger_types.h
@@ -98,6 +98,7 @@ enum dc_log_type {
 	LOG_EVENT_UNDERFLOW,
 	LOG_IF_TRACE,
 	LOG_PERF_TRACE,
+	LOG_PROFILING,
 
 	LOG_SECTION_TOTAL_COUNT
 };
diff --git a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
index b4723af368a5..e849b704f2f6 100644
--- a/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
+++ b/drivers/gpu/drm/amd/display/modules/freesync/freesync.c
@@ -33,7 +33,7 @@
 /* Refresh rate ramp at a fixed rate of 65 Hz/second */
 #define STATIC_SCREEN_RAMP_DELTA_REFRESH_RATE_PER_FRAME ((1000 / 60) * 65)
 /* Number of elements in the render times cache array */
-#define RENDER_TIMES_MAX_COUNT 20
+#define RENDER_TIMES_MAX_COUNT 10
 /* Threshold to exit BTR (to avoid frequent enter-exits at the lower limit) */
 #define BTR_EXIT_MARGIN 2000
 /* Number of consecutive frames to check before entering/exiting fixed refresh*/
@@ -52,7 +52,7 @@ struct gradual_static_ramp {
 	unsigned int ramp_current_frame_duration_in_ns;
 };
 
-struct time_cache {
+struct freesync_time {
 	/* video (48Hz feature) related */
 	unsigned int update_duration_in_ns;
 
@@ -64,6 +64,9 @@ struct time_cache {
 
 	unsigned int render_times_index;
 	unsigned int render_times[RENDER_TIMES_MAX_COUNT];
+
+	unsigned int min_window;
+	unsigned int max_window;
 };
 
 struct below_the_range {
@@ -98,11 +101,14 @@ struct freesync_state {
 	bool static_screen;
 	bool video;
 
+	unsigned int vmin;
+	unsigned int vmax;
+
+	struct freesync_time time;
+
 	unsigned int nominal_refresh_rate_in_micro_hz;
 	bool windowed_fullscreen;
 
-	struct time_cache time;
-
 	struct gradual_static_ramp static_ramp;
 	struct below_the_range btr;
 	struct fixed_refresh fixed_refresh;
@@ -124,9 +130,9 @@ struct freesync_registry_options {
 struct core_freesync {
 	struct mod_freesync public;
 	struct dc *dc;
+	struct freesync_registry_options opts;
 	struct freesync_entity *map;
 	int num_entities;
-	struct freesync_registry_options opts;
 };
 
 #define MOD_FREESYNC_TO_CORE(mod_freesync)\
@@ -146,7 +152,7 @@ struct mod_freesync *mod_freesync_create(struct dc *dc)
 		goto fail_alloc_context;
 
 	core_freesync->map = kzalloc(sizeof(struct freesync_entity) * MOD_FREESYNC_MAX_CONCURRENT_STREAMS,
-				     GFP_KERNEL);
+					GFP_KERNEL);
 
 	if (core_freesync->map == NULL)
 		goto fail_alloc_map;
@@ -330,6 +336,25 @@ bool mod_freesync_remove_stream(struct mod_freesync *mod_freesync,
 	return true;
 }
 
+static void adjust_vmin_vmax(struct core_freesync *core_freesync,
+				struct dc_stream_state **streams,
+				int num_streams,
+				int map_index,
+				unsigned int v_total_min,
+				unsigned int v_total_max)
+{
+	if (num_streams == 0 || streams == NULL || num_streams > 1)
+		return;
+
+	core_freesync->map[map_index].state.vmin = v_total_min;
+	core_freesync->map[map_index].state.vmax = v_total_max;
+
+	dc_stream_adjust_vmin_vmax(core_freesync->dc, streams,
+				num_streams, v_total_min,
+				v_total_max);
+}
+
+
 static void update_stream_freesync_context(struct core_freesync *core_freesync,
 		struct dc_stream_state *stream)
 {
@@ -588,9 +613,10 @@ static bool set_freesync_on_streams(struct core_freesync *core_freesync,
 				update_stream_freesync_context(core_freesync,
 						streams[stream_idx]);
 
-				dc_stream_adjust_vmin_vmax(core_freesync->dc, streams,
-							   num_streams, v_total_min,
-							   v_total_max);
+				adjust_vmin_vmax(core_freesync, streams,
+						num_streams, map_index,
+						v_total_min,
+						v_total_max);
 
 				return true;
 
@@ -613,9 +639,10 @@ static bool set_freesync_on_streams(struct core_freesync *core_freesync,
 						core_freesync,
 						streams[stream_idx]);
 
-					dc_stream_adjust_vmin_vmax(
-						core_freesync->dc, streams,
-						num_streams, v_total_nominal,
+					adjust_vmin_vmax(
+						core_freesync, streams,
+						num_streams, map_index,
+						v_total_nominal,
 						v_total_nominal);
 				}
 				return true;
@@ -632,9 +659,10 @@ static bool set_freesync_on_streams(struct core_freesync *core_freesync,
 					core_freesync,
 					streams[stream_idx]);
 
-				dc_stream_adjust_vmin_vmax(core_freesync->dc, streams,
-							   num_streams, v_total_nominal,
-							   v_total_nominal);
+				adjust_vmin_vmax(core_freesync, streams,
+						num_streams, map_index,
+						v_total_nominal,
+						v_total_nominal);
 
 				/* Reset the cached variables */
 				reset_freesync_state_variables(state);
@@ -650,9 +678,10 @@ static bool set_freesync_on_streams(struct core_freesync *core_freesync,
 			 * not support freesync because a former stream has
 			 * be programmed
 			 */
-			dc_stream_adjust_vmin_vmax(core_freesync->dc, streams,
-						   num_streams, v_total_nominal,
-						   v_total_nominal);
+			adjust_vmin_vmax(core_freesync, streams,
+						num_streams, map_index,
+						v_total_nominal,
+						v_total_nominal);
 			/* Reset the cached variables */
 			reset_freesync_state_variables(state);
 		}
@@ -769,8 +798,9 @@ void mod_freesync_handle_v_update(struct mod_freesync *mod_freesync,
 			vmin = inserted_frame_v_total;
 
 			/* Program V_TOTAL */
-			dc_stream_adjust_vmin_vmax(core_freesync->dc, streams,
-						   num_streams, vmin, vmax);
+			adjust_vmin_vmax(core_freesync, streams,
+						num_streams, index,
+						vmin, vmax);
 		}
 
 		if (state->btr.frame_counter > 0)
@@ -804,9 +834,10 @@ void mod_freesync_handle_v_update(struct mod_freesync *mod_freesync,
 		update_stream_freesync_context(core_freesync, streams[0]);
 
 		/* Program static screen ramp values */
-		dc_stream_adjust_vmin_vmax(core_freesync->dc, streams,
-					   num_streams, v_total,
-					   v_total);
+		adjust_vmin_vmax(core_freesync, streams,
+					num_streams, index,
+					v_total,
+					v_total);
 
 		triggers.overlay_update = true;
 		triggers.surface_update = true;
@@ -1063,9 +1094,9 @@ bool mod_freesync_override_min_max(struct mod_freesync *mod_freesync,
 				max_refresh);
 
 		/* Program vtotal min/max */
-		dc_stream_adjust_vmin_vmax(core_freesync->dc, &streams, 1,
-					   state->freesync_range.vmin,
-					   state->freesync_range.vmax);
+		adjust_vmin_vmax(core_freesync, &streams, 1, index,
+				state->freesync_range.vmin,
+				state->freesync_range.vmax);
 	}
 
 	if (min_refresh != 0 &&
@@ -1399,11 +1430,9 @@ static void apply_fixed_refresh(struct core_freesync *core_freesync,
 	} else {
 
 		vmin = state->freesync_range.vmin;
-
 		vmax = vmin;
-
-		dc_stream_adjust_vmin_vmax(core_freesync->dc, &stream,
-					   1, vmin, vmax);
+		adjust_vmin_vmax(core_freesync, &stream, map_index,
+					1, vmin, vmax);
 	}
 }
 
@@ -1457,3 +1486,43 @@ void mod_freesync_pre_update_plane_addresses(struct mod_freesync *mod_freesync,
 
 	}
 }
+
+void mod_freesync_get_settings(struct mod_freesync *mod_freesync,
+		struct dc_stream_state **streams, int num_streams,
+		unsigned int *v_total_min, unsigned int *v_total_max,
+		unsigned int *event_triggers,
+		unsigned int *window_min, unsigned int *window_max,
+		unsigned int *lfc_mid_point_in_us,
+		unsigned int *inserted_frames,
+		unsigned int *inserted_duration_in_us)
+{
+	unsigned int stream_index, map_index;
+	struct core_freesync *core_freesync = NULL;
+
+	if (mod_freesync == NULL)
+		return;
+
+	core_freesync = MOD_FREESYNC_TO_CORE(mod_freesync);
+
+	for (stream_index = 0; stream_index < num_streams; stream_index++) {
+
+		map_index = map_index_from_stream(core_freesync,
+						streams[stream_index]);
+
+		if (core_freesync->map[map_index].caps->supported) {
+			struct freesync_state state =
+					core_freesync->map[map_index].state;
+			*v_total_min = state.vmin;
+			*v_total_max = state.vmax;
+			*event_triggers = 0;
+			*window_min = state.time.min_window;
+			*window_max = state.time.max_window;
+			*lfc_mid_point_in_us = state.btr.mid_point_in_us;
+			*inserted_frames = state.btr.frames_to_insert;
+			*inserted_duration_in_us =
+					state.btr.inserted_frame_duration_in_us;
+		}
+
+	}
+}
+
diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h b/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h
index 84b53425f2c8..f083e1619dbe 100644
--- a/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h
+++ b/drivers/gpu/drm/amd/display/modules/inc/mod_freesync.h
@@ -164,4 +164,13 @@ void mod_freesync_pre_update_plane_addresses(struct mod_freesync *mod_freesync,
 		struct dc_stream_state **streams, int num_streams,
 		unsigned int curr_time_stamp);
 
+void mod_freesync_get_settings(struct mod_freesync *mod_freesync,
+		struct dc_stream_state **streams, int num_streams,
+		unsigned int *v_total_min, unsigned int *v_total_max,
+		unsigned int *event_triggers,
+		unsigned int *window_min, unsigned int *window_max,
+		unsigned int *lfc_mid_point_in_us,
+		unsigned int *inserted_frames,
+		unsigned int *inserted_duration_in_us);
+
 #endif
diff --git a/drivers/gpu/drm/amd/display/modules/inc/mod_stats.h b/drivers/gpu/drm/amd/display/modules/inc/mod_stats.h
new file mode 100644
index 000000000000..3230e2adb870
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/modules/inc/mod_stats.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2016 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#ifndef MODULES_INC_MOD_STATS_H_
+#define MODULES_INC_MOD_STATS_H_
+
+#include "dm_services.h"
+
+struct mod_stats {
+	int dummy;
+};
+
+struct mod_stats_caps {
+	bool dummy;
+};
+
+struct mod_stats *mod_stats_create(struct dc *dc);
+
+void mod_stats_destroy(struct mod_stats *mod_stats);
+
+bool mod_stats_init(struct mod_stats *mod_stats);
+
+void mod_stats_dump(struct mod_stats *mod_stats);
+
+void mod_stats_reset_data(struct mod_stats *mod_stats);
+
+void mod_stats_update_flip(struct mod_stats *mod_stats,
+		unsigned long timestamp_in_ns);
+
+void mod_stats_update_vupdate(struct mod_stats *mod_stats,
+		unsigned long timestamp_in_ns);
+
+void mod_stats_update_freesync(struct mod_stats *mod_stats,
+		unsigned int v_total_min,
+		unsigned int v_total_max,
+		unsigned int event_triggers,
+		unsigned int window_min,
+		unsigned int window_max,
+		unsigned int lfc_mid_point_in_us,
+		unsigned int inserted_frames,
+		unsigned int inserted_frame_duration_in_us);
+
+#endif /* MODULES_INC_MOD_STATS_H_ */
diff --git a/drivers/gpu/drm/amd/display/modules/stats/stats.c b/drivers/gpu/drm/amd/display/modules/stats/stats.c
new file mode 100644
index 000000000000..041f87b73d5f
--- /dev/null
+++ b/drivers/gpu/drm/amd/display/modules/stats/stats.c
@@ -0,0 +1,334 @@
+/*
+ * Copyright 2016 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors: AMD
+ *
+ */
+
+#include "mod_stats.h"
+#include "dm_services.h"
+#include "dc.h"
+#include "core_types.h"
+
+#define DAL_STATS_ENABLE_REGKEY			"DalStatsEnable"
+#define DAL_STATS_ENABLE_REGKEY_DEFAULT		0x00000001
+#define DAL_STATS_ENABLE_REGKEY_ENABLED		0x00000001
+
+#define DAL_STATS_ENTRIES_REGKEY		"DalStatsEntries"
+#define DAL_STATS_ENTRIES_REGKEY_DEFAULT	0x00350000
+#define DAL_STATS_ENTRIES_REGKEY_MAX		0x01000000
+
+#define MOD_STATS_NUM_VSYNCS			5
+
+struct stats_time_cache {
+	unsigned long flip_timestamp_in_ns;
+	unsigned long vupdate_timestamp_in_ns;
+
+	unsigned int render_time_in_us;
+	unsigned int avg_render_time_in_us_last_ten;
+	unsigned int v_sync_time_in_us[MOD_STATS_NUM_VSYNCS];
+	unsigned int num_vsync_between_flips;
+
+	unsigned int flip_to_vsync_time_in_us;
+	unsigned int vsync_to_flip_time_in_us;
+
+	unsigned int min_window;
+	unsigned int max_window;
+	unsigned int v_total_min;
+	unsigned int v_total_max;
+	unsigned int event_triggers;
+
+	unsigned int lfc_mid_point_in_us;
+	unsigned int num_frames_inserted;
+	unsigned int inserted_duration_in_us;
+
+	unsigned int flags;
+};
+
+struct core_stats {
+	struct mod_stats public;
+	struct dc *dc;
+
+	struct stats_time_cache *time;
+	unsigned int index;
+
+	bool enabled;
+	unsigned int entries;
+};
+
+#define MOD_STATS_TO_CORE(mod_stats)\
+		container_of(mod_stats, struct core_stats, public)
+
+bool mod_stats_init(struct mod_stats *mod_stats)
+{
+	bool result = false;
+	struct core_stats *core_stats = NULL;
+	struct dc *dc = NULL;
+
+	if (mod_stats == NULL)
+		return false;
+
+	core_stats = MOD_STATS_TO_CORE(mod_stats);
+	dc = core_stats->dc;
+
+	return result;
+}
+
+struct mod_stats *mod_stats_create(struct dc *dc)
+{
+	struct core_stats *core_stats = NULL;
+	struct persistent_data_flag flag;
+	unsigned int reg_data;
+	int i = 0;
+
+	core_stats = kzalloc(sizeof(struct core_stats), GFP_KERNEL);
+
+	if (core_stats == NULL)
+		goto fail_alloc_context;
+
+	if (dc == NULL)
+		goto fail_construct;
+
+	core_stats->dc = dc;
+
+	core_stats->enabled = DAL_STATS_ENABLE_REGKEY_DEFAULT;
+	if (dm_read_persistent_data(dc->ctx, NULL, NULL,
+			DAL_STATS_ENABLE_REGKEY,
+			&reg_data, sizeof(unsigned int), &flag))
+		core_stats->enabled = reg_data;
+
+	core_stats->entries = DAL_STATS_ENTRIES_REGKEY_DEFAULT;
+	if (dm_read_persistent_data(dc->ctx, NULL, NULL,
+			DAL_STATS_ENTRIES_REGKEY,
+			&reg_data, sizeof(unsigned int), &flag)) {
+		if (reg_data > DAL_STATS_ENTRIES_REGKEY_MAX)
+			core_stats->entries = DAL_STATS_ENTRIES_REGKEY_MAX;
+		else
+			core_stats->entries = reg_data;
+	}
+
+	core_stats->time = kzalloc(sizeof(struct stats_time_cache) * core_stats->entries,
+					GFP_KERNEL);
+
+	if (core_stats->time == NULL)
+		goto fail_construct;
+
+	/* Purposely leave index 0 unused so we don't need special logic to
+	 * handle calculation cases that depend on previous flip data.
+	 */
+	core_stats->index = 1;
+
+	return &core_stats->public;
+
+fail_construct:
+	kfree(core_stats);
+
+fail_alloc_context:
+	return NULL;
+}
+
+void mod_stats_destroy(struct mod_stats *mod_stats)
+{
+	if (mod_stats != NULL) {
+		struct core_stats *core_stats = MOD_STATS_TO_CORE(mod_stats);
+
+		if (core_stats->time != NULL)
+			kfree(core_stats->time);
+
+		kfree(core_stats);
+	}
+}
+
+void mod_stats_dump(struct mod_stats *mod_stats)
+{
+	struct dc  *dc = NULL;
+	struct dal_logger *logger = NULL;
+	struct core_stats *core_stats = NULL;
+	struct stats_time_cache *time = NULL;
+	unsigned int index = 0;
+
+	if (mod_stats == NULL)
+		return;
+
+	core_stats = MOD_STATS_TO_CORE(mod_stats);
+	dc = core_stats->dc;
+	logger = dc->ctx->logger;
+	time = core_stats->time;
+
+	//LogEntry* pLog = GetLog()->Open(LogMajor_ISR, LogMinor_ISR_FreeSyncSW);
+
+	//if (!pLog->IsDummyEntry())
+	{
+		dm_logger_write(logger, LOG_PROFILING, "==Display Caps==\n");
+		dm_logger_write(logger, LOG_PROFILING, "\n");
+		dm_logger_write(logger, LOG_PROFILING, "\n");
+
+		dm_logger_write(logger, LOG_PROFILING, "==Stats==\n");
+		dm_logger_write(logger, LOG_PROFILING,
+			"render avgRender minWindow midPoint maxWindow vsyncToFlip flipToVsync #vsyncBetweenFlip #frame insertDuration vTotalMin vTotalMax eventTrigs vSyncTime1 vSyncTime2 vSyncTime3 vSyncTime4 vSyncTime5 flags\n");
+
+		for (int i = 0; i < core_stats->index && i < core_stats->entries; i++) {
+			dm_logger_write(logger, LOG_PROFILING,
+					"%u  %u  %u  %u  %u  %u  %u  %u  %u  %u  %u  %u  %u  %u  %u  %u  %u  %u  %u\n",
+					time[i].render_time_in_us,
+					time[i].avg_render_time_in_us_last_ten,
+					time[i].min_window,
+					time[i].lfc_mid_point_in_us,
+					time[i].max_window,
+					time[i].vsync_to_flip_time_in_us,
+					time[i].flip_to_vsync_time_in_us,
+					time[i].num_vsync_between_flips,
+					time[i].num_frames_inserted,
+					time[i].inserted_duration_in_us,
+					time[i].v_total_min,
+					time[i].v_total_max,
+					time[i].event_triggers,
+					time[i].v_sync_time_in_us[0],
+					time[i].v_sync_time_in_us[1],
+					time[i].v_sync_time_in_us[2],
+					time[i].v_sync_time_in_us[3],
+					time[i].v_sync_time_in_us[4],
+					time[i].flags);
+		}
+	}
+	//GetLog()->Close(pLog);
+	//GetLog()->UnSetLogMask(LogMajor_ISR, LogMinor_ISR_FreeSyncSW);
+}
+
+void mod_stats_reset_data(struct mod_stats *mod_stats)
+{
+	struct core_stats *core_stats = NULL;
+	struct stats_time_cache *time = NULL;
+	unsigned int index = 0;
+
+	if (mod_stats == NULL)
+		return;
+
+	core_stats = MOD_STATS_TO_CORE(mod_stats);
+
+	memset(core_stats->time, 0,
+		sizeof(struct stats_time_cache) * core_stats->entries);
+
+	core_stats->index = 0;
+}
+
+void mod_stats_update_flip(struct mod_stats *mod_stats,
+		unsigned long timestamp_in_ns)
+{
+	struct core_stats *core_stats = NULL;
+	struct stats_time_cache *time = NULL;
+	unsigned int index = 0;
+
+	if (mod_stats == NULL)
+		return;
+
+	core_stats = MOD_STATS_TO_CORE(mod_stats);
+
+	if (core_stats->index >= core_stats->entries)
+		return;
+
+	time = core_stats->time;
+	index = core_stats->index;
+
+	time[index].flip_timestamp_in_ns = timestamp_in_ns;
+	time[index].render_time_in_us =
+		timestamp_in_ns - time[index - 1].flip_timestamp_in_ns;
+
+	if (index >= 10) {
+		for (unsigned int i = 0; i < 10; i++)
+			time[index].avg_render_time_in_us_last_ten +=
+					time[index - i].render_time_in_us;
+		time[index].avg_render_time_in_us_last_ten /= 10;
+	}
+
+	if (time[index].num_vsync_between_flips > 0)
+		time[index].vsync_to_flip_time_in_us =
+			timestamp_in_ns - time[index].vupdate_timestamp_in_ns;
+	else
+		time[index].vsync_to_flip_time_in_us =
+			timestamp_in_ns - time[index - 1].vupdate_timestamp_in_ns;
+
+	core_stats->index++;
+}
+
+void mod_stats_update_vupdate(struct mod_stats *mod_stats,
+		unsigned long timestamp_in_ns)
+{
+	struct core_stats *core_stats = NULL;
+	struct stats_time_cache *time = NULL;
+	unsigned int index = 0;
+
+	if (mod_stats == NULL)
+		return;
+
+	core_stats = MOD_STATS_TO_CORE(mod_stats);
+
+	if (core_stats->index >= core_stats->entries)
+		return;
+
+	time = core_stats->time;
+	index = core_stats->index;
+
+	time[index].vupdate_timestamp_in_ns = timestamp_in_ns;
+	if (time[index].num_vsync_between_flips < MOD_STATS_NUM_VSYNCS)
+		time[index].v_sync_time_in_us[time[index].num_vsync_between_flips] =
+			timestamp_in_ns - time[index - 1].vupdate_timestamp_in_ns;
+	time[index].flip_to_vsync_time_in_us =
+		timestamp_in_ns - time[index - 1].flip_timestamp_in_ns;
+
+	time[index].num_vsync_between_flips++;
+}
+
+void mod_stats_update_freesync(struct mod_stats *mod_stats,
+		unsigned int v_total_min,
+		unsigned int v_total_max,
+		unsigned int event_triggers,
+		unsigned int window_min,
+		unsigned int window_max,
+		unsigned int lfc_mid_point_in_us,
+		unsigned int inserted_frames,
+		unsigned int inserted_duration_in_us)
+{
+	struct core_stats *core_stats = NULL;
+	struct stats_time_cache *time = NULL;
+	unsigned int index = 0;
+
+	if (mod_stats == NULL)
+		return;
+
+	core_stats = MOD_STATS_TO_CORE(mod_stats);
+
+	if (core_stats->index >= core_stats->entries)
+		return;
+
+	time = core_stats->time;
+	index = core_stats->index;
+
+	time[index].v_total_min = v_total_min;
+	time[index].v_total_max = v_total_max;
+	time[index].event_triggers = event_triggers;
+	time[index].min_window = window_min;
+	time[index].max_window = window_max;
+	time[index].lfc_mid_point_in_us = lfc_mid_point_in_us;
+	time[index].num_frames_inserted = inserted_frames;
+	time[index].inserted_duration_in_us = inserted_duration_in_us;
+}
+
-- 
2.14.1



More information about the amd-gfx mailing list