/*
 * Copyright © 2014 Intel Corporation
 *
 * 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, sublicense,
 * 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 NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS 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 <linux/firmware.h>
#include "i915_drv.h"
#include "i915_reg.h"

/**
 * DOC: csr support for dmc
 *
 * Display Context Save and Restore (CSR) firmware support added from gen9
 * onwards to drive newly added DMC (Display microcontroller) in display
 * engine to save and restore the state of display engine when it enter into
 * low-power state and comes back to normal.
 *
 * Firmware loading status will be one of the below states: FW_UNINITIALIZED,
 * FW_LOADED, FW_FAILED.
 *
 * Once the firmware is written into the registers status will be moved from
 * FW_UNINITIALIZED to FW_LOADED and for any erroneous condition status will
 * be moved to FW_FAILED.
 */

#define I915_CSR_SKL "i915/skl_dmc_ver1.bin"
#define I915_CSR_BXT "i915/bxt_dmc_ver1.bin"

MODULE_FIRMWARE(I915_CSR_SKL);
MODULE_FIRMWARE(I915_CSR_BXT);

/*
* SKL CSR registers for DC5 and DC6
*/
#define CSR_PROGRAM(i)			(0x80000 + (i) * 4)
#define CSR_SSP_BASE_ADDR_GEN9		0x00002FC0
#define CSR_HTP_ADDR_SKL		0x00500034
#define CSR_SSP_BASE			0x8F074
#define CSR_HTP_SKL			0x8F004
#define CSR_LAST_WRITE			0x8F034
#define CSR_LAST_WRITE_VALUE		0xc003b400
/* MMIO address range for CSR program (0x80000 - 0x82FFF) */
#define CSR_MAX_FW_SIZE			0x2FFF
#define CSR_DEFAULT_FW_OFFSET		0xFFFFFFFF
#define CSR_MMIO_START_RANGE	0x80000
#define CSR_MMIO_END_RANGE		0x8FFFF

struct intel_css_header {
	/* 0x09 for DMC */
	uint32_t module_type;

	/* Includes the DMC specific header in dwords */
	uint32_t header_len;

	/* always value would be 0x10000 */
	uint32_t header_ver;

	/* Not used */
	uint32_t module_id;

	/* Not used */
	uint32_t module_vendor;

	/* in YYYYMMDD format */
	uint32_t date;

	/* Size in dwords (CSS_Headerlen + PackageHeaderLen + dmc FWsLen)/4 */
	uint32_t size;

	/* Not used */
	uint32_t key_size;

	/* Not used */
	uint32_t modulus_size;

	/* Not used */
	uint32_t exponent_size;

	/* Not used */
	uint32_t reserved1[12];

	/* Major Minor */
	uint32_t version;

	/* Not used */
	uint32_t reserved2[8];

	/* Not used */
	uint32_t kernel_header_info;
} __packed;

struct intel_fw_info {
	uint16_t reserved1;

	/* Stepping (A, B, C, ..., *). * is a wildcard */
	char stepping;

	/* Sub-stepping (0, 1, ..., *). * is a wildcard */
	char substepping;

	uint32_t offset;
	uint32_t reserved2;
} __packed;

struct intel_package_header {
	/* DMC container header length in dwords */
	unsigned char header_len;

	/* always value would be 0x01 */
	unsigned char header_ver;

	unsigned char reserved[10];

	/* Number of valid entries in the FWInfo array below */
	uint32_t num_entries;

	struct intel_fw_info fw_info[20];
} __packed;

struct intel_dmc_header {
	/* always value would be 0x40403E3E */
	uint32_t signature;

	/* DMC binary header length */
	unsigned char header_len;

	/* 0x01 */
	unsigned char header_ver;

	/* Reserved */
	uint16_t dmcc_ver;

	/* Major, Minor */
	uint32_t	project;

	/* Firmware program size (excluding header) in dwords */
	uint32_t	fw_size;

	/* Major Minor version */
	uint32_t fw_version;

	/* Number of valid MMIO cycles present. */
	uint32_t mmio_count;

	/* MMIO address */
	uint32_t mmioaddr[8];

	/* MMIO data */
	uint32_t mmiodata[8];

	/* FW filename  */
	unsigned char dfile[32];

	uint32_t reserved1[2];
} __packed;

struct stepping_info {
	char stepping;
	char substepping;
};

static const struct stepping_info skl_stepping_info[] = {
		{'A', '0'}, {'B', '0'}, {'C', '0'},
		{'D', '0'}, {'E', '0'}, {'F', '0'},
		{'G', '0'}, {'H', '0'}, {'I', '0'},
		{'J', '0'}, {'K', '0'}
};

static struct stepping_info bxt_stepping_info[] = {
	{'A', '0'}, {'A', '1'}, {'A', '2'},
	{'B', '0'}, {'B', '1'}, {'B', '2'}
};

static char intel_get_stepping(struct drm_device *dev)
{
	if (IS_SKYLAKE(dev) && (dev->pdev->revision <
			ARRAY_SIZE(skl_stepping_info)))
		return skl_stepping_info[dev->pdev->revision].stepping;
	else if (IS_BROXTON(dev) && (dev->pdev->revision <
				ARRAY_SIZE(bxt_stepping_info)))
		return bxt_stepping_info[dev->pdev->revision].stepping;
	else
		return -ENODATA;
}

static char intel_get_substepping(struct drm_device *dev)
{
	if (IS_SKYLAKE(dev) && (dev->pdev->revision <
			ARRAY_SIZE(skl_stepping_info)))
		return skl_stepping_info[dev->pdev->revision].substepping;
	else if (IS_BROXTON(dev) && (dev->pdev->revision <
			ARRAY_SIZE(bxt_stepping_info)))
		return bxt_stepping_info[dev->pdev->revision].substepping;
	else
		return -ENODATA;
}

/**
 * intel_csr_load_status_get() - to get firmware loading status.
 * @dev_priv: i915 device.
 *
 * This function helps to get the firmware loading status.
 *
 * Return: Firmware loading status.
 */
enum csr_state intel_csr_load_status_get(struct drm_i915_private *dev_priv)
{
	enum csr_state state;

	mutex_lock(&dev_priv->csr_lock);
	state = dev_priv->csr.state;
	mutex_unlock(&dev_priv->csr_lock);

	return state;
}

/**
 * intel_csr_load_status_set() - help to set firmware loading status.
 * @dev_priv: i915 device.
 * @state: enumeration of firmware loading status.
 *
 * Set the firmware loading status.
 */
void intel_csr_load_status_set(struct drm_i915_private *dev_priv,
			enum csr_state state)
{
	mutex_lock(&dev_priv->csr_lock);
	dev_priv->csr.state = state;
	mutex_unlock(&dev_priv->csr_lock);
}

/**
 * intel_csr_load_program() - write the firmware from memory to register.
 * @dev: drm device.
 *
 * CSR firmware is read from a .bin file and kept in internal memory one time.
 * Everytime display comes back from low power state this function is called to
 * copy the firmware from internal memory to registers.
 */
void intel_csr_load_program(struct drm_device *dev)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
	u32 *payload = dev_priv->csr.dmc_payload;
	uint32_t i, fw_size;

	if (!IS_GEN9(dev)) {
		DRM_ERROR("No CSR support available for this platform\n");
		return;
	}

	/*
	 * FIXME: Firmware gets lost on S3/S4, but not when entering system
	 * standby or suspend-to-idle (which is just like forced runtime pm).
	 * Unfortunately the ACPI subsystem doesn't yet give us a way to
	 * differentiate this, hence figure it out with this hack.
	 */
	if (I915_READ(CSR_PROGRAM(0)))
		return;

	mutex_lock(&dev_priv->csr_lock);
	fw_size = dev_priv->csr.dmc_fw_size;
	for (i = 0; i < fw_size; i++)
		I915_WRITE(CSR_PROGRAM(i), payload[i]);

	for (i = 0; i < dev_priv->csr.mmio_count; i++) {
		I915_WRITE(dev_priv->csr.mmioaddr[i],
			dev_priv->csr.mmiodata[i]);
	}

	dev_priv->csr.state = FW_LOADED;
	mutex_unlock(&dev_priv->csr_lock);
}

static void finish_csr_load(const struct firmware *fw, void *context)
{
	struct drm_i915_private *dev_priv = context;
	struct drm_device *dev = dev_priv->dev;
	struct intel_css_header *css_header;
	struct intel_package_header *package_header;
	struct intel_dmc_header *dmc_header;
	struct intel_csr *csr = &dev_priv->csr;
	char stepping = intel_get_stepping(dev);
	char substepping = intel_get_substepping(dev);
	uint32_t dmc_offset = CSR_DEFAULT_FW_OFFSET, readcount = 0, nbytes;
	uint32_t i;
	uint32_t *dmc_payload;
	bool fw_loaded = false;

	if (!fw) {
		i915_firmware_load_error_print(csr->fw_path, 0);
		goto out;
	}

	if ((stepping == -ENODATA) || (substepping == -ENODATA)) {
		DRM_ERROR("Unknown stepping info, firmware loading failed\n");
		goto out;
	}

	/* Extract CSS Header information*/
	css_header = (struct intel_css_header *)fw->data;
	if (sizeof(struct intel_css_header) !=
		(css_header->header_len * 4)) {
		DRM_ERROR("Firmware has wrong CSS header length %u bytes\n",
			(css_header->header_len * 4));
		goto out;
	}
	readcount += sizeof(struct intel_css_header);

	/* Extract Package Header information*/
	package_header = (struct intel_package_header *)
					&fw->data[readcount];
	if (sizeof(struct intel_package_header) !=
		(package_header->header_len * 4)) {
		DRM_ERROR("Firmware has wrong package header length %u bytes\n",
			(package_header->header_len * 4));
		goto out;
	}
	readcount += sizeof(struct intel_package_header);

	/* Search for dmc_offset to find firware binary. */
	for (i = 0; i < package_header->num_entries; i++) {
		if (package_header->fw_info[i].substepping == '*' &&
			stepping == package_header->fw_info[i].stepping) {
			dmc_offset = package_header->fw_info[i].offset;
			break;
		} else if (stepping == package_header->fw_info[i].stepping &&
			substepping == package_header->fw_info[i].substepping) {
			dmc_offset = package_header->fw_info[i].offset;
			break;
		} else if (package_header->fw_info[i].stepping == '*' &&
			package_header->fw_info[i].substepping == '*')
			dmc_offset = package_header->fw_info[i].offset;
	}
	if (dmc_offset == CSR_DEFAULT_FW_OFFSET) {
		DRM_ERROR("Firmware not supported for %c stepping\n", stepping);
		goto out;
	}
	readcount += dmc_offset;

	/* Extract dmc_header information. */
	dmc_header = (struct intel_dmc_header *)&fw->data[readcount];
	if (sizeof(struct intel_dmc_header) != (dmc_header->header_len)) {
		DRM_ERROR("Firmware has wrong dmc header length %u bytes\n",
				(dmc_header->header_len));
		goto out;
	}
	readcount += sizeof(struct intel_dmc_header);

	/* Cache the dmc header info. */
	if (dmc_header->mmio_count > ARRAY_SIZE(csr->mmioaddr)) {
		DRM_ERROR("Firmware has wrong mmio count %u\n",
						dmc_header->mmio_count);
		goto out;
	}
	csr->mmio_count = dmc_header->mmio_count;
	for (i = 0; i < dmc_header->mmio_count; i++) {
		if (dmc_header->mmioaddr[i] < CSR_MMIO_START_RANGE ||
			dmc_header->mmioaddr[i] > CSR_MMIO_END_RANGE) {
			DRM_ERROR(" Firmware has wrong mmio address 0x%x\n",
						dmc_header->mmioaddr[i]);
			goto out;
		}
		csr->mmioaddr[i] = dmc_header->mmioaddr[i];
		csr->mmiodata[i] = dmc_header->mmiodata[i];
	}

	/* fw_size is in dwords, so multiplied by 4 to convert into bytes. */
	nbytes = dmc_header->fw_size * 4;
	if (nbytes > CSR_MAX_FW_SIZE) {
		DRM_ERROR("CSR firmware too big (%u) bytes\n", nbytes);
		goto out;
	}
	csr->dmc_fw_size = dmc_header->fw_size;

	csr->dmc_payload = kmalloc(nbytes, GFP_KERNEL);
	if (!csr->dmc_payload) {
		DRM_ERROR("Memory allocation failed for dmc payload\n");
		goto out;
	}

	dmc_payload = csr->dmc_payload;
	memcpy(dmc_payload, &fw->data[readcount], nbytes);

	/* load csr program during system boot, as needed for DC states */
	intel_csr_load_program(dev);
	fw_loaded = true;

	DRM_DEBUG_KMS("Finished loading %s\n", dev_priv->csr.fw_path);
out:
	if (fw_loaded)
		intel_runtime_pm_put(dev_priv);
	else
		intel_csr_load_status_set(dev_priv, FW_FAILED);

	release_firmware(fw);
}

/**
 * intel_csr_ucode_init() - initialize the firmware loading.
 * @dev: drm device.
 *
 * This function is called at the time of loading the display driver to read
 * firmware from a .bin file and copied into a internal memory.
 */
void intel_csr_ucode_init(struct drm_device *dev)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
	struct intel_csr *csr = &dev_priv->csr;
	int ret;

	if (!HAS_CSR(dev))
		return;

	if (IS_SKYLAKE(dev))
		csr->fw_path = I915_CSR_SKL;
	else if (IS_BROXTON(dev_priv))
		csr->fw_path = I915_CSR_BXT;
	else {
		DRM_ERROR("Unexpected: no known CSR firmware for platform\n");
		intel_csr_load_status_set(dev_priv, FW_FAILED);
		return;
	}

	DRM_DEBUG_KMS("Loading %s\n", csr->fw_path);

	/*
	 * Obtain a runtime pm reference, until CSR is loaded,
	 * to avoid entering runtime-suspend.
	 */
	intel_runtime_pm_get(dev_priv);

	/* CSR supported for platform, load firmware */
	ret = request_firmware_nowait(THIS_MODULE, true, csr->fw_path,
				&dev_priv->dev->pdev->dev,
				GFP_KERNEL, dev_priv,
				finish_csr_load);
	if (ret) {
		i915_firmware_load_error_print(csr->fw_path, ret);
		intel_csr_load_status_set(dev_priv, FW_FAILED);
	}
}

/**
 * intel_csr_ucode_fini() - unload the CSR firmware.
 * @dev: drm device.
 *
 * Firmmware unloading includes freeing the internal momory and reset the
 * firmware loading status.
 */
void intel_csr_ucode_fini(struct drm_device *dev)
{
	struct drm_i915_private *dev_priv = dev->dev_private;

	if (!HAS_CSR(dev))
		return;

	intel_csr_load_status_set(dev_priv, FW_FAILED);
	kfree(dev_priv->csr.dmc_payload);
}

void assert_csr_loaded(struct drm_i915_private *dev_priv)
{
	WARN_ONCE(intel_csr_load_status_get(dev_priv) != FW_LOADED,
		  "CSR is not loaded.\n");
	WARN_ONCE(!I915_READ(CSR_PROGRAM(0)),
		  "CSR program storage start is NULL\n");
	WARN_ONCE(!I915_READ(CSR_SSP_BASE), "CSR SSP Base Not fine\n");
	WARN_ONCE(!I915_READ(CSR_HTP_SKL), "CSR HTP Not fine\n");
}
