// 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 false;
}

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++) {
			kfree(fw_minibuffer[i].name);
			kvfree(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;
}
