// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
/*
 *
 * (C) COPYRIGHT 2014-2016, 2018-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 <mali_kbase.h>
#include <device/mali_kbase_device.h>
#include <backend/gpu/mali_kbase_irq_internal.h>

#include <linux/interrupt.h>

#if !IS_ENABLED(CONFIG_MALI_NO_MALI)

/* GPU IRQ Tags */
#define	JOB_IRQ_TAG	0
#define MMU_IRQ_TAG	1
#define GPU_IRQ_TAG	2

static void *kbase_tag(void *ptr, u32 tag)
{
	return (void *)(((uintptr_t) ptr) | tag);
}

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

static irqreturn_t kbase_job_irq_handler(int irq, void *data)
{
	unsigned long flags;
	struct kbase_device *kbdev = kbase_untag(data);
	u32 val;

	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);

	if (!kbdev->pm.backend.gpu_powered) {
		/* GPU is turned off - IRQ is not for us */
		spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
		return IRQ_NONE;
	}

	val = kbase_reg_read(kbdev, JOB_CONTROL_REG(JOB_IRQ_STATUS));

#ifdef CONFIG_MALI_DEBUG
	if (!kbdev->pm.backend.driver_ready_for_irqs)
		dev_warn(kbdev->dev, "%s: irq %d irqstatus 0x%x before driver is ready\n",
				__func__, irq, val);
#endif /* CONFIG_MALI_DEBUG */

	if (!val) {
		spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
		return IRQ_NONE;
	}

	dev_dbg(kbdev->dev, "%s: irq %d irqstatus 0x%x\n", __func__, irq, val);

#if MALI_USE_CSF
	/* call the csf interrupt handler */
	kbase_csf_interrupt(kbdev, val);
#else
	kbase_job_done(kbdev, val);
#endif

	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);

	return IRQ_HANDLED;
}

static irqreturn_t kbase_mmu_irq_handler(int irq, void *data)
{
	unsigned long flags;
	struct kbase_device *kbdev = kbase_untag(data);
	u32 val;

	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);

	if (!kbdev->pm.backend.gpu_powered) {
		/* GPU is turned off - IRQ is not for us */
		spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
		return IRQ_NONE;
	}

	atomic_inc(&kbdev->faults_pending);

	val = kbase_reg_read(kbdev, MMU_REG(MMU_IRQ_STATUS));

#ifdef CONFIG_MALI_DEBUG
	if (!kbdev->pm.backend.driver_ready_for_irqs)
		dev_warn(kbdev->dev, "%s: irq %d irqstatus 0x%x before driver is ready\n",
				__func__, irq, val);
#endif /* CONFIG_MALI_DEBUG */
	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);

	if (!val) {
		atomic_dec(&kbdev->faults_pending);
		return IRQ_NONE;
	}

	dev_dbg(kbdev->dev, "%s: irq %d irqstatus 0x%x\n", __func__, irq, val);

	kbase_mmu_interrupt(kbdev, val);

	atomic_dec(&kbdev->faults_pending);

	return IRQ_HANDLED;
}

static irqreturn_t kbase_gpu_irq_handler(int irq, void *data)
{
	unsigned long flags;
	struct kbase_device *kbdev = kbase_untag(data);
	u32 val;

	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);

	if (!kbdev->pm.backend.gpu_powered) {
		/* GPU is turned off - IRQ is not for us */
		spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
		return IRQ_NONE;
	}

	val = kbase_reg_read(kbdev, GPU_CONTROL_REG(GPU_IRQ_STATUS));

#ifdef CONFIG_MALI_DEBUG
	if (!kbdev->pm.backend.driver_ready_for_irqs)
		dev_dbg(kbdev->dev, "%s: irq %d irqstatus 0x%x before driver is ready\n",
				__func__, irq, val);
#endif /* CONFIG_MALI_DEBUG */
	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);

	if (!val)
		return IRQ_NONE;

	dev_dbg(kbdev->dev, "%s: irq %d irqstatus 0x%x\n", __func__, irq, val);

	kbase_gpu_interrupt(kbdev, val);

	return IRQ_HANDLED;
}

static irq_handler_t kbase_handler_table[] = {
	[JOB_IRQ_TAG] = kbase_job_irq_handler,
	[MMU_IRQ_TAG] = kbase_mmu_irq_handler,
	[GPU_IRQ_TAG] = kbase_gpu_irq_handler,
};

#ifdef CONFIG_MALI_DEBUG
#define  JOB_IRQ_HANDLER JOB_IRQ_TAG
#define  MMU_IRQ_HANDLER MMU_IRQ_TAG
#define  GPU_IRQ_HANDLER GPU_IRQ_TAG

/**
 * kbase_gpu_irq_test_handler - Variant (for test) of kbase_gpu_irq_handler()
 * @irq:  IRQ number
 * @data: Data associated with this IRQ (i.e. kbdev)
 * @val:  Value of the GPU_CONTROL_REG(GPU_IRQ_STATUS)
 *
 * Handle the GPU device interrupt source requests reflected in the
 * given source bit-pattern. The test code caller is responsible for
 * undertaking the required device power maintenace.
 *
 * Return: IRQ_HANDLED if the requests are from the GPU device,
 *         IRQ_NONE otherwise
 */
irqreturn_t kbase_gpu_irq_test_handler(int irq, void *data, u32 val)
{
	struct kbase_device *kbdev = kbase_untag(data);

	if (!val)
		return IRQ_NONE;

	dev_dbg(kbdev->dev, "%s: irq %d irqstatus 0x%x\n", __func__, irq, val);

	kbase_gpu_interrupt(kbdev, val);

	return IRQ_HANDLED;
}

KBASE_EXPORT_TEST_API(kbase_gpu_irq_test_handler);

/**
 * kbase_set_custom_irq_handler - Set a custom IRQ handler
 * @kbdev: Device for which the handler is to be registered
 * @custom_handler: Handler to be registered
 * @irq_type: Interrupt type
 *
 * Registers given interrupt handler for requested interrupt type
 * In the case where irq handler is not specified, the default handler shall be
 * registered
 *
 * Return: 0 case success, error code otherwise
 */
int kbase_set_custom_irq_handler(struct kbase_device *kbdev,
					irq_handler_t custom_handler,
					int irq_type)
{
	int result = 0;
	irq_handler_t requested_irq_handler = NULL;

	KBASE_DEBUG_ASSERT((irq_type >= JOB_IRQ_HANDLER) &&
			   (irq_type <= GPU_IRQ_HANDLER));

	/* Release previous handler */
	if (kbdev->irqs[irq_type].irq)
		free_irq(kbdev->irqs[irq_type].irq, kbase_tag(kbdev, irq_type));

	requested_irq_handler = (custom_handler != NULL) ?
					custom_handler :
					kbase_handler_table[irq_type];

	if (request_irq(kbdev->irqs[irq_type].irq, requested_irq_handler,
			kbdev->irqs[irq_type].flags | IRQF_SHARED,
			dev_name(kbdev->dev),
			kbase_tag(kbdev, irq_type)) != 0) {
		result = -EINVAL;
		dev_err(kbdev->dev, "Can't request interrupt %d (index %d)\n",
					kbdev->irqs[irq_type].irq, irq_type);
#if IS_ENABLED(CONFIG_SPARSE_IRQ)
		dev_err(kbdev->dev, "You have CONFIG_SPARSE_IRQ support enabled - is the interrupt number correct for this configuration?\n");
#endif /* CONFIG_SPARSE_IRQ */
	}

	return result;
}

KBASE_EXPORT_TEST_API(kbase_set_custom_irq_handler);

/* test correct interrupt assigment and reception by cpu */
struct kbasep_irq_test {
	struct hrtimer timer;
	wait_queue_head_t wait;
	int triggered;
	u32 timeout;
};

static struct kbasep_irq_test kbasep_irq_test_data;

#define IRQ_TEST_TIMEOUT    500

static irqreturn_t kbase_job_irq_test_handler(int irq, void *data)
{
	unsigned long flags;
	struct kbase_device *kbdev = kbase_untag(data);
	u32 val;

	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);

	if (!kbdev->pm.backend.gpu_powered) {
		/* GPU is turned off - IRQ is not for us */
		spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
		return IRQ_NONE;
	}

	val = kbase_reg_read(kbdev, JOB_CONTROL_REG(JOB_IRQ_STATUS));

	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);

	if (!val)
		return IRQ_NONE;

	dev_dbg(kbdev->dev, "%s: irq %d irqstatus 0x%x\n", __func__, irq, val);

	kbasep_irq_test_data.triggered = 1;
	wake_up(&kbasep_irq_test_data.wait);

	kbase_reg_write(kbdev, JOB_CONTROL_REG(JOB_IRQ_CLEAR), val);

	return IRQ_HANDLED;
}

static irqreturn_t kbase_mmu_irq_test_handler(int irq, void *data)
{
	unsigned long flags;
	struct kbase_device *kbdev = kbase_untag(data);
	u32 val;

	spin_lock_irqsave(&kbdev->hwaccess_lock, flags);

	if (!kbdev->pm.backend.gpu_powered) {
		/* GPU is turned off - IRQ is not for us */
		spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);
		return IRQ_NONE;
	}

	val = kbase_reg_read(kbdev, MMU_REG(MMU_IRQ_STATUS));

	spin_unlock_irqrestore(&kbdev->hwaccess_lock, flags);

	if (!val)
		return IRQ_NONE;

	dev_dbg(kbdev->dev, "%s: irq %d irqstatus 0x%x\n", __func__, irq, val);

	kbasep_irq_test_data.triggered = 1;
	wake_up(&kbasep_irq_test_data.wait);

	kbase_reg_write(kbdev, MMU_REG(MMU_IRQ_CLEAR), val);

	return IRQ_HANDLED;
}

static enum hrtimer_restart kbasep_test_interrupt_timeout(struct hrtimer *timer)
{
	struct kbasep_irq_test *test_data = container_of(timer,
						struct kbasep_irq_test, timer);

	test_data->timeout = 1;
	test_data->triggered = 1;
	wake_up(&test_data->wait);
	return HRTIMER_NORESTART;
}

static int kbasep_common_test_interrupt(
				struct kbase_device * const kbdev, u32 tag)
{
	int err = 0;
	irq_handler_t test_handler;

	u32 old_mask_val;
	u16 mask_offset;
	u16 rawstat_offset;

	switch (tag) {
	case JOB_IRQ_TAG:
		test_handler = kbase_job_irq_test_handler;
		rawstat_offset = JOB_CONTROL_REG(JOB_IRQ_RAWSTAT);
		mask_offset = JOB_CONTROL_REG(JOB_IRQ_MASK);
		break;
	case MMU_IRQ_TAG:
		test_handler = kbase_mmu_irq_test_handler;
		rawstat_offset = MMU_REG(MMU_IRQ_RAWSTAT);
		mask_offset = MMU_REG(MMU_IRQ_MASK);
		break;
	case GPU_IRQ_TAG:
		/* already tested by pm_driver - bail out */
	default:
		return 0;
	}

	/* store old mask */
	old_mask_val = kbase_reg_read(kbdev, mask_offset);
	/* mask interrupts */
	kbase_reg_write(kbdev, mask_offset, 0x0);

	if (kbdev->irqs[tag].irq) {
		/* release original handler and install test handler */
		if (kbase_set_custom_irq_handler(kbdev, test_handler, tag) != 0) {
			err = -EINVAL;
		} else {
			kbasep_irq_test_data.timeout = 0;
			hrtimer_init(&kbasep_irq_test_data.timer,
					CLOCK_MONOTONIC, HRTIMER_MODE_REL);
			kbasep_irq_test_data.timer.function =
						kbasep_test_interrupt_timeout;

			/* trigger interrupt */
			kbase_reg_write(kbdev, mask_offset, 0x1);
			kbase_reg_write(kbdev, rawstat_offset, 0x1);

			hrtimer_start(&kbasep_irq_test_data.timer,
					HR_TIMER_DELAY_MSEC(IRQ_TEST_TIMEOUT),
					HRTIMER_MODE_REL);

			wait_event(kbasep_irq_test_data.wait,
					kbasep_irq_test_data.triggered != 0);

			if (kbasep_irq_test_data.timeout != 0) {
				dev_err(kbdev->dev, "Interrupt %d (index %d) didn't reach CPU.\n",
						kbdev->irqs[tag].irq, tag);
				err = -EINVAL;
			} else {
				dev_dbg(kbdev->dev, "Interrupt %d (index %d) reached CPU.\n",
						kbdev->irqs[tag].irq, tag);
			}

			hrtimer_cancel(&kbasep_irq_test_data.timer);
			kbasep_irq_test_data.triggered = 0;

			/* mask interrupts */
			kbase_reg_write(kbdev, mask_offset, 0x0);

			/* release test handler */
			free_irq(kbdev->irqs[tag].irq, kbase_tag(kbdev, tag));
		}

		/* restore original interrupt */
		if (request_irq(kbdev->irqs[tag].irq, kbase_handler_table[tag],
				kbdev->irqs[tag].flags | IRQF_SHARED,
				dev_name(kbdev->dev), kbase_tag(kbdev, tag))) {
			dev_err(kbdev->dev, "Can't restore original interrupt %d (index %d)\n",
						kbdev->irqs[tag].irq, tag);
			err = -EINVAL;
		}
	}
	/* restore old mask */
	kbase_reg_write(kbdev, mask_offset, old_mask_val);

	return err;
}

int kbasep_common_test_interrupt_handlers(
					struct kbase_device * const kbdev)
{
	int err;

	init_waitqueue_head(&kbasep_irq_test_data.wait);
	kbasep_irq_test_data.triggered = 0;

	/* A suspend won't happen during startup/insmod */
	kbase_pm_context_active(kbdev);

	err = kbasep_common_test_interrupt(kbdev, JOB_IRQ_TAG);
	if (err) {
		dev_err(kbdev->dev, "Interrupt JOB_IRQ didn't reach CPU. Check interrupt assignments.\n");
		goto out;
	}

	err = kbasep_common_test_interrupt(kbdev, MMU_IRQ_TAG);
	if (err) {
		dev_err(kbdev->dev, "Interrupt MMU_IRQ didn't reach CPU. Check interrupt assignments.\n");
		goto out;
	}

	dev_dbg(kbdev->dev, "Interrupts are correctly assigned.\n");

 out:
	kbase_pm_context_idle(kbdev);

	return err;
}
#endif /* CONFIG_MALI_DEBUG */

int kbase_install_interrupts(struct kbase_device *kbdev)
{
	u32 nr = ARRAY_SIZE(kbase_handler_table);
	int err;
	u32 i;

	for (i = 0; i < nr; i++) {
		err = request_irq(kbdev->irqs[i].irq, kbase_handler_table[i],
				kbdev->irqs[i].flags | IRQF_SHARED,
				dev_name(kbdev->dev),
				kbase_tag(kbdev, i));
		if (err) {
			dev_err(kbdev->dev, "Can't request interrupt %d (index %d)\n",
							kbdev->irqs[i].irq, i);
#if IS_ENABLED(CONFIG_SPARSE_IRQ)
			dev_err(kbdev->dev, "You have CONFIG_SPARSE_IRQ support enabled - is the interrupt number correct for this configuration?\n");
#endif /* CONFIG_SPARSE_IRQ */
			goto release;
		}
	}

	return 0;

 release:
	while (i-- > 0)
		free_irq(kbdev->irqs[i].irq, kbase_tag(kbdev, i));

	return err;
}

void kbase_release_interrupts(struct kbase_device *kbdev)
{
	u32 nr = ARRAY_SIZE(kbase_handler_table);
	u32 i;

	for (i = 0; i < nr; i++) {
		if (kbdev->irqs[i].irq)
			free_irq(kbdev->irqs[i].irq, kbase_tag(kbdev, i));
	}
}

void kbase_synchronize_irqs(struct kbase_device *kbdev)
{
	u32 nr = ARRAY_SIZE(kbase_handler_table);
	u32 i;

	for (i = 0; i < nr; i++) {
		if (kbdev->irqs[i].irq)
			synchronize_irq(kbdev->irqs[i].irq);
	}
}

KBASE_EXPORT_TEST_API(kbase_synchronize_irqs);

#endif /* !IS_ENABLED(CONFIG_MALI_NO_MALI) */
