// 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++) {
			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;
}
