// SPDX-License-Identifier: GPL-2.0 OR MIT

/*
 *  Xen para-virtual DRM device
 *
 * Copyright (C) 2016-2018 EPAM Systems Inc.
 *
 * Author: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
 */

#include <drm/drmP.h>

#include <linux/errno.h>
#include <linux/irq.h>

#include <xen/xenbus.h>
#include <xen/events.h>
#include <xen/grant_table.h>

#include "xen_drm_front.h"
#include "xen_drm_front_evtchnl.h"

static irqreturn_t evtchnl_interrupt_ctrl(int irq, void *dev_id)
{
	struct xen_drm_front_evtchnl *evtchnl = dev_id;
	struct xen_drm_front_info *front_info = evtchnl->front_info;
	struct xendispl_resp *resp;
	RING_IDX i, rp;
	unsigned long flags;

	if (unlikely(evtchnl->state != EVTCHNL_STATE_CONNECTED))
		return IRQ_HANDLED;

	spin_lock_irqsave(&front_info->io_lock, flags);

again:
	rp = evtchnl->u.req.ring.sring->rsp_prod;
	/* ensure we see queued responses up to rp */
	virt_rmb();

	for (i = evtchnl->u.req.ring.rsp_cons; i != rp; i++) {
		resp = RING_GET_RESPONSE(&evtchnl->u.req.ring, i);
		if (unlikely(resp->id != evtchnl->evt_id))
			continue;

		switch (resp->operation) {
		case XENDISPL_OP_PG_FLIP:
		case XENDISPL_OP_FB_ATTACH:
		case XENDISPL_OP_FB_DETACH:
		case XENDISPL_OP_DBUF_CREATE:
		case XENDISPL_OP_DBUF_DESTROY:
		case XENDISPL_OP_SET_CONFIG:
			evtchnl->u.req.resp_status = resp->status;
			complete(&evtchnl->u.req.completion);
			break;

		default:
			DRM_ERROR("Operation %d is not supported\n",
				  resp->operation);
			break;
		}
	}

	evtchnl->u.req.ring.rsp_cons = i;

	if (i != evtchnl->u.req.ring.req_prod_pvt) {
		int more_to_do;

		RING_FINAL_CHECK_FOR_RESPONSES(&evtchnl->u.req.ring,
					       more_to_do);
		if (more_to_do)
			goto again;
	} else {
		evtchnl->u.req.ring.sring->rsp_event = i + 1;
	}

	spin_unlock_irqrestore(&front_info->io_lock, flags);
	return IRQ_HANDLED;
}

static irqreturn_t evtchnl_interrupt_evt(int irq, void *dev_id)
{
	struct xen_drm_front_evtchnl *evtchnl = dev_id;
	struct xen_drm_front_info *front_info = evtchnl->front_info;
	struct xendispl_event_page *page = evtchnl->u.evt.page;
	u32 cons, prod;
	unsigned long flags;

	if (unlikely(evtchnl->state != EVTCHNL_STATE_CONNECTED))
		return IRQ_HANDLED;

	spin_lock_irqsave(&front_info->io_lock, flags);

	prod = page->in_prod;
	/* ensure we see ring contents up to prod */
	virt_rmb();
	if (prod == page->in_cons)
		goto out;

	for (cons = page->in_cons; cons != prod; cons++) {
		struct xendispl_evt *event;

		event = &XENDISPL_IN_RING_REF(page, cons);
		if (unlikely(event->id != evtchnl->evt_id++))
			continue;

		switch (event->type) {
		case XENDISPL_EVT_PG_FLIP:
			xen_drm_front_on_frame_done(front_info, evtchnl->index,
						    event->op.pg_flip.fb_cookie);
			break;
		}
	}
	page->in_cons = cons;
	/* ensure ring contents */
	virt_wmb();

out:
	spin_unlock_irqrestore(&front_info->io_lock, flags);
	return IRQ_HANDLED;
}

static void evtchnl_free(struct xen_drm_front_info *front_info,
			 struct xen_drm_front_evtchnl *evtchnl)
{
	unsigned long page = 0;

	if (evtchnl->type == EVTCHNL_TYPE_REQ)
		page = (unsigned long)evtchnl->u.req.ring.sring;
	else if (evtchnl->type == EVTCHNL_TYPE_EVT)
		page = (unsigned long)evtchnl->u.evt.page;
	if (!page)
		return;

	evtchnl->state = EVTCHNL_STATE_DISCONNECTED;

	if (evtchnl->type == EVTCHNL_TYPE_REQ) {
		/* release all who still waits for response if any */
		evtchnl->u.req.resp_status = -EIO;
		complete_all(&evtchnl->u.req.completion);
	}

	if (evtchnl->irq)
		unbind_from_irqhandler(evtchnl->irq, evtchnl);

	if (evtchnl->port)
		xenbus_free_evtchn(front_info->xb_dev, evtchnl->port);

	/* end access and free the page */
	if (evtchnl->gref != GRANT_INVALID_REF)
		gnttab_end_foreign_access(evtchnl->gref, 0, page);

	memset(evtchnl, 0, sizeof(*evtchnl));
}

static int evtchnl_alloc(struct xen_drm_front_info *front_info, int index,
			 struct xen_drm_front_evtchnl *evtchnl,
			 enum xen_drm_front_evtchnl_type type)
{
	struct xenbus_device *xb_dev = front_info->xb_dev;
	unsigned long page;
	grant_ref_t gref;
	irq_handler_t handler;
	int ret;

	memset(evtchnl, 0, sizeof(*evtchnl));
	evtchnl->type = type;
	evtchnl->index = index;
	evtchnl->front_info = front_info;
	evtchnl->state = EVTCHNL_STATE_DISCONNECTED;
	evtchnl->gref = GRANT_INVALID_REF;

	page = get_zeroed_page(GFP_NOIO | __GFP_HIGH);
	if (!page) {
		ret = -ENOMEM;
		goto fail;
	}

	if (type == EVTCHNL_TYPE_REQ) {
		struct xen_displif_sring *sring;

		init_completion(&evtchnl->u.req.completion);
		mutex_init(&evtchnl->u.req.req_io_lock);
		sring = (struct xen_displif_sring *)page;
		SHARED_RING_INIT(sring);
		FRONT_RING_INIT(&evtchnl->u.req.ring, sring, XEN_PAGE_SIZE);

		ret = xenbus_grant_ring(xb_dev, sring, 1, &gref);
		if (ret < 0) {
			evtchnl->u.req.ring.sring = NULL;
			free_page(page);
			goto fail;
		}

		handler = evtchnl_interrupt_ctrl;
	} else {
		ret = gnttab_grant_foreign_access(xb_dev->otherend_id,
						  virt_to_gfn((void *)page), 0);
		if (ret < 0) {
			free_page(page);
			goto fail;
		}

		evtchnl->u.evt.page = (struct xendispl_event_page *)page;
		gref = ret;
		handler = evtchnl_interrupt_evt;
	}
	evtchnl->gref = gref;

	ret = xenbus_alloc_evtchn(xb_dev, &evtchnl->port);
	if (ret < 0)
		goto fail;

	ret = bind_evtchn_to_irqhandler(evtchnl->port,
					handler, 0, xb_dev->devicetype,
					evtchnl);
	if (ret < 0)
		goto fail;

	evtchnl->irq = ret;
	return 0;

fail:
	DRM_ERROR("Failed to allocate ring: %d\n", ret);
	return ret;
}

int xen_drm_front_evtchnl_create_all(struct xen_drm_front_info *front_info)
{
	struct xen_drm_front_cfg *cfg;
	int ret, conn;

	cfg = &front_info->cfg;

	front_info->evt_pairs =
			kcalloc(cfg->num_connectors,
				sizeof(struct xen_drm_front_evtchnl_pair),
				GFP_KERNEL);
	if (!front_info->evt_pairs) {
		ret = -ENOMEM;
		goto fail;
	}

	for (conn = 0; conn < cfg->num_connectors; conn++) {
		ret = evtchnl_alloc(front_info, conn,
				    &front_info->evt_pairs[conn].req,
				    EVTCHNL_TYPE_REQ);
		if (ret < 0) {
			DRM_ERROR("Error allocating control channel\n");
			goto fail;
		}

		ret = evtchnl_alloc(front_info, conn,
				    &front_info->evt_pairs[conn].evt,
				    EVTCHNL_TYPE_EVT);
		if (ret < 0) {
			DRM_ERROR("Error allocating in-event channel\n");
			goto fail;
		}
	}
	front_info->num_evt_pairs = cfg->num_connectors;
	return 0;

fail:
	xen_drm_front_evtchnl_free_all(front_info);
	return ret;
}

static int evtchnl_publish(struct xenbus_transaction xbt,
			   struct xen_drm_front_evtchnl *evtchnl,
			   const char *path, const char *node_ring,
			   const char *node_chnl)
{
	struct xenbus_device *xb_dev = evtchnl->front_info->xb_dev;
	int ret;

	/* write control channel ring reference */
	ret = xenbus_printf(xbt, path, node_ring, "%u", evtchnl->gref);
	if (ret < 0) {
		xenbus_dev_error(xb_dev, ret, "writing ring-ref");
		return ret;
	}

	/* write event channel ring reference */
	ret = xenbus_printf(xbt, path, node_chnl, "%u", evtchnl->port);
	if (ret < 0) {
		xenbus_dev_error(xb_dev, ret, "writing event channel");
		return ret;
	}

	return 0;
}

int xen_drm_front_evtchnl_publish_all(struct xen_drm_front_info *front_info)
{
	struct xenbus_transaction xbt;
	struct xen_drm_front_cfg *plat_data;
	int ret, conn;

	plat_data = &front_info->cfg;

again:
	ret = xenbus_transaction_start(&xbt);
	if (ret < 0) {
		xenbus_dev_fatal(front_info->xb_dev, ret,
				 "starting transaction");
		return ret;
	}

	for (conn = 0; conn < plat_data->num_connectors; conn++) {
		ret = evtchnl_publish(xbt, &front_info->evt_pairs[conn].req,
				      plat_data->connectors[conn].xenstore_path,
				      XENDISPL_FIELD_REQ_RING_REF,
				      XENDISPL_FIELD_REQ_CHANNEL);
		if (ret < 0)
			goto fail;

		ret = evtchnl_publish(xbt, &front_info->evt_pairs[conn].evt,
				      plat_data->connectors[conn].xenstore_path,
				      XENDISPL_FIELD_EVT_RING_REF,
				      XENDISPL_FIELD_EVT_CHANNEL);
		if (ret < 0)
			goto fail;
	}

	ret = xenbus_transaction_end(xbt, 0);
	if (ret < 0) {
		if (ret == -EAGAIN)
			goto again;

		xenbus_dev_fatal(front_info->xb_dev, ret,
				 "completing transaction");
		goto fail_to_end;
	}

	return 0;

fail:
	xenbus_transaction_end(xbt, 1);

fail_to_end:
	xenbus_dev_fatal(front_info->xb_dev, ret, "writing Xen store");
	return ret;
}

void xen_drm_front_evtchnl_flush(struct xen_drm_front_evtchnl *evtchnl)
{
	int notify;

	evtchnl->u.req.ring.req_prod_pvt++;
	RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&evtchnl->u.req.ring, notify);
	if (notify)
		notify_remote_via_irq(evtchnl->irq);
}

void xen_drm_front_evtchnl_set_state(struct xen_drm_front_info *front_info,
				     enum xen_drm_front_evtchnl_state state)
{
	unsigned long flags;
	int i;

	if (!front_info->evt_pairs)
		return;

	spin_lock_irqsave(&front_info->io_lock, flags);
	for (i = 0; i < front_info->num_evt_pairs; i++) {
		front_info->evt_pairs[i].req.state = state;
		front_info->evt_pairs[i].evt.state = state;
	}
	spin_unlock_irqrestore(&front_info->io_lock, flags);
}

void xen_drm_front_evtchnl_free_all(struct xen_drm_front_info *front_info)
{
	int i;

	if (!front_info->evt_pairs)
		return;

	for (i = 0; i < front_info->num_evt_pairs; i++) {
		evtchnl_free(front_info, &front_info->evt_pairs[i].req);
		evtchnl_free(front_info, &front_info->evt_pairs[i].evt);
	}

	kfree(front_info->evt_pairs);
	front_info->evt_pairs = NULL;
}
