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