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

#include <linux/intel_dg_nvm_aux.h>
#include <linux/pci.h>

#include "xe_device.h"
#include "xe_device_types.h"
#include "xe_mmio.h"
#include "xe_nvm.h"
#include "regs/xe_gsc_regs.h"
#include "xe_sriov.h"

#define GEN12_GUNIT_NVM_BASE 0x00102040
#define GEN12_DEBUG_NVM_BASE 0x00101018

#define GEN12_CNTL_PROTECTED_NVM_REG 0x0010100C

#define GEN12_GUNIT_NVM_SIZE 0x80
#define GEN12_DEBUG_NVM_SIZE 0x4

#define NVM_NON_POSTED_ERASE_CHICKEN_BIT BIT(13)

#define HECI_FW_STATUS_2_NVM_ACCESS_MODE BIT(3)

static const struct intel_dg_nvm_region regions[INTEL_DG_NVM_REGIONS] = {
	[0] = { .name = "DESCRIPTOR", },
	[2] = { .name = "GSC", },
	[9] = { .name = "PADDING", },
	[11] = { .name = "OptionROM", },
	[12] = { .name = "DAM", },
};

static void xe_nvm_release_dev(struct device *dev)
{
}

static bool xe_nvm_non_posted_erase(struct xe_device *xe)
{
	struct xe_gt *gt = xe_root_mmio_gt(xe);

	if (xe->info.platform != XE_BATTLEMAGE)
		return false;
	return !(xe_mmio_read32(&gt->mmio, XE_REG(GEN12_CNTL_PROTECTED_NVM_REG)) &
		 NVM_NON_POSTED_ERASE_CHICKEN_BIT);
}

static bool xe_nvm_writable_override(struct xe_device *xe)
{
	struct xe_gt *gt = xe_root_mmio_gt(xe);
	bool writable_override;
	resource_size_t base;

	switch (xe->info.platform) {
	case XE_BATTLEMAGE:
		base = DG2_GSC_HECI2_BASE;
		break;
	case XE_PVC:
		base = PVC_GSC_HECI2_BASE;
		break;
	case XE_DG2:
		base = DG2_GSC_HECI2_BASE;
		break;
	case XE_DG1:
		base = DG1_GSC_HECI2_BASE;
		break;
	default:
		drm_err(&xe->drm, "Unknown platform\n");
		return true;
	}

	writable_override =
		!(xe_mmio_read32(&gt->mmio, HECI_FWSTS2(base)) &
		  HECI_FW_STATUS_2_NVM_ACCESS_MODE);
	if (writable_override)
		drm_info(&xe->drm, "NVM access overridden by jumper\n");
	return writable_override;
}

int xe_nvm_init(struct xe_device *xe)
{
	struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
	struct auxiliary_device *aux_dev;
	struct intel_dg_nvm_dev *nvm;
	int ret;

	if (!xe->info.has_gsc_nvm)
		return 0;

	/* No access to internal NVM from VFs */
	if (IS_SRIOV_VF(xe))
		return 0;

	/* Nvm pointer should be NULL here */
	if (WARN_ON(xe->nvm))
		return -EFAULT;

	xe->nvm = kzalloc(sizeof(*nvm), GFP_KERNEL);
	if (!xe->nvm)
		return -ENOMEM;

	nvm = xe->nvm;

	nvm->writable_override = xe_nvm_writable_override(xe);
	nvm->non_posted_erase = xe_nvm_non_posted_erase(xe);
	nvm->bar.parent = &pdev->resource[0];
	nvm->bar.start = GEN12_GUNIT_NVM_BASE + pdev->resource[0].start;
	nvm->bar.end = nvm->bar.start + GEN12_GUNIT_NVM_SIZE - 1;
	nvm->bar.flags = IORESOURCE_MEM;
	nvm->bar.desc = IORES_DESC_NONE;
	nvm->regions = regions;

	nvm->bar2.parent = &pdev->resource[0];
	nvm->bar2.start = GEN12_DEBUG_NVM_BASE + pdev->resource[0].start;
	nvm->bar2.end = nvm->bar2.start + GEN12_DEBUG_NVM_SIZE - 1;
	nvm->bar2.flags = IORESOURCE_MEM;
	nvm->bar2.desc = IORES_DESC_NONE;

	aux_dev = &nvm->aux_dev;

	aux_dev->name = "nvm";
	aux_dev->id = (pci_domain_nr(pdev->bus) << 16) | pci_dev_id(pdev);
	aux_dev->dev.parent = &pdev->dev;
	aux_dev->dev.release = xe_nvm_release_dev;

	ret = auxiliary_device_init(aux_dev);
	if (ret) {
		drm_err(&xe->drm, "xe-nvm aux init failed %d\n", ret);
		goto err;
	}

	ret = auxiliary_device_add(aux_dev);
	if (ret) {
		drm_err(&xe->drm, "xe-nvm aux add failed %d\n", ret);
		auxiliary_device_uninit(aux_dev);
		goto err;
	}
	return 0;

err:
	kfree(nvm);
	xe->nvm = NULL;
	return ret;
}

void xe_nvm_fini(struct xe_device *xe)
{
	struct intel_dg_nvm_dev *nvm = xe->nvm;

	if (!xe->info.has_gsc_nvm)
		return;

	/* No access to internal NVM from VFs */
	if (IS_SRIOV_VF(xe))
		return;

	/* Nvm pointer should not be NULL here */
	if (WARN_ON(!nvm))
		return;

	auxiliary_device_delete(&nvm->aux_dev);
	auxiliary_device_uninit(&nvm->aux_dev);
	kfree(nvm);
	xe->nvm = NULL;
}
