/*
 * 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		0x00000000
#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 DAL_STATS_EVENT_ENTRIES_DEFAULT		0x00000100

#define MOD_STATS_NUM_VSYNCS			5
#define MOD_STATS_EVENT_STRING_MAX		512

struct stats_time_cache {
	unsigned int entry_id;

	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 stats_event_cache {
	unsigned int entry_id;
	char event_string[MOD_STATS_EVENT_STRING_MAX];
};

struct core_stats {
	struct mod_stats public;
	struct dc *dc;

	bool enabled;
	unsigned int entries;
	unsigned int event_entries;
	unsigned int entry_id;

	struct stats_time_cache *time;
	unsigned int index;

	struct stats_event_cache *events;
	unsigned int event_index;

};

#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;

	if (dc == NULL)
		goto fail_construct;

	core_stats = kzalloc(sizeof(struct core_stats), GFP_KERNEL);

	if (core_stats == 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;

	if (core_stats->enabled) {
		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 = kcalloc(core_stats->entries,
						sizeof(struct stats_time_cache),
						GFP_KERNEL);

		if (core_stats->time == NULL)
			goto fail_construct_time;

		core_stats->event_entries = DAL_STATS_EVENT_ENTRIES_DEFAULT;
		core_stats->events = kcalloc(core_stats->event_entries,
					     sizeof(struct stats_event_cache),
					     GFP_KERNEL);

		if (core_stats->events == NULL)
			goto fail_construct_events;

	} else {
		core_stats->entries = 0;
	}

	/* 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;
	core_stats->event_index = 0;

	// Keeps track of ordering within the different stats structures
	core_stats->entry_id = 0;

	return &core_stats->public;

fail_construct_events:
	kfree(core_stats->time);

fail_construct_time:
	kfree(core_stats);

fail_construct:
	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);

		if (core_stats->events != NULL)
			kfree(core_stats->events);

		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;
	struct stats_event_cache *events = NULL;
	unsigned int time_index = 1;
	unsigned int event_index = 0;
	unsigned int index = 0;
	struct log_entry log_entry;

	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;
	events = core_stats->events;

	DISPLAY_STATS_BEGIN(log_entry);

	DISPLAY_STATS("==Display Caps==\n");

	DISPLAY_STATS("==Display Stats==\n");

	DISPLAY_STATS("%10s %10s %10s %10s %10s"
			" %11s %11s %17s %10s %14s"
			" %10s %10s %10s %10s %10s"
			" %10s %10s %10s %10s\n",
		"render", "avgRender",
		"minWindow", "midPoint", "maxWindow",
		"vsyncToFlip", "flipToVsync", "vsyncsBetweenFlip",
		"numFrame", "insertDuration",
		"vTotalMin", "vTotalMax", "eventTrigs",
		"vSyncTime1", "vSyncTime2", "vSyncTime3",
		"vSyncTime4", "vSyncTime5", "flags");

	for (int i = 0; i < core_stats->entry_id; i++) {
		if (event_index < core_stats->event_index &&
				i == events[event_index].entry_id) {
			DISPLAY_STATS("==Event==%s\n", events[event_index].event_string);
			event_index++;
		} else if (time_index < core_stats->index &&
				i == time[time_index].entry_id) {
			DISPLAY_STATS("%10u %10u %10u %10u %10u"
					" %11u %11u %17u %10u %14u"
					" %10u %10u %10u %10u %10u"
					" %10u %10u %10u %10u\n",
				time[time_index].render_time_in_us,
				time[time_index].avg_render_time_in_us_last_ten,
				time[time_index].min_window,
				time[time_index].lfc_mid_point_in_us,
				time[time_index].max_window,
				time[time_index].vsync_to_flip_time_in_us,
				time[time_index].flip_to_vsync_time_in_us,
				time[time_index].num_vsync_between_flips,
				time[time_index].num_frames_inserted,
				time[time_index].inserted_duration_in_us,
				time[time_index].v_total_min,
				time[time_index].v_total_max,
				time[time_index].event_triggers,
				time[time_index].v_sync_time_in_us[0],
				time[time_index].v_sync_time_in_us[1],
				time[time_index].v_sync_time_in_us[2],
				time[time_index].v_sync_time_in_us[3],
				time[time_index].v_sync_time_in_us[4],
				time[time_index].flags);

			time_index++;
		}
	}

	DISPLAY_STATS_END(log_entry);
}

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);

	memset(core_stats->events, 0,
		sizeof(struct stats_event_cache) * core_stats->event_entries);

	core_stats->index = 1;
	core_stats->event_index = 0;

	// Keeps track of ordering within the different stats structures
	core_stats->entry_id = 0;
}

void mod_stats_update_event(struct mod_stats *mod_stats,
		char *event_string,
		unsigned int length)
{
	struct core_stats *core_stats = NULL;
	struct stats_event_cache *events = NULL;
	unsigned int index = 0;
	unsigned int copy_length = 0;

	if (mod_stats == NULL)
		return;

	core_stats = MOD_STATS_TO_CORE(mod_stats);

	if (core_stats->event_index >= core_stats->event_entries)
		return;

	events = core_stats->events;
	index = core_stats->event_index;

	copy_length = length;
	if (length > MOD_STATS_EVENT_STRING_MAX)
		copy_length = MOD_STATS_EVENT_STRING_MAX;

	memcpy(&events[index].event_string, event_string, copy_length);
	events[index].event_string[copy_length - 1] = '\0';

	events[index].entry_id = core_stats->entry_id;
	core_stats->event_index++;
	core_stats->entry_id++;
}

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) / 1000;

	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) / 1000;
	else
		time[index].vsync_to_flip_time_in_us =
			(timestamp_in_ns -
				time[index - 1].vupdate_timestamp_in_ns) / 1000;

	time[index].entry_id = core_stats->entry_id;
	core_stats->index++;
	core_stats->entry_id++;
}

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;
	unsigned int num_vsyncs = 0;
	unsigned int prev_vsync_in_ns = 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;
	num_vsyncs = time[index].num_vsync_between_flips;

	if (num_vsyncs < MOD_STATS_NUM_VSYNCS) {
		if (num_vsyncs == 0) {
			prev_vsync_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) /
					1000;
		} else {
			prev_vsync_in_ns =
				time[index].vupdate_timestamp_in_ns;
		}

		time[index].v_sync_time_in_us[num_vsyncs] =
			(timestamp_in_ns - prev_vsync_in_ns) / 1000;
	}

	time[index].vupdate_timestamp_in_ns = 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;
}

