// 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 "atomisp_internal.h"

#include "ia_css_vf.host.h"
#include <assert_support.h>
#include <ia_css_err.h>
#include <ia_css_frame.h>
#include <ia_css_frame_public.h>
#include <ia_css_pipeline.h>
#define IA_CSS_INCLUDE_CONFIGURATIONS
#include "ia_css_isp_configs.h"

#include "isp.h"

void
ia_css_vf_config(
    struct sh_css_isp_vf_isp_config      *to,
    const struct ia_css_vf_configuration *from,
    unsigned int size)
{
	unsigned int elems_a = ISP_VEC_NELEMS;

	(void)size;
	to->vf_downscale_bits = from->vf_downscale_bits;
	to->enable = from->info != NULL;

	if (from->info) {
		ia_css_frame_info_to_frame_sp_info(&to->info, from->info);
		ia_css_dma_configure_from_info(&to->dma.port_b, from->info);
		to->dma.width_a_over_b = elems_a / to->dma.port_b.elems;

		/* Assume divisiblity here, may need to generalize to fixed point. */
		assert(elems_a % to->dma.port_b.elems == 0);
	}
}

/* compute the log2 of the downscale factor needed to get closest
 * to the requested viewfinder resolution on the upper side. The output cannot
 * be smaller than the requested viewfinder resolution.
 */
int
sh_css_vf_downscale_log2(
    const struct ia_css_frame_info *out_info,
    const struct ia_css_frame_info *vf_info,
    unsigned int *downscale_log2) {
	unsigned int ds_log2 = 0;
	unsigned int out_width;

	if ((!out_info) || (!vf_info))
		return -EINVAL;

	out_width = out_info->res.width;

	if (out_width == 0)
		return -EINVAL;

	/* downscale until width smaller than the viewfinder width. We don't
	* test for the height since the vmem buffers only put restrictions on
	* the width of a line, not on the number of lines in a frame.
	*/
	while (out_width >= vf_info->res.width)
	{
		ds_log2++;
		out_width /= 2;
	}
	/* now width is smaller, so we go up one step */
	if ((ds_log2 > 0) && (out_width < ia_css_binary_max_vf_width()))
		ds_log2--;
	/* TODO: use actual max input resolution of vf_pp binary */
	if ((out_info->res.width >> ds_log2) >= 2 * ia_css_binary_max_vf_width())
		return -EINVAL;
	*downscale_log2 = ds_log2;
	return 0;
}

static int
configure_kernel(
    const struct ia_css_binary_info *info,
    const struct ia_css_frame_info *out_info,
    const struct ia_css_frame_info *vf_info,
    unsigned int *downscale_log2,
    struct ia_css_vf_configuration *config) {
	int err;
	unsigned int vf_log_ds = 0;

	/* First compute value */
	if (vf_info)
	{
		err = sh_css_vf_downscale_log2(out_info, vf_info, &vf_log_ds);
		if (err)
			return err;
	}
	vf_log_ds = min(vf_log_ds, info->vf_dec.max_log_downscale);
	*downscale_log2 = vf_log_ds;

	/* Then store it in isp config section */
	config->vf_downscale_bits = vf_log_ds;
	return 0;
}

static void
configure_dma(
    struct ia_css_vf_configuration *config,
    const struct ia_css_frame_info *vf_info)
{
	config->info = vf_info;
}

int
ia_css_vf_configure(
    const struct ia_css_binary *binary,
    const struct ia_css_frame_info *out_info,
    struct ia_css_frame_info *vf_info,
    unsigned int *downscale_log2) {
	int err;
	struct ia_css_vf_configuration config;
	const struct ia_css_binary_info *info = &binary->info->sp;

	err = configure_kernel(info, out_info, vf_info, downscale_log2, &config);
	if (err)
		dev_warn(atomisp_dev, "Couldn't setup downscale\n");

	configure_dma(&config, vf_info);

	if (vf_info)
		vf_info->raw_bit_depth = info->dma.vfdec_bits_per_pixel;
	ia_css_configure_vf(binary, &config);

	return 0;
}
