// SPDX-License-Identifier: GPL-2.0 OR MIT
/**************************************************************************
 *
 * Copyright 2009-2023 VMware, Inc., Palo Alto, CA., USA
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sub license, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 **************************************************************************/
#include "vmwgfx_bo.h"
#include "vmwgfx_drv.h"

#include "device_include/svga_overlay.h"
#include "device_include/svga_escape.h"

#include <drm/ttm/ttm_placement.h>

#define VMW_MAX_NUM_STREAMS 1
#define VMW_OVERLAY_CAP_MASK (SVGA_FIFO_CAP_VIDEO | SVGA_FIFO_CAP_ESCAPE)

struct vmw_stream {
	struct vmw_bo *buf;
	bool claimed;
	bool paused;
	struct drm_vmw_control_stream_arg saved;
};

/*
 * Overlay control
 */
struct vmw_overlay {
	/*
	 * Each stream is a single overlay. In Xv these are called ports.
	 */
	struct mutex mutex;
	struct vmw_stream stream[VMW_MAX_NUM_STREAMS];
};

struct vmw_escape_header {
	uint32_t cmd;
	SVGAFifoCmdEscape body;
};

struct vmw_escape_video_flush {
	struct vmw_escape_header escape;
	SVGAEscapeVideoFlush flush;
};

static inline void fill_escape(struct vmw_escape_header *header,
			       uint32_t size)
{
	header->cmd = SVGA_CMD_ESCAPE;
	header->body.nsid = SVGA_ESCAPE_NSID_VMWARE;
	header->body.size = size;
}

static inline void fill_flush(struct vmw_escape_video_flush *cmd,
			      uint32_t stream_id)
{
	fill_escape(&cmd->escape, sizeof(cmd->flush));
	cmd->flush.cmdType = SVGA_ESCAPE_VMWARE_VIDEO_FLUSH;
	cmd->flush.streamId = stream_id;
}

/*
 * Send put command to hw.
 *
 * Returns
 * -ERESTARTSYS if interrupted by a signal.
 */
static int vmw_overlay_send_put(struct vmw_private *dev_priv,
				struct vmw_bo *buf,
				struct drm_vmw_control_stream_arg *arg,
				bool interruptible)
{
	struct vmw_escape_video_flush *flush;
	size_t fifo_size;
	bool have_so = (dev_priv->active_display_unit == vmw_du_screen_object);
	int i, num_items;
	SVGAGuestPtr ptr;

	struct {
		struct vmw_escape_header escape;
		struct {
			uint32_t cmdType;
			uint32_t streamId;
		} header;
	} *cmds;
	struct {
		uint32_t registerId;
		uint32_t value;
	} *items;

	/* defines are a index needs + 1 */
	if (have_so)
		num_items = SVGA_VIDEO_DST_SCREEN_ID + 1;
	else
		num_items = SVGA_VIDEO_PITCH_3 + 1;

	fifo_size = sizeof(*cmds) + sizeof(*flush) + sizeof(*items) * num_items;

	cmds = VMW_CMD_RESERVE(dev_priv, fifo_size);
	/* hardware has hung, can't do anything here */
	if (!cmds)
		return -ENOMEM;

	items = (typeof(items))&cmds[1];
	flush = (struct vmw_escape_video_flush *)&items[num_items];

	/* the size is header + number of items */
	fill_escape(&cmds->escape, sizeof(*items) * (num_items + 1));

	cmds->header.cmdType = SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS;
	cmds->header.streamId = arg->stream_id;

	/* the IDs are neatly numbered */
	for (i = 0; i < num_items; i++)
		items[i].registerId = i;

	vmw_bo_get_guest_ptr(&buf->tbo, &ptr);
	ptr.offset += arg->offset;

	items[SVGA_VIDEO_ENABLED].value     = true;
	items[SVGA_VIDEO_FLAGS].value       = arg->flags;
	items[SVGA_VIDEO_DATA_OFFSET].value = ptr.offset;
	items[SVGA_VIDEO_FORMAT].value      = arg->format;
	items[SVGA_VIDEO_COLORKEY].value    = arg->color_key;
	items[SVGA_VIDEO_SIZE].value        = arg->size;
	items[SVGA_VIDEO_WIDTH].value       = arg->width;
	items[SVGA_VIDEO_HEIGHT].value      = arg->height;
	items[SVGA_VIDEO_SRC_X].value       = arg->src.x;
	items[SVGA_VIDEO_SRC_Y].value       = arg->src.y;
	items[SVGA_VIDEO_SRC_WIDTH].value   = arg->src.w;
	items[SVGA_VIDEO_SRC_HEIGHT].value  = arg->src.h;
	items[SVGA_VIDEO_DST_X].value       = arg->dst.x;
	items[SVGA_VIDEO_DST_Y].value       = arg->dst.y;
	items[SVGA_VIDEO_DST_WIDTH].value   = arg->dst.w;
	items[SVGA_VIDEO_DST_HEIGHT].value  = arg->dst.h;
	items[SVGA_VIDEO_PITCH_1].value     = arg->pitch[0];
	items[SVGA_VIDEO_PITCH_2].value     = arg->pitch[1];
	items[SVGA_VIDEO_PITCH_3].value     = arg->pitch[2];
	if (have_so) {
		items[SVGA_VIDEO_DATA_GMRID].value    = ptr.gmrId;
		items[SVGA_VIDEO_DST_SCREEN_ID].value = SVGA_ID_INVALID;
	}

	fill_flush(flush, arg->stream_id);

	vmw_cmd_commit(dev_priv, fifo_size);

	return 0;
}

/*
 * Send stop command to hw.
 *
 * Returns
 * -ERESTARTSYS if interrupted by a signal.
 */
static int vmw_overlay_send_stop(struct vmw_private *dev_priv,
				 uint32_t stream_id,
				 bool interruptible)
{
	struct {
		struct vmw_escape_header escape;
		SVGAEscapeVideoSetRegs body;
		struct vmw_escape_video_flush flush;
	} *cmds;
	int ret;

	for (;;) {
		cmds = VMW_CMD_RESERVE(dev_priv, sizeof(*cmds));
		if (cmds)
			break;

		ret = vmw_fallback_wait(dev_priv, false, true, 0,
					interruptible, 3*HZ);
		if (interruptible && ret == -ERESTARTSYS)
			return ret;
		else
			BUG_ON(ret != 0);
	}

	fill_escape(&cmds->escape, sizeof(cmds->body));
	cmds->body.header.cmdType = SVGA_ESCAPE_VMWARE_VIDEO_SET_REGS;
	cmds->body.header.streamId = stream_id;
	cmds->body.items[0].registerId = SVGA_VIDEO_ENABLED;
	cmds->body.items[0].value = false;
	fill_flush(&cmds->flush, stream_id);

	vmw_cmd_commit(dev_priv, sizeof(*cmds));

	return 0;
}

/*
 * Move a buffer to vram or gmr if @pin is set, else unpin the buffer.
 *
 * With the introduction of screen objects buffers could now be
 * used with GMRs instead of being locked to vram.
 */
static int vmw_overlay_move_buffer(struct vmw_private *dev_priv,
				   struct vmw_bo *buf,
				   bool pin, bool inter)
{
	if (!pin)
		return vmw_bo_unpin(dev_priv, buf, inter);

	if (dev_priv->active_display_unit == vmw_du_legacy)
		return vmw_bo_pin_in_vram(dev_priv, buf, inter);

	return vmw_bo_pin_in_vram_or_gmr(dev_priv, buf, inter);
}

/*
 * Stop or pause a stream.
 *
 * If the stream is paused the no evict flag is removed from the buffer
 * but left in vram. This allows for instance mode_set to evict it
 * should it need to.
 *
 * The caller must hold the overlay lock.
 *
 * @stream_id which stream to stop/pause.
 * @pause true to pause, false to stop completely.
 */
static int vmw_overlay_stop(struct vmw_private *dev_priv,
			    uint32_t stream_id, bool pause,
			    bool interruptible)
{
	struct vmw_overlay *overlay = dev_priv->overlay_priv;
	struct vmw_stream *stream = &overlay->stream[stream_id];
	int ret;

	/* no buffer attached the stream is completely stopped */
	if (!stream->buf)
		return 0;

	/* If the stream is paused this is already done */
	if (!stream->paused) {
		ret = vmw_overlay_send_stop(dev_priv, stream_id,
					    interruptible);
		if (ret)
			return ret;

		/* We just remove the NO_EVICT flag so no -ENOMEM */
		ret = vmw_overlay_move_buffer(dev_priv, stream->buf, false,
					      interruptible);
		if (interruptible && ret == -ERESTARTSYS)
			return ret;
		else
			BUG_ON(ret != 0);
	}

	if (!pause) {
		vmw_bo_unreference(&stream->buf);
		stream->paused = false;
	} else {
		stream->paused = true;
	}

	return 0;
}

/*
 * Update a stream and send any put or stop fifo commands needed.
 *
 * The caller must hold the overlay lock.
 *
 * Returns
 * -ENOMEM if buffer doesn't fit in vram.
 * -ERESTARTSYS if interrupted.
 */
static int vmw_overlay_update_stream(struct vmw_private *dev_priv,
				     struct vmw_bo *buf,
				     struct drm_vmw_control_stream_arg *arg,
				     bool interruptible)
{
	struct vmw_overlay *overlay = dev_priv->overlay_priv;
	struct vmw_stream *stream = &overlay->stream[arg->stream_id];
	int ret = 0;

	if (!buf)
		return -EINVAL;

	DRM_DEBUG("   %s: old %p, new %p, %spaused\n", __func__,
		  stream->buf, buf, stream->paused ? "" : "not ");

	if (stream->buf != buf) {
		ret = vmw_overlay_stop(dev_priv, arg->stream_id,
				       false, interruptible);
		if (ret)
			return ret;
	} else if (!stream->paused) {
		/* If the buffers match and not paused then just send
		 * the put command, no need to do anything else.
		 */
		ret = vmw_overlay_send_put(dev_priv, buf, arg, interruptible);
		if (ret == 0)
			stream->saved = *arg;
		else
			BUG_ON(!interruptible);

		return ret;
	}

	/* We don't start the old stream if we are interrupted.
	 * Might return -ENOMEM if it can't fit the buffer in vram.
	 */
	ret = vmw_overlay_move_buffer(dev_priv, buf, true, interruptible);
	if (ret)
		return ret;

	ret = vmw_overlay_send_put(dev_priv, buf, arg, interruptible);
	if (ret) {
		/* This one needs to happen no matter what. We only remove
		 * the NO_EVICT flag so this is safe from -ENOMEM.
		 */
		BUG_ON(vmw_overlay_move_buffer(dev_priv, buf, false, false)
		       != 0);
		return ret;
	}

	if (stream->buf != buf)
		stream->buf = vmw_bo_reference(buf);
	stream->saved = *arg;
	/* stream is no longer stopped/paused */
	stream->paused = false;

	return 0;
}

/*
 * Try to resume all paused streams.
 *
 * Used by the kms code after moving a new scanout buffer to vram.
 *
 * Takes the overlay lock.
 */
int vmw_overlay_resume_all(struct vmw_private *dev_priv)
{
	struct vmw_overlay *overlay = dev_priv->overlay_priv;
	int i, ret;

	if (!overlay)
		return 0;

	mutex_lock(&overlay->mutex);

	for (i = 0; i < VMW_MAX_NUM_STREAMS; i++) {
		struct vmw_stream *stream = &overlay->stream[i];
		if (!stream->paused)
			continue;

		ret = vmw_overlay_update_stream(dev_priv, stream->buf,
						&stream->saved, false);
		if (ret != 0)
			DRM_INFO("%s: *warning* failed to resume stream %i\n",
				 __func__, i);
	}

	mutex_unlock(&overlay->mutex);

	return 0;
}

/*
 * Pauses all active streams.
 *
 * Used by the kms code when moving a new scanout buffer to vram.
 *
 * Takes the overlay lock.
 */
int vmw_overlay_pause_all(struct vmw_private *dev_priv)
{
	struct vmw_overlay *overlay = dev_priv->overlay_priv;
	int i, ret;

	if (!overlay)
		return 0;

	mutex_lock(&overlay->mutex);

	for (i = 0; i < VMW_MAX_NUM_STREAMS; i++) {
		if (overlay->stream[i].paused)
			DRM_INFO("%s: *warning* stream %i already paused\n",
				 __func__, i);
		ret = vmw_overlay_stop(dev_priv, i, true, false);
		WARN_ON(ret != 0);
	}

	mutex_unlock(&overlay->mutex);

	return 0;
}


static bool vmw_overlay_available(const struct vmw_private *dev_priv)
{
	return (dev_priv->overlay_priv != NULL &&
		((vmw_fifo_caps(dev_priv) & VMW_OVERLAY_CAP_MASK) ==
		 VMW_OVERLAY_CAP_MASK));
}

int vmw_overlay_ioctl(struct drm_device *dev, void *data,
		      struct drm_file *file_priv)
{
	struct ttm_object_file *tfile = vmw_fpriv(file_priv)->tfile;
	struct vmw_private *dev_priv = vmw_priv(dev);
	struct vmw_overlay *overlay = dev_priv->overlay_priv;
	struct drm_vmw_control_stream_arg *arg =
	    (struct drm_vmw_control_stream_arg *)data;
	struct vmw_bo *buf;
	struct vmw_resource *res;
	int ret;

	if (!vmw_overlay_available(dev_priv))
		return -ENOSYS;

	ret = vmw_user_stream_lookup(dev_priv, tfile, &arg->stream_id, &res);
	if (ret)
		return ret;

	mutex_lock(&overlay->mutex);

	if (!arg->enabled) {
		ret = vmw_overlay_stop(dev_priv, arg->stream_id, false, true);
		goto out_unlock;
	}

	ret = vmw_user_bo_lookup(file_priv, arg->handle, &buf);
	if (ret)
		goto out_unlock;

	ret = vmw_overlay_update_stream(dev_priv, buf, arg, true);

	vmw_user_bo_unref(&buf);

out_unlock:
	mutex_unlock(&overlay->mutex);
	vmw_resource_unreference(&res);

	return ret;
}

int vmw_overlay_num_overlays(struct vmw_private *dev_priv)
{
	if (!vmw_overlay_available(dev_priv))
		return 0;

	return VMW_MAX_NUM_STREAMS;
}

int vmw_overlay_num_free_overlays(struct vmw_private *dev_priv)
{
	struct vmw_overlay *overlay = dev_priv->overlay_priv;
	int i, k;

	if (!vmw_overlay_available(dev_priv))
		return 0;

	mutex_lock(&overlay->mutex);

	for (i = 0, k = 0; i < VMW_MAX_NUM_STREAMS; i++)
		if (!overlay->stream[i].claimed)
			k++;

	mutex_unlock(&overlay->mutex);

	return k;
}

int vmw_overlay_claim(struct vmw_private *dev_priv, uint32_t *out)
{
	struct vmw_overlay *overlay = dev_priv->overlay_priv;
	int i;

	if (!overlay)
		return -ENOSYS;

	mutex_lock(&overlay->mutex);

	for (i = 0; i < VMW_MAX_NUM_STREAMS; i++) {

		if (overlay->stream[i].claimed)
			continue;

		overlay->stream[i].claimed = true;
		*out = i;
		mutex_unlock(&overlay->mutex);
		return 0;
	}

	mutex_unlock(&overlay->mutex);
	return -ESRCH;
}

int vmw_overlay_unref(struct vmw_private *dev_priv, uint32_t stream_id)
{
	struct vmw_overlay *overlay = dev_priv->overlay_priv;

	BUG_ON(stream_id >= VMW_MAX_NUM_STREAMS);

	if (!overlay)
		return -ENOSYS;

	mutex_lock(&overlay->mutex);

	WARN_ON(!overlay->stream[stream_id].claimed);
	vmw_overlay_stop(dev_priv, stream_id, false, false);
	overlay->stream[stream_id].claimed = false;

	mutex_unlock(&overlay->mutex);
	return 0;
}

int vmw_overlay_init(struct vmw_private *dev_priv)
{
	struct vmw_overlay *overlay;
	int i;

	if (dev_priv->overlay_priv)
		return -EINVAL;

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

	mutex_init(&overlay->mutex);
	for (i = 0; i < VMW_MAX_NUM_STREAMS; i++) {
		overlay->stream[i].buf = NULL;
		overlay->stream[i].paused = false;
		overlay->stream[i].claimed = false;
	}

	dev_priv->overlay_priv = overlay;

	return 0;
}

int vmw_overlay_close(struct vmw_private *dev_priv)
{
	struct vmw_overlay *overlay = dev_priv->overlay_priv;
	bool forgotten_buffer = false;
	int i;

	if (!overlay)
		return -ENOSYS;

	for (i = 0; i < VMW_MAX_NUM_STREAMS; i++) {
		if (overlay->stream[i].buf) {
			forgotten_buffer = true;
			vmw_overlay_stop(dev_priv, i, false, false);
		}
	}

	WARN_ON(forgotten_buffer);

	dev_priv->overlay_priv = NULL;
	kfree(overlay);

	return 0;
}
