// SPDX-License-Identifier: MIT
/*
 * Copyright(c) 2019-2022, Intel Corporation. All rights reserved.
 */

#include <linux/irq.h>
#include <linux/mei_aux.h>
#include "i915_drv.h"
#include "i915_reg.h"
#include "gem/i915_gem_lmem.h"
#include "gem/i915_gem_region.h"
#include "gt/intel_gsc.h"
#include "gt/intel_gt.h"
#include "gt/intel_gt_print.h"

#define GSC_BAR_LENGTH  0x00000FFC

static void gsc_irq_mask(struct irq_data *d)
{
	/* generic irq handling */
}

static void gsc_irq_unmask(struct irq_data *d)
{
	/* generic irq handling */
}

static struct irq_chip gsc_irq_chip = {
	.name = "gsc_irq_chip",
	.irq_mask = gsc_irq_mask,
	.irq_unmask = gsc_irq_unmask,
};

static int gsc_irq_init(int irq)
{
	irq_set_chip_and_handler_name(irq, &gsc_irq_chip,
				      handle_simple_irq, "gsc_irq_handler");

	return irq_set_chip_data(irq, NULL);
}

static int
gsc_ext_om_alloc(struct intel_gsc *gsc, struct intel_gsc_intf *intf, size_t size)
{
	struct intel_gt *gt = gsc_to_gt(gsc);
	struct drm_i915_gem_object *obj;
	int err;

	obj = i915_gem_object_create_lmem(gt->i915, size,
					  I915_BO_ALLOC_CONTIGUOUS |
					  I915_BO_ALLOC_CPU_CLEAR);
	if (IS_ERR(obj)) {
		gt_err(gt, "Failed to allocate gsc memory\n");
		return PTR_ERR(obj);
	}

	err = i915_gem_object_pin_pages_unlocked(obj);
	if (err) {
		gt_err(gt, "Failed to pin pages for gsc memory\n");
		goto out_put;
	}

	intf->gem_obj = obj;

	return 0;

out_put:
	i915_gem_object_put(obj);
	return err;
}

static void gsc_ext_om_destroy(struct intel_gsc_intf *intf)
{
	struct drm_i915_gem_object *obj = fetch_and_zero(&intf->gem_obj);

	if (!obj)
		return;

	if (i915_gem_object_has_pinned_pages(obj))
		i915_gem_object_unpin_pages(obj);

	i915_gem_object_put(obj);
}

struct gsc_def {
	const char *name;
	unsigned long bar;
	size_t bar_size;
	bool use_polling;
	bool slow_firmware;
	size_t lmem_size;
};

/* gsc resources and definitions (HECI1 and HECI2) */
static const struct gsc_def gsc_def_dg1[] = {
	{
		/* HECI1 not yet implemented. */
	},
	{
		.name = "mei-gscfi",
		.bar = DG1_GSC_HECI2_BASE,
		.bar_size = GSC_BAR_LENGTH,
	}
};

static const struct gsc_def gsc_def_xehpsdv[] = {
	{
		/* HECI1 not enabled on the device. */
	},
	{
		.name = "mei-gscfi",
		.bar = DG1_GSC_HECI2_BASE,
		.bar_size = GSC_BAR_LENGTH,
		.use_polling = true,
		.slow_firmware = true,
	}
};

static const struct gsc_def gsc_def_dg2[] = {
	{
		.name = "mei-gsc",
		.bar = DG2_GSC_HECI1_BASE,
		.bar_size = GSC_BAR_LENGTH,
		.lmem_size = SZ_4M,
	},
	{
		.name = "mei-gscfi",
		.bar = DG2_GSC_HECI2_BASE,
		.bar_size = GSC_BAR_LENGTH,
	}
};

static void gsc_release_dev(struct device *dev)
{
	struct auxiliary_device *aux_dev = to_auxiliary_dev(dev);
	struct mei_aux_device *adev = auxiliary_dev_to_mei_aux_dev(aux_dev);

	kfree(adev);
}

static void gsc_destroy_one(struct drm_i915_private *i915,
			    struct intel_gsc *gsc, unsigned int intf_id)
{
	struct intel_gsc_intf *intf = &gsc->intf[intf_id];

	if (intf->adev) {
		struct auxiliary_device *aux_dev = &intf->adev->aux_dev;

		if (intf_id == 0)
			intel_huc_unregister_gsc_notifier(&gsc_to_gt(gsc)->uc.huc,
							  aux_dev->dev.bus);

		auxiliary_device_delete(aux_dev);
		auxiliary_device_uninit(aux_dev);
		intf->adev = NULL;
	}

	if (intf->irq >= 0)
		irq_free_desc(intf->irq);
	intf->irq = -1;

	gsc_ext_om_destroy(intf);
}

static void gsc_init_one(struct drm_i915_private *i915, struct intel_gsc *gsc,
			 unsigned int intf_id)
{
	struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
	struct mei_aux_device *adev;
	struct auxiliary_device *aux_dev;
	const struct gsc_def *def;
	struct intel_gsc_intf *intf = &gsc->intf[intf_id];
	int ret;

	intf->irq = -1;
	intf->id = intf_id;

	/*
	 * On the multi-tile setups the GSC is functional on the first tile only
	 */
	if (gsc_to_gt(gsc)->info.id != 0) {
		drm_dbg(&i915->drm, "Not initializing gsc for remote tiles\n");
		return;
	}

	if (intf_id == 0 && !HAS_HECI_PXP(i915))
		return;

	if (IS_DG1(i915)) {
		def = &gsc_def_dg1[intf_id];
	} else if (IS_XEHPSDV(i915)) {
		def = &gsc_def_xehpsdv[intf_id];
	} else if (IS_DG2(i915)) {
		def = &gsc_def_dg2[intf_id];
	} else {
		drm_warn_once(&i915->drm, "Unknown platform\n");
		return;
	}

	if (!def->name) {
		drm_warn_once(&i915->drm, "HECI%d is not implemented!\n", intf_id + 1);
		return;
	}

	/* skip irq initialization */
	if (def->use_polling)
		goto add_device;

	intf->irq = irq_alloc_desc(0);
	if (intf->irq < 0) {
		drm_err(&i915->drm, "gsc irq error %d\n", intf->irq);
		goto fail;
	}

	ret = gsc_irq_init(intf->irq);
	if (ret < 0) {
		drm_err(&i915->drm, "gsc irq init failed %d\n", ret);
		goto fail;
	}

add_device:
	adev = kzalloc(sizeof(*adev), GFP_KERNEL);
	if (!adev)
		goto fail;

	if (def->lmem_size) {
		drm_dbg(&i915->drm, "setting up GSC lmem\n");

		if (gsc_ext_om_alloc(gsc, intf, def->lmem_size)) {
			drm_err(&i915->drm, "setting up gsc extended operational memory failed\n");
			kfree(adev);
			goto fail;
		}

		adev->ext_op_mem.start = i915_gem_object_get_dma_address(intf->gem_obj, 0);
		adev->ext_op_mem.end = adev->ext_op_mem.start + def->lmem_size;
	}

	adev->irq = intf->irq;
	adev->bar.parent = &pdev->resource[0];
	adev->bar.start = def->bar + pdev->resource[0].start;
	adev->bar.end = adev->bar.start + def->bar_size - 1;
	adev->bar.flags = IORESOURCE_MEM;
	adev->bar.desc = IORES_DESC_NONE;
	adev->slow_firmware = def->slow_firmware;

	aux_dev = &adev->aux_dev;
	aux_dev->name = def->name;
	aux_dev->id = (pci_domain_nr(pdev->bus) << 16) |
		      PCI_DEVID(pdev->bus->number, pdev->devfn);
	aux_dev->dev.parent = &pdev->dev;
	aux_dev->dev.release = gsc_release_dev;

	ret = auxiliary_device_init(aux_dev);
	if (ret < 0) {
		drm_err(&i915->drm, "gsc aux init failed %d\n", ret);
		kfree(adev);
		goto fail;
	}

	intf->adev = adev; /* needed by the notifier */

	if (intf_id == 0)
		intel_huc_register_gsc_notifier(&gsc_to_gt(gsc)->uc.huc,
						aux_dev->dev.bus);

	ret = auxiliary_device_add(aux_dev);
	if (ret < 0) {
		drm_err(&i915->drm, "gsc aux add failed %d\n", ret);
		if (intf_id == 0)
			intel_huc_unregister_gsc_notifier(&gsc_to_gt(gsc)->uc.huc,
							  aux_dev->dev.bus);
		intf->adev = NULL;

		/* adev will be freed with the put_device() and .release sequence */
		auxiliary_device_uninit(aux_dev);
		goto fail;
	}

	return;
fail:
	gsc_destroy_one(i915, gsc, intf->id);
}

static void gsc_irq_handler(struct intel_gt *gt, unsigned int intf_id)
{
	int ret;

	if (intf_id >= INTEL_GSC_NUM_INTERFACES) {
		gt_warn_once(gt, "GSC irq: intf_id %d is out of range", intf_id);
		return;
	}

	if (!HAS_HECI_GSC(gt->i915)) {
		gt_warn_once(gt, "GSC irq: not supported");
		return;
	}

	if (gt->gsc.intf[intf_id].irq < 0)
		return;

	ret = generic_handle_irq(gt->gsc.intf[intf_id].irq);
	if (ret)
		gt_err_ratelimited(gt, "error handling GSC irq: %d\n", ret);
}

void intel_gsc_irq_handler(struct intel_gt *gt, u32 iir)
{
	if (iir & GSC_IRQ_INTF(0))
		gsc_irq_handler(gt, 0);
	if (iir & GSC_IRQ_INTF(1))
		gsc_irq_handler(gt, 1);
}

void intel_gsc_init(struct intel_gsc *gsc, struct drm_i915_private *i915)
{
	unsigned int i;

	if (!HAS_HECI_GSC(i915))
		return;

	for (i = 0; i < INTEL_GSC_NUM_INTERFACES; i++)
		gsc_init_one(i915, gsc, i);
}

void intel_gsc_fini(struct intel_gsc *gsc)
{
	struct intel_gt *gt = gsc_to_gt(gsc);
	unsigned int i;

	if (!HAS_HECI_GSC(gt->i915))
		return;

	for (i = 0; i < INTEL_GSC_NUM_INTERFACES; i++)
		gsc_destroy_one(gt->i915, gsc, i);
}
