/*
 * 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/slab.h>
#include <linux/vmalloc.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 "memory_access.h"
#include "assert_support.h"
#include "string_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;
};

/* Warning: same order as SH_CSS_BINARY_ID_* */
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  */
#ifndef ISP2401
static const char *release_version = STR(irci_stable_candrpv_0415_20150521_0458);
#else
static const char *release_version = STR(irci_ecr-master_20150911_0724);
#endif

#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		  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 enum ia_css_err
setup_binary(struct ia_css_fw_info *fw, const char *fw_data, struct ia_css_fw_info *sh_css_fw, unsigned binary_id)
{
	const char *blob_data;

	if ((fw == NULL) || (fw_data == NULL))
		return IA_CSS_ERR_INVALID_ARGUMENTS;

	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 == NULL)
		return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;

	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 IA_CSS_SUCCESS;
}
enum ia_css_err
sh_css_load_blob_info(const char *fw, const struct ia_css_fw_info *bi, struct ia_css_blob_descr *bd, unsigned index)
{
	const char *name;
	const unsigned char *blob;

	if ((fw == NULL) || (bd == NULL))
		return IA_CSS_ERR_INVALID_ARGUMENTS;

	/* Special case: only one binary in fw */
	if (bi == NULL) 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 IA_CSS_ERR_INVALID_ARGUMENTS;
	}

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

	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 IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
		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 = (char *)kmalloc(paramstruct_size + configstruct_size + statestruct_size,
							GFP_KERNEL);
		if (parambuf == NULL)
			return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;

		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 IA_CSS_SUCCESS;
}

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

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

	if (strcmp(file_header->version, release_version) != 0) {
		return false;
	} else {
		/* firmware version matches */
		return true;
	}
}

enum ia_css_err
sh_css_load_firmware(const char *fw_data,
		     unsigned int fw_size)
{
	unsigned i;
	struct ia_css_fw_info *binaries;
	struct sh_css_fw_bi_file_h *file_header;
	bool valid_firmware = false;

	firmware_header = (struct firmware_header *)fw_data;
	file_header = &firmware_header->file_header;
	binaries = &firmware_header->binary_header;
	strncpy(FW_rel_ver_name, file_header->version, min(sizeof(FW_rel_ver_name), sizeof(file_header->version)) - 1);
	valid_firmware = sh_css_check_firmware_version(fw_data);
	if (!valid_firmware) {
#if !defined(HRT_RTL)
		IA_CSS_ERROR("CSS code version (%s) and firmware version (%s) mismatch!",
				file_header->version, release_version);
		return IA_CSS_ERR_VERSION_MISMATCH;
#endif
	} 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 IA_CSS_ERR_INTERNAL_ERROR;

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

	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 == NULL)
			return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
	} else {
		sh_css_blob_info = NULL;
	}

	fw_minibuffer = kzalloc(sh_css_num_binaries * sizeof(struct fw_param), GFP_KERNEL);
	if (fw_minibuffer == NULL)
		return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;

	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;
		enum ia_css_err err;

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

		if (err != IA_CSS_SUCCESS)
			return IA_CSS_ERR_INTERNAL_ERROR;

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

		if (bi->type == ia_css_sp_firmware) {
			if (i != SP_FIRMWARE)
				return IA_CSS_ERR_INTERNAL_ERROR;
			err = setup_binary(bi, fw_data, &sh_css_sp_fw, i);
			if (err != IA_CSS_SUCCESS)
				return err;
		} else {
			/* All subsequent binaries (including bootloaders) (i>NUM_OF_SPS) are ISP firmware */
			if (i < NUM_OF_SPS)
				return IA_CSS_ERR_INTERNAL_ERROR;

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

	return IA_CSS_SUCCESS;
}

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));
	if (sh_css_blob_info) {
		kfree(sh_css_blob_info);
		sh_css_blob_info = NULL;
	}
	sh_css_num_binaries = 0;
}

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

	assert(blob != NULL);
	if (target_addr) 
		mmgr_store(target_addr, blob, size);
	return target_addr;
}
