// SPDX-License-Identifier: MIT
/*
 * Copyright © 2023 Intel Corporation
 */

#include "xe_gsc_proxy.h"

#include <linux/component.h>
#include <linux/delay.h>

#include <drm/drm_managed.h>
#include <drm/intel/i915_component.h>
#include <drm/intel/i915_gsc_proxy_mei_interface.h>

#include "abi/gsc_proxy_commands_abi.h"
#include "regs/xe_gsc_regs.h"
#include "xe_bo.h"
#include "xe_force_wake.h"
#include "xe_gsc.h"
#include "xe_gsc_submit.h"
#include "xe_gt.h"
#include "xe_gt_printk.h"
#include "xe_map.h"
#include "xe_mmio.h"
#include "xe_pm.h"
#include "xe_tile.h"

/*
 * GSC proxy:
 * The GSC uC needs to communicate with the CSME to perform certain operations.
 * Since the GSC can't perform this communication directly on platforms where it
 * is integrated in GT, the graphics driver needs to transfer the messages from
 * GSC to CSME and back. The proxy flow must be manually started after the GSC
 * is loaded to signal to GSC that we're ready to handle its messages and allow
 * it to query its init data from CSME; GSC will then trigger an HECI2 interrupt
 * if it needs to send messages to CSME again.
 * The proxy flow is as follow:
 * 1 - Xe submits a request to GSC asking for the message to CSME
 * 2 - GSC replies with the proxy header + payload for CSME
 * 3 - Xe sends the reply from GSC as-is to CSME via the mei proxy component
 * 4 - CSME replies with the proxy header + payload for GSC
 * 5 - Xe submits a request to GSC with the reply from CSME
 * 6 - GSC replies either with a new header + payload (same as step 2, so we
 *     restart from there) or with an end message.
 */

/*
 * The component should load quite quickly in most cases, but it could take
 * a bit. Using a very big timeout just to cover the worst case scenario
 */
#define GSC_PROXY_INIT_TIMEOUT_MS 20000

/* shorthand define for code compactness */
#define PROXY_HDR_SIZE (sizeof(struct xe_gsc_proxy_header))

/* the protocol supports up to 32K in each direction */
#define GSC_PROXY_BUFFER_SIZE SZ_32K
#define GSC_PROXY_CHANNEL_SIZE (GSC_PROXY_BUFFER_SIZE * 2)

static struct xe_gt *
gsc_to_gt(struct xe_gsc *gsc)
{
	return container_of(gsc, struct xe_gt, uc.gsc);
}

bool xe_gsc_proxy_init_done(struct xe_gsc *gsc)
{
	struct xe_gt *gt = gsc_to_gt(gsc);
	u32 fwsts1 = xe_mmio_read32(&gt->mmio, HECI_FWSTS1(MTL_GSC_HECI1_BASE));

	return REG_FIELD_GET(HECI1_FWSTS1_CURRENT_STATE, fwsts1) ==
	       HECI1_FWSTS1_PROXY_STATE_NORMAL;
}

int xe_gsc_wait_for_proxy_init_done(struct xe_gsc *gsc)
{
	struct xe_gt *gt = gsc_to_gt(gsc);

	/* Proxy init can take up to 500ms, so wait double that for safety */
	return xe_mmio_wait32(&gt->mmio, HECI_FWSTS1(MTL_GSC_HECI1_BASE),
			      HECI1_FWSTS1_CURRENT_STATE,
			      HECI1_FWSTS1_PROXY_STATE_NORMAL,
			      USEC_PER_SEC, NULL, false);
}

static void __gsc_proxy_irq_rmw(struct xe_gsc *gsc, u32 clr, u32 set)
{
	struct xe_gt *gt = gsc_to_gt(gsc);

	/* make sure we never accidentally write the RST bit */
	clr |= HECI_H_CSR_RST;

	xe_mmio_rmw32(&gt->mmio, HECI_H_CSR(MTL_GSC_HECI2_BASE), clr, set);
}

static void gsc_proxy_irq_clear(struct xe_gsc *gsc)
{
	/* The status bit is cleared by writing to it */
	__gsc_proxy_irq_rmw(gsc, 0, HECI_H_CSR_IS);
}

static void gsc_proxy_irq_toggle(struct xe_gsc *gsc, bool enabled)
{
	u32 set = enabled ? HECI_H_CSR_IE : 0;
	u32 clr = enabled ? 0 : HECI_H_CSR_IE;

	__gsc_proxy_irq_rmw(gsc, clr, set);
}

static int proxy_send_to_csme(struct xe_gsc *gsc, u32 size)
{
	struct xe_gt *gt = gsc_to_gt(gsc);
	struct i915_gsc_proxy_component *comp = gsc->proxy.component;
	int ret;

	ret = comp->ops->send(comp->mei_dev, gsc->proxy.to_csme, size);
	if (ret < 0) {
		xe_gt_err(gt, "Failed to send CSME proxy message\n");
		return ret;
	}

	ret = comp->ops->recv(comp->mei_dev, gsc->proxy.from_csme, GSC_PROXY_BUFFER_SIZE);
	if (ret < 0) {
		xe_gt_err(gt, "Failed to receive CSME proxy message\n");
		return ret;
	}

	return ret;
}

static int proxy_send_to_gsc(struct xe_gsc *gsc, u32 size)
{
	struct xe_gt *gt = gsc_to_gt(gsc);
	u64 addr_in = xe_bo_ggtt_addr(gsc->proxy.bo);
	u64 addr_out = addr_in + GSC_PROXY_BUFFER_SIZE;
	int err;

	/* the message must contain at least the gsc and proxy headers */
	if (size > GSC_PROXY_BUFFER_SIZE) {
		xe_gt_err(gt, "Invalid GSC proxy message size: %u\n", size);
		return -EINVAL;
	}

	err = xe_gsc_pkt_submit_kernel(gsc, addr_in, size,
				       addr_out, GSC_PROXY_BUFFER_SIZE);
	if (err) {
		xe_gt_err(gt, "Failed to submit gsc proxy rq (%pe)\n", ERR_PTR(err));
		return err;
	}

	return 0;
}

static int validate_proxy_header(struct xe_gt *gt,
				 struct xe_gsc_proxy_header *header,
				 u32 source, u32 dest, u32 max_size)
{
	u32 type = FIELD_GET(GSC_PROXY_TYPE, header->hdr);
	u32 length = FIELD_GET(GSC_PROXY_PAYLOAD_LENGTH, header->hdr);
	int ret = 0;

	if (header->destination != dest || header->source != source) {
		ret = -ENOEXEC;
		goto out;
	}

	if (length + PROXY_HDR_SIZE > max_size) {
		ret = -E2BIG;
		goto out;
	}

	/* We only care about the status if this is a message for the driver */
	if (dest == GSC_PROXY_ADDRESSING_KMD && header->status != 0) {
		ret = -EIO;
		goto out;
	}

	switch (type) {
	case GSC_PROXY_MSG_TYPE_PROXY_PAYLOAD:
		if (length > 0)
			break;
		fallthrough;
	case GSC_PROXY_MSG_TYPE_PROXY_INVALID:
		ret = -EIO;
		break;
	default:
		break;
	}

out:
	if (ret)
		xe_gt_err(gt,
			  "GSC proxy error: s=0x%x[0x%x], d=0x%x[0x%x], t=%u, l=0x%x, st=0x%x\n",
			  header->source, source, header->destination, dest,
			  type, length, header->status);

	return ret;
}

#define proxy_header_wr(xe_, map_, offset_, field_, val_) \
	xe_map_wr_field(xe_, map_, offset_, struct xe_gsc_proxy_header, field_, val_)

#define proxy_header_rd(xe_, map_, offset_, field_) \
	xe_map_rd_field(xe_, map_, offset_, struct xe_gsc_proxy_header, field_)

static u32 emit_proxy_header(struct xe_device *xe, struct iosys_map *map, u32 offset)
{
	xe_map_memset(xe, map, offset, 0, PROXY_HDR_SIZE);

	proxy_header_wr(xe, map, offset, hdr,
			FIELD_PREP(GSC_PROXY_TYPE, GSC_PROXY_MSG_TYPE_PROXY_QUERY) |
			FIELD_PREP(GSC_PROXY_PAYLOAD_LENGTH, 0));

	proxy_header_wr(xe, map, offset, source, GSC_PROXY_ADDRESSING_KMD);
	proxy_header_wr(xe, map, offset, destination, GSC_PROXY_ADDRESSING_GSC);
	proxy_header_wr(xe, map, offset, status, 0);

	return offset + PROXY_HDR_SIZE;
}

static int proxy_query(struct xe_gsc *gsc)
{
	struct xe_gt *gt = gsc_to_gt(gsc);
	struct xe_device *xe = gt_to_xe(gt);
	struct xe_gsc_proxy_header *to_csme_hdr = gsc->proxy.to_csme;
	void *to_csme_payload = gsc->proxy.to_csme + PROXY_HDR_SIZE;
	u32 wr_offset;
	u32 reply_offset;
	u32 size;
	int ret;

	wr_offset = xe_gsc_emit_header(xe, &gsc->proxy.to_gsc, 0,
				       HECI_MEADDRESS_PROXY, 0, PROXY_HDR_SIZE);
	wr_offset = emit_proxy_header(xe, &gsc->proxy.to_gsc, wr_offset);

	size = wr_offset;

	while (1) {
		/*
		 * Poison the GSC response header space to make sure we don't
		 * read a stale reply.
		 */
		xe_gsc_poison_header(xe, &gsc->proxy.from_gsc, 0);

		/* send proxy message to GSC */
		ret = proxy_send_to_gsc(gsc, size);
		if (ret)
			goto proxy_error;

		/* check the reply from GSC */
		ret = xe_gsc_read_out_header(xe, &gsc->proxy.from_gsc, 0,
					     PROXY_HDR_SIZE, &reply_offset);
		if (ret) {
			xe_gt_err(gt, "Invalid gsc header in proxy reply (%pe)\n",
				  ERR_PTR(ret));
			goto proxy_error;
		}

		/* copy the proxy header reply from GSC */
		xe_map_memcpy_from(xe, to_csme_hdr, &gsc->proxy.from_gsc,
				   reply_offset, PROXY_HDR_SIZE);

		/* Check the status and stop if this was the last message */
		if (FIELD_GET(GSC_PROXY_TYPE, to_csme_hdr->hdr) == GSC_PROXY_MSG_TYPE_PROXY_END) {
			ret = validate_proxy_header(gt, to_csme_hdr,
						    GSC_PROXY_ADDRESSING_GSC,
						    GSC_PROXY_ADDRESSING_KMD,
						    GSC_PROXY_BUFFER_SIZE - reply_offset);
			break;
		}

		/* make sure the GSC-to-CSME proxy header is sane */
		ret = validate_proxy_header(gt, to_csme_hdr,
					    GSC_PROXY_ADDRESSING_GSC,
					    GSC_PROXY_ADDRESSING_CSME,
					    GSC_PROXY_BUFFER_SIZE - reply_offset);
		if (ret) {
			xe_gt_err(gt, "invalid GSC to CSME proxy header! (%pe)\n",
				  ERR_PTR(ret));
			goto proxy_error;
		}

		/* copy the rest of the message */
		size = FIELD_GET(GSC_PROXY_PAYLOAD_LENGTH, to_csme_hdr->hdr);
		xe_map_memcpy_from(xe, to_csme_payload, &gsc->proxy.from_gsc,
				   reply_offset + PROXY_HDR_SIZE, size);

		/* send the GSC message to the CSME */
		ret = proxy_send_to_csme(gsc, size + PROXY_HDR_SIZE);
		if (ret < 0)
			goto proxy_error;

		/* reply size from CSME, including the proxy header */
		size = ret;
		if (size < PROXY_HDR_SIZE) {
			xe_gt_err(gt, "CSME to GSC proxy msg too small: 0x%x\n", size);
			ret = -EPROTO;
			goto proxy_error;
		}

		/* make sure the CSME-to-GSC proxy header is sane */
		ret = validate_proxy_header(gt, gsc->proxy.from_csme,
					    GSC_PROXY_ADDRESSING_CSME,
					    GSC_PROXY_ADDRESSING_GSC,
					    GSC_PROXY_BUFFER_SIZE - reply_offset);
		if (ret) {
			xe_gt_err(gt, "invalid CSME to GSC proxy header! %d\n", ret);
			goto proxy_error;
		}

		/* Emit a new header for sending the reply to the GSC */
		wr_offset = xe_gsc_emit_header(xe, &gsc->proxy.to_gsc, 0,
					       HECI_MEADDRESS_PROXY, 0, size);

		/* copy the CSME reply and update the total msg size to include the GSC header */
		xe_map_memcpy_to(xe, &gsc->proxy.to_gsc, wr_offset, gsc->proxy.from_csme, size);

		size += wr_offset;
	}

proxy_error:
	return ret < 0 ? ret : 0;
}

int xe_gsc_proxy_request_handler(struct xe_gsc *gsc)
{
	struct xe_gt *gt = gsc_to_gt(gsc);
	int slept;
	int err;

	if (!gsc->proxy.component_added)
		return -ENODEV;

	/* when GSC is loaded, we can queue this before the component is bound */
	for (slept = 0; slept < GSC_PROXY_INIT_TIMEOUT_MS; slept += 100) {
		if (gsc->proxy.component)
			break;

		msleep(100);
	}

	mutex_lock(&gsc->proxy.mutex);
	if (!gsc->proxy.component) {
		xe_gt_err(gt, "GSC proxy component not bound!\n");
		err = -EIO;
	} else {
		/*
		 * clear the pending interrupt and allow new proxy requests to
		 * be generated while we handle the current one
		 */
		gsc_proxy_irq_clear(gsc);
		err = proxy_query(gsc);
	}
	mutex_unlock(&gsc->proxy.mutex);
	return err;
}

void xe_gsc_proxy_irq_handler(struct xe_gsc *gsc, u32 iir)
{
	struct xe_gt *gt = gsc_to_gt(gsc);

	if (unlikely(!iir))
		return;

	if (!gsc->proxy.component) {
		xe_gt_err(gt, "GSC proxy irq received without the component being bound!\n");
		return;
	}

	spin_lock(&gsc->lock);
	gsc->work_actions |= GSC_ACTION_SW_PROXY;
	spin_unlock(&gsc->lock);

	queue_work(gsc->wq, &gsc->work);
}

static int xe_gsc_proxy_component_bind(struct device *xe_kdev,
				       struct device *mei_kdev, void *data)
{
	struct xe_device *xe = kdev_to_xe_device(xe_kdev);
	struct xe_gt *gt = xe->tiles[0].media_gt;
	struct xe_gsc *gsc = &gt->uc.gsc;

	mutex_lock(&gsc->proxy.mutex);
	gsc->proxy.component = data;
	gsc->proxy.component->mei_dev = mei_kdev;
	mutex_unlock(&gsc->proxy.mutex);

	return 0;
}

static void xe_gsc_proxy_component_unbind(struct device *xe_kdev,
					  struct device *mei_kdev, void *data)
{
	struct xe_device *xe = kdev_to_xe_device(xe_kdev);
	struct xe_gt *gt = xe->tiles[0].media_gt;
	struct xe_gsc *gsc = &gt->uc.gsc;

	xe_gsc_wait_for_worker_completion(gsc);

	mutex_lock(&gsc->proxy.mutex);
	gsc->proxy.component = NULL;
	mutex_unlock(&gsc->proxy.mutex);
}

static const struct component_ops xe_gsc_proxy_component_ops = {
	.bind   = xe_gsc_proxy_component_bind,
	.unbind = xe_gsc_proxy_component_unbind,
};

static int proxy_channel_alloc(struct xe_gsc *gsc)
{
	struct xe_gt *gt = gsc_to_gt(gsc);
	struct xe_tile *tile = gt_to_tile(gt);
	struct xe_device *xe = gt_to_xe(gt);
	struct xe_bo *bo;
	void *csme;

	csme = drmm_kzalloc(&xe->drm, GSC_PROXY_CHANNEL_SIZE, GFP_KERNEL);
	if (!csme)
		return -ENOMEM;

	bo = xe_managed_bo_create_pin_map(xe, tile, GSC_PROXY_CHANNEL_SIZE,
					  XE_BO_FLAG_SYSTEM |
					  XE_BO_FLAG_GGTT);
	if (IS_ERR(bo))
		return PTR_ERR(bo);

	gsc->proxy.bo = bo;
	gsc->proxy.to_gsc = IOSYS_MAP_INIT_OFFSET(&bo->vmap, 0);
	gsc->proxy.from_gsc = IOSYS_MAP_INIT_OFFSET(&bo->vmap, GSC_PROXY_BUFFER_SIZE);
	gsc->proxy.to_csme = csme;
	gsc->proxy.from_csme = csme + GSC_PROXY_BUFFER_SIZE;

	return 0;
}

static void xe_gsc_proxy_remove(void *arg)
{
	struct xe_gsc *gsc = arg;
	struct xe_gt *gt = gsc_to_gt(gsc);
	struct xe_device *xe = gt_to_xe(gt);
	unsigned int fw_ref = 0;

	if (!gsc->proxy.component_added)
		return;

	/* disable HECI2 IRQs */
	xe_pm_runtime_get(xe);
	fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FW_GSC);
	if (!fw_ref)
		xe_gt_err(gt, "failed to get forcewake to disable GSC interrupts\n");

	/* try do disable irq even if forcewake failed */
	gsc_proxy_irq_toggle(gsc, false);

	xe_force_wake_put(gt_to_fw(gt), fw_ref);
	xe_pm_runtime_put(xe);

	xe_gsc_wait_for_worker_completion(gsc);

	component_del(xe->drm.dev, &xe_gsc_proxy_component_ops);
	gsc->proxy.component_added = false;
}

/**
 * xe_gsc_proxy_init() - init objects and MEI component required by GSC proxy
 * @gsc: the GSC uC
 *
 * Return: 0 if the initialization was successful, a negative errno otherwise.
 */
int xe_gsc_proxy_init(struct xe_gsc *gsc)
{
	int err;
	struct xe_gt *gt = gsc_to_gt(gsc);
	struct xe_tile *tile = gt_to_tile(gt);
	struct xe_device *xe = tile_to_xe(tile);

	mutex_init(&gsc->proxy.mutex);

	if (!IS_ENABLED(CONFIG_INTEL_MEI_GSC_PROXY)) {
		xe_gt_info(gt, "can't init GSC proxy due to missing mei component\n");
		return -ENODEV;
	}

	/* no multi-tile devices with this feature yet */
	if (!xe_tile_is_root(tile)) {
		xe_gt_err(gt, "unexpected GSC proxy init on tile %u\n", tile->id);
		return -EINVAL;
	}

	err = proxy_channel_alloc(gsc);
	if (err)
		return err;

	err = component_add_typed(xe->drm.dev, &xe_gsc_proxy_component_ops,
				  I915_COMPONENT_GSC_PROXY);
	if (err < 0) {
		xe_gt_err(gt, "Failed to add GSC_PROXY component (%pe)\n", ERR_PTR(err));
		return err;
	}

	gsc->proxy.component_added = true;

	return devm_add_action_or_reset(xe->drm.dev, xe_gsc_proxy_remove, gsc);
}

/**
 * xe_gsc_proxy_start() - start the proxy by submitting the first request
 * @gsc: the GSC uC
 *
 * Return: 0 if the proxy are now enabled, a negative errno otherwise.
 */
int xe_gsc_proxy_start(struct xe_gsc *gsc)
{
	int err;

	/* enable the proxy interrupt in the GSC shim layer */
	gsc_proxy_irq_toggle(gsc, true);

	/*
	 * The handling of the first proxy request must be manually triggered to
	 * notify the GSC that we're ready to support the proxy flow.
	 */
	err = xe_gsc_proxy_request_handler(gsc);
	if (err)
		return err;

	if (!xe_gsc_proxy_init_done(gsc)) {
		xe_gt_err(gsc_to_gt(gsc), "GSC FW reports proxy init not completed\n");
		return -EIO;
	}

	return 0;
}
