/*
 * 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.
 */

/* Generated code: do not edit or commmit. */

#include "ia_css_pipeline.h"
#include "ia_css_isp_states.h"
#include "ia_css_debug.h"
#include "assert_support.h"

/* Code generated by genparam/genstate.c:gen_init_function() */

static void
ia_css_initialize_aa_state(
	const struct ia_css_binary *binary)
{
	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_initialize_aa_state() enter:\n");

	{
		unsigned size   = binary->info->mem_offsets.offsets.state->vmem.aa.size;
		unsigned offset = binary->info->mem_offsets.offsets.state->vmem.aa.offset;

		if (size)
			memset(&binary->mem_params.params[IA_CSS_PARAM_CLASS_STATE][IA_CSS_ISP_VMEM].address[offset], 0, size);

	}
	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_initialize_aa_state() leave:\n");
}

/* Code generated by genparam/genstate.c:gen_init_function() */

static void
ia_css_initialize_cnr_state(
	const struct ia_css_binary *binary)
{
	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_initialize_cnr_state() enter:\n");

	{
		unsigned size   = binary->info->mem_offsets.offsets.state->vmem.cnr.size;

		unsigned offset = binary->info->mem_offsets.offsets.state->vmem.cnr.offset;

		if (size) {
			ia_css_init_cnr_state(
				&binary->mem_params.params[IA_CSS_PARAM_CLASS_STATE][IA_CSS_ISP_VMEM].address[offset],
				size);
		}

	}
	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_initialize_cnr_state() leave:\n");
}

/* Code generated by genparam/genstate.c:gen_init_function() */

static void
ia_css_initialize_cnr2_state(
	const struct ia_css_binary *binary)
{
	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_initialize_cnr2_state() enter:\n");

	{
		unsigned size   = binary->info->mem_offsets.offsets.state->vmem.cnr2.size;

		unsigned offset = binary->info->mem_offsets.offsets.state->vmem.cnr2.offset;

		if (size) {
			ia_css_init_cnr2_state(
				&binary->mem_params.params[IA_CSS_PARAM_CLASS_STATE][IA_CSS_ISP_VMEM].address[offset],
				size);
		}

	}
	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_initialize_cnr2_state() leave:\n");
}

/* Code generated by genparam/genstate.c:gen_init_function() */

static void
ia_css_initialize_dp_state(
	const struct ia_css_binary *binary)
{
	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_initialize_dp_state() enter:\n");

	{
		unsigned size   = binary->info->mem_offsets.offsets.state->vmem.dp.size;

		unsigned offset = binary->info->mem_offsets.offsets.state->vmem.dp.offset;

		if (size) {
			ia_css_init_dp_state(
				&binary->mem_params.params[IA_CSS_PARAM_CLASS_STATE][IA_CSS_ISP_VMEM].address[offset],
				size);
		}

	}
	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_initialize_dp_state() leave:\n");
}

/* Code generated by genparam/genstate.c:gen_init_function() */

static void
ia_css_initialize_de_state(
	const struct ia_css_binary *binary)
{
	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_initialize_de_state() enter:\n");

	{
		unsigned size   = binary->info->mem_offsets.offsets.state->vmem.de.size;

		unsigned offset = binary->info->mem_offsets.offsets.state->vmem.de.offset;

		if (size) {
			ia_css_init_de_state(
				&binary->mem_params.params[IA_CSS_PARAM_CLASS_STATE][IA_CSS_ISP_VMEM].address[offset],
				size);
		}

	}
	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_initialize_de_state() leave:\n");
}

/* Code generated by genparam/genstate.c:gen_init_function() */

static void
ia_css_initialize_tnr_state(
	const struct ia_css_binary *binary)
{
	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_initialize_tnr_state() enter:\n");

	{
		unsigned size   = binary->info->mem_offsets.offsets.state->dmem.tnr.size;

		unsigned offset = binary->info->mem_offsets.offsets.state->dmem.tnr.offset;

		if (size) {
			ia_css_init_tnr_state((struct sh_css_isp_tnr_dmem_state *)
				&binary->mem_params.params[IA_CSS_PARAM_CLASS_STATE][IA_CSS_ISP_DMEM].address[offset],
				size);
		}

	}
	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_initialize_tnr_state() leave:\n");
}

/* Code generated by genparam/genstate.c:gen_init_function() */

static void
ia_css_initialize_ref_state(
	const struct ia_css_binary *binary)
{
	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_initialize_ref_state() enter:\n");

	{
		unsigned size   = binary->info->mem_offsets.offsets.state->dmem.ref.size;

		unsigned offset = binary->info->mem_offsets.offsets.state->dmem.ref.offset;

		if (size) {
			ia_css_init_ref_state((struct sh_css_isp_ref_dmem_state *)
				&binary->mem_params.params[IA_CSS_PARAM_CLASS_STATE][IA_CSS_ISP_DMEM].address[offset],
				size);
		}

	}
	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_initialize_ref_state() leave:\n");
}

/* Code generated by genparam/genstate.c:gen_init_function() */

static void
ia_css_initialize_ynr_state(
	const struct ia_css_binary *binary)
{
	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_initialize_ynr_state() enter:\n");

	{
		unsigned size   = binary->info->mem_offsets.offsets.state->vmem.ynr.size;

		unsigned offset = binary->info->mem_offsets.offsets.state->vmem.ynr.offset;

		if (size) {
			ia_css_init_ynr_state(
				&binary->mem_params.params[IA_CSS_PARAM_CLASS_STATE][IA_CSS_ISP_VMEM].address[offset],
				size);
		}

	}
	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_initialize_ynr_state() leave:\n");
}

/* Code generated by genparam/genstate.c:gen_state_init_table() */

void (* ia_css_kernel_init_state[IA_CSS_NUM_STATE_IDS])(const struct ia_css_binary *binary) = {
	ia_css_initialize_aa_state,
	ia_css_initialize_cnr_state,
	ia_css_initialize_cnr2_state,
	ia_css_initialize_dp_state,
	ia_css_initialize_de_state,
	ia_css_initialize_tnr_state,
	ia_css_initialize_ref_state,
	ia_css_initialize_ynr_state,
};

