// SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
/*
 *
 * (C) COPYRIGHT 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 "mali_kbase_hwcnt_legacy.h"
#include "mali_kbase_hwcnt_virtualizer.h"
#include "mali_kbase_hwcnt_types.h"
#include "mali_kbase_hwcnt_gpu.h"
#include <uapi/gpu/arm/midgard/mali_kbase_ioctl.h>

#include <linux/slab.h>
#include <linux/uaccess.h>

/**
 * struct kbase_hwcnt_legacy_client - Legacy hardware counter client.
 * @user_dump_buf: Pointer to a non-NULL user buffer, where dumps are returned.
 * @enable_map:    Counter enable map.
 * @dump_buf:      Dump buffer used to manipulate dumps before copied to user.
 * @hvcli:         Hardware counter virtualizer client.
 */
struct kbase_hwcnt_legacy_client {
	void __user *user_dump_buf;
	struct kbase_hwcnt_enable_map enable_map;
	struct kbase_hwcnt_dump_buffer dump_buf;
	struct kbase_hwcnt_virtualizer_client *hvcli;
};

int kbase_hwcnt_legacy_client_create(
	struct kbase_hwcnt_virtualizer *hvirt,
	struct kbase_ioctl_hwcnt_enable *enable,
	struct kbase_hwcnt_legacy_client **out_hlcli)
{
	int errcode;
	struct kbase_hwcnt_legacy_client *hlcli;
	const struct kbase_hwcnt_metadata *metadata;
	struct kbase_hwcnt_physical_enable_map phys_em;

	if (!hvirt || !enable || !enable->dump_buffer || !out_hlcli)
		return -EINVAL;

	metadata = kbase_hwcnt_virtualizer_metadata(hvirt);

	hlcli = kzalloc(sizeof(*hlcli), GFP_KERNEL);
	if (!hlcli)
		return -ENOMEM;

	hlcli->user_dump_buf = (void __user *)(uintptr_t)enable->dump_buffer;

	errcode = kbase_hwcnt_enable_map_alloc(metadata, &hlcli->enable_map);
	if (errcode)
		goto error;

	/* Translate from the ioctl enable map to the internal one */
	phys_em.fe_bm = enable->fe_bm;
	phys_em.shader_bm = enable->shader_bm;
	phys_em.tiler_bm = enable->tiler_bm;
	phys_em.mmu_l2_bm = enable->mmu_l2_bm;
	kbase_hwcnt_gpu_enable_map_from_physical(&hlcli->enable_map, &phys_em);

	errcode = kbase_hwcnt_dump_buffer_alloc(metadata, &hlcli->dump_buf);
	if (errcode)
		goto error;

	errcode = kbase_hwcnt_virtualizer_client_create(
		hvirt, &hlcli->enable_map, &hlcli->hvcli);
	if (errcode)
		goto error;

	*out_hlcli = hlcli;
	return 0;

error:
	kbase_hwcnt_legacy_client_destroy(hlcli);
	return errcode;
}

void kbase_hwcnt_legacy_client_destroy(struct kbase_hwcnt_legacy_client *hlcli)
{
	if (!hlcli)
		return;

	kbase_hwcnt_virtualizer_client_destroy(hlcli->hvcli);
	kbase_hwcnt_dump_buffer_free(&hlcli->dump_buf);
	kbase_hwcnt_enable_map_free(&hlcli->enable_map);
	kfree(hlcli);
}

int kbase_hwcnt_legacy_client_dump(struct kbase_hwcnt_legacy_client *hlcli)
{
	int errcode;
	u64 ts_start_ns;
	u64 ts_end_ns;

	if (!hlcli)
		return -EINVAL;

	/* Dump into the kernel buffer */
	errcode = kbase_hwcnt_virtualizer_client_dump(hlcli->hvcli,
		&ts_start_ns, &ts_end_ns, &hlcli->dump_buf);
	if (errcode)
		return errcode;

	/* Patch the dump buf headers, to hide the counters that other hwcnt
	 * clients are using.
	 */
	kbase_hwcnt_gpu_patch_dump_headers(
		&hlcli->dump_buf, &hlcli->enable_map);

	/* Zero all non-enabled counters (current values are undefined) */
	kbase_hwcnt_dump_buffer_zero_non_enabled(
		&hlcli->dump_buf, &hlcli->enable_map);

	/* Copy into the user's buffer */
	errcode = copy_to_user(hlcli->user_dump_buf, hlcli->dump_buf.dump_buf,
		hlcli->dump_buf.metadata->dump_buf_bytes);
	/* Non-zero errcode implies user buf was invalid or too small */
	if (errcode)
		return -EFAULT;

	return 0;
}

int kbase_hwcnt_legacy_client_clear(struct kbase_hwcnt_legacy_client *hlcli)
{
	u64 ts_start_ns;
	u64 ts_end_ns;

	if (!hlcli)
		return -EINVAL;

	/* Dump with a NULL buffer to clear this client's counters */
	return kbase_hwcnt_virtualizer_client_dump(hlcli->hvcli,
		&ts_start_ns, &ts_end_ns, NULL);
}
