/*
 *
 * (C) COPYRIGHT 2016, 2017 ARM Limited. All rights reserved.
 *
 * This program is free software and is provided to you under the terms of the
 * GNU General Public License version 2 as published by the Free Software
 * Foundation, and any use by you of this program is subject to the terms
 * of such GNU licence.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, you can access it online at
 * http://www.gnu.org/licenses/gpl-2.0.html.
 *
 * SPDX-License-Identifier: GPL-2.0
 *
 */

#include <linux/module.h>
#include <linux/delay.h>
#include <linux/interrupt.h>

#include "mali_kbase.h"
#include <midgard/backend/gpu/mali_kbase_device_internal.h>

#include <kutf/kutf_suite.h>
#include <kutf/kutf_utils.h>

/*
 * This file contains the code which is used for measuring interrupt latency
 * of the Mali GPU IRQ. In particular, function mali_kutf_irq_latency() is
 * used with this purpose and it is called within KUTF framework - a kernel
 * unit test framework. The measured latency provided by this test should
 * be representative for the latency of the Mali JOB/MMU IRQs as well.
 */

/* KUTF test application pointer for this test */
struct kutf_application *irq_app;

/**
 * struct kutf_irq_fixture data - test fixture used by the test functions.
 * @kbdev:	kbase device for the GPU.
 *
 */
struct kutf_irq_fixture_data {
	struct kbase_device *kbdev;
};

#define SEC_TO_NANO(s)	      ((s)*1000000000LL)

/* ID for the GPU IRQ */
#define GPU_IRQ_HANDLER 2

#define NR_TEST_IRQS 1000000

/* IRQ for the test to trigger. Currently MULTIPLE_GPU_FAULTS as we would not
 * expect to see this in normal use (e.g., when Android is running). */
#define TEST_IRQ MULTIPLE_GPU_FAULTS

#define IRQ_TIMEOUT HZ

/* Kernel API for setting irq throttle hook callback and irq time in us*/
extern int kbase_set_custom_irq_handler(struct kbase_device *kbdev,
		irq_handler_t custom_handler,
		int irq_type);
extern irqreturn_t kbase_gpu_irq_handler(int irq, void *data);

static DECLARE_WAIT_QUEUE_HEAD(wait);
static bool triggered;
static u64 irq_time;

static void *kbase_untag(void *ptr)
{
	return (void *)(((uintptr_t) ptr) & ~3);
}

/**
 * kbase_gpu_irq_custom_handler - Custom IRQ throttle handler
 * @irq:  IRQ number
 * @data: Data associated with this IRQ
 *
 * Return: state of the IRQ
 */
static irqreturn_t kbase_gpu_irq_custom_handler(int irq, void *data)
{
	struct kbase_device *kbdev = kbase_untag(data);
	u32 val;

	val = kbase_reg_read(kbdev, GPU_CONTROL_REG(GPU_IRQ_STATUS), NULL);
	if (val & TEST_IRQ) {
		struct timespec tval;

		getnstimeofday(&tval);
		irq_time = SEC_TO_NANO(tval.tv_sec) + (tval.tv_nsec);

		kbase_reg_write(kbdev, GPU_CONTROL_REG(GPU_IRQ_CLEAR), val,
				NULL);

		triggered = true;
		wake_up(&wait);

		return IRQ_HANDLED;
	}

	/* Trigger main irq handler */
	return kbase_gpu_irq_handler(irq, data);
}

/**
 * mali_kutf_irq_default_create_fixture() - Creates the fixture data required
 *                                          for all the tests in the irq suite.
 * @context:             KUTF context.
 *
 * Return: Fixture data created on success or NULL on failure
 */
static void *mali_kutf_irq_default_create_fixture(
		struct kutf_context *context)
{
	struct kutf_irq_fixture_data *data;

	data = kutf_mempool_alloc(&context->fixture_pool,
			sizeof(struct kutf_irq_fixture_data));

	if (!data)
		goto fail;

	/* Acquire the kbase device */
	data->kbdev = kbase_find_device(-1);
	if (data->kbdev == NULL) {
		kutf_test_fail(context, "Failed to find kbase device");
		goto fail;
	}

	return data;

fail:
	return NULL;
}

/**
 * mali_kutf_irq_default_remove_fixture() - Destroy fixture data previously
 *                          created by mali_kutf_irq_default_create_fixture.
 *
 * @context:             KUTF context.
 */
static void mali_kutf_irq_default_remove_fixture(
		struct kutf_context *context)
{
	struct kutf_irq_fixture_data *data = context->fixture;
	struct kbase_device *kbdev = data->kbdev;

	kbase_release_device(kbdev);
}

/**
 * mali_kutf_irq_latency() - measure GPU IRQ latency
 * @context:		kutf context within which to perform the test
 *
 * The test triggers IRQs manually, and measures the
 * time between triggering the IRQ and the IRQ handler being executed.
 *
 * This is not a traditional test, in that the pass/fail status has little
 * meaning (other than indicating that the IRQ handler executed at all). Instead
 * the results are in the latencies provided with the test result. There is no
 * meaningful pass/fail result that can be obtained here, instead the latencies
 * are provided for manual analysis only.
 */
static void mali_kutf_irq_latency(struct kutf_context *context)
{
	struct kutf_irq_fixture_data *data = context->fixture;
	struct kbase_device *kbdev = data->kbdev;
	u64 min_time = U64_MAX, max_time = 0, average_time = 0;
	int i;
	bool test_failed = false;

	/* Force GPU to be powered */
	kbase_pm_context_active(kbdev);

	kbase_set_custom_irq_handler(kbdev, kbase_gpu_irq_custom_handler,
			GPU_IRQ_HANDLER);

	for (i = 0; i < NR_TEST_IRQS; i++) {
		struct timespec tval;
		u64 start_time;
		int ret;

		triggered = false;
		getnstimeofday(&tval);
		start_time = SEC_TO_NANO(tval.tv_sec) + (tval.tv_nsec);

		/* Trigger fake IRQ */
		kbase_reg_write(kbdev, GPU_CONTROL_REG(GPU_IRQ_RAWSTAT),
				TEST_IRQ, NULL);

		ret = wait_event_timeout(wait, triggered != false, IRQ_TIMEOUT);

		if (ret == 0) {
			kutf_test_fail(context, "Timed out waiting for IRQ\n");
			test_failed = true;
			break;
		}

		if ((irq_time - start_time) < min_time)
			min_time = irq_time - start_time;
		if ((irq_time - start_time) > max_time)
			max_time = irq_time - start_time;
		average_time += irq_time - start_time;

		udelay(10);
	}

	/* Go back to default handler */
	kbase_set_custom_irq_handler(kbdev, NULL, GPU_IRQ_HANDLER);

	kbase_pm_context_idle(kbdev);

	if (!test_failed) {
		const char *results;

		do_div(average_time, NR_TEST_IRQS);
		results = kutf_dsprintf(&context->fixture_pool,
				"Min latency = %lldns, Max latency = %lldns, Average latency = %lldns\n",
				min_time, max_time, average_time);
		kutf_test_pass(context, results);
	}
}

/**
 * Module entry point for this test.
 */
int mali_kutf_irq_test_main_init(void)
{
	struct kutf_suite *suite;

	irq_app = kutf_create_application("irq");

	if (NULL == irq_app) {
		pr_warn("Creation of test application failed!\n");
		return -ENOMEM;
	}

	suite = kutf_create_suite(irq_app, "irq_default",
			1, mali_kutf_irq_default_create_fixture,
			mali_kutf_irq_default_remove_fixture);

	if (NULL == suite) {
		pr_warn("Creation of test suite failed!\n");
		kutf_destroy_application(irq_app);
		return -ENOMEM;
	}

	kutf_add_test(suite, 0x0, "irq_latency",
			mali_kutf_irq_latency);
	return 0;
}

/**
 * Module exit point for this test.
 */
void mali_kutf_irq_test_main_exit(void)
{
	kutf_destroy_application(irq_app);
}

module_init(mali_kutf_irq_test_main_init);
module_exit(mali_kutf_irq_test_main_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("ARM Ltd.");
MODULE_VERSION("1.0");
