// SPDX-License-Identifier: GPL-2.0
/*
 * Support for Intel Camera Imaging ISP subsystem.
 * Copyright (c) 2015, Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 */

#include <linux/string.h> /* for memcpy() */
#include <linux/slab.h>
#include <linux/vmalloc.h>

#include "hmm.h"

#include <math_support.h>
#include "platform_support.h"
#include "sh_css_firmware.h"

#include "sh_css_defs.h"
#include "ia_css_debug.h"
#include "sh_css_internal.h"
#include "ia_css_isp_param.h"

#include "assert_support.h"

#include "isp.h"				/* PMEM_WIDTH_LOG2 */

#include "ia_css_isp_params.h"
#include "ia_css_isp_configs.h"
#include "ia_css_isp_states.h"

#define _STR(x) #x
#define STR(x) _STR(x)

struct firmware_header {
	struct sh_css_fw_bi_file_h file_header;
	struct ia_css_fw_info      binary_header;
};

struct fw_param {
	const char *name;
	const void *buffer;
};

static struct firmware_header *firmware_header;

/* The string STR is a place holder
 * which will be replaced with the actual RELEASE_VERSION
 * during package generation. Please do not modify  */
static const char *isp2400_release_version = STR(irci_stable_candrpv_0415_20150521_0458);
static const char *isp2401_release_version = STR(irci_ecr - master_20150911_0724);

#define MAX_FW_REL_VER_NAME	300
static char FW_rel_ver_name[MAX_FW_REL_VER_NAME] = "---";

struct ia_css_fw_info	  sh_css_sp_fw;
struct ia_css_blob_descr *sh_css_blob_info; /* Only ISP blob info (no SP) */
unsigned int sh_css_num_binaries; /* This includes 1 SP binary */

static struct fw_param *fw_minibuffer;

char *sh_css_get_fw_version(void)
{
	return FW_rel_ver_name;
}

/*
 * Split the loaded firmware into blobs
 */

/* Setup sp/sp1 binary */
static int
setup_binary(struct ia_css_fw_info *fw, const char *fw_data,
	     struct ia_css_fw_info *sh_css_fw, unsigned int binary_id) {
	const char *blob_data;

	if ((!fw) || (!fw_data))
		return -EINVAL;

	blob_data = fw_data + fw->blob.offset;

	*sh_css_fw = *fw;

	sh_css_fw->blob.code = vmalloc(fw->blob.size);
	if (!sh_css_fw->blob.code)
		return -ENOMEM;

	memcpy((void *)sh_css_fw->blob.code, blob_data, fw->blob.size);
	sh_css_fw->blob.data = (char *)sh_css_fw->blob.code + fw->blob.data_source;
	fw_minibuffer[binary_id].buffer = sh_css_fw->blob.code;

	return 0;
}

int
sh_css_load_blob_info(const char *fw, const struct ia_css_fw_info *bi,
		      struct ia_css_blob_descr *bd,
		      unsigned int index) {
	const char *name;
	const unsigned char *blob;

	if ((!fw) || (!bd))
		return -EINVAL;

	/* Special case: only one binary in fw */
	if (!bi) bi = (const struct ia_css_fw_info *)fw;

	name = fw + bi->blob.prog_name_offset;
	blob = (const unsigned char *)fw + bi->blob.offset;

	/* sanity check */
	if (bi->blob.size != bi->blob.text_size + bi->blob.icache_size + bi->blob.data_size + bi->blob.padding_size)
	{
		/* sanity check, note the padding bytes added for section to DDR alignment */
		return -EINVAL;
	}

	if ((bi->blob.offset % (1UL << (ISP_PMEM_WIDTH_LOG2 - 3))) != 0)
		return -EINVAL;

	bd->blob = blob;
	bd->header = *bi;

	if (bi->type == ia_css_isp_firmware || bi->type == ia_css_sp_firmware)
	{
		char *namebuffer;

		namebuffer = kstrdup(name, GFP_KERNEL);
		if (!namebuffer)
			return -ENOMEM;
		bd->name = fw_minibuffer[index].name = namebuffer;
	} else
	{
		bd->name = name;
	}

	if (bi->type == ia_css_isp_firmware)
	{
		size_t paramstruct_size = sizeof(struct ia_css_memory_offsets);
		size_t configstruct_size = sizeof(struct ia_css_config_memory_offsets);
		size_t statestruct_size = sizeof(struct ia_css_state_memory_offsets);

		char *parambuf = kmalloc(paramstruct_size + configstruct_size +
					 statestruct_size,
					 GFP_KERNEL);
		if (!parambuf)
			return -ENOMEM;

		bd->mem_offsets.array[IA_CSS_PARAM_CLASS_PARAM].ptr = NULL;
		bd->mem_offsets.array[IA_CSS_PARAM_CLASS_CONFIG].ptr = NULL;
		bd->mem_offsets.array[IA_CSS_PARAM_CLASS_STATE].ptr = NULL;

		fw_minibuffer[index].buffer = parambuf;

		/* copy ia_css_memory_offsets */
		memcpy(parambuf, (void *)(fw +
					  bi->blob.memory_offsets.offsets[IA_CSS_PARAM_CLASS_PARAM]),
		       paramstruct_size);
		bd->mem_offsets.array[IA_CSS_PARAM_CLASS_PARAM].ptr = parambuf;

		/* copy ia_css_config_memory_offsets */
		memcpy(parambuf + paramstruct_size,
		       (void *)(fw + bi->blob.memory_offsets.offsets[IA_CSS_PARAM_CLASS_CONFIG]),
		       configstruct_size);
		bd->mem_offsets.array[IA_CSS_PARAM_CLASS_CONFIG].ptr = parambuf +
		paramstruct_size;

		/* copy ia_css_state_memory_offsets */
		memcpy(parambuf + paramstruct_size + configstruct_size,
		       (void *)(fw + bi->blob.memory_offsets.offsets[IA_CSS_PARAM_CLASS_STATE]),
		       statestruct_size);
		bd->mem_offsets.array[IA_CSS_PARAM_CLASS_STATE].ptr = parambuf +
		paramstruct_size + configstruct_size;
	}
	return 0;
}

bool
sh_css_check_firmware_version(struct device *dev, const char *fw_data)
{
	struct sh_css_fw_bi_file_h *file_header;

	const char *release_version;

	if (!IS_ISP2401)
		release_version = isp2400_release_version;
	else
		release_version = isp2401_release_version;

	firmware_header = (struct firmware_header *)fw_data;
	file_header = &firmware_header->file_header;

	if (strcmp(file_header->version, release_version) != 0) {
		dev_err(dev, "Firmware version may not be compatible with this driver\n");
		dev_err(dev, "Expecting version '%s', but firmware is '%s'.\n",
			release_version, file_header->version);
	}

	/* For now, let's just accept a wrong version, even if wrong */
	return 0;
}

static const char * const fw_type_name[] = {
	[ia_css_sp_firmware]		= "SP",
	[ia_css_isp_firmware]		= "ISP",
	[ia_css_bootloader_firmware]	= "BootLoader",
	[ia_css_acc_firmware]		= "accel",
};

static const char * const fw_acc_type_name[] = {
	[IA_CSS_ACC_NONE] =		"Normal",
	[IA_CSS_ACC_OUTPUT] =		"Accel for output",
	[IA_CSS_ACC_VIEWFINDER] =	"Accel for viewfinder",
	[IA_CSS_ACC_STANDALONE] =	"Stand-alone accel",
};

int
sh_css_load_firmware(struct device *dev, const char *fw_data,
		     unsigned int fw_size) {
	unsigned int i;
	struct ia_css_fw_info *binaries;
	struct sh_css_fw_bi_file_h *file_header;
	int ret;
	const char *release_version;

	if (!IS_ISP2401)
		release_version = isp2400_release_version;
	else
		release_version = isp2401_release_version;

	firmware_header = (struct firmware_header *)fw_data;
	file_header = &firmware_header->file_header;
	binaries = &firmware_header->binary_header;
	strscpy(FW_rel_ver_name, file_header->version, min(sizeof(FW_rel_ver_name), sizeof(file_header->version)));
	ret = sh_css_check_firmware_version(dev, fw_data);
	if (ret) {
		IA_CSS_ERROR("CSS code version (%s) and firmware version (%s) mismatch!",
			     file_header->version, release_version);
		return -EINVAL;
	} else {
		IA_CSS_LOG("successfully load firmware version %s", release_version);
	}

	/* some sanity checks */
	if (!fw_data || fw_size < sizeof(struct sh_css_fw_bi_file_h))
		return -EINVAL;

	if (file_header->h_size != sizeof(struct sh_css_fw_bi_file_h))
		return -EINVAL;

	sh_css_num_binaries = file_header->binary_nr;
	/* Only allocate memory for ISP blob info */
	if (sh_css_num_binaries > NUM_OF_SPS)
	{
		sh_css_blob_info = kmalloc(
		    (sh_css_num_binaries - NUM_OF_SPS) *
		    sizeof(*sh_css_blob_info), GFP_KERNEL);
		if (!sh_css_blob_info)
			return -ENOMEM;
	} else {
		sh_css_blob_info = NULL;
	}

	fw_minibuffer = kcalloc(sh_css_num_binaries, sizeof(struct fw_param),
				GFP_KERNEL);
	if (!fw_minibuffer)
		return -ENOMEM;

	for (i = 0; i < sh_css_num_binaries; i++)
	{
		struct ia_css_fw_info *bi = &binaries[i];
		/* note: the var below is made static as it is quite large;
		   if it is not static it ends up on the stack which could
		   cause issues for drivers
		*/
		static struct ia_css_blob_descr bd;
		int err;

		err = sh_css_load_blob_info(fw_data, bi, &bd, i);

		if (err)
			return -EINVAL;

		if (bi->blob.offset + bi->blob.size > fw_size)
			return -EINVAL;

		switch (bd.header.type) {
		case ia_css_isp_firmware:
			if (bd.header.info.isp.type > IA_CSS_ACC_STANDALONE) {
				dev_err(dev, "binary #%2d: invalid SP type\n",
					i);
				return -EINVAL;
			}

			dev_dbg(dev,
				"binary #%-2d type %s (%s), binary id is %2d: %s\n",
				i,
				fw_type_name[bd.header.type],
				fw_acc_type_name[bd.header.info.isp.type],
				bd.header.info.isp.sp.id,
				bd.name);
			break;
		case ia_css_sp_firmware:
		case ia_css_bootloader_firmware:
		case ia_css_acc_firmware:
			dev_dbg(dev,
				"binary #%-2d type %s: %s\n",
				i, fw_type_name[bd.header.type],
				bd.name);
			break;
		default:
			if (bd.header.info.isp.type > IA_CSS_ACC_STANDALONE) {
				dev_err(dev,
					"binary #%2d: invalid firmware type\n",
					i);
				return -EINVAL;
			}
			break;
		}

		if (bi->type == ia_css_sp_firmware) {
			if (i != SP_FIRMWARE)
				return -EINVAL;
			err = setup_binary(bi, fw_data, &sh_css_sp_fw, i);
			if (err)
				return err;

		} else {
			/* All subsequent binaries (including bootloaders) (i>NUM_OF_SPS) are ISP firmware */
			if (i < NUM_OF_SPS)
				return -EINVAL;

			if (bi->type != ia_css_isp_firmware)
				return -EINVAL;
			if (!sh_css_blob_info) /* cannot happen but KW does not see this */
				return -EINVAL;
			sh_css_blob_info[i - NUM_OF_SPS] = bd;
		}
	}

	return 0;
}

void sh_css_unload_firmware(void)
{
	/* release firmware minibuffer */
	if (fw_minibuffer) {
		unsigned int i = 0;

		for (i = 0; i < sh_css_num_binaries; i++) {
			if (fw_minibuffer[i].name)
				kfree((void *)fw_minibuffer[i].name);
			if (fw_minibuffer[i].buffer)
				vfree((void *)fw_minibuffer[i].buffer);
		}
		kfree(fw_minibuffer);
		fw_minibuffer = NULL;
	}

	memset(&sh_css_sp_fw, 0, sizeof(sh_css_sp_fw));
	kfree(sh_css_blob_info);
	sh_css_blob_info = NULL;
	sh_css_num_binaries = 0;
}

ia_css_ptr
sh_css_load_blob(const unsigned char *blob, unsigned int size)
{
	ia_css_ptr target_addr = hmm_alloc(size, HMM_BO_PRIVATE, 0, NULL, 0);
	/* this will allocate memory aligned to a DDR word boundary which
	   is required for the CSS DMA to read the instructions. */

	assert(blob);
	if (target_addr)
		hmm_store(target_addr, blob, size);
	return target_addr;
}
