RE: [PATCH v3 08/12] intel-ipu3: params: compute and program ccs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi, Sakari,

> -----Original Message-----
> From: Sakari Ailus [mailto:sakari.ailus@xxxxxx]
> Sent: Friday, October 20, 2017 2:58 AM
> To: Zhi, Yong <yong.zhi@xxxxxxxxx>
> Cc: linux-media@xxxxxxxxxxxxxxx; sakari.ailus@xxxxxxxxxxxxxxx; Zheng, Jian
> Xu <jian.xu.zheng@xxxxxxxxx>; Mani, Rajmohan
> <rajmohan.mani@xxxxxxxxx>; Yang, Hyungwoo
> <hyungwoo.yang@xxxxxxxxx>; Hu, Jerry W <jerry.w.hu@xxxxxxxxx>
> Subject: Re: [PATCH v3 08/12] intel-ipu3: params: compute and program ccs
> 
> Hi Yong,
> 
> On Tue, Jul 18, 2017 at 10:13:40PM -0500, Yong Zhi wrote:
> > A collection of routines that are mainly responsible to calculate the
> > acc parameters.
> >
> > Signed-off-by: Yong Zhi <yong.zhi@xxxxxxxxx>
> > ---
> >  drivers/media/pci/intel/ipu3/ipu3-css-params.c | 3114
> > ++++++++++++++++++++++++  drivers/media/pci/intel/ipu3/ipu3-css-
> params.h |  105 +
> >  drivers/media/pci/intel/ipu3/ipu3-css.h        |   92 +
> >  3 files changed, 3311 insertions(+)
> >  create mode 100644 drivers/media/pci/intel/ipu3/ipu3-css-params.c
> >  create mode 100644 drivers/media/pci/intel/ipu3/ipu3-css-params.h
> >
> > diff --git a/drivers/media/pci/intel/ipu3/ipu3-css-params.c
> > b/drivers/media/pci/intel/ipu3/ipu3-css-params.c
> > new file mode 100644
> > index 0000000..4b600bc
> > --- /dev/null
> > +++ b/drivers/media/pci/intel/ipu3/ipu3-css-params.c
> > @@ -0,0 +1,3114 @@
> > +/*
> > + * Copyright (c) 2017 Intel Corporation.
> > + *
> > + * This program is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU General Public License
> > +version
> > + * 2 as published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope that 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 <linux/device.h>
> > +#include <linux/dma-mapping.h>
> > +
> > +#include "ipu3-abi.h"
> > +#include "ipu3-css.h"
> > +#include "ipu3-css-fw.h"
> > +#include "ipu3-css-params.h"
> > +#include "ipu3-tables.h"
> > +
> > +static unsigned int ipu3_css_scaler_get_exp(unsigned int counter,
> > +					    unsigned int divider)
> > +{
> > +	int i = fls(divider) - fls(counter);
> > +
> > +	if (i <= 0)
> > +		return 0;
> > +
> > +	if (divider >> i < counter)
> > +		i = i - 1;
> 
> i--;
> 
> > +
> > +	return i;
> > +}
> > +
> > +/* Set up the CSS scaler look up table */ static void
> > +ipu3_css_scaler_setup_lut(unsigned int taps,
> > +				      unsigned int input_width,
> > +				      unsigned int output_width,
> > +				      int phase_step_correction,
> > +				      const int *coeffs,
> > +				      unsigned int coeffs_size,
> > +				      s8 coeff_lut[IMGU_SCALER_PHASES *
> > +
> IMGU_SCALER_FILTER_TAPS],
> > +				      struct ipu3_css_scaler_info *info) {
> > +	int tap;
> > +	int phase;
> > +	int exponent = ipu3_css_scaler_get_exp(output_width, input_width);
> > +	int mantissa = (1 << exponent) * output_width;
> > +	unsigned int phase_step = 0;
> > +	int phase_sum_left = 0;
> > +	int phase_sum_right = 0;
> > +
> > +	for (phase = 0; phase < IMGU_SCALER_PHASES; phase++) {
> > +		for (tap = 0; tap < taps; tap++) {
> > +			/* flip table to for convolution reverse indexing */
> > +			s64 coeff =  coeffs[coeffs_size -
> > +						((tap * (coeffs_size / taps)) +
> > +						phase) - 1];
> > +			coeff *= mantissa;
> > +			coeff /= input_width;
> 
> Please use do_div() so this will compile on 32-bit machines.
> 

Thanks, above was implemented in v4.

> > +
> > +			/* Add +"0.5" */
> > +			coeff += 1 << (IMGU_SCALER_COEFF_BITS - 1);
> > +			coeff >>= IMGU_SCALER_COEFF_BITS;
> > +
> > +			coeff_lut[phase * IMGU_SCALER_FILTER_TAPS + tap]
> =
> > +				coeff;
> > +		}
> > +	}
> > +
> > +	phase_step = IMGU_SCALER_PHASES *
> > +			(1 << IMGU_SCALER_PHASE_COUNTER_PREC_REF)
> > +			* output_width / input_width;
> > +	phase_step += phase_step_correction;
> > +	phase_sum_left = (taps / 2 * IMGU_SCALER_PHASES *
> > +			(1 << IMGU_SCALER_PHASE_COUNTER_PREC_REF))
> > +			- (1 << (IMGU_SCALER_PHASE_COUNTER_PREC_REF -
> 1));
> > +	phase_sum_right = (taps / 2 * IMGU_SCALER_PHASES *
> > +			(1 << IMGU_SCALER_PHASE_COUNTER_PREC_REF))
> > +			+ (1 << (IMGU_SCALER_PHASE_COUNTER_PREC_REF -
> 1));
> > +
> > +	info->exp_shift = IMGU_SCALER_MAX_EXPONENT_SHIFT - exponent;
> > +	info->pad_left = (phase_sum_left % phase_step == 0) ?
> > +		phase_sum_left / phase_step - 1 : phase_sum_left /
> phase_step;
> > +	info->pad_right = (phase_sum_right % phase_step == 0) ?
> > +		phase_sum_right / phase_step - 1 : phase_sum_right /
> phase_step;
> > +	info->phase_init = phase_sum_left - phase_step * info->pad_left;
> > +	info->phase_step = phase_step;
> > +	info->crop_left = taps - 1;
> > +	info->crop_top = taps - 1;
> > +}
> > +
> > +/*
> > + * Calculates the exact output image width/height, based on
> > +phase_step setting
> > + * (must be perfectly aligned with hardware).
> > + */
> > +static unsigned int ipu3_css_scaler_calc_scaled_output(unsigned int input,
> > +					struct ipu3_css_scaler_info *info) {
> > +	unsigned int arg1 = input * info->phase_step +
> > +		(1 - IMGU_SCALER_TAPS_Y / 2) *
> > +		IMGU_SCALER_FIR_PHASES - IMGU_SCALER_FIR_PHASES
> > +		/ (2 * IMGU_SCALER_PHASES);
> > +	unsigned int arg2 = ((IMGU_SCALER_TAPS_Y / 2) *
> IMGU_SCALER_FIR_PHASES
> > +		+ IMGU_SCALER_FIR_PHASES / (2 * IMGU_SCALER_PHASES))
> > +		* IMGU_SCALER_FIR_PHASES + info->phase_step / 2;
> > +
> > +	return ((arg1 + (arg2 - IMGU_SCALER_FIR_PHASES * info->phase_step)
> > +		/ IMGU_SCALER_FIR_PHASES) / (2 *
> IMGU_SCALER_FIR_PHASES)) * 2; }
> > +
> > +/*
> > + * Calculate the output width and height, given the luma
> > + * and chroma details of a scaler
> > + */
> > +static int ipu3_css_scaler_calc(u32 input_width, u32 input_height,
> > +				u32 target_width, u32 target_height,
> > +				struct ipu3_uapi_osys_config *cfg,
> > +				struct ipu3_css_scaler_info *info_luma,
> > +				struct ipu3_css_scaler_info *info_chroma,
> > +				unsigned int *output_width,
> > +				unsigned int *output_height)
> > +{
> > +	u32 out_width = target_width;
> > +	u32 out_height = target_height;
> > +	unsigned int height_alignment = 2;
> > +	int phase_step_correction = -1;
> > +
> > +	/*
> > +	 * Calculate scaled output width. If the horizontal and vertical scaling
> > +	 * factor is different, then choose the biggest and crop off excess
> > +	 * lines or columns after formatting.
> > +	 */
> > +	if (target_height * input_width > target_width * input_height)
> > +		target_width = DIV_ROUND_UP(target_height * input_width,
> > +			input_height);
> > +
> > +	memset(&cfg->scaler_coeffs_chroma, 0,
> > +		sizeof(cfg->scaler_coeffs_chroma));
> > +	memset(&cfg->scaler_coeffs_luma, 0, sizeof(*cfg-
> >scaler_coeffs_luma));
> > +	do {
> > +		phase_step_correction++;
> > +
> > +		ipu3_css_scaler_setup_lut(IMGU_SCALER_TAPS_Y,
> > +					  input_width, target_width,
> > +					  phase_step_correction,
> > +					  ipu3_css_downscale_4taps,
> > +
> IMGU_SCALER_DOWNSCALE_4TAPS_LEN,
> > +					  cfg->scaler_coeffs_luma, info_luma);
> > +
> > +		ipu3_css_scaler_setup_lut(IMGU_SCALER_TAPS_UV,
> > +					  input_width, target_width,
> > +					  phase_step_correction,
> > +					  ipu3_css_downscale_2taps,
> > +
> IMGU_SCALER_DOWNSCALE_2TAPS_LEN,
> > +					  cfg->scaler_coeffs_chroma,
> > +					  info_chroma);
> > +
> > +		out_width = ipu3_css_scaler_calc_scaled_output(input_width,
> > +							       info_luma);
> > +		out_height =
> ipu3_css_scaler_calc_scaled_output(input_height,
> > +								info_luma);
> > +	} while ((out_width < target_width || out_height < target_height
> > +		  || !IS_ALIGNED(out_height, height_alignment))
> > +		 && phase_step_correction <= 5);
> > +
> > +	*output_width = out_width;
> > +	*output_height = out_height;
> > +
> > +	return 0;
> > +}
> > +
> > +/********************** Osys routines for
> > +scaler*****************************/
> > +
> > +/* FIXME:
> > + * The OSYS formats could be added nicely into table
> > + * "ipu3_css_formats", avoiding the "switch...case" here.
> > + */
> 
> I think the switch below is entirely reasonable, no need for such a comment.
> 

Agree, removed in v4 update. 

> > +static void ipu3_css_osys_set_format(enum imgu_abi_frame_format
> host_format,
> > +				     unsigned int *osys_format,
> > +				     unsigned int *osys_tiling)
> > +{
> > +	*osys_format = IMGU_ABI_OSYS_FORMAT_YUV420;
> > +	*osys_tiling = IMGU_ABI_OSYS_TILING_NONE;
> > +
> > +	switch (host_format) {
> > +	case IMGU_ABI_FRAME_FORMAT_YUV420:
> > +		*osys_format = IMGU_ABI_OSYS_FORMAT_YUV420;
> > +		break;
> > +	case IMGU_ABI_FRAME_FORMAT_YV12:
> > +		*osys_format = IMGU_ABI_OSYS_FORMAT_YV12;
> > +		break;
> > +	case IMGU_ABI_FRAME_FORMAT_NV12:
> > +		*osys_format = IMGU_ABI_OSYS_FORMAT_NV12;
> > +		break;
> > +	case IMGU_ABI_FRAME_FORMAT_NV16:
> > +		*osys_format = IMGU_ABI_OSYS_FORMAT_NV16;
> > +		break;
> > +	case IMGU_ABI_FRAME_FORMAT_NV21:
> > +		*osys_format = IMGU_ABI_OSYS_FORMAT_NV21;
> > +		break;
> > +	case IMGU_ABI_FRAME_FORMAT_NV12_TILEY:
> > +		*osys_format = IMGU_ABI_OSYS_FORMAT_NV12;
> > +		*osys_tiling = IMGU_ABI_OSYS_TILING_Y;
> > +		break;
> > +	default:
> > +		/* For now, assume use default values */
> > +		break;
> > +	}
> > +}
> 
> --
> Sakari Ailus
> e-mail: sakari.ailus@xxxxxx



[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux