// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
/*
 *
 * (C) COPYRIGHT 2016-2018, 2020-2021 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 license.
 *
 * 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.
 *
 */

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

#include "mali_kbase.h"
#include <device/mali_kbase_device.h>
#include <backend/gpu/mali_kbase_pm_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 ((u32)1000000)

/* IRQ for the test to trigger. Currently POWER_CHANGED_SINGLE as it is
 * otherwise unused in the DDK
 */
#define TEST_IRQ POWER_CHANGED_SINGLE

#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_test_handler(int irq, void *data, u32 val);

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 = kbase_reg_read(kbdev, GPU_CONTROL_REG(GPU_IRQ_STATUS));
	irqreturn_t result;
	u64 tval;
	bool has_test_irq = val & TEST_IRQ;

	if (has_test_irq) {
		tval = ktime_get_real_ns();
		/* Clear the test source only here */
		kbase_reg_write(kbdev, GPU_CONTROL_REG(GPU_IRQ_CLEAR),
				TEST_IRQ);
		/* Remove the test IRQ status bit */
		val = val ^ TEST_IRQ;
	}

	result = kbase_gpu_irq_test_handler(irq, data, val);

	if (has_test_irq) {
		irq_time = tval;
		triggered = true;
		wake_up(&wait);
		result = IRQ_HANDLED;
	}

	return result;
}

/**
 * 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;
	u32 i;
	const char *results;

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

	kbase_set_custom_irq_handler(kbdev, kbase_gpu_irq_custom_handler,
			GPU_IRQ_HANDLER);

	for (i = 1; i <= NR_TEST_IRQS; i++) {
		u64 start_time = ktime_get_real_ns();

		triggered = false;

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

		if (wait_event_timeout(wait, triggered, IRQ_TIMEOUT) == 0) {
			/* Wait extra time to see if it would come */
			wait_event_timeout(wait, triggered, 10 * IRQ_TIMEOUT);
			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 (i > NR_TEST_IRQS) {
		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);
	} else {
		results = kutf_dsprintf(&context->fixture_pool,
				"Timed out for the %u-th IRQ (loop_limit: %u), triggered late: %d\n",
				i, NR_TEST_IRQS, triggered);
		kutf_test_fail(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 (irq_app == NULL) {
		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 (suite == NULL) {
		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");
