// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
/*
 *
 * (C) COPYRIGHT 2019-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/kernel.h>
#include <linux/device.h>
#include <linux/mutex.h>
#include <linux/sysfs.h>
#include <linux/of.h>

#include "mali_kbase.h"
#include "mali_kbase_config_defaults.h"
#include "mali_kbase_csf_firmware.h"
#include "mali_kbase_csf_timeout.h"
#include "mali_kbase_reset_gpu.h"
#include "backend/gpu/mali_kbase_pm_internal.h"

/**
 * set_timeout - set a new global progress timeout.
 *
 * @kbdev:   Instance of a GPU platform device that implements a CSF interface.
 * @timeout: the maximum number of GPU cycles without forward progress to allow
 *           to elapse before terminating a GPU command queue group.
 *
 * Return:   0 on success, or negative on failure
 *           (e.g. -ERANGE if the requested timeout is too large).
 */
static int set_timeout(struct kbase_device *const kbdev, u64 const timeout)
{
	if (timeout > GLB_PROGRESS_TIMER_TIMEOUT_MAX) {
		dev_err(kbdev->dev, "Timeout %llu is too large.\n", timeout);
		return -ERANGE;
	}

	dev_dbg(kbdev->dev, "New progress timeout: %llu cycles\n", timeout);

	atomic64_set(&kbdev->csf.progress_timeout, timeout);

	return 0;
}

/**
 * progress_timeout_store - Store the progress_timeout device attribute.
 * @dev:   The device that has the attribute.
 * @attr:  The attributes of the sysfs file.
 * @buf:   The value written to the sysfs file.
 * @count: The number of bytes written to the sysfs file.
 *
 * This function is called when the progress_timeout sysfs file is written to.
 * It checks the data written, and if valid updates the progress timeout value.
 * The function also checks gpu reset status, if the gpu is in reset process,
 * the function will return an error code (-EBUSY), and no change for timeout
 * value.
 *
 * Return: @count if the function succeeded. An error code on failure.
 */
static ssize_t progress_timeout_store(struct device * const dev,
		struct device_attribute * const attr, const char * const buf,
		size_t const count)
{
	struct kbase_device *const kbdev = dev_get_drvdata(dev);
	int err;
	u64 timeout;

	if (!kbdev)
		return -ENODEV;

	err = kbase_reset_gpu_try_prevent(kbdev);
	if (err) {
		dev_warn(kbdev->dev,
			 "Couldn't process progress_timeout write operation for GPU reset.\n");
		return -EBUSY;
	}

	err = kstrtou64(buf, 0, &timeout);
	if (err)
		dev_err(kbdev->dev,
			"Couldn't process progress_timeout write operation.\n"
			"Use format <progress_timeout>\n");
	else
		err = set_timeout(kbdev, timeout);

	if (!err) {
		kbase_csf_scheduler_pm_active(kbdev);

		err = kbase_pm_wait_for_desired_state(kbdev);
		if (!err)
			err = kbase_csf_firmware_set_timeout(kbdev, timeout);

		kbase_csf_scheduler_pm_idle(kbdev);
	}

	kbase_reset_gpu_allow(kbdev);
	if (err)
		return err;

	return count;
}

/**
 * progress_timeout_show - Show the progress_timeout device attribute.
 * @dev: The device that has the attribute.
 * @attr: The attributes of the sysfs file.
 * @buf:  The output buffer to receive the global timeout.
 *
 * This function is called to get the progress timeout value.
 *
 * Return: The number of bytes output to @buf.
 */
static ssize_t progress_timeout_show(struct device * const dev,
		struct device_attribute * const attr, char * const buf)
{
	struct kbase_device *const kbdev = dev_get_drvdata(dev);
	int err;

	if (!kbdev)
		return -ENODEV;

	err = scnprintf(buf, PAGE_SIZE, "%llu\n", kbase_csf_timeout_get(kbdev));

	return err;

}

static DEVICE_ATTR(progress_timeout, 0644, progress_timeout_show,
	progress_timeout_store);

int kbase_csf_timeout_init(struct kbase_device *const kbdev)
{
	u64 timeout = DEFAULT_PROGRESS_TIMEOUT;
	int err;

#if IS_ENABLED(CONFIG_OF)
	err = of_property_read_u64(kbdev->dev->of_node,
		"progress_timeout", &timeout);
	if (!err)
		dev_info(kbdev->dev, "Found progress_timeout = %llu in Devicetree\n",
			timeout);
#endif

	err = set_timeout(kbdev, timeout);
	if (err)
		return err;

	err = sysfs_create_file(&kbdev->dev->kobj,
		&dev_attr_progress_timeout.attr);
	if (err)
		dev_err(kbdev->dev, "SysFS file creation failed\n");

	return err;
}

void kbase_csf_timeout_term(struct kbase_device * const kbdev)
{
	sysfs_remove_file(&kbdev->dev->kobj, &dev_attr_progress_timeout.attr);
}

u64 kbase_csf_timeout_get(struct kbase_device *const kbdev)
{
	return atomic64_read(&kbdev->csf.progress_timeout);
}
