// SPDX-License-Identifier: GPL-2.0
/*
 * Support for Intel Camera Imaging ISP subsystem.
 * Copyright (c) 2010 - 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 "hmm.h"

#include "ia_css_pipeline.h"
#include "ia_css_isp_param.h"

/* Set functions for parameter memory descriptors */

void
ia_css_isp_param_set_mem_init(
    struct ia_css_isp_param_host_segments *mem_init,
    enum ia_css_param_class pclass,
    enum ia_css_isp_memories mem,
    char *address, size_t size)
{
	mem_init->params[pclass][mem].address = address;
	mem_init->params[pclass][mem].size = (uint32_t)size;
}

void
ia_css_isp_param_set_css_mem_init(
    struct ia_css_isp_param_css_segments *mem_init,
    enum ia_css_param_class pclass,
    enum ia_css_isp_memories mem,
    ia_css_ptr address, size_t size)
{
	mem_init->params[pclass][mem].address = address;
	mem_init->params[pclass][mem].size = (uint32_t)size;
}

void
ia_css_isp_param_set_isp_mem_init(
    struct ia_css_isp_param_isp_segments *mem_init,
    enum ia_css_param_class pclass,
    enum ia_css_isp_memories mem,
    u32 address, size_t size)
{
	mem_init->params[pclass][mem].address = address;
	mem_init->params[pclass][mem].size = (uint32_t)size;
}

/* Get functions for parameter memory descriptors */
const struct ia_css_host_data *
ia_css_isp_param_get_mem_init(
    const struct ia_css_isp_param_host_segments *mem_init,
    enum ia_css_param_class pclass,
    enum ia_css_isp_memories mem)
{
	return &mem_init->params[pclass][mem];
}

const struct ia_css_data *
ia_css_isp_param_get_css_mem_init(
    const struct ia_css_isp_param_css_segments *mem_init,
    enum ia_css_param_class pclass,
    enum ia_css_isp_memories mem)
{
	return &mem_init->params[pclass][mem];
}

const struct ia_css_isp_data *
ia_css_isp_param_get_isp_mem_init(
    const struct ia_css_isp_param_isp_segments *mem_init,
    enum ia_css_param_class pclass,
    enum ia_css_isp_memories mem)
{
	return &mem_init->params[pclass][mem];
}

void
ia_css_init_memory_interface(
    struct ia_css_isp_param_css_segments *isp_mem_if,
    const struct ia_css_isp_param_host_segments *mem_params,
    const struct ia_css_isp_param_css_segments *css_params)
{
	unsigned int pclass, mem;

	for (pclass = 0; pclass < IA_CSS_NUM_PARAM_CLASSES; pclass++) {
		memset(isp_mem_if->params[pclass], 0, sizeof(isp_mem_if->params[pclass]));
		for (mem = 0; mem < IA_CSS_NUM_MEMORIES; mem++) {
			if (!mem_params->params[pclass][mem].address)
				continue;
			isp_mem_if->params[pclass][mem].size = mem_params->params[pclass][mem].size;
			if (pclass != IA_CSS_PARAM_CLASS_PARAM)
				isp_mem_if->params[pclass][mem].address =
				    css_params->params[pclass][mem].address;
		}
	}
}

int
ia_css_isp_param_allocate_isp_parameters(
    struct ia_css_isp_param_host_segments *mem_params,
    struct ia_css_isp_param_css_segments *css_params,
    const struct ia_css_isp_param_isp_segments *mem_initializers) {
	int err = 0;
	unsigned int mem, pclass;

	pclass = IA_CSS_PARAM_CLASS_PARAM;
	for (mem = 0; mem < IA_CSS_NUM_MEMORIES; mem++)
	{
		for (pclass = 0; pclass < IA_CSS_NUM_PARAM_CLASSES; pclass++) {
			u32 size = 0;

			if (mem_initializers)
				size = mem_initializers->params[pclass][mem].size;
			mem_params->params[pclass][mem].size = size;
			mem_params->params[pclass][mem].address = NULL;
			css_params->params[pclass][mem].size = size;
			css_params->params[pclass][mem].address = 0x0;
			if (size) {
				mem_params->params[pclass][mem].address = kvcalloc(1,
										   size,
										   GFP_KERNEL);
				if (!mem_params->params[pclass][mem].address) {
					err = -ENOMEM;
					goto cleanup;
				}
				if (pclass != IA_CSS_PARAM_CLASS_PARAM) {
					css_params->params[pclass][mem].address = hmm_alloc(size, HMM_BO_PRIVATE, 0, NULL, 0);
					if (!css_params->params[pclass][mem].address) {
						err = -ENOMEM;
						goto cleanup;
					}
				}
			}
		}
	}
	return err;
cleanup:
	ia_css_isp_param_destroy_isp_parameters(mem_params, css_params);
	return err;
}

void
ia_css_isp_param_destroy_isp_parameters(
    struct ia_css_isp_param_host_segments *mem_params,
    struct ia_css_isp_param_css_segments *css_params)
{
	unsigned int mem, pclass;

	for (mem = 0; mem < IA_CSS_NUM_MEMORIES; mem++) {
		for (pclass = 0; pclass < IA_CSS_NUM_PARAM_CLASSES; pclass++) {
			if (mem_params->params[pclass][mem].address)
				kvfree(mem_params->params[pclass][mem].address);
			if (css_params->params[pclass][mem].address)
				hmm_free(css_params->params[pclass][mem].address);
			mem_params->params[pclass][mem].address = NULL;
			css_params->params[pclass][mem].address = 0x0;
		}
	}
}

void
ia_css_isp_param_load_fw_params(
    const char *fw,
    union ia_css_all_memory_offsets *mem_offsets,
    const struct ia_css_isp_param_memory_offsets *memory_offsets,
    bool init)
{
	unsigned int pclass;

	for (pclass = 0; pclass < IA_CSS_NUM_PARAM_CLASSES; pclass++) {
		mem_offsets->array[pclass].ptr = NULL;
		if (init)
			mem_offsets->array[pclass].ptr = (void *)(fw + memory_offsets->offsets[pclass]);
	}
}

int
ia_css_isp_param_copy_isp_mem_if_to_ddr(
    struct ia_css_isp_param_css_segments *ddr,
    const struct ia_css_isp_param_host_segments *host,
    enum ia_css_param_class pclass) {
	unsigned int mem;

	for (mem = 0; mem < N_IA_CSS_ISP_MEMORIES; mem++)
	{
		size_t       size	  = host->params[pclass][mem].size;
		ia_css_ptr ddr_mem_ptr  = ddr->params[pclass][mem].address;
		char	    *host_mem_ptr = host->params[pclass][mem].address;

		if (size != ddr->params[pclass][mem].size)
			return -EINVAL;
		if (!size)
			continue;
		hmm_store(ddr_mem_ptr, host_mem_ptr, size);
	}
	return 0;
}

void
ia_css_isp_param_enable_pipeline(
    const struct ia_css_isp_param_host_segments *mem_params)
{
	/* By protocol b0 of the mandatory uint32_t first field of the
	   input parameter is a disable bit*/
	short dmem_offset = 0;

	if (mem_params->params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM0].size == 0)
		return;

	*(uint32_t *)
	&mem_params->params[IA_CSS_PARAM_CLASS_PARAM][IA_CSS_ISP_DMEM0].address[dmem_offset]
	    = 0x0;
}
