diff options
Diffstat (limited to 'drivers/staging/media/atomisp/pci/camera')
8 files changed, 1753 insertions, 0 deletions
diff --git a/drivers/staging/media/atomisp/pci/camera/pipe/interface/ia_css_pipe_binarydesc.h b/drivers/staging/media/atomisp/pci/camera/pipe/interface/ia_css_pipe_binarydesc.h new file mode 100644 index 000000000..965cfda50 --- /dev/null +++ b/drivers/staging/media/atomisp/pci/camera/pipe/interface/ia_css_pipe_binarydesc.h @@ -0,0 +1,298 @@ +/* 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. + */ + +#ifndef __IA_CSS_PIPE_BINARYDESC_H__ +#define __IA_CSS_PIPE_BINARYDESC_H__ + +#include <ia_css_types.h> /* ia_css_pipe */ +#include <ia_css_frame_public.h> /* ia_css_frame_info */ +#include <ia_css_binary.h> /* ia_css_binary_descr */ + +/* @brief Get a binary descriptor for copy. + * + * @param[in] pipe + * @param[out] copy_desc + * @param[in/out] in_info + * @param[in/out] out_info + * @param[in/out] vf_info + * @return None + * + */ +void ia_css_pipe_get_copy_binarydesc( + struct ia_css_pipe const *const pipe, + struct ia_css_binary_descr *copy_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *out_info, + struct ia_css_frame_info *vf_info); + +/* @brief Get a binary descriptor for vfpp. + * + * @param[in] pipe + * @param[out] vfpp_descr + * @param[in/out] in_info + * @param[in/out] out_info + * @return None + * + */ +void ia_css_pipe_get_vfpp_binarydesc( + struct ia_css_pipe const *const pipe, + struct ia_css_binary_descr *vf_pp_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *out_info); + +/* @brief Get numerator and denominator of bayer downscaling factor. + * + * @param[in] bds_factor: The bayer downscaling factor. + * (= The bds_factor member in the sh_css_bds_factor structure.) + * @param[out] bds_factor_numerator: The numerator of the bayer downscaling factor. + * (= The numerator member in the sh_css_bds_factor structure.) + * @param[out] bds_factor_denominator: The denominator of the bayer downscaling factor. + * (= The denominator member in the sh_css_bds_factor structure.) + * @return 0 or error code upon error. + * + */ +int sh_css_bds_factor_get_numerator_denominator( + unsigned int bds_factor, + unsigned int *bds_factor_numerator, + unsigned int *bds_factor_denominator); + +/* @brief Get a binary descriptor for preview stage. + * + * @param[in] pipe + * @param[out] preview_descr + * @param[in/out] in_info + * @param[in/out] bds_out_info + * @param[in/out] out_info + * @param[in/out] vf_info + * @return 0 or error code upon error. + * + */ +int ia_css_pipe_get_preview_binarydesc( + struct ia_css_pipe *const pipe, + struct ia_css_binary_descr *preview_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *bds_out_info, + struct ia_css_frame_info *out_info, + struct ia_css_frame_info *vf_info); + +/* @brief Get a binary descriptor for video stage. + * + * @param[in/out] pipe + * @param[out] video_descr + * @param[in/out] in_info + * @param[in/out] bds_out_info + * @param[in/out] vf_info + * @return 0 or error code upon error. + * + */ +int ia_css_pipe_get_video_binarydesc( + struct ia_css_pipe *const pipe, + struct ia_css_binary_descr *video_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *bds_out_info, + struct ia_css_frame_info *out_info, + struct ia_css_frame_info *vf_info, + int stream_config_left_padding); + +/* @brief Get a binary descriptor for yuv scaler stage. + * + * @param[in/out] pipe + * @param[out] yuv_scaler_descr + * @param[in/out] in_info + * @param[in/out] out_info + * @param[in/out] internal_out_info + * @param[in/out] vf_info + * @return None + * + */ +void ia_css_pipe_get_yuvscaler_binarydesc( + struct ia_css_pipe const *const pipe, + struct ia_css_binary_descr *yuv_scaler_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *out_info, + struct ia_css_frame_info *internal_out_info, + struct ia_css_frame_info *vf_info); + +/* @brief Get a binary descriptor for capture pp stage. + * + * @param[in/out] pipe + * @param[out] capture_pp_descr + * @param[in/out] in_info + * @param[in/out] vf_info + * @return None + * + */ +void ia_css_pipe_get_capturepp_binarydesc( + struct ia_css_pipe *const pipe, + struct ia_css_binary_descr *capture_pp_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *out_info, + struct ia_css_frame_info *vf_info); + +/* @brief Get a binary descriptor for primary capture. + * + * @param[in] pipe + * @param[out] prim_descr + * @param[in/out] in_info + * @param[in/out] out_info + * @param[in/out] vf_info + * @return None + * + */ +void ia_css_pipe_get_primary_binarydesc( + struct ia_css_pipe const *const pipe, + struct ia_css_binary_descr *prim_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *out_info, + struct ia_css_frame_info *vf_info, + unsigned int stage_idx); + +/* @brief Get a binary descriptor for pre gdc stage. + * + * @param[in] pipe + * @param[out] pre_gdc_descr + * @param[in/out] in_info + * @param[in/out] out_info + * @return None + * + */ +void ia_css_pipe_get_pre_gdc_binarydesc( + struct ia_css_pipe const *const pipe, + struct ia_css_binary_descr *gdc_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *out_info); + +/* @brief Get a binary descriptor for gdc stage. + * + * @param[in] pipe + * @param[out] gdc_descr + * @param[in/out] in_info + * @param[in/out] out_info + * @return None + * + */ +void ia_css_pipe_get_gdc_binarydesc( + struct ia_css_pipe const *const pipe, + struct ia_css_binary_descr *gdc_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *out_info); + +/* @brief Get a binary descriptor for post gdc. + * + * @param[in] pipe + * @param[out] post_gdc_descr + * @param[in/out] in_info + * @param[in/out] out_info + * @param[in/out] vf_info + * @return None + * + */ +void ia_css_pipe_get_post_gdc_binarydesc( + struct ia_css_pipe const *const pipe, + struct ia_css_binary_descr *post_gdc_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *out_info, + struct ia_css_frame_info *vf_info); + +/* @brief Get a binary descriptor for de. + * + * @param[in] pipe + * @param[out] pre_de_descr + * @param[in/out] in_info + * @param[in/out] out_info + * @return None + * + */ +void ia_css_pipe_get_pre_de_binarydesc( + struct ia_css_pipe const *const pipe, + struct ia_css_binary_descr *pre_de_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *out_info); + +/* @brief Get a binary descriptor for pre anr stage. + * + * @param[in] pipe + * @param[out] pre_anr_descr + * @param[in/out] in_info + * @param[in/out] out_info + * @return None + * + */ +void ia_css_pipe_get_pre_anr_binarydesc( + struct ia_css_pipe const *const pipe, + struct ia_css_binary_descr *pre_anr_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *out_info); + +/* @brief Get a binary descriptor for ANR stage. + * + * @param[in] pipe + * @param[out] anr_descr + * @param[in/out] in_info + * @param[in/out] out_info + * @return None + * + */ +void ia_css_pipe_get_anr_binarydesc( + struct ia_css_pipe const *const pipe, + struct ia_css_binary_descr *anr_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *out_info); + +/* @brief Get a binary descriptor for post anr stage. + * + * @param[in] pipe + * @param[out] post_anr_descr + * @param[in/out] in_info + * @param[in/out] out_info + * @param[in/out] vf_info + * @return None + * + */ +void ia_css_pipe_get_post_anr_binarydesc( + struct ia_css_pipe const *const pipe, + struct ia_css_binary_descr *post_anr_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *out_info, + struct ia_css_frame_info *vf_info); + +/* @brief Get a binary descriptor for ldc stage. + * + * @param[in/out] pipe + * @param[out] capture_pp_descr + * @param[in/out] in_info + * @param[in/out] vf_info + * @return None + * + */ +void ia_css_pipe_get_ldc_binarydesc( + struct ia_css_pipe const *const pipe, + struct ia_css_binary_descr *ldc_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *out_info); + +/* @brief Calculates the required BDS factor + * + * @param[in] input_res + * @param[in] output_res + * @param[in/out] bds_factor + * @return 0 or error code upon error. + */ +int binarydesc_calculate_bds_factor( + struct ia_css_resolution input_res, + struct ia_css_resolution output_res, + unsigned int *bds_factor); + +#endif /* __IA_CSS_PIPE_BINARYDESC_H__ */ diff --git a/drivers/staging/media/atomisp/pci/camera/pipe/interface/ia_css_pipe_stagedesc.h b/drivers/staging/media/atomisp/pci/camera/pipe/interface/ia_css_pipe_stagedesc.h new file mode 100644 index 000000000..40c8145a0 --- /dev/null +++ b/drivers/staging/media/atomisp/pci/camera/pipe/interface/ia_css_pipe_stagedesc.h @@ -0,0 +1,52 @@ +/* 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. + */ + +#ifndef __IA_CSS_PIPE_STAGEDESC_H__ +#define __IA_CSS_PIPE_STAGEDESC_H__ + +#include <ia_css_acc_types.h> /* ia_css_fw_info */ +#include <ia_css_frame_public.h> +#include <ia_css_binary.h> +#include "ia_css_pipeline.h" +#include "ia_css_pipeline_common.h" + +void ia_css_pipe_get_generic_stage_desc( + struct ia_css_pipeline_stage_desc *stage_desc, + struct ia_css_binary *binary, + struct ia_css_frame *out_frame[], + struct ia_css_frame *in_frame, + struct ia_css_frame *vf_frame); + +void ia_css_pipe_get_firmwares_stage_desc( + struct ia_css_pipeline_stage_desc *stage_desc, + struct ia_css_binary *binary, + struct ia_css_frame *out_frame[], + struct ia_css_frame *in_frame, + struct ia_css_frame *vf_frame, + const struct ia_css_fw_info *fw, + unsigned int mode); + +void ia_css_pipe_get_acc_stage_desc( + struct ia_css_pipeline_stage_desc *stage_desc, + struct ia_css_binary *binary, + struct ia_css_fw_info *fw); + +void ia_css_pipe_get_sp_func_stage_desc( + struct ia_css_pipeline_stage_desc *stage_desc, + struct ia_css_frame *out_frame, + enum ia_css_pipeline_stage_sp_func sp_func, + unsigned int max_input_width); + +#endif /*__IA_CSS_PIPE_STAGEDESC__H__ */ diff --git a/drivers/staging/media/atomisp/pci/camera/pipe/interface/ia_css_pipe_util.h b/drivers/staging/media/atomisp/pci/camera/pipe/interface/ia_css_pipe_util.h new file mode 100644 index 000000000..c23d1bd91 --- /dev/null +++ b/drivers/staging/media/atomisp/pci/camera/pipe/interface/ia_css_pipe_util.h @@ -0,0 +1,40 @@ +/* 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. + */ + +#ifndef __IA_CSS_PIPE_UTIL_H__ +#define __IA_CSS_PIPE_UTIL_H__ + +#include <ia_css_types.h> +#include <ia_css_frame_public.h> + +/* @brief Get Input format bits per pixel based on stream configuration of this + * pipe. + * + * @param[in] pipe + * @return bits per pixel for the underlying stream + * + */ +unsigned int ia_css_pipe_util_pipe_input_format_bpp( + const struct ia_css_pipe *const pipe); + +void ia_css_pipe_util_create_output_frames( + struct ia_css_frame *frames[]); + +void ia_css_pipe_util_set_output_frames( + struct ia_css_frame *frames[], + unsigned int idx, + struct ia_css_frame *frame); + +#endif /* __IA_CSS_PIPE_UTIL_H__ */ diff --git a/drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_binarydesc.c b/drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_binarydesc.c new file mode 100644 index 000000000..7dd0e4a53 --- /dev/null +++ b/drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_binarydesc.c @@ -0,0 +1,853 @@ +// 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_pipe_binarydesc.h" +#include "ia_css_frame_format.h" +#include "ia_css_pipe.h" +#include "ia_css_pipe_util.h" +#include "ia_css_util.h" +#include "ia_css_debug.h" +#include "sh_css_params.h" +#include <assert_support.h> +/* HRT_GDC_N */ +#include "gdc_device.h" +#include <linux/kernel.h> + +/* This module provides a binary descriptions to used to find a binary. Since, + * every stage is associated with a binary, it implicity helps stage + * description. Apart from providing a binary description, this module also + * populates the frame info's when required.*/ + +/* Generic descriptor for offline binaries. Internal function. */ +static void pipe_binarydesc_get_offline( + struct ia_css_pipe const *const pipe, + const int mode, + struct ia_css_binary_descr *descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *out_info[], + struct ia_css_frame_info *vf_info) +{ + unsigned int i; + /* in_info, out_info, vf_info can be NULL */ + assert(pipe); + assert(descr); + ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, + "pipe_binarydesc_get_offline() enter:\n"); + + descr->mode = mode; + descr->online = false; + descr->continuous = pipe->stream->config.continuous; + descr->striped = false; + descr->two_ppc = false; + descr->enable_yuv_ds = false; + descr->enable_high_speed = false; + descr->enable_dvs_6axis = false; + descr->enable_reduced_pipe = false; + descr->enable_dz = true; + descr->enable_xnr = false; + descr->enable_dpc = false; + descr->enable_tnr = false; + descr->enable_capture_pp_bli = false; + descr->enable_fractional_ds = false; + descr->dvs_env.width = 0; + descr->dvs_env.height = 0; + descr->stream_format = pipe->stream->config.input_config.format; + descr->in_info = in_info; + descr->bds_out_info = NULL; + for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) + descr->out_info[i] = out_info[i]; + descr->vf_info = vf_info; + descr->isp_pipe_version = pipe->config.isp_pipe_version; + descr->required_bds_factor = SH_CSS_BDS_FACTOR_1_00; + descr->stream_config_left_padding = -1; +} + +void ia_css_pipe_get_copy_binarydesc( + struct ia_css_pipe const *const pipe, + struct ia_css_binary_descr *copy_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *out_info, + struct ia_css_frame_info *vf_info) +{ + struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS]; + unsigned int i; + /* out_info can be NULL */ + assert(pipe); + assert(in_info); + IA_CSS_ENTER_PRIVATE(""); + + *in_info = *out_info; + out_infos[0] = out_info; + for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) + out_infos[i] = NULL; + pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_COPY, + copy_descr, in_info, out_infos, vf_info); + copy_descr->online = true; + copy_descr->continuous = false; + copy_descr->two_ppc = (pipe->stream->config.pixels_per_clock == 2); + copy_descr->enable_dz = false; + copy_descr->isp_pipe_version = IA_CSS_PIPE_VERSION_1; + IA_CSS_LEAVE_PRIVATE(""); +} + +void ia_css_pipe_get_vfpp_binarydesc( + struct ia_css_pipe const *const pipe, + struct ia_css_binary_descr *vf_pp_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *out_info) +{ + struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS]; + unsigned int i; + /* out_info can be NULL ??? */ + assert(pipe); + assert(in_info); + IA_CSS_ENTER_PRIVATE(""); + + in_info->raw_bit_depth = 0; + out_infos[0] = out_info; + for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) + out_infos[i] = NULL; + + pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_VF_PP, + vf_pp_descr, in_info, out_infos, NULL); + vf_pp_descr->enable_fractional_ds = true; + IA_CSS_LEAVE_PRIVATE(""); +} + +static struct sh_css_bds_factor bds_factors_list[] = { + {1, 1, SH_CSS_BDS_FACTOR_1_00}, + {5, 4, SH_CSS_BDS_FACTOR_1_25}, + {3, 2, SH_CSS_BDS_FACTOR_1_50}, + {2, 1, SH_CSS_BDS_FACTOR_2_00}, + {9, 4, SH_CSS_BDS_FACTOR_2_25}, + {5, 2, SH_CSS_BDS_FACTOR_2_50}, + {3, 1, SH_CSS_BDS_FACTOR_3_00}, + {4, 1, SH_CSS_BDS_FACTOR_4_00}, + {9, 2, SH_CSS_BDS_FACTOR_4_50}, + {5, 1, SH_CSS_BDS_FACTOR_5_00}, + {6, 1, SH_CSS_BDS_FACTOR_6_00}, + {8, 1, SH_CSS_BDS_FACTOR_8_00} +}; + +int sh_css_bds_factor_get_numerator_denominator( + unsigned int bds_factor, + unsigned int *bds_factor_numerator, + unsigned int *bds_factor_denominator) +{ + unsigned int i; + + /* Loop over all bds factors until a match is found */ + for (i = 0; i < ARRAY_SIZE(bds_factors_list); i++) { + if (bds_factors_list[i].bds_factor == bds_factor) { + *bds_factor_numerator = bds_factors_list[i].numerator; + *bds_factor_denominator = bds_factors_list[i].denominator; + return 0; + } + } + + /* Throw an error since bds_factor cannot be found + in bds_factors_list */ + return -EINVAL; +} + +int binarydesc_calculate_bds_factor( + struct ia_css_resolution input_res, + struct ia_css_resolution output_res, + unsigned int *bds_factor) +{ + unsigned int i; + unsigned int in_w = input_res.width, + in_h = input_res.height, + out_w = output_res.width, out_h = output_res.height; + + unsigned int max_bds_factor = 8; + unsigned int max_rounding_margin = 2; + /* delta in pixels to account for rounding margin in the calculation */ + unsigned int delta = max_bds_factor * max_rounding_margin; + + /* Assert if the resolutions are not set */ + assert(in_w != 0 && in_h != 0); + assert(out_w != 0 && out_h != 0); + + /* Loop over all bds factors until a match is found */ + for (i = 0; i < ARRAY_SIZE(bds_factors_list); i++) { + unsigned int num = bds_factors_list[i].numerator; + unsigned int den = bds_factors_list[i].denominator; + + /* See width-wise and height-wise if this bds_factor + * satisfies the condition */ + bool cond = (out_w * num / den + delta > in_w) && + (out_w * num / den <= in_w) && + (out_h * num / den + delta > in_h) && + (out_h * num / den <= in_h); + + if (cond) { + *bds_factor = bds_factors_list[i].bds_factor; + return 0; + } + } + + /* Throw an error since a suitable bds_factor cannot be found */ + return -EINVAL; +} + +int ia_css_pipe_get_preview_binarydesc( + struct ia_css_pipe *const pipe, + struct ia_css_binary_descr *preview_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *bds_out_info, + struct ia_css_frame_info *out_info, + struct ia_css_frame_info *vf_info) +{ + int err; + struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS]; + int mode = IA_CSS_BINARY_MODE_PREVIEW; + unsigned int i; + + assert(pipe); + assert(in_info); + assert(out_info); + assert(vf_info); + IA_CSS_ENTER_PRIVATE(""); + + /* + * Set up the info of the input frame with + * the ISP required resolution + */ + in_info->res = pipe->config.input_effective_res; + in_info->padded_width = in_info->res.width; + in_info->raw_bit_depth = ia_css_pipe_util_pipe_input_format_bpp(pipe); + + if (ia_css_util_is_input_format_yuv(pipe->stream->config.input_config.format)) + mode = IA_CSS_BINARY_MODE_COPY; + else + in_info->format = IA_CSS_FRAME_FORMAT_RAW; + + out_infos[0] = out_info; + for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) + out_infos[i] = NULL; + + pipe_binarydesc_get_offline(pipe, mode, + preview_descr, in_info, out_infos, vf_info); + if (pipe->stream->config.online) { + preview_descr->online = pipe->stream->config.online; + preview_descr->two_ppc = + (pipe->stream->config.pixels_per_clock == 2); + } + preview_descr->stream_format = pipe->stream->config.input_config.format; + + /* TODO: Remove this when bds_out_info is available! */ + *bds_out_info = *in_info; + + if (pipe->extra_config.enable_raw_binning) { + if (pipe->config.bayer_ds_out_res.width != 0 && + pipe->config.bayer_ds_out_res.height != 0) { + bds_out_info->res.width = + pipe->config.bayer_ds_out_res.width; + bds_out_info->res.height = + pipe->config.bayer_ds_out_res.height; + bds_out_info->padded_width = + pipe->config.bayer_ds_out_res.width; + err = + binarydesc_calculate_bds_factor(in_info->res, + bds_out_info->res, + &preview_descr->required_bds_factor); + if (err) + return err; + } else { + bds_out_info->res.width = in_info->res.width / 2; + bds_out_info->res.height = in_info->res.height / 2; + bds_out_info->padded_width = in_info->padded_width / 2; + preview_descr->required_bds_factor = + SH_CSS_BDS_FACTOR_2_00; + } + } else { + /* TODO: Remove this when bds_out_info->is available! */ + bds_out_info->res.width = in_info->res.width; + bds_out_info->res.height = in_info->res.height; + bds_out_info->padded_width = in_info->padded_width; + preview_descr->required_bds_factor = SH_CSS_BDS_FACTOR_1_00; + } + pipe->required_bds_factor = preview_descr->required_bds_factor; + + /* bayer ds and fractional ds cannot be enabled at the same time, + so we disable bds_out_info when fractional ds is used */ + if (!pipe->extra_config.enable_fractional_ds) + preview_descr->bds_out_info = bds_out_info; + else + preview_descr->bds_out_info = NULL; + /* + ----Preview binary----- + --in-->|--out->|vf_veceven|--|--->vf + ----------------------- + * Preview binary normally doesn't have a vf_port but + * instead it has an output port. However, the output is + * generated by vf_veceven module in which we might have + * a downscaling (by 1x, 2x, or 4x). Because the resolution + * might change, we need two different info, namely out_info + * & vf_info. In fill_binary_info we use out&vf info to + * calculate vf decimation factor. + */ + *out_info = *vf_info; + + /* In case of preview_ds binary, we can do any fractional amount + * of downscale, so there is no DS needed in vf_veceven. Therefore, + * out and vf infos will be the same. Otherwise, we set out resolution + * equal to in resolution. */ + if (!pipe->extra_config.enable_fractional_ds) { + /* TODO: Change this when bds_out_info is available! */ + out_info->res.width = bds_out_info->res.width; + out_info->res.height = bds_out_info->res.height; + out_info->padded_width = bds_out_info->padded_width; + } + preview_descr->enable_fractional_ds = + pipe->extra_config.enable_fractional_ds; + + preview_descr->enable_dpc = pipe->config.enable_dpc; + + preview_descr->isp_pipe_version = pipe->config.isp_pipe_version; + IA_CSS_LEAVE_ERR_PRIVATE(0); + return 0; +} + +int ia_css_pipe_get_video_binarydesc( + struct ia_css_pipe *const pipe, + struct ia_css_binary_descr *video_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *bds_out_info, + struct ia_css_frame_info *out_info, + struct ia_css_frame_info *vf_info, + int stream_config_left_padding) +{ + int mode = IA_CSS_BINARY_MODE_VIDEO; + unsigned int i; + struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS]; + int err = 0; + bool stream_dz_config = false; + + /* vf_info can be NULL */ + assert(pipe); + assert(in_info); + /* assert(vf_info != NULL); */ + IA_CSS_ENTER_PRIVATE(""); + + /* The solution below is not optimal; we should move to using ia_css_pipe_get_copy_binarydesc() + * But for now this fixes things; this code used to be there but was removed + * with gerrit 8908 as this was wrong for Skycam; however 240x still needs this + */ + if (ia_css_util_is_input_format_yuv(pipe->stream->config.input_config.format)) + mode = IA_CSS_BINARY_MODE_COPY; + + in_info->res = pipe->config.input_effective_res; + in_info->padded_width = in_info->res.width; + in_info->format = IA_CSS_FRAME_FORMAT_RAW; + in_info->raw_bit_depth = ia_css_pipe_util_pipe_input_format_bpp(pipe); + out_infos[0] = out_info; + for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) + out_infos[i] = NULL; + + pipe_binarydesc_get_offline(pipe, mode, + video_descr, in_info, out_infos, vf_info); + + if (pipe->stream->config.online) { + video_descr->online = pipe->stream->config.online; + video_descr->two_ppc = + (pipe->stream->config.pixels_per_clock == 2); + } + + if (mode == IA_CSS_BINARY_MODE_VIDEO) { + stream_dz_config = + ((pipe->stream->isp_params_configs->dz_config.dx != + HRT_GDC_N) + || (pipe->stream->isp_params_configs->dz_config.dy != + HRT_GDC_N)); + + video_descr->enable_dz = pipe->config.enable_dz + || stream_dz_config; + video_descr->dvs_env = pipe->config.dvs_envelope; + video_descr->enable_yuv_ds = pipe->extra_config.enable_yuv_ds; + video_descr->enable_high_speed = + pipe->extra_config.enable_high_speed; + video_descr->enable_dvs_6axis = + pipe->extra_config.enable_dvs_6axis; + video_descr->enable_reduced_pipe = + pipe->extra_config.enable_reduced_pipe; + video_descr->isp_pipe_version = pipe->config.isp_pipe_version; + video_descr->enable_fractional_ds = + pipe->extra_config.enable_fractional_ds; + video_descr->enable_dpc = + pipe->config.enable_dpc; + video_descr->enable_tnr = + pipe->config.enable_tnr; + + if (pipe->extra_config.enable_raw_binning) { + if (pipe->config.bayer_ds_out_res.width != 0 && + pipe->config.bayer_ds_out_res.height != 0) { + bds_out_info->res.width = + pipe->config.bayer_ds_out_res.width; + bds_out_info->res.height = + pipe->config.bayer_ds_out_res.height; + bds_out_info->padded_width = + pipe->config.bayer_ds_out_res.width; + err = + binarydesc_calculate_bds_factor( + in_info->res, bds_out_info->res, + &video_descr->required_bds_factor); + if (err) + return err; + } else { + bds_out_info->res.width = + in_info->res.width / 2; + bds_out_info->res.height = + in_info->res.height / 2; + bds_out_info->padded_width = + in_info->padded_width / 2; + video_descr->required_bds_factor = + SH_CSS_BDS_FACTOR_2_00; + } + } else { + bds_out_info->res.width = in_info->res.width; + bds_out_info->res.height = in_info->res.height; + bds_out_info->padded_width = in_info->padded_width; + video_descr->required_bds_factor = + SH_CSS_BDS_FACTOR_1_00; + } + + pipe->required_bds_factor = video_descr->required_bds_factor; + + /* bayer ds and fractional ds cannot be enabled + at the same time, so we disable bds_out_info when + fractional ds is used */ + if (!pipe->extra_config.enable_fractional_ds) + video_descr->bds_out_info = bds_out_info; + else + video_descr->bds_out_info = NULL; + + video_descr->enable_fractional_ds = + pipe->extra_config.enable_fractional_ds; + video_descr->stream_config_left_padding = stream_config_left_padding; + } + IA_CSS_LEAVE_ERR_PRIVATE(err); + return err; +} + +void ia_css_pipe_get_yuvscaler_binarydesc( + struct ia_css_pipe const *const pipe, + struct ia_css_binary_descr *yuv_scaler_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *out_info, + struct ia_css_frame_info *internal_out_info, + struct ia_css_frame_info *vf_info) +{ + struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS]; + struct ia_css_frame_info *this_vf_info = NULL; + + assert(pipe); + assert(in_info); + /* Note: if the following assert fails, the number of ports has been + * changed; in that case an additional initializer must be added + * a few lines below after which this assert can be updated. + */ + assert(IA_CSS_BINARY_MAX_OUTPUT_PORTS == 2); + IA_CSS_ENTER_PRIVATE(""); + + in_info->padded_width = in_info->res.width; + in_info->raw_bit_depth = 0; + ia_css_frame_info_set_width(in_info, in_info->res.width, 0); + out_infos[0] = out_info; + out_infos[1] = internal_out_info; + /* add initializers here if + * assert(IA_CSS_BINARY_MAX_OUTPUT_PORTS == ...); + * fails + */ + + if (vf_info) { + this_vf_info = (vf_info->res.width == 0 && + vf_info->res.height == 0) ? NULL : vf_info; + } + + pipe_binarydesc_get_offline(pipe, + IA_CSS_BINARY_MODE_CAPTURE_PP, + yuv_scaler_descr, + in_info, out_infos, this_vf_info); + + yuv_scaler_descr->enable_fractional_ds = true; + IA_CSS_LEAVE_PRIVATE(""); +} + +void ia_css_pipe_get_capturepp_binarydesc( + struct ia_css_pipe *const pipe, + struct ia_css_binary_descr *capture_pp_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *out_info, + struct ia_css_frame_info *vf_info) +{ + unsigned int i; + struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS]; + + assert(pipe); + assert(in_info); + assert(vf_info); + IA_CSS_ENTER_PRIVATE(""); + + /* the in_info is only used for resolution to enable + bayer down scaling. */ + if (pipe->out_yuv_ds_input_info.res.width) + *in_info = pipe->out_yuv_ds_input_info; + else + *in_info = *out_info; + in_info->format = IA_CSS_FRAME_FORMAT_YUV420; + in_info->raw_bit_depth = 0; + ia_css_frame_info_set_width(in_info, in_info->res.width, 0); + + out_infos[0] = out_info; + for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) + out_infos[i] = NULL; + + pipe_binarydesc_get_offline(pipe, + IA_CSS_BINARY_MODE_CAPTURE_PP, + capture_pp_descr, + in_info, out_infos, vf_info); + + capture_pp_descr->enable_capture_pp_bli = + pipe->config.default_capture_config.enable_capture_pp_bli; + capture_pp_descr->enable_fractional_ds = true; + capture_pp_descr->enable_xnr = + pipe->config.default_capture_config.enable_xnr != 0; + IA_CSS_LEAVE_PRIVATE(""); +} + +/* lookup table for high quality primary binaries */ +static unsigned int primary_hq_binary_modes[NUM_PRIMARY_HQ_STAGES] = { + IA_CSS_BINARY_MODE_PRIMARY_HQ_STAGE0, + IA_CSS_BINARY_MODE_PRIMARY_HQ_STAGE1, + IA_CSS_BINARY_MODE_PRIMARY_HQ_STAGE2, + IA_CSS_BINARY_MODE_PRIMARY_HQ_STAGE3, + IA_CSS_BINARY_MODE_PRIMARY_HQ_STAGE4, + IA_CSS_BINARY_MODE_PRIMARY_HQ_STAGE5 +}; + +void ia_css_pipe_get_primary_binarydesc( + struct ia_css_pipe const *const pipe, + struct ia_css_binary_descr *prim_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *out_info, + struct ia_css_frame_info *vf_info, + unsigned int stage_idx) +{ + enum ia_css_pipe_version pipe_version = pipe->config.isp_pipe_version; + int mode; + unsigned int i; + struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS]; + + assert(pipe); + assert(in_info); + assert(out_info); + assert(stage_idx < NUM_PRIMARY_HQ_STAGES); + /* vf_info can be NULL - example video_binarydescr */ + /*assert(vf_info != NULL);*/ + IA_CSS_ENTER_PRIVATE(""); + + if (pipe_version == IA_CSS_PIPE_VERSION_2_6_1) + mode = primary_hq_binary_modes[stage_idx]; + else + mode = IA_CSS_BINARY_MODE_PRIMARY; + + if (ia_css_util_is_input_format_yuv(pipe->stream->config.input_config.format)) + mode = IA_CSS_BINARY_MODE_COPY; + + in_info->res = pipe->config.input_effective_res; + in_info->padded_width = in_info->res.width; + + if (pipe->stream->config.pack_raw_pixels) + in_info->format = IA_CSS_FRAME_FORMAT_RAW_PACKED; + else + in_info->format = IA_CSS_FRAME_FORMAT_RAW; + + in_info->raw_bit_depth = ia_css_pipe_util_pipe_input_format_bpp(pipe); + out_infos[0] = out_info; + for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) + out_infos[i] = NULL; + + pipe_binarydesc_get_offline(pipe, mode, + prim_descr, in_info, out_infos, vf_info); + + if (pipe->stream->config.online && + pipe->stream->config.mode != IA_CSS_INPUT_MODE_MEMORY) { + prim_descr->online = true; + prim_descr->two_ppc = + (pipe->stream->config.pixels_per_clock == 2); + prim_descr->stream_format = pipe->stream->config.input_config.format; + } + if (mode == IA_CSS_BINARY_MODE_PRIMARY) { + prim_descr->isp_pipe_version = pipe->config.isp_pipe_version; + prim_descr->enable_fractional_ds = + pipe->extra_config.enable_fractional_ds; + /* We have both striped and non-striped primary binaries, + * if continuous viewfinder is required, then we must select + * a striped one. Otherwise we prefer to use a non-striped + * since it has better performance. */ + if (pipe_version == IA_CSS_PIPE_VERSION_2_6_1) + prim_descr->striped = false; + else + prim_descr->striped = prim_descr->continuous && + (!pipe->stream->stop_copy_preview || !pipe->stream->disable_cont_vf); + } + IA_CSS_LEAVE_PRIVATE(""); +} + +void ia_css_pipe_get_pre_gdc_binarydesc( + struct ia_css_pipe const *const pipe, + struct ia_css_binary_descr *pre_gdc_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *out_info) +{ + unsigned int i; + struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS]; + + assert(pipe); + assert(in_info); + assert(out_info); + IA_CSS_ENTER_PRIVATE(""); + + *in_info = *out_info; + in_info->format = IA_CSS_FRAME_FORMAT_RAW; + in_info->raw_bit_depth = ia_css_pipe_util_pipe_input_format_bpp(pipe); + out_infos[0] = out_info; + for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) + out_infos[i] = NULL; + + pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_PRE_ISP, + pre_gdc_descr, in_info, out_infos, NULL); + pre_gdc_descr->isp_pipe_version = pipe->config.isp_pipe_version; + IA_CSS_LEAVE_PRIVATE(""); +} + +void ia_css_pipe_get_gdc_binarydesc( + struct ia_css_pipe const *const pipe, + struct ia_css_binary_descr *gdc_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *out_info) +{ + unsigned int i; + struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS]; + + assert(pipe); + assert(in_info); + assert(out_info); + IA_CSS_ENTER_PRIVATE(""); + + *in_info = *out_info; + in_info->format = IA_CSS_FRAME_FORMAT_QPLANE6; + out_infos[0] = out_info; + for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) + out_infos[i] = NULL; + + pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_GDC, + gdc_descr, in_info, out_infos, NULL); + IA_CSS_LEAVE_PRIVATE(""); +} + +void ia_css_pipe_get_post_gdc_binarydesc( + struct ia_css_pipe const *const pipe, + struct ia_css_binary_descr *post_gdc_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *out_info, + struct ia_css_frame_info *vf_info) +{ + unsigned int i; + struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS]; + + assert(pipe); + assert(in_info); + assert(out_info); + assert(vf_info); + IA_CSS_ENTER_PRIVATE(""); + + *in_info = *out_info; + in_info->format = IA_CSS_FRAME_FORMAT_YUV420_16; + in_info->raw_bit_depth = 16; + out_infos[0] = out_info; + for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) + out_infos[i] = NULL; + + pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_POST_ISP, + post_gdc_descr, in_info, out_infos, vf_info); + + post_gdc_descr->isp_pipe_version = pipe->config.isp_pipe_version; + IA_CSS_LEAVE_PRIVATE(""); +} + +void ia_css_pipe_get_pre_de_binarydesc( + struct ia_css_pipe const *const pipe, + struct ia_css_binary_descr *pre_de_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *out_info) +{ + unsigned int i; + struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS]; + + assert(pipe); + assert(in_info); + assert(out_info); + IA_CSS_ENTER_PRIVATE(""); + + *in_info = *out_info; + in_info->format = IA_CSS_FRAME_FORMAT_RAW; + in_info->raw_bit_depth = ia_css_pipe_util_pipe_input_format_bpp(pipe); + out_infos[0] = out_info; + for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) + out_infos[i] = NULL; + + if (pipe->config.isp_pipe_version == IA_CSS_PIPE_VERSION_1) + pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_PRE_ISP, + pre_de_descr, in_info, out_infos, NULL); + else if (pipe->config.isp_pipe_version == IA_CSS_PIPE_VERSION_2_2) { + pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_PRE_DE, + pre_de_descr, in_info, out_infos, NULL); + } + + if (pipe->stream->config.online) { + pre_de_descr->online = true; + pre_de_descr->two_ppc = + (pipe->stream->config.pixels_per_clock == 2); + pre_de_descr->stream_format = pipe->stream->config.input_config.format; + } + pre_de_descr->isp_pipe_version = pipe->config.isp_pipe_version; + IA_CSS_LEAVE_PRIVATE(""); +} + +void ia_css_pipe_get_pre_anr_binarydesc( + struct ia_css_pipe const *const pipe, + struct ia_css_binary_descr *pre_anr_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *out_info) +{ + unsigned int i; + struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS]; + + assert(pipe); + assert(in_info); + assert(out_info); + IA_CSS_ENTER_PRIVATE(""); + + *in_info = *out_info; + in_info->format = IA_CSS_FRAME_FORMAT_RAW; + in_info->raw_bit_depth = ia_css_pipe_util_pipe_input_format_bpp(pipe); + out_infos[0] = out_info; + for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) + out_infos[i] = NULL; + + pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_PRE_ISP, + pre_anr_descr, in_info, out_infos, NULL); + + if (pipe->stream->config.online) { + pre_anr_descr->online = true; + pre_anr_descr->two_ppc = + (pipe->stream->config.pixels_per_clock == 2); + pre_anr_descr->stream_format = pipe->stream->config.input_config.format; + } + pre_anr_descr->isp_pipe_version = pipe->config.isp_pipe_version; + IA_CSS_LEAVE_PRIVATE(""); +} + +void ia_css_pipe_get_anr_binarydesc( + struct ia_css_pipe const *const pipe, + struct ia_css_binary_descr *anr_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *out_info) +{ + unsigned int i; + struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS]; + + assert(pipe); + assert(in_info); + assert(out_info); + IA_CSS_ENTER_PRIVATE(""); + + *in_info = *out_info; + in_info->format = IA_CSS_FRAME_FORMAT_RAW; + in_info->raw_bit_depth = ANR_ELEMENT_BITS; + out_infos[0] = out_info; + for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) + out_infos[i] = NULL; + + pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_ANR, + anr_descr, in_info, out_infos, NULL); + + anr_descr->isp_pipe_version = pipe->config.isp_pipe_version; + IA_CSS_LEAVE_PRIVATE(""); +} + +void ia_css_pipe_get_post_anr_binarydesc( + struct ia_css_pipe const *const pipe, + struct ia_css_binary_descr *post_anr_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *out_info, + struct ia_css_frame_info *vf_info) +{ + unsigned int i; + struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS]; + + assert(pipe); + assert(in_info); + assert(out_info); + assert(vf_info); + IA_CSS_ENTER_PRIVATE(""); + + *in_info = *out_info; + in_info->format = IA_CSS_FRAME_FORMAT_RAW; + in_info->raw_bit_depth = ANR_ELEMENT_BITS; + out_infos[0] = out_info; + for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) + out_infos[i] = NULL; + + pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_POST_ISP, + post_anr_descr, in_info, out_infos, vf_info); + + post_anr_descr->isp_pipe_version = pipe->config.isp_pipe_version; + IA_CSS_LEAVE_PRIVATE(""); +} + +void ia_css_pipe_get_ldc_binarydesc( + struct ia_css_pipe const *const pipe, + struct ia_css_binary_descr *ldc_descr, + struct ia_css_frame_info *in_info, + struct ia_css_frame_info *out_info) +{ + unsigned int i; + struct ia_css_frame_info *out_infos[IA_CSS_BINARY_MAX_OUTPUT_PORTS]; + + assert(pipe); + assert(in_info); + assert(out_info); + IA_CSS_ENTER_PRIVATE(""); + + *in_info = *out_info; + + in_info->format = IA_CSS_FRAME_FORMAT_YUV420; + in_info->raw_bit_depth = 0; + ia_css_frame_info_set_width(in_info, in_info->res.width, 0); + + out_infos[0] = out_info; + for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) + out_infos[i] = NULL; + + pipe_binarydesc_get_offline(pipe, IA_CSS_BINARY_MODE_CAPTURE_PP, + ldc_descr, in_info, out_infos, NULL); + ldc_descr->enable_dvs_6axis = + pipe->extra_config.enable_dvs_6axis; + IA_CSS_LEAVE_PRIVATE(""); +} diff --git a/drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_stagedesc.c b/drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_stagedesc.c new file mode 100644 index 000000000..82a24aabe --- /dev/null +++ b/drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_stagedesc.c @@ -0,0 +1,119 @@ +// 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_pipe_stagedesc.h" +#include "assert_support.h" +#include "ia_css_debug.h" + +void ia_css_pipe_get_generic_stage_desc( + struct ia_css_pipeline_stage_desc *stage_desc, + struct ia_css_binary *binary, + struct ia_css_frame *out_frame[], + struct ia_css_frame *in_frame, + struct ia_css_frame *vf_frame) +{ + unsigned int i; + + IA_CSS_ENTER_PRIVATE("stage_desc = %p, binary = %p, out_frame = %p, in_frame = %p, vf_frame = %p", + stage_desc, binary, out_frame, in_frame, vf_frame); + + assert(stage_desc && binary && binary->info); + if (!stage_desc || !binary || !binary->info) { + IA_CSS_ERROR("invalid arguments"); + goto ERR; + } + + stage_desc->binary = binary; + stage_desc->firmware = NULL; + stage_desc->sp_func = IA_CSS_PIPELINE_NO_FUNC; + stage_desc->max_input_width = 0; + stage_desc->mode = binary->info->sp.pipeline.mode; + stage_desc->in_frame = in_frame; + for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) { + stage_desc->out_frame[i] = out_frame[i]; + } + stage_desc->vf_frame = vf_frame; +ERR: + IA_CSS_LEAVE_PRIVATE(""); +} + +void ia_css_pipe_get_firmwares_stage_desc( + struct ia_css_pipeline_stage_desc *stage_desc, + struct ia_css_binary *binary, + struct ia_css_frame *out_frame[], + struct ia_css_frame *in_frame, + struct ia_css_frame *vf_frame, + const struct ia_css_fw_info *fw, + unsigned int mode) +{ + unsigned int i; + + ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, + "ia_css_pipe_get_firmwares_stage_desc() enter:\n"); + stage_desc->binary = binary; + stage_desc->firmware = fw; + stage_desc->sp_func = IA_CSS_PIPELINE_NO_FUNC; + stage_desc->max_input_width = 0; + stage_desc->mode = mode; + stage_desc->in_frame = in_frame; + for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) { + stage_desc->out_frame[i] = out_frame[i]; + } + stage_desc->vf_frame = vf_frame; +} + +void ia_css_pipe_get_acc_stage_desc( + struct ia_css_pipeline_stage_desc *stage_desc, + struct ia_css_binary *binary, + struct ia_css_fw_info *fw) +{ + unsigned int i; + + ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, + "ia_css_pipe_get_acc_stage_desc() enter:\n"); + stage_desc->binary = binary; + stage_desc->firmware = fw; + stage_desc->sp_func = IA_CSS_PIPELINE_NO_FUNC; + stage_desc->max_input_width = 0; + stage_desc->mode = IA_CSS_BINARY_MODE_VF_PP; + stage_desc->in_frame = NULL; + for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) { + stage_desc->out_frame[i] = NULL; + } + stage_desc->vf_frame = NULL; +} + +void ia_css_pipe_get_sp_func_stage_desc( + struct ia_css_pipeline_stage_desc *stage_desc, + struct ia_css_frame *out_frame, + enum ia_css_pipeline_stage_sp_func sp_func, + unsigned int max_input_width) +{ + unsigned int i; + + ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, + "ia_css_pipe_get_sp_func_stage_desc() enter:\n"); + stage_desc->binary = NULL; + stage_desc->firmware = NULL; + stage_desc->sp_func = sp_func; + stage_desc->max_input_width = max_input_width; + stage_desc->mode = (unsigned int)-1; + stage_desc->in_frame = NULL; + stage_desc->out_frame[0] = out_frame; + for (i = 1; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) { + stage_desc->out_frame[i] = NULL; + } + stage_desc->vf_frame = NULL; +} diff --git a/drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_util.c b/drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_util.c new file mode 100644 index 000000000..03d9d168f --- /dev/null +++ b/drivers/staging/media/atomisp/pci/camera/pipe/src/pipe_util.c @@ -0,0 +1,51 @@ +// 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_pipe_util.h" +#include "ia_css_frame_public.h" +#include "ia_css_pipe.h" +#include "ia_css_util.h" +#include "assert_support.h" + +unsigned int ia_css_pipe_util_pipe_input_format_bpp( + const struct ia_css_pipe *const pipe) +{ + assert(pipe); + assert(pipe->stream); + + return ia_css_util_input_format_bpp(pipe->stream->config.input_config.format, + pipe->stream->config.pixels_per_clock == 2); +} + +void ia_css_pipe_util_create_output_frames( + struct ia_css_frame *frames[]) +{ + unsigned int i; + + assert(frames); + for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) { + frames[i] = NULL; + } +} + +void ia_css_pipe_util_set_output_frames( + struct ia_css_frame *frames[], + unsigned int idx, + struct ia_css_frame *frame) +{ + assert(idx < IA_CSS_BINARY_MAX_OUTPUT_PORTS); + + frames[idx] = frame; +} diff --git a/drivers/staging/media/atomisp/pci/camera/util/interface/ia_css_util.h b/drivers/staging/media/atomisp/pci/camera/util/interface/ia_css_util.h new file mode 100644 index 000000000..59df44d69 --- /dev/null +++ b/drivers/staging/media/atomisp/pci/camera/util/interface/ia_css_util.h @@ -0,0 +1,143 @@ +/* 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. + */ + +#ifndef __IA_CSS_UTIL_H__ +#define __IA_CSS_UTIL_H__ + +#include <linux/errno.h> + +#include <ia_css_err.h> +#include <type_support.h> +#include <ia_css_frame_public.h> +#include <ia_css_stream_public.h> +#include <ia_css_stream_format.h> + +/* @brief convert "errno" error code to "ia_css_err" error code + * + * @param[in] "errno" error code + * @return "ia_css_err" error code + * + */ +int ia_css_convert_errno( + int in_err); + +/* @brief check vf frame info. + * + * @param[in] info + * @return 0 or error code upon error. + * + */ +int ia_css_util_check_vf_info( + const struct ia_css_frame_info *const info); + +/* @brief check input configuration. + * + * @param[in] stream_config + * @param[in] must_be_raw + * @return 0 or error code upon error. + * + */ +int ia_css_util_check_input( + const struct ia_css_stream_config *const stream_config, + bool must_be_raw, + bool must_be_yuv); + +/* @brief check vf and out frame info. + * + * @param[in] out_info + * @param[in] vf_info + * @return 0 or error code upon error. + * + */ +int ia_css_util_check_vf_out_info( + const struct ia_css_frame_info *const out_info, + const struct ia_css_frame_info *const vf_info); + +/* @brief check width and height + * + * @param[in] width + * @param[in] height + * @return 0 or error code upon error. + * + */ +int ia_css_util_check_res( + unsigned int width, + unsigned int height); + +/* ISP2401 */ +/* @brief compare resolutions (less or equal) + * + * @param[in] a resolution + * @param[in] b resolution + * @return true if both dimensions of a are less or + * equal than those of b, false otherwise + * + */ +bool ia_css_util_res_leq( + struct ia_css_resolution a, + struct ia_css_resolution b); + +/* ISP2401 */ +/** + * @brief Check if resolution is zero + * + * @param[in] resolution The resolution to check + * + * @returns true if resolution is zero + */ +bool ia_css_util_resolution_is_zero( + const struct ia_css_resolution resolution); + +/* ISP2401 */ +/** + * @brief Check if resolution is even + * + * @param[in] resolution The resolution to check + * + * @returns true if resolution is even + */ +bool ia_css_util_resolution_is_even( + const struct ia_css_resolution resolution); + +/* @brief check width and height + * + * @param[in] stream_format + * @param[in] two_ppc + * @return bits per pixel based on given parameters. + * + */ +unsigned int ia_css_util_input_format_bpp( + enum atomisp_input_format stream_format, + bool two_ppc); + +/* @brief check if input format it raw + * + * @param[in] stream_format + * @return true if the input format is raw or false otherwise + * + */ +bool ia_css_util_is_input_format_raw( + enum atomisp_input_format stream_format); + +/* @brief check if input format it yuv + * + * @param[in] stream_format + * @return true if the input format is yuv or false otherwise + * + */ +bool ia_css_util_is_input_format_yuv( + enum atomisp_input_format stream_format); + +#endif /* __IA_CSS_UTIL_H__ */ diff --git a/drivers/staging/media/atomisp/pci/camera/util/src/util.c b/drivers/staging/media/atomisp/pci/camera/util/src/util.c new file mode 100644 index 000000000..40a71e37c --- /dev/null +++ b/drivers/staging/media/atomisp/pci/camera/util/src/util.c @@ -0,0 +1,197 @@ +// 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_util.h" +#include <ia_css_frame.h> +#include <assert_support.h> +#include <math_support.h> + +/* for ia_css_binary_max_vf_width() */ +#include "ia_css_binary.h" + +/* MW: Table look-up ??? */ +unsigned int ia_css_util_input_format_bpp( + enum atomisp_input_format format, + bool two_ppc) +{ + unsigned int rval = 0; + + switch (format) { + case ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY: + case ATOMISP_INPUT_FORMAT_YUV420_8: + case ATOMISP_INPUT_FORMAT_YUV422_8: + case ATOMISP_INPUT_FORMAT_RGB_888: + case ATOMISP_INPUT_FORMAT_RAW_8: + case ATOMISP_INPUT_FORMAT_BINARY_8: + case ATOMISP_INPUT_FORMAT_EMBEDDED: + rval = 8; + break; + case ATOMISP_INPUT_FORMAT_YUV420_10: + case ATOMISP_INPUT_FORMAT_YUV422_10: + case ATOMISP_INPUT_FORMAT_RAW_10: + rval = 10; + break; + case ATOMISP_INPUT_FORMAT_YUV420_16: + case ATOMISP_INPUT_FORMAT_YUV422_16: + rval = 16; + break; + case ATOMISP_INPUT_FORMAT_RGB_444: + rval = 4; + break; + case ATOMISP_INPUT_FORMAT_RGB_555: + rval = 5; + break; + case ATOMISP_INPUT_FORMAT_RGB_565: + rval = 65; + break; + case ATOMISP_INPUT_FORMAT_RGB_666: + case ATOMISP_INPUT_FORMAT_RAW_6: + rval = 6; + break; + case ATOMISP_INPUT_FORMAT_RAW_7: + rval = 7; + break; + case ATOMISP_INPUT_FORMAT_RAW_12: + rval = 12; + break; + case ATOMISP_INPUT_FORMAT_RAW_14: + if (two_ppc) + rval = 14; + else + rval = 12; + break; + case ATOMISP_INPUT_FORMAT_RAW_16: + if (two_ppc) + rval = 16; + else + rval = 12; + break; + default: + rval = 0; + break; + } + return rval; +} + +int ia_css_util_check_vf_info( + const struct ia_css_frame_info *const info) +{ + int err; + unsigned int max_vf_width; + + assert(info); + err = ia_css_frame_check_info(info); + if (err) + return err; + max_vf_width = ia_css_binary_max_vf_width(); + if (max_vf_width != 0 && info->res.width > max_vf_width * 2) + return -EINVAL; + return 0; +} + +int ia_css_util_check_vf_out_info( + const struct ia_css_frame_info *const out_info, + const struct ia_css_frame_info *const vf_info) +{ + int err; + + assert(out_info); + assert(vf_info); + + err = ia_css_frame_check_info(out_info); + if (err) + return err; + err = ia_css_util_check_vf_info(vf_info); + if (err) + return err; + return 0; +} + +int ia_css_util_check_res(unsigned int width, unsigned int height) +{ + /* height can be odd number for jpeg/embedded data from ISYS2401 */ + if (((width == 0) || + (height == 0) || + IS_ODD(width))) { + return -EINVAL; + } + return 0; +} + +/* ISP2401 */ +bool ia_css_util_res_leq(struct ia_css_resolution a, struct ia_css_resolution b) +{ + return a.width <= b.width && a.height <= b.height; +} + +/* ISP2401 */ +bool ia_css_util_resolution_is_zero(const struct ia_css_resolution resolution) +{ + return (resolution.width == 0) || (resolution.height == 0); +} + +/* ISP2401 */ +bool ia_css_util_resolution_is_even(const struct ia_css_resolution resolution) +{ + return IS_EVEN(resolution.height) && IS_EVEN(resolution.width); +} + +bool ia_css_util_is_input_format_raw(enum atomisp_input_format format) +{ + return ((format == ATOMISP_INPUT_FORMAT_RAW_6) || + (format == ATOMISP_INPUT_FORMAT_RAW_7) || + (format == ATOMISP_INPUT_FORMAT_RAW_8) || + (format == ATOMISP_INPUT_FORMAT_RAW_10) || + (format == ATOMISP_INPUT_FORMAT_RAW_12)); + /* raw_14 and raw_16 are not supported as input formats to the ISP. + * They can only be copied to a frame in memory using the + * copy binary. + */ +} + +bool ia_css_util_is_input_format_yuv(enum atomisp_input_format format) +{ + return format == ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY || + format == ATOMISP_INPUT_FORMAT_YUV420_8 || + format == ATOMISP_INPUT_FORMAT_YUV420_10 || + format == ATOMISP_INPUT_FORMAT_YUV420_16 || + format == ATOMISP_INPUT_FORMAT_YUV422_8 || + format == ATOMISP_INPUT_FORMAT_YUV422_10 || + format == ATOMISP_INPUT_FORMAT_YUV422_16; +} + +int ia_css_util_check_input( + const struct ia_css_stream_config *const stream_config, + bool must_be_raw, + bool must_be_yuv) +{ + assert(stream_config); + + if (!stream_config) + return -EINVAL; + + if (stream_config->input_config.effective_res.width == 0 || + stream_config->input_config.effective_res.height == 0) + return -EINVAL; + if (must_be_raw && + !ia_css_util_is_input_format_raw(stream_config->input_config.format)) + return -EINVAL; + + if (must_be_yuv && + !ia_css_util_is_input_format_yuv(stream_config->input_config.format)) + return -EINVAL; + + return 0; +} |