// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
 * Copyright (C) 2020-2024 Intel Corporation
 */

#include <drm/drm_file.h>

#include "ivpu_drv.h"
#include "ivpu_gem.h"
#include "ivpu_jsm_msg.h"
#include "ivpu_ms.h"
#include "ivpu_pm.h"

#define MS_INFO_BUFFER_SIZE	  SZ_16K
#define MS_NUM_BUFFERS		  2
#define MS_READ_PERIOD_MULTIPLIER 2
#define MS_MIN_SAMPLE_PERIOD_NS   1000000

static struct ivpu_ms_instance *
get_instance_by_mask(struct ivpu_file_priv *file_priv, u64 metric_mask)
{
	struct ivpu_ms_instance *ms;

	lockdep_assert_held(&file_priv->ms_lock);

	list_for_each_entry(ms, &file_priv->ms_instance_list, ms_instance_node)
		if (ms->mask == metric_mask)
			return ms;

	return NULL;
}

int ivpu_ms_start_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
{
	struct ivpu_file_priv *file_priv = file->driver_priv;
	struct drm_ivpu_metric_streamer_start *args = data;
	struct ivpu_device *vdev = file_priv->vdev;
	struct ivpu_ms_instance *ms;
	u64 single_buff_size;
	u32 sample_size;
	int ret;

	if (!args->metric_group_mask || !args->read_period_samples ||
	    args->sampling_period_ns < MS_MIN_SAMPLE_PERIOD_NS)
		return -EINVAL;

	mutex_lock(&file_priv->ms_lock);

	if (get_instance_by_mask(file_priv, args->metric_group_mask)) {
		ivpu_err(vdev, "Instance already exists (mask %#llx)\n", args->metric_group_mask);
		ret = -EALREADY;
		goto unlock;
	}

	ms = kzalloc(sizeof(*ms), GFP_KERNEL);
	if (!ms) {
		ret = -ENOMEM;
		goto unlock;
	}

	ms->mask = args->metric_group_mask;

	ret = ivpu_jsm_metric_streamer_info(vdev, ms->mask, 0, 0, &sample_size, NULL);
	if (ret)
		goto err_free_ms;

	single_buff_size = sample_size *
		((u64)args->read_period_samples * MS_READ_PERIOD_MULTIPLIER);
	ms->bo = ivpu_bo_create_global(vdev, PAGE_ALIGN(single_buff_size * MS_NUM_BUFFERS),
				       DRM_IVPU_BO_CACHED | DRM_IVPU_BO_MAPPABLE);
	if (!ms->bo) {
		ivpu_err(vdev, "Failed to allocate MS buffer (size %llu)\n", single_buff_size);
		ret = -ENOMEM;
		goto err_free_ms;
	}

	ms->buff_size = ivpu_bo_size(ms->bo) / MS_NUM_BUFFERS;
	ms->active_buff_vpu_addr = ms->bo->vpu_addr;
	ms->inactive_buff_vpu_addr = ms->bo->vpu_addr + ms->buff_size;
	ms->active_buff_ptr = ivpu_bo_vaddr(ms->bo);
	ms->inactive_buff_ptr = ivpu_bo_vaddr(ms->bo) + ms->buff_size;

	ret = ivpu_jsm_metric_streamer_start(vdev, ms->mask, args->sampling_period_ns,
					     ms->active_buff_vpu_addr, ms->buff_size);
	if (ret)
		goto err_free_bo;

	args->sample_size = sample_size;
	args->max_data_size = ivpu_bo_size(ms->bo);
	list_add_tail(&ms->ms_instance_node, &file_priv->ms_instance_list);
	goto unlock;

err_free_bo:
	ivpu_bo_free(ms->bo);
err_free_ms:
	kfree(ms);
unlock:
	mutex_unlock(&file_priv->ms_lock);
	return ret;
}

static int
copy_leftover_bytes(struct ivpu_ms_instance *ms,
		    void __user *user_ptr, u64 user_size, u64 *user_bytes_copied)
{
	u64 copy_bytes;

	if (ms->leftover_bytes) {
		copy_bytes = min(user_size - *user_bytes_copied, ms->leftover_bytes);
		if (copy_to_user(user_ptr + *user_bytes_copied, ms->leftover_addr, copy_bytes))
			return -EFAULT;

		ms->leftover_bytes -= copy_bytes;
		ms->leftover_addr += copy_bytes;
		*user_bytes_copied += copy_bytes;
	}

	return 0;
}

static int
copy_samples_to_user(struct ivpu_device *vdev, struct ivpu_ms_instance *ms,
		     void __user *user_ptr, u64 user_size, u64 *user_bytes_copied)
{
	u64 bytes_written;
	int ret;

	*user_bytes_copied = 0;

	ret = copy_leftover_bytes(ms, user_ptr, user_size, user_bytes_copied);
	if (ret)
		return ret;

	if (*user_bytes_copied == user_size)
		return 0;

	ret = ivpu_jsm_metric_streamer_update(vdev, ms->mask, ms->inactive_buff_vpu_addr,
					      ms->buff_size, &bytes_written);
	if (ret)
		return ret;

	swap(ms->active_buff_vpu_addr, ms->inactive_buff_vpu_addr);
	swap(ms->active_buff_ptr, ms->inactive_buff_ptr);

	ms->leftover_bytes = bytes_written;
	ms->leftover_addr = ms->inactive_buff_ptr;

	return copy_leftover_bytes(ms, user_ptr, user_size, user_bytes_copied);
}

int ivpu_ms_get_data_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
{
	struct drm_ivpu_metric_streamer_get_data *args = data;
	struct ivpu_file_priv *file_priv = file->driver_priv;
	struct ivpu_device *vdev = file_priv->vdev;
	struct ivpu_ms_instance *ms;
	u64 bytes_written;
	int ret;

	if (!args->metric_group_mask)
		return -EINVAL;

	mutex_lock(&file_priv->ms_lock);

	ms = get_instance_by_mask(file_priv, args->metric_group_mask);
	if (!ms) {
		ivpu_err(vdev, "Instance doesn't exist for mask: %#llx\n", args->metric_group_mask);
		ret = -EINVAL;
		goto unlock;
	}

	if (!args->buffer_size) {
		ret = ivpu_jsm_metric_streamer_update(vdev, ms->mask, 0, 0, &bytes_written);
		if (ret)
			goto unlock;
		args->data_size = bytes_written + ms->leftover_bytes;
		goto unlock;
	}

	if (!args->buffer_ptr) {
		ret = -EINVAL;
		goto unlock;
	}

	ret = copy_samples_to_user(vdev, ms, u64_to_user_ptr(args->buffer_ptr),
				   args->buffer_size, &args->data_size);
unlock:
	mutex_unlock(&file_priv->ms_lock);

	return ret;
}

static void free_instance(struct ivpu_file_priv *file_priv, struct ivpu_ms_instance *ms)
{
	lockdep_assert_held(&file_priv->ms_lock);

	list_del(&ms->ms_instance_node);
	ivpu_jsm_metric_streamer_stop(file_priv->vdev, ms->mask);
	ivpu_bo_free(ms->bo);
	kfree(ms);
}

int ivpu_ms_stop_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
{
	struct ivpu_file_priv *file_priv = file->driver_priv;
	struct drm_ivpu_metric_streamer_stop *args = data;
	struct ivpu_ms_instance *ms;

	if (!args->metric_group_mask)
		return -EINVAL;

	mutex_lock(&file_priv->ms_lock);

	ms = get_instance_by_mask(file_priv, args->metric_group_mask);
	if (ms)
		free_instance(file_priv, ms);

	mutex_unlock(&file_priv->ms_lock);

	return ms ? 0 : -EINVAL;
}

static inline struct ivpu_bo *get_ms_info_bo(struct ivpu_file_priv *file_priv)
{
	lockdep_assert_held(&file_priv->ms_lock);

	if (file_priv->ms_info_bo)
		return file_priv->ms_info_bo;

	file_priv->ms_info_bo = ivpu_bo_create_global(file_priv->vdev, MS_INFO_BUFFER_SIZE,
						      DRM_IVPU_BO_CACHED | DRM_IVPU_BO_MAPPABLE);
	return file_priv->ms_info_bo;
}

int ivpu_ms_get_info_ioctl(struct drm_device *dev, void *data, struct drm_file *file)
{
	struct drm_ivpu_metric_streamer_get_data *args = data;
	struct ivpu_file_priv *file_priv = file->driver_priv;
	struct ivpu_device *vdev = file_priv->vdev;
	struct ivpu_bo *bo;
	u64 info_size;
	int ret;

	if (!args->metric_group_mask)
		return -EINVAL;

	if (!args->buffer_size)
		return ivpu_jsm_metric_streamer_info(vdev, args->metric_group_mask,
						     0, 0, NULL, &args->data_size);
	if (!args->buffer_ptr)
		return -EINVAL;

	mutex_lock(&file_priv->ms_lock);

	bo = get_ms_info_bo(file_priv);
	if (!bo) {
		ret = -ENOMEM;
		goto unlock;
	}

	ret = ivpu_jsm_metric_streamer_info(vdev, args->metric_group_mask, bo->vpu_addr,
					    ivpu_bo_size(bo), NULL, &info_size);
	if (ret)
		goto unlock;

	if (args->buffer_size < info_size) {
		ret = -ENOSPC;
		goto unlock;
	}

	if (copy_to_user(u64_to_user_ptr(args->buffer_ptr), ivpu_bo_vaddr(bo), info_size))
		ret = -EFAULT;

	args->data_size = info_size;
unlock:
	mutex_unlock(&file_priv->ms_lock);

	return ret;
}

void ivpu_ms_cleanup(struct ivpu_file_priv *file_priv)
{
	struct ivpu_ms_instance *ms, *tmp;

	mutex_lock(&file_priv->ms_lock);

	if (file_priv->ms_info_bo) {
		ivpu_bo_free(file_priv->ms_info_bo);
		file_priv->ms_info_bo = NULL;
	}

	list_for_each_entry_safe(ms, tmp, &file_priv->ms_instance_list, ms_instance_node)
		free_instance(file_priv, ms);

	mutex_unlock(&file_priv->ms_lock);
}

void ivpu_ms_cleanup_all(struct ivpu_device *vdev)
{
	struct ivpu_file_priv *file_priv;
	unsigned long ctx_id;

	mutex_lock(&vdev->context_list_lock);

	xa_for_each(&vdev->context_xa, ctx_id, file_priv)
		ivpu_ms_cleanup(file_priv);

	mutex_unlock(&vdev->context_list_lock);
}
