linux/drivers/staging/media/atomisp/pci/atomisp2/css2400/runtime/binary/src/binary.c
<<
>>
Prefs
   1/*
   2 * Support for Intel Camera Imaging ISP subsystem.
   3 * Copyright (c) 2015, Intel Corporation.
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms and conditions of the GNU General Public License,
   7 * version 2, as published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope it will be useful, but WITHOUT
  10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  12 * more details.
  13 */
  14
  15#include <math_support.h>
  16#include <gdc_device.h> /* HR_GDC_N */
  17#include "isp.h"        /* ISP_VEC_NELEMS */
  18
  19#include "ia_css_binary.h"
  20#include "ia_css_debug.h"
  21#include "ia_css_util.h"
  22#include "ia_css_isp_param.h"
  23#include "sh_css_internal.h"
  24#include "sh_css_sp.h"
  25#include "sh_css_firmware.h"
  26#include "sh_css_defs.h"
  27#include "sh_css_legacy.h"
  28
  29#include "vf/vf_1.0/ia_css_vf.host.h"
  30#ifdef ISP2401
  31#include "sc/sc_1.0/ia_css_sc.host.h"
  32#endif
  33#include "sdis/sdis_1.0/ia_css_sdis.host.h"
  34#ifdef ISP2401
  35#include "fixedbds/fixedbds_1.0/ia_css_fixedbds_param.h"        /* FRAC_ACC */
  36#endif
  37
  38#include "camera/pipe/interface/ia_css_pipe_binarydesc.h"
  39
  40#include "memory_access.h"
  41
  42#include "assert_support.h"
  43
  44#define IMPLIES(a, b)           (!(a) || (b))   /* A => B */
  45
  46static struct ia_css_binary_xinfo *all_binaries; /* ISP binaries only (no SP) */
  47static struct ia_css_binary_xinfo
  48        *binary_infos[IA_CSS_BINARY_NUM_MODES] = { NULL, };
  49
  50static void
  51ia_css_binary_dvs_env(const struct ia_css_binary_info *info,
  52                      const struct ia_css_resolution *dvs_env,
  53                      struct ia_css_resolution *binary_dvs_env)
  54{
  55        if (info->enable.dvs_envelope) {
  56                assert(dvs_env != NULL);
  57                binary_dvs_env->width  = max(dvs_env->width, SH_CSS_MIN_DVS_ENVELOPE);
  58                binary_dvs_env->height = max(dvs_env->height, SH_CSS_MIN_DVS_ENVELOPE);
  59        }
  60}
  61
  62static void
  63ia_css_binary_internal_res(const struct ia_css_frame_info *in_info,
  64                           const struct ia_css_frame_info *bds_out_info,
  65                           const struct ia_css_frame_info *out_info,
  66                           const struct ia_css_resolution *dvs_env,
  67                           const struct ia_css_binary_info *info,
  68                           struct ia_css_resolution *internal_res)
  69{
  70        unsigned int isp_tmp_internal_width = 0,
  71                     isp_tmp_internal_height = 0;
  72        bool binary_supports_yuv_ds = info->enable.ds & 2;
  73        struct ia_css_resolution binary_dvs_env;
  74
  75        binary_dvs_env.width = 0;
  76        binary_dvs_env.height = 0;
  77        ia_css_binary_dvs_env(info, dvs_env, &binary_dvs_env);
  78
  79        if (binary_supports_yuv_ds) {
  80                if (in_info != NULL) {
  81                        isp_tmp_internal_width = in_info->res.width
  82                                + info->pipeline.left_cropping + binary_dvs_env.width;
  83                        isp_tmp_internal_height = in_info->res.height
  84                                + info->pipeline.top_cropping + binary_dvs_env.height;
  85                }
  86        } else if ((bds_out_info != NULL) && (out_info != NULL) &&
  87                                /* TODO: hack to make video_us case work. this should be reverted after
  88                                a nice solution in ISP */
  89                                (bds_out_info->res.width >= out_info->res.width)) {
  90                        isp_tmp_internal_width = bds_out_info->padded_width;
  91                        isp_tmp_internal_height = bds_out_info->res.height;
  92        } else {
  93                if (out_info != NULL) {
  94                        isp_tmp_internal_width = out_info->padded_width;
  95                        isp_tmp_internal_height = out_info->res.height;
  96                }
  97        }
  98
  99        /* We first calculate the resolutions used by the ISP. After that,
 100         * we use those resolutions to compute sizes for tables etc. */
 101        internal_res->width = __ISP_INTERNAL_WIDTH(isp_tmp_internal_width,
 102                (int)binary_dvs_env.width,
 103                info->pipeline.left_cropping, info->pipeline.mode,
 104                info->pipeline.c_subsampling,
 105                info->output.num_chunks, info->pipeline.pipelining);
 106        internal_res->height = __ISP_INTERNAL_HEIGHT(isp_tmp_internal_height,
 107                info->pipeline.top_cropping,
 108                binary_dvs_env.height);
 109}
 110
 111#ifndef ISP2401
 112/* Computation results of the origin coordinate of bayer on the shading table. */
 113struct sh_css_shading_table_bayer_origin_compute_results {
 114        uint32_t bayer_scale_hor_ratio_in;      /* Horizontal ratio (in) of bayer scaling. */
 115        uint32_t bayer_scale_hor_ratio_out;     /* Horizontal ratio (out) of bayer scaling. */
 116        uint32_t bayer_scale_ver_ratio_in;      /* Vertical ratio (in) of bayer scaling. */
 117        uint32_t bayer_scale_ver_ratio_out;     /* Vertical ratio (out) of bayer scaling. */
 118        uint32_t sc_bayer_origin_x_bqs_on_shading_table; /* X coordinate (in bqs) of bayer origin on shading table. */
 119        uint32_t sc_bayer_origin_y_bqs_on_shading_table; /* Y coordinate (in bqs) of bayer origin on shading table. */
 120#else
 121/* Requirements for the shading correction. */
 122struct sh_css_binary_sc_requirements {
 123        /* Bayer scaling factor, for the scaling which is applied before shading correction. */
 124        uint32_t bayer_scale_hor_ratio_in;  /* Horizontal ratio (in) of scaling applied BEFORE shading correction. */
 125        uint32_t bayer_scale_hor_ratio_out; /* Horizontal ratio (out) of scaling applied BEFORE shading correction. */
 126        uint32_t bayer_scale_ver_ratio_in;  /* Vertical ratio (in) of scaling applied BEFORE shading correction. */
 127        uint32_t bayer_scale_ver_ratio_out; /* Vertical ratio (out) of scaling applied BEFORE shading correction. */
 128
 129        /* ISP internal frame is composed of the real sensor data and the padding data. */
 130        uint32_t sensor_data_origin_x_bqs_on_internal; /* X origin (in bqs) of sensor data on internal frame
 131                                                                at shading correction. */
 132        uint32_t sensor_data_origin_y_bqs_on_internal; /* Y origin (in bqs) of sensor data on internal frame
 133                                                                at shading correction. */
 134#endif
 135};
 136
 137/* Get the requirements for the shading correction. */
 138static enum ia_css_err
 139#ifndef ISP2401
 140ia_css_binary_compute_shading_table_bayer_origin(
 141        const struct ia_css_binary *binary,                             /* [in] */
 142        unsigned int required_bds_factor,                               /* [in] */
 143        const struct ia_css_stream_config *stream_config,               /* [in] */
 144        struct sh_css_shading_table_bayer_origin_compute_results *res)  /* [out] */
 145#else
 146sh_css_binary_get_sc_requirements(
 147        const struct ia_css_binary *binary,                     /* [in] */
 148        unsigned int required_bds_factor,                       /* [in] */
 149        const struct ia_css_stream_config *stream_config,       /* [in] */
 150        struct sh_css_binary_sc_requirements *scr)              /* [out] */
 151#endif
 152{
 153        enum ia_css_err err;
 154
 155#ifndef ISP2401
 156        /* Numerator and denominator of the fixed bayer downscaling factor.
 157        (numerator >= denominator) */
 158#else
 159        /* Numerator and denominator of the fixed bayer downscaling factor. (numerator >= denominator) */
 160#endif
 161        unsigned int bds_num, bds_den;
 162
 163#ifndef ISP2401
 164        /* Horizontal/Vertical ratio of bayer scaling
 165        between input area and output area. */
 166        unsigned int bs_hor_ratio_in;
 167        unsigned int bs_hor_ratio_out;
 168        unsigned int bs_ver_ratio_in;
 169        unsigned int bs_ver_ratio_out;
 170#else
 171        /* Horizontal/Vertical ratio of bayer scaling between input area and output area. */
 172        unsigned int bs_hor_ratio_in, bs_hor_ratio_out, bs_ver_ratio_in, bs_ver_ratio_out;
 173#endif
 174
 175        /* Left padding set by InputFormatter. */
 176#ifndef ISP2401
 177        unsigned int left_padding_bqs;                  /* in bqs */
 178#else
 179        unsigned int left_padding_bqs;
 180#endif
 181
 182#ifndef ISP2401
 183        /* Flag for the NEED_BDS_FACTOR_2_00 macro defined in isp kernels. */
 184        unsigned int need_bds_factor_2_00;
 185
 186        /* Left padding adjusted inside the isp. */
 187        unsigned int left_padding_adjusted_bqs;         /* in bqs */
 188
 189        /* Bad pixels caused by filters.
 190        NxN-filter (before/after bayer scaling) moves the image position
 191        to right/bottom directions by a few pixels.
 192        It causes bad pixels at left/top sides,
 193        and effective bayer size decreases. */
 194        unsigned int bad_bqs_on_left_before_bs; /* in bqs */
 195        unsigned int bad_bqs_on_left_after_bs;  /* in bqs */
 196        unsigned int bad_bqs_on_top_before_bs;  /* in bqs */
 197        unsigned int bad_bqs_on_top_after_bs;   /* in bqs */
 198
 199        /* Get the numerator and denominator of bayer downscaling factor. */
 200        err = sh_css_bds_factor_get_numerator_denominator
 201                (required_bds_factor, &bds_num, &bds_den);
 202        if (err != IA_CSS_SUCCESS)
 203#else
 204        /* Flags corresponding to NEED_BDS_FACTOR_2_00/NEED_BDS_FACTOR_1_50/NEED_BDS_FACTOR_1_25 macros
 205         * defined in isp kernels. */
 206        unsigned int need_bds_factor_2_00, need_bds_factor_1_50, need_bds_factor_1_25;
 207
 208        /* Left padding adjusted inside the isp kernels. */
 209        unsigned int left_padding_adjusted_bqs;
 210
 211        /* Top padding padded inside the isp kernel for bayer downscaling binaries. */
 212        unsigned int top_padding_bqs;
 213
 214        /* Bayer downscaling factor 1.0 by fixed-point. */
 215        int bds_frac_acc = FRAC_ACC;    /* FRAC_ACC is defined in ia_css_fixedbds_param.h. */
 216
 217        /* Right/Down shift amount caused by filters applied BEFORE shading corrertion. */
 218        unsigned int right_shift_bqs_before_bs; /* right shift before bayer scaling */
 219        unsigned int right_shift_bqs_after_bs;  /* right shift after bayer scaling */
 220        unsigned int down_shift_bqs_before_bs;  /* down shift before bayer scaling */
 221        unsigned int down_shift_bqs_after_bs;   /* down shift after bayer scaling */
 222
 223        /* Origin of the real sensor data area on the internal frame at shading correction. */
 224        unsigned int sensor_data_origin_x_bqs_on_internal;
 225        unsigned int sensor_data_origin_y_bqs_on_internal;
 226
 227        IA_CSS_ENTER_PRIVATE("binary=%p, required_bds_factor=%d, stream_config=%p",
 228                binary, required_bds_factor, stream_config);
 229
 230        /* Get the numerator and denominator of the required bayer downscaling factor. */
 231        err = sh_css_bds_factor_get_numerator_denominator(required_bds_factor, &bds_num, &bds_den);
 232        if (err != IA_CSS_SUCCESS) {
 233                IA_CSS_LEAVE_ERR_PRIVATE(err);
 234#endif
 235                return err;
 236#ifdef ISP2401
 237        }
 238#endif
 239
 240#ifndef ISP2401
 241        /* Set the horizontal/vertical ratio of bayer scaling
 242        between input area and output area. */
 243#else
 244        IA_CSS_LOG("bds_num=%d, bds_den=%d", bds_num, bds_den);
 245
 246        /* Set the horizontal/vertical ratio of bayer scaling between input area and output area. */
 247#endif
 248        bs_hor_ratio_in  = bds_num;
 249        bs_hor_ratio_out = bds_den;
 250        bs_ver_ratio_in  = bds_num;
 251        bs_ver_ratio_out = bds_den;
 252
 253#ifndef ISP2401
 254        /* Set the left padding set by InputFormatter. (ifmtr.c) */
 255#else
 256        /* Set the left padding set by InputFormatter. (ia_css_ifmtr_configure() in ifmtr.c) */
 257#endif
 258        if (stream_config->left_padding == -1)
 259                left_padding_bqs = _ISP_BQS(binary->left_padding);
 260        else
 261#ifndef ISP2401
 262                left_padding_bqs = (unsigned int)((int)ISP_VEC_NELEMS
 263                        - _ISP_BQS(stream_config->left_padding));
 264#else
 265                left_padding_bqs = (unsigned int)((int)ISP_VEC_NELEMS - _ISP_BQS(stream_config->left_padding));
 266#endif
 267
 268#ifndef ISP2401
 269        /* Set the left padding adjusted inside the isp.
 270        When bds_factor 2.00 is needed, some padding is added to left_padding
 271        inside the isp, before bayer downscaling. (raw.isp.c)
 272        (Hopefully, left_crop/left_padding/top_crop should be defined in css
 273        appropriately, depending on bds_factor.)
 274        */
 275#else
 276        IA_CSS_LOG("stream.left_padding=%d, binary.left_padding=%d, left_padding_bqs=%d",
 277                stream_config->left_padding, binary->left_padding, left_padding_bqs);
 278
 279        /* Set the left padding adjusted inside the isp kernels.
 280         * When the bds_factor isn't 1.00, the left padding size is adjusted inside the isp,
 281         * before bayer downscaling. (scaled_hor_plane_index(), raw_compute_hphase() in raw.isp.c)
 282         */
 283#endif
 284        need_bds_factor_2_00 = ((binary->info->sp.bds.supported_bds_factors &
 285                (PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_2_00) |
 286                 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_2_50) |
 287                 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_3_00) |
 288                 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_4_00) |
 289                 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_4_50) |
 290                 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_5_00) |
 291                 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_6_00) |
 292                 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_8_00))) != 0);
 293
 294#ifndef ISP2401
 295        if (need_bds_factor_2_00 && binary->info->sp.pipeline.left_cropping > 0)
 296                left_padding_adjusted_bqs = left_padding_bqs + ISP_VEC_NELEMS;
 297        else
 298#else
 299        need_bds_factor_1_50 = ((binary->info->sp.bds.supported_bds_factors &
 300                (PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_1_50) |
 301                 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_2_25) |
 302                 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_3_00) |
 303                 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_4_50) |
 304                 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_6_00))) != 0);
 305
 306        need_bds_factor_1_25 = ((binary->info->sp.bds.supported_bds_factors &
 307                (PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_1_25) |
 308                 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_2_50) |
 309                 PACK_BDS_FACTOR(SH_CSS_BDS_FACTOR_5_00))) != 0);
 310
 311        if (binary->info->sp.pipeline.left_cropping > 0 &&
 312            (need_bds_factor_2_00 || need_bds_factor_1_50 || need_bds_factor_1_25)) {
 313                /*
 314                 * downscale 2.0  -> first_vec_adjusted_bqs = 128
 315                 * downscale 1.5  -> first_vec_adjusted_bqs = 96
 316                 * downscale 1.25 -> first_vec_adjusted_bqs = 80
 317                 */
 318                unsigned int first_vec_adjusted_bqs
 319                        = ISP_VEC_NELEMS * bs_hor_ratio_in / bs_hor_ratio_out;
 320                left_padding_adjusted_bqs = first_vec_adjusted_bqs
 321                        - _ISP_BQS(binary->info->sp.pipeline.left_cropping);
 322        } else
 323#endif
 324                left_padding_adjusted_bqs = left_padding_bqs;
 325
 326#ifndef ISP2401
 327        /* Currently, the bad pixel caused by filters before bayer scaling
 328        is NOT considered, because the bad pixel is subtle.
 329        When some large filter is used in the future,
 330        we need to consider the bad pixel.
 331
 332        Currently, when bds_factor isn't 1.00, 3x3 anti-alias filter is applied
 333        to each color plane(Gr/R/B/Gb) before bayer downscaling.
 334        This filter moves each color plane to right/bottom directions
 335        by 1 pixel at the most, depending on downscaling factor.
 336        */
 337        bad_bqs_on_left_before_bs = 0;
 338        bad_bqs_on_top_before_bs = 0;
 339#else
 340        IA_CSS_LOG("supported_bds_factors=%d, need_bds_factor:2_00=%d, 1_50=%d, 1_25=%d",
 341                binary->info->sp.bds.supported_bds_factors,
 342                need_bds_factor_2_00, need_bds_factor_1_50, need_bds_factor_1_25);
 343        IA_CSS_LOG("left_cropping=%d, left_padding_adjusted_bqs=%d",
 344                binary->info->sp.pipeline.left_cropping, left_padding_adjusted_bqs);
 345
 346        /* Set the top padding padded inside the isp kernel for bayer downscaling binaries.
 347         * When the bds_factor isn't 1.00, the top padding is padded inside the isp
 348         * before bayer downscaling, because the top cropping size (input margin) is not enough.
 349         * (calculate_input_line(), raw_compute_vphase(), dma_read_raw() in raw.isp.c)
 350         * NOTE: In dma_read_raw(), the factor passed to raw_compute_vphase() is got by get_bds_factor_for_dma_read().
 351         *       This factor is BDS_FPVAL_100/BDS_FPVAL_125/BDS_FPVAL_150/BDS_FPVAL_200.
 352         */
 353        top_padding_bqs = 0;
 354        if (binary->info->sp.pipeline.top_cropping > 0 &&
 355            (required_bds_factor == SH_CSS_BDS_FACTOR_1_25 ||
 356             required_bds_factor == SH_CSS_BDS_FACTOR_1_50 ||
 357             required_bds_factor == SH_CSS_BDS_FACTOR_2_00)) {
 358                /* Calculation from calculate_input_line() and raw_compute_vphase() in raw.isp.c. */
 359                int top_cropping_bqs = _ISP_BQS(binary->info->sp.pipeline.top_cropping);
 360                                                                /* top cropping (in bqs) */
 361                int factor = bds_num * bds_frac_acc / bds_den;  /* downscaling factor by fixed-point */
 362                int top_padding_bqsxfrac_acc = (top_cropping_bqs * factor - top_cropping_bqs * bds_frac_acc)
 363                                + (2 * bds_frac_acc - factor);  /* top padding by fixed-point (in bqs) */
 364
 365                top_padding_bqs = (unsigned int)((top_padding_bqsxfrac_acc + bds_frac_acc/2 - 1) / bds_frac_acc);
 366        }
 367
 368        IA_CSS_LOG("top_cropping=%d, top_padding_bqs=%d", binary->info->sp.pipeline.top_cropping, top_padding_bqs);
 369
 370        /* Set the right/down shift amount caused by filters applied BEFORE bayer scaling,
 371         * which scaling is applied BEFORE shading corrertion.
 372         *
 373         * When the bds_factor isn't 1.00, 3x3 anti-alias filter is applied to each color plane(Gr/R/B/Gb)
 374         * before bayer downscaling.
 375         * This filter shifts each color plane (Gr/R/B/Gb) to right/down directions by 1 pixel.
 376         */
 377        right_shift_bqs_before_bs = 0;
 378        down_shift_bqs_before_bs = 0;
 379#endif
 380
 381#ifndef ISP2401
 382        /* Currently, the bad pixel caused by filters after bayer scaling
 383        is NOT considered, because the bad pixel is subtle.
 384        When some large filter is used in the future,
 385        we need to consider the bad pixel.
 386
 387        Currently, when DPC&BNR is processed between bayer scaling and
 388        shading correction, DPC&BNR moves each color plane to
 389        right/bottom directions by 1 pixel.
 390        */
 391        bad_bqs_on_left_after_bs = 0;
 392        bad_bqs_on_top_after_bs = 0;
 393#else
 394        if (need_bds_factor_2_00 || need_bds_factor_1_50 || need_bds_factor_1_25) {
 395                right_shift_bqs_before_bs = 1;
 396                down_shift_bqs_before_bs = 1;
 397        }
 398
 399        IA_CSS_LOG("right_shift_bqs_before_bs=%d, down_shift_bqs_before_bs=%d",
 400                right_shift_bqs_before_bs, down_shift_bqs_before_bs);
 401
 402        /* Set the right/down shift amount caused by filters applied AFTER bayer scaling,
 403         * which scaling is applied BEFORE shading corrertion.
 404         *
 405         * When DPC&BNR is processed between bayer scaling and shading correction,
 406         * DPC&BNR moves each color plane (Gr/R/B/Gb) to right/down directions by 1 pixel.
 407         */
 408        right_shift_bqs_after_bs = 0;
 409        down_shift_bqs_after_bs = 0;
 410#endif
 411
 412#ifndef ISP2401
 413        /* Calculate the origin of bayer (real sensor data area)
 414        located on the shading table during the shading correction. */
 415        res->sc_bayer_origin_x_bqs_on_shading_table
 416                = ((left_padding_adjusted_bqs + bad_bqs_on_left_before_bs)
 417                * bs_hor_ratio_out + bs_hor_ratio_in/2) / bs_hor_ratio_in
 418                + bad_bqs_on_left_after_bs;
 419                        /* "+ bs_hor_ratio_in/2": rounding for division by bs_hor_ratio_in */
 420        res->sc_bayer_origin_y_bqs_on_shading_table
 421                = (bad_bqs_on_top_before_bs
 422                * bs_ver_ratio_out + bs_ver_ratio_in/2) / bs_ver_ratio_in
 423                + bad_bqs_on_top_after_bs;
 424                        /* "+ bs_ver_ratio_in/2": rounding for division by bs_ver_ratio_in */
 425
 426        res->bayer_scale_hor_ratio_in  = (uint32_t)bs_hor_ratio_in;
 427        res->bayer_scale_hor_ratio_out = (uint32_t)bs_hor_ratio_out;
 428        res->bayer_scale_ver_ratio_in  = (uint32_t)bs_ver_ratio_in;
 429        res->bayer_scale_ver_ratio_out = (uint32_t)bs_ver_ratio_out;
 430#else
 431        if (binary->info->mem_offsets.offsets.param->dmem.dp.size != 0) { /* if DPC&BNR is enabled in the binary */
 432                right_shift_bqs_after_bs = 1;
 433                down_shift_bqs_after_bs = 1;
 434        }
 435
 436        IA_CSS_LOG("right_shift_bqs_after_bs=%d, down_shift_bqs_after_bs=%d",
 437                right_shift_bqs_after_bs, down_shift_bqs_after_bs);
 438
 439        /* Set the origin of the sensor data area on the internal frame at shading correction. */
 440        {
 441                unsigned int bs_frac = bds_frac_acc;    /* scaling factor 1.0 in fixed point */
 442                unsigned int bs_out, bs_in;             /* scaling ratio in fixed point */
 443
 444                bs_out = bs_hor_ratio_out * bs_frac;
 445                bs_in = bs_hor_ratio_in * bs_frac;
 446                sensor_data_origin_x_bqs_on_internal
 447                        = ((left_padding_adjusted_bqs + right_shift_bqs_before_bs) * bs_out + bs_in/2) / bs_in
 448                                + right_shift_bqs_after_bs;     /* "+ bs_in/2": rounding */
 449
 450                bs_out = bs_ver_ratio_out * bs_frac;
 451                bs_in = bs_ver_ratio_in * bs_frac;
 452                sensor_data_origin_y_bqs_on_internal
 453                        = ((top_padding_bqs + down_shift_bqs_before_bs) * bs_out + bs_in/2) / bs_in
 454                                + down_shift_bqs_after_bs;      /* "+ bs_in/2": rounding */
 455        }
 456
 457        scr->bayer_scale_hor_ratio_in                   = (uint32_t)bs_hor_ratio_in;
 458        scr->bayer_scale_hor_ratio_out                  = (uint32_t)bs_hor_ratio_out;
 459        scr->bayer_scale_ver_ratio_in                   = (uint32_t)bs_ver_ratio_in;
 460        scr->bayer_scale_ver_ratio_out                  = (uint32_t)bs_ver_ratio_out;
 461        scr->sensor_data_origin_x_bqs_on_internal       = (uint32_t)sensor_data_origin_x_bqs_on_internal;
 462        scr->sensor_data_origin_y_bqs_on_internal       = (uint32_t)sensor_data_origin_y_bqs_on_internal;
 463
 464        IA_CSS_LOG("sc_requirements: %d, %d, %d, %d, %d, %d",
 465                scr->bayer_scale_hor_ratio_in, scr->bayer_scale_hor_ratio_out,
 466                scr->bayer_scale_ver_ratio_in, scr->bayer_scale_ver_ratio_out,
 467                scr->sensor_data_origin_x_bqs_on_internal, scr->sensor_data_origin_y_bqs_on_internal);
 468#endif
 469
 470#ifdef ISP2401
 471        IA_CSS_LEAVE_ERR_PRIVATE(err);
 472#endif
 473        return err;
 474}
 475
 476/* Get the shading information of Shading Correction Type 1. */
 477static enum ia_css_err
 478ia_css_binary_get_shading_info_type_1(const struct ia_css_binary *binary,       /* [in] */
 479                        unsigned int required_bds_factor,                       /* [in] */
 480                        const struct ia_css_stream_config *stream_config,       /* [in] */
 481#ifndef ISP2401
 482                        struct ia_css_shading_info *info)                       /* [out] */
 483#else
 484                        struct ia_css_shading_info *shading_info,               /* [out] */
 485                        struct ia_css_pipe_config *pipe_config)                 /* [out] */
 486#endif
 487{
 488        enum ia_css_err err;
 489#ifndef ISP2401
 490        struct sh_css_shading_table_bayer_origin_compute_results res;
 491#else
 492        struct sh_css_binary_sc_requirements scr;
 493#endif
 494
 495#ifndef ISP2401
 496        assert(binary != NULL);
 497        assert(info != NULL);
 498#else
 499        uint32_t in_width_bqs, in_height_bqs, internal_width_bqs, internal_height_bqs;
 500        uint32_t num_hor_grids, num_ver_grids, bqs_per_grid_cell, tbl_width_bqs, tbl_height_bqs;
 501        uint32_t sensor_org_x_bqs_on_internal, sensor_org_y_bqs_on_internal, sensor_width_bqs, sensor_height_bqs;
 502        uint32_t sensor_center_x_bqs_on_internal, sensor_center_y_bqs_on_internal;
 503        uint32_t left, right, upper, lower;
 504        uint32_t adjust_left, adjust_right, adjust_upper, adjust_lower, adjust_width_bqs, adjust_height_bqs;
 505        uint32_t internal_org_x_bqs_on_tbl, internal_org_y_bqs_on_tbl;
 506        uint32_t sensor_org_x_bqs_on_tbl, sensor_org_y_bqs_on_tbl;
 507#endif
 508
 509#ifndef ISP2401
 510        info->type = IA_CSS_SHADING_CORRECTION_TYPE_1;
 511#else
 512        assert(binary != NULL);
 513        assert(stream_config != NULL);
 514        assert(shading_info != NULL);
 515        assert(pipe_config != NULL);
 516#endif
 517
 518#ifndef ISP2401
 519        info->info.type_1.enable            = binary->info->sp.enable.sc;
 520        info->info.type_1.num_hor_grids     = binary->sctbl_width_per_color;
 521        info->info.type_1.num_ver_grids     = binary->sctbl_height;
 522        info->info.type_1.bqs_per_grid_cell = (1 << binary->deci_factor_log2);
 523#else
 524        IA_CSS_ENTER_PRIVATE("binary=%p, required_bds_factor=%d, stream_config=%p",
 525                binary, required_bds_factor, stream_config);
 526#endif
 527
 528        /* Initialize by default values. */
 529#ifndef ISP2401
 530        info->info.type_1.bayer_scale_hor_ratio_in      = 1;
 531        info->info.type_1.bayer_scale_hor_ratio_out     = 1;
 532        info->info.type_1.bayer_scale_ver_ratio_in      = 1;
 533        info->info.type_1.bayer_scale_ver_ratio_out     = 1;
 534        info->info.type_1.sc_bayer_origin_x_bqs_on_shading_table = 0;
 535        info->info.type_1.sc_bayer_origin_y_bqs_on_shading_table = 0;
 536
 537        err = ia_css_binary_compute_shading_table_bayer_origin(
 538                binary,
 539                required_bds_factor,
 540                stream_config,
 541                &res);
 542        if (err != IA_CSS_SUCCESS)
 543#else
 544        *shading_info = DEFAULT_SHADING_INFO_TYPE_1;
 545
 546        err = sh_css_binary_get_sc_requirements(binary, required_bds_factor, stream_config, &scr);
 547        if (err != IA_CSS_SUCCESS) {
 548                IA_CSS_LEAVE_ERR_PRIVATE(err);
 549#endif
 550                return err;
 551#ifdef ISP2401
 552        }
 553
 554        IA_CSS_LOG("binary: id=%d, sctbl=%dx%d, deci=%d",
 555                binary->info->sp.id, binary->sctbl_width_per_color, binary->sctbl_height, binary->deci_factor_log2);
 556        IA_CSS_LOG("binary: in=%dx%d, in_padded_w=%d, int=%dx%d, int_padded_w=%d, out=%dx%d, out_padded_w=%d",
 557                binary->in_frame_info.res.width, binary->in_frame_info.res.height, binary->in_frame_info.padded_width,
 558                binary->internal_frame_info.res.width, binary->internal_frame_info.res.height,
 559                binary->internal_frame_info.padded_width,
 560                binary->out_frame_info[0].res.width, binary->out_frame_info[0].res.height,
 561                binary->out_frame_info[0].padded_width);
 562
 563        /* Set the input size from sensor, which includes left/top crop size. */
 564        in_width_bqs        = _ISP_BQS(binary->in_frame_info.res.width);
 565        in_height_bqs       = _ISP_BQS(binary->in_frame_info.res.height);
 566
 567        /* Frame size internally used in ISP, including sensor data and padding.
 568         * This is the frame size, to which the shading correction is applied.
 569         */
 570        internal_width_bqs  = _ISP_BQS(binary->internal_frame_info.res.width);
 571        internal_height_bqs = _ISP_BQS(binary->internal_frame_info.res.height);
 572
 573        /* Shading table. */
 574        num_hor_grids = binary->sctbl_width_per_color;
 575        num_ver_grids = binary->sctbl_height;
 576        bqs_per_grid_cell = (1 << binary->deci_factor_log2);
 577        tbl_width_bqs  = (num_hor_grids - 1) * bqs_per_grid_cell;
 578        tbl_height_bqs = (num_ver_grids - 1) * bqs_per_grid_cell;
 579#endif
 580
 581#ifndef ISP2401
 582        info->info.type_1.bayer_scale_hor_ratio_in      = res.bayer_scale_hor_ratio_in;
 583        info->info.type_1.bayer_scale_hor_ratio_out     = res.bayer_scale_hor_ratio_out;
 584        info->info.type_1.bayer_scale_ver_ratio_in      = res.bayer_scale_ver_ratio_in;
 585        info->info.type_1.bayer_scale_ver_ratio_out     = res.bayer_scale_ver_ratio_out;
 586        info->info.type_1.sc_bayer_origin_x_bqs_on_shading_table = res.sc_bayer_origin_x_bqs_on_shading_table;
 587        info->info.type_1.sc_bayer_origin_y_bqs_on_shading_table = res.sc_bayer_origin_y_bqs_on_shading_table;
 588#else
 589        IA_CSS_LOG("tbl_width_bqs=%d, tbl_height_bqs=%d", tbl_width_bqs, tbl_height_bqs);
 590#endif
 591
 592#ifdef ISP2401
 593        /* Real sensor data area on the internal frame at shading correction.
 594         * Filters and scaling are applied to the internal frame before shading correction, depending on the binary.
 595         */
 596        sensor_org_x_bqs_on_internal = scr.sensor_data_origin_x_bqs_on_internal;
 597        sensor_org_y_bqs_on_internal = scr.sensor_data_origin_y_bqs_on_internal;
 598        {
 599                unsigned int bs_frac = 8;       /* scaling factor 1.0 in fixed point (8 == FRAC_ACC macro in ISP) */
 600                unsigned int bs_out, bs_in;     /* scaling ratio in fixed point */
 601
 602                bs_out = scr.bayer_scale_hor_ratio_out * bs_frac;
 603                bs_in = scr.bayer_scale_hor_ratio_in * bs_frac;
 604                sensor_width_bqs  = (in_width_bqs * bs_out + bs_in/2) / bs_in; /* "+ bs_in/2": rounding */
 605
 606                bs_out = scr.bayer_scale_ver_ratio_out * bs_frac;
 607                bs_in = scr.bayer_scale_ver_ratio_in * bs_frac;
 608                sensor_height_bqs = (in_height_bqs * bs_out + bs_in/2) / bs_in; /* "+ bs_in/2": rounding */
 609        }
 610
 611        /* Center of the sensor data on the internal frame at shading correction. */
 612        sensor_center_x_bqs_on_internal = sensor_org_x_bqs_on_internal + sensor_width_bqs / 2;
 613        sensor_center_y_bqs_on_internal = sensor_org_y_bqs_on_internal + sensor_height_bqs / 2;
 614
 615        /* Size of left/right/upper/lower sides of the sensor center on the internal frame. */
 616        left  = sensor_center_x_bqs_on_internal;
 617        right = internal_width_bqs - sensor_center_x_bqs_on_internal;
 618        upper = sensor_center_y_bqs_on_internal;
 619        lower = internal_height_bqs - sensor_center_y_bqs_on_internal;
 620
 621        /* Align the size of left/right/upper/lower sides to a multiple of the grid cell size. */
 622        adjust_left  = CEIL_MUL(left,  bqs_per_grid_cell);
 623        adjust_right = CEIL_MUL(right, bqs_per_grid_cell);
 624        adjust_upper = CEIL_MUL(upper, bqs_per_grid_cell);
 625        adjust_lower = CEIL_MUL(lower, bqs_per_grid_cell);
 626
 627        /* Shading table should cover the adjusted frame size. */
 628        adjust_width_bqs  = adjust_left + adjust_right;
 629        adjust_height_bqs = adjust_upper + adjust_lower;
 630
 631        IA_CSS_LOG("adjust_width_bqs=%d, adjust_height_bqs=%d", adjust_width_bqs, adjust_height_bqs);
 632
 633        if (adjust_width_bqs > tbl_width_bqs || adjust_height_bqs > tbl_height_bqs) {
 634                IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INTERNAL_ERROR);
 635                return IA_CSS_ERR_INTERNAL_ERROR;
 636        }
 637
 638        /* Origin of the internal frame on the shading table. */
 639        internal_org_x_bqs_on_tbl = adjust_left - left;
 640        internal_org_y_bqs_on_tbl = adjust_upper - upper;
 641
 642        /* Origin of the real sensor data area on the shading table. */
 643        sensor_org_x_bqs_on_tbl = internal_org_x_bqs_on_tbl + sensor_org_x_bqs_on_internal;
 644        sensor_org_y_bqs_on_tbl = internal_org_y_bqs_on_tbl + sensor_org_y_bqs_on_internal;
 645
 646        /* The shading information necessary as API is stored in the shading_info. */
 647        shading_info->info.type_1.num_hor_grids     = num_hor_grids;
 648        shading_info->info.type_1.num_ver_grids     = num_ver_grids;
 649        shading_info->info.type_1.bqs_per_grid_cell = bqs_per_grid_cell;
 650
 651        shading_info->info.type_1.bayer_scale_hor_ratio_in  = scr.bayer_scale_hor_ratio_in;
 652        shading_info->info.type_1.bayer_scale_hor_ratio_out = scr.bayer_scale_hor_ratio_out;
 653        shading_info->info.type_1.bayer_scale_ver_ratio_in  = scr.bayer_scale_ver_ratio_in;
 654        shading_info->info.type_1.bayer_scale_ver_ratio_out = scr.bayer_scale_ver_ratio_out;
 655
 656        shading_info->info.type_1.isp_input_sensor_data_res_bqs.width  = in_width_bqs;
 657        shading_info->info.type_1.isp_input_sensor_data_res_bqs.height = in_height_bqs;
 658
 659        shading_info->info.type_1.sensor_data_res_bqs.width  = sensor_width_bqs;
 660        shading_info->info.type_1.sensor_data_res_bqs.height = sensor_height_bqs;
 661
 662        shading_info->info.type_1.sensor_data_origin_bqs_on_sctbl.x = (int32_t)sensor_org_x_bqs_on_tbl;
 663        shading_info->info.type_1.sensor_data_origin_bqs_on_sctbl.y = (int32_t)sensor_org_y_bqs_on_tbl;
 664
 665        /* The shading information related to ISP (but, not necessary as API) is stored in the pipe_config. */
 666        pipe_config->internal_frame_origin_bqs_on_sctbl.x = (int32_t)internal_org_x_bqs_on_tbl;
 667        pipe_config->internal_frame_origin_bqs_on_sctbl.y = (int32_t)internal_org_y_bqs_on_tbl;
 668
 669        IA_CSS_LOG("shading_info: grids=%dx%d, cell=%d, scale=%d,%d,%d,%d, input=%dx%d, data=%dx%d, origin=(%d,%d)",
 670                shading_info->info.type_1.num_hor_grids,
 671                shading_info->info.type_1.num_ver_grids,
 672                shading_info->info.type_1.bqs_per_grid_cell,
 673                shading_info->info.type_1.bayer_scale_hor_ratio_in,
 674                shading_info->info.type_1.bayer_scale_hor_ratio_out,
 675                shading_info->info.type_1.bayer_scale_ver_ratio_in,
 676                shading_info->info.type_1.bayer_scale_ver_ratio_out,
 677                shading_info->info.type_1.isp_input_sensor_data_res_bqs.width,
 678                shading_info->info.type_1.isp_input_sensor_data_res_bqs.height,
 679                shading_info->info.type_1.sensor_data_res_bqs.width,
 680                shading_info->info.type_1.sensor_data_res_bqs.height,
 681                shading_info->info.type_1.sensor_data_origin_bqs_on_sctbl.x,
 682                shading_info->info.type_1.sensor_data_origin_bqs_on_sctbl.y);
 683
 684        IA_CSS_LOG("pipe_config: origin=(%d,%d)",
 685                pipe_config->internal_frame_origin_bqs_on_sctbl.x,
 686                pipe_config->internal_frame_origin_bqs_on_sctbl.y);
 687
 688        IA_CSS_LEAVE_ERR_PRIVATE(err);
 689#endif
 690        return err;
 691}
 692
 693enum ia_css_err
 694ia_css_binary_get_shading_info(const struct ia_css_binary *binary,                      /* [in] */
 695                                enum ia_css_shading_correction_type type,               /* [in] */
 696                                unsigned int required_bds_factor,                       /* [in] */
 697                                const struct ia_css_stream_config *stream_config,       /* [in] */
 698#ifndef ISP2401
 699                                struct ia_css_shading_info *info)                       /* [out] */
 700#else
 701                                struct ia_css_shading_info *shading_info,               /* [out] */
 702                                struct ia_css_pipe_config *pipe_config)                 /* [out] */
 703#endif
 704{
 705        enum ia_css_err err;
 706
 707        assert(binary != NULL);
 708#ifndef ISP2401
 709        assert(info != NULL);
 710#else
 711        assert(shading_info != NULL);
 712
 713        IA_CSS_ENTER_PRIVATE("binary=%p, type=%d, required_bds_factor=%d, stream_config=%p",
 714                binary, type, required_bds_factor, stream_config);
 715#endif
 716
 717        if (type == IA_CSS_SHADING_CORRECTION_TYPE_1)
 718#ifndef ISP2401
 719                err = ia_css_binary_get_shading_info_type_1(binary, required_bds_factor, stream_config, info);
 720#else
 721                err = ia_css_binary_get_shading_info_type_1(binary, required_bds_factor, stream_config,
 722                                                                shading_info, pipe_config);
 723#endif
 724
 725        /* Other function calls can be added here when other shading correction types will be added in the future. */
 726
 727        else
 728                err = IA_CSS_ERR_NOT_SUPPORTED;
 729
 730        IA_CSS_LEAVE_ERR_PRIVATE(err);
 731        return err;
 732}
 733
 734static void sh_css_binary_common_grid_info(const struct ia_css_binary *binary,
 735                                struct ia_css_grid_info *info)
 736{
 737        assert(binary != NULL);
 738        assert(info != NULL);
 739
 740        info->isp_in_width = binary->internal_frame_info.res.width;
 741        info->isp_in_height = binary->internal_frame_info.res.height;
 742
 743        info->vamem_type = IA_CSS_VAMEM_TYPE_2;
 744}
 745
 746void
 747ia_css_binary_dvs_grid_info(const struct ia_css_binary *binary,
 748                            struct ia_css_grid_info *info,
 749                            struct ia_css_pipe *pipe)
 750{
 751        struct ia_css_dvs_grid_info *dvs_info;
 752
 753        (void)pipe;
 754        assert(binary != NULL);
 755        assert(info != NULL);
 756
 757        dvs_info = &info->dvs_grid.dvs_grid_info;
 758
 759        /* for DIS, we use a division instead of a ceil_div. If this is smaller
 760         * than the 3a grid size, it indicates that the outer values are not
 761         * valid for DIS.
 762         */
 763        dvs_info->enable            = binary->info->sp.enable.dis;
 764        dvs_info->width             = binary->dis.grid.dim.width;
 765        dvs_info->height            = binary->dis.grid.dim.height;
 766        dvs_info->aligned_width     = binary->dis.grid.pad.width;
 767        dvs_info->aligned_height    = binary->dis.grid.pad.height;
 768        dvs_info->bqs_per_grid_cell = 1 << binary->dis.deci_factor_log2;
 769        dvs_info->num_hor_coefs     = binary->dis.coef.dim.width;
 770        dvs_info->num_ver_coefs     = binary->dis.coef.dim.height;
 771
 772        sh_css_binary_common_grid_info(binary, info);
 773}
 774
 775void
 776ia_css_binary_dvs_stat_grid_info(
 777        const struct ia_css_binary *binary,
 778        struct ia_css_grid_info *info,
 779        struct ia_css_pipe *pipe)
 780{
 781        (void)pipe;
 782        sh_css_binary_common_grid_info(binary, info);
 783        return;
 784}
 785
 786enum ia_css_err
 787ia_css_binary_3a_grid_info(const struct ia_css_binary *binary,
 788                           struct ia_css_grid_info *info,
 789                           struct ia_css_pipe *pipe)
 790{
 791        struct ia_css_3a_grid_info *s3a_info;
 792        enum ia_css_err err = IA_CSS_SUCCESS;
 793
 794        IA_CSS_ENTER_PRIVATE("binary=%p, info=%p, pipe=%p",
 795                             binary, info, pipe);
 796
 797        assert(binary != NULL);
 798        assert(info != NULL);
 799        s3a_info = &info->s3a_grid;
 800
 801
 802        /* 3A statistics grid */
 803        s3a_info->enable            = binary->info->sp.enable.s3a;
 804        s3a_info->width             = binary->s3atbl_width;
 805        s3a_info->height            = binary->s3atbl_height;
 806        s3a_info->aligned_width     = binary->s3atbl_isp_width;
 807        s3a_info->aligned_height    = binary->s3atbl_isp_height;
 808        s3a_info->bqs_per_grid_cell = (1 << binary->deci_factor_log2);
 809        s3a_info->deci_factor_log2  = binary->deci_factor_log2;
 810        s3a_info->elem_bit_depth    = SH_CSS_BAYER_BITS;
 811        s3a_info->use_dmem          = binary->info->sp.s3a.s3atbl_use_dmem;
 812#if defined(HAS_NO_HMEM)
 813        s3a_info->has_histogram     = 1;
 814#else
 815        s3a_info->has_histogram     = 0;
 816#endif
 817        IA_CSS_LEAVE_ERR_PRIVATE(err);
 818        return err;
 819}
 820
 821static void
 822binary_init_pc_histogram(struct sh_css_pc_histogram *histo)
 823{
 824        assert(histo != NULL);
 825
 826        histo->length = 0;
 827        histo->run = NULL;
 828        histo->stall = NULL;
 829}
 830
 831static void
 832binary_init_metrics(struct sh_css_binary_metrics *metrics,
 833             const struct ia_css_binary_info *info)
 834{
 835        assert(metrics != NULL);
 836        assert(info != NULL);
 837
 838        metrics->mode = info->pipeline.mode;
 839        metrics->id   = info->id;
 840        metrics->next = NULL;
 841        binary_init_pc_histogram(&metrics->isp_histogram);
 842        binary_init_pc_histogram(&metrics->sp_histogram);
 843}
 844
 845/* move to host part of output module */
 846static bool
 847binary_supports_output_format(const struct ia_css_binary_xinfo *info,
 848                       enum ia_css_frame_format format)
 849{
 850        int i;
 851
 852        assert(info != NULL);
 853
 854        for (i = 0; i < info->num_output_formats; i++) {
 855                if (info->output_formats[i] == format)
 856                        return true;
 857        }
 858        return false;
 859}
 860
 861#ifdef ISP2401
 862static bool
 863binary_supports_input_format(const struct ia_css_binary_xinfo *info,
 864                             enum atomisp_input_format format)
 865{
 866
 867        assert(info != NULL);
 868        (void)format;
 869
 870        return true;
 871}
 872#endif
 873
 874static bool
 875binary_supports_vf_format(const struct ia_css_binary_xinfo *info,
 876                          enum ia_css_frame_format format)
 877{
 878        int i;
 879
 880        assert(info != NULL);
 881
 882        for (i = 0; i < info->num_vf_formats; i++) {
 883                if (info->vf_formats[i] == format)
 884                        return true;
 885        }
 886        return false;
 887}
 888
 889/* move to host part of bds module */
 890static bool
 891supports_bds_factor(uint32_t supported_factors,
 892                       uint32_t bds_factor)
 893{
 894        return ((supported_factors & PACK_BDS_FACTOR(bds_factor)) != 0);
 895}
 896
 897static enum ia_css_err
 898binary_init_info(struct ia_css_binary_xinfo *info, unsigned int i,
 899                 bool *binary_found)
 900{
 901        const unsigned char *blob = sh_css_blob_info[i].blob;
 902        unsigned size = sh_css_blob_info[i].header.blob.size;
 903
 904        if ((info == NULL) || (binary_found == NULL))
 905                return IA_CSS_ERR_INVALID_ARGUMENTS;
 906
 907        *info = sh_css_blob_info[i].header.info.isp;
 908        *binary_found = blob != NULL;
 909        info->blob_index = i;
 910        /* we don't have this binary, skip it */
 911        if (!size)
 912                return IA_CSS_SUCCESS;
 913
 914        info->xmem_addr = sh_css_load_blob(blob, size);
 915        if (!info->xmem_addr)
 916                return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
 917        return IA_CSS_SUCCESS;
 918}
 919
 920/* When binaries are put at the beginning, they will only
 921 * be selected if no other primary matches.
 922 */
 923enum ia_css_err
 924ia_css_binary_init_infos(void)
 925{
 926        unsigned int i;
 927        unsigned int num_of_isp_binaries = sh_css_num_binaries - NUM_OF_SPS - NUM_OF_BLS;
 928
 929        if (num_of_isp_binaries == 0)
 930                return IA_CSS_SUCCESS;
 931
 932        all_binaries = sh_css_malloc(num_of_isp_binaries *
 933                                                sizeof(*all_binaries));
 934        if (all_binaries == NULL)
 935                return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
 936
 937        for (i = 0; i < num_of_isp_binaries; i++) {
 938                enum ia_css_err ret;
 939                struct ia_css_binary_xinfo *binary = &all_binaries[i];
 940                bool binary_found;
 941
 942                ret = binary_init_info(binary, i, &binary_found);
 943                if (ret != IA_CSS_SUCCESS)
 944                        return ret;
 945                if (!binary_found)
 946                        continue;
 947                /* Prepend new binary information */
 948                binary->next = binary_infos[binary->sp.pipeline.mode];
 949                binary_infos[binary->sp.pipeline.mode] = binary;
 950                binary->blob = &sh_css_blob_info[i];
 951                binary->mem_offsets = sh_css_blob_info[i].mem_offsets;
 952        }
 953        return IA_CSS_SUCCESS;
 954}
 955
 956enum ia_css_err
 957ia_css_binary_uninit(void)
 958{
 959        unsigned int i;
 960        struct ia_css_binary_xinfo *b;
 961
 962        for (i = 0; i < IA_CSS_BINARY_NUM_MODES; i++) {
 963                for (b = binary_infos[i]; b; b = b->next) {
 964                        if (b->xmem_addr)
 965                                hmm_free(b->xmem_addr);
 966                        b->xmem_addr = mmgr_NULL;
 967                }
 968                binary_infos[i] = NULL;
 969        }
 970        sh_css_free(all_binaries);
 971        return IA_CSS_SUCCESS;
 972}
 973
 974/* @brief Compute decimation factor for 3A statistics and shading correction.
 975 *
 976 * @param[in]   width   Frame width in pixels.
 977 * @param[in]   height  Frame height in pixels.
 978 * @return      Log2 of decimation factor (= grid cell size) in bayer quads.
 979 */
 980static int
 981binary_grid_deci_factor_log2(int width, int height)
 982{
 983/* 3A/Shading decimation factor spcification (at August 2008)
 984 * ------------------------------------------------------------------
 985 * [Image Width (BQ)] [Decimation Factor (BQ)] [Resulting grid cells]
 986#ifndef ISP2401
 987 * 1280 ?c             32                       40 ?c
 988 *  640 ?c 1279        16                       40 ?c 80
 989 *      ?c  639         8                          ?c 80
 990#else
 991 * from 1280                   32                 from 40
 992 * from  640 to 1279           16                 from 40 to 80
 993 *           to  639            8                         to 80
 994#endif
 995 * ------------------------------------------------------------------
 996 */
 997/* Maximum and minimum decimation factor by the specification */
 998#define MAX_SPEC_DECI_FACT_LOG2         5
 999#define MIN_SPEC_DECI_FACT_LOG2         3
1000/* the smallest frame width in bayer quads when decimation factor (log2) is 5 or 4, by the specification */
1001#define DECI_FACT_LOG2_5_SMALLEST_FRAME_WIDTH_BQ        1280
1002#define DECI_FACT_LOG2_4_SMALLEST_FRAME_WIDTH_BQ        640
1003
1004        int smallest_factor; /* the smallest factor (log2) where the number of cells does not exceed the limitation */
1005        int spec_factor;     /* the factor (log2) which satisfies the specification */
1006
1007        /* Currently supported maximum width and height are 5120(=80*64) and 3840(=60*64). */
1008        assert(ISP_BQ_GRID_WIDTH(width, MAX_SPEC_DECI_FACT_LOG2) <= SH_CSS_MAX_BQ_GRID_WIDTH);
1009        assert(ISP_BQ_GRID_HEIGHT(height, MAX_SPEC_DECI_FACT_LOG2) <= SH_CSS_MAX_BQ_GRID_HEIGHT);
1010
1011        /* Compute the smallest factor. */
1012        smallest_factor = MAX_SPEC_DECI_FACT_LOG2;
1013        while (ISP_BQ_GRID_WIDTH(width, smallest_factor - 1) <= SH_CSS_MAX_BQ_GRID_WIDTH &&
1014               ISP_BQ_GRID_HEIGHT(height, smallest_factor - 1) <= SH_CSS_MAX_BQ_GRID_HEIGHT
1015               && smallest_factor > MIN_SPEC_DECI_FACT_LOG2)
1016                smallest_factor--;
1017
1018        /* Get the factor by the specification. */
1019        if (_ISP_BQS(width) >= DECI_FACT_LOG2_5_SMALLEST_FRAME_WIDTH_BQ)
1020                spec_factor = 5;
1021        else if (_ISP_BQS(width) >= DECI_FACT_LOG2_4_SMALLEST_FRAME_WIDTH_BQ)
1022                spec_factor = 4;
1023        else
1024                spec_factor = 3;
1025
1026        /* If smallest_factor is smaller than or equal to spec_factor, choose spec_factor to follow the specification.
1027           If smallest_factor is larger than spec_factor, choose smallest_factor.
1028
1029                ex. width=2560, height=1920
1030                        smallest_factor=4, spec_factor=5
1031                        smallest_factor < spec_factor   ->   return spec_factor
1032
1033                ex. width=300, height=3000
1034                        smallest_factor=5, spec_factor=3
1035                        smallest_factor > spec_factor   ->   return smallest_factor
1036        */
1037        return max(smallest_factor, spec_factor);
1038
1039#undef MAX_SPEC_DECI_FACT_LOG2
1040#undef MIN_SPEC_DECI_FACT_LOG2
1041#undef DECI_FACT_LOG2_5_SMALLEST_FRAME_WIDTH_BQ
1042#undef DECI_FACT_LOG2_4_SMALLEST_FRAME_WIDTH_BQ
1043}
1044
1045static int
1046binary_in_frame_padded_width(int in_frame_width,
1047                             int isp_internal_width,
1048                             int dvs_env_width,
1049                             int stream_config_left_padding,
1050                             int left_cropping,
1051                             bool need_scaling)
1052{
1053        int rval;
1054        int nr_of_left_paddings;        /* number of paddings pixels on the left of an image line */
1055
1056#if defined(USE_INPUT_SYSTEM_VERSION_2401)
1057        /* the output image line of Input System 2401 does not have the left paddings  */
1058        nr_of_left_paddings = 0;
1059#else
1060        /* in other cases, the left padding pixels are always 128 */
1061        nr_of_left_paddings = 2*ISP_VEC_NELEMS;
1062#endif
1063        if (need_scaling) {
1064                /* In SDV use-case, we need to match left-padding of
1065                 * primary and the video binary. */
1066                if (stream_config_left_padding != -1) {
1067                        /* Different than before, we do left&right padding. */
1068                        rval =
1069                                CEIL_MUL(in_frame_width + nr_of_left_paddings,
1070                                        2*ISP_VEC_NELEMS);
1071                } else {
1072                        /* Different than before, we do left&right padding. */
1073                        in_frame_width += dvs_env_width;
1074                        rval =
1075                                CEIL_MUL(in_frame_width +
1076                                        (left_cropping ? nr_of_left_paddings : 0),
1077                                        2*ISP_VEC_NELEMS);
1078                }
1079        } else {
1080                rval = isp_internal_width;
1081        }
1082
1083        return rval;
1084}
1085
1086
1087enum ia_css_err
1088ia_css_binary_fill_info(const struct ia_css_binary_xinfo *xinfo,
1089                 bool online,
1090                 bool two_ppc,
1091                 enum atomisp_input_format stream_format,
1092                 const struct ia_css_frame_info *in_info, /* can be NULL */
1093                 const struct ia_css_frame_info *bds_out_info, /* can be NULL */
1094                 const struct ia_css_frame_info *out_info[], /* can be NULL */
1095                 const struct ia_css_frame_info *vf_info, /* can be NULL */
1096                 struct ia_css_binary *binary,
1097                 struct ia_css_resolution *dvs_env,
1098                 int stream_config_left_padding,
1099                 bool accelerator)
1100{
1101        const struct ia_css_binary_info *info = &xinfo->sp;
1102        unsigned int dvs_env_width = 0,
1103                     dvs_env_height = 0,
1104                     vf_log_ds = 0,
1105                     s3a_log_deci = 0,
1106                     bits_per_pixel = 0,
1107                     /* Resolution at SC/3A/DIS kernel. */
1108                     sc_3a_dis_width = 0,
1109                     /* Resolution at SC/3A/DIS kernel. */
1110                     sc_3a_dis_padded_width = 0,
1111                     /* Resolution at SC/3A/DIS kernel. */
1112                     sc_3a_dis_height = 0,
1113                     isp_internal_width = 0,
1114                     isp_internal_height = 0,
1115                     s3a_isp_width = 0;
1116
1117        bool need_scaling = false;
1118        struct ia_css_resolution binary_dvs_env, internal_res;
1119        enum ia_css_err err;
1120        unsigned int i;
1121        const struct ia_css_frame_info *bin_out_info = NULL;
1122
1123        assert(info != NULL);
1124        assert(binary != NULL);
1125
1126        binary->info = xinfo;
1127        if (!accelerator) {
1128                /* binary->css_params has been filled by accelerator itself. */
1129                err = ia_css_isp_param_allocate_isp_parameters(
1130                        &binary->mem_params, &binary->css_params,
1131                        &info->mem_initializers);
1132                if (err != IA_CSS_SUCCESS) {
1133                        return err;
1134                }
1135        }
1136        for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) {
1137                if (out_info[i] && (out_info[i]->res.width != 0)) {
1138                        bin_out_info = out_info[i];
1139                        break;
1140                }
1141        }
1142        if (in_info != NULL && bin_out_info != NULL) {
1143                need_scaling = (in_info->res.width != bin_out_info->res.width) ||
1144                        (in_info->res.height != bin_out_info->res.height);
1145        }
1146
1147
1148        /* binary_dvs_env has to be equal or larger than SH_CSS_MIN_DVS_ENVELOPE */
1149        binary_dvs_env.width = 0;
1150        binary_dvs_env.height = 0;
1151        ia_css_binary_dvs_env(info, dvs_env, &binary_dvs_env);
1152        dvs_env_width = binary_dvs_env.width;
1153        dvs_env_height = binary_dvs_env.height;
1154        binary->dvs_envelope.width  = dvs_env_width;
1155        binary->dvs_envelope.height = dvs_env_height;
1156
1157        /* internal resolution calculation */
1158        internal_res.width = 0;
1159        internal_res.height = 0;
1160        ia_css_binary_internal_res(in_info, bds_out_info, bin_out_info, dvs_env,
1161                                   info, &internal_res);
1162        isp_internal_width = internal_res.width;
1163        isp_internal_height = internal_res.height;
1164
1165        /* internal frame info */
1166        if (bin_out_info != NULL) /* { */
1167                binary->internal_frame_info.format = bin_out_info->format;
1168        /* } */
1169        binary->internal_frame_info.res.width       = isp_internal_width;
1170        binary->internal_frame_info.padded_width    = CEIL_MUL(isp_internal_width, 2*ISP_VEC_NELEMS);
1171        binary->internal_frame_info.res.height      = isp_internal_height;
1172        binary->internal_frame_info.raw_bit_depth   = bits_per_pixel;
1173
1174        if (in_info != NULL) {
1175                binary->effective_in_frame_res.width = in_info->res.width;
1176                binary->effective_in_frame_res.height = in_info->res.height;
1177
1178                bits_per_pixel = in_info->raw_bit_depth;
1179
1180                /* input info */
1181                binary->in_frame_info.res.width = in_info->res.width + info->pipeline.left_cropping;
1182                binary->in_frame_info.res.height = in_info->res.height + info->pipeline.top_cropping;
1183
1184                binary->in_frame_info.res.width += dvs_env_width;
1185                binary->in_frame_info.res.height += dvs_env_height;
1186
1187                binary->in_frame_info.padded_width =
1188                        binary_in_frame_padded_width(in_info->res.width,
1189                                                     isp_internal_width,
1190                                                     dvs_env_width,
1191                                                     stream_config_left_padding,
1192                                                     info->pipeline.left_cropping,
1193                                                     need_scaling);
1194
1195                binary->in_frame_info.format = in_info->format;
1196                binary->in_frame_info.raw_bayer_order = in_info->raw_bayer_order;
1197                binary->in_frame_info.crop_info = in_info->crop_info;
1198        }
1199
1200        if (online) {
1201                bits_per_pixel = ia_css_util_input_format_bpp(
1202                        stream_format, two_ppc);
1203        }
1204        binary->in_frame_info.raw_bit_depth = bits_per_pixel;
1205
1206        for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) {
1207                if (out_info[i] != NULL) {
1208                        binary->out_frame_info[i].res.width     = out_info[i]->res.width;
1209                        binary->out_frame_info[i].res.height    = out_info[i]->res.height;
1210                        binary->out_frame_info[i].padded_width  = out_info[i]->padded_width;
1211                        if (info->pipeline.mode == IA_CSS_BINARY_MODE_COPY) {
1212                                binary->out_frame_info[i].raw_bit_depth = bits_per_pixel;
1213                        } else {
1214                                /* Only relevant for RAW format.
1215                                 * At the moment, all outputs are raw, 16 bit per pixel, except for copy.
1216                                 * To do this cleanly, the binary should specify in its info
1217                                 * the bit depth per output channel.
1218                                 */
1219                                binary->out_frame_info[i].raw_bit_depth = 16;
1220                        }
1221                        binary->out_frame_info[i].format        = out_info[i]->format;
1222                }
1223        }
1224
1225        if (vf_info && (vf_info->res.width != 0)) {
1226                err = ia_css_vf_configure(binary, bin_out_info, (struct ia_css_frame_info *)vf_info, &vf_log_ds);
1227                if (err != IA_CSS_SUCCESS) {
1228                        if (!accelerator) {
1229                                ia_css_isp_param_destroy_isp_parameters(
1230                                        &binary->mem_params,
1231                                        &binary->css_params);
1232                        }
1233                        return err;
1234                }
1235        }
1236        binary->vf_downscale_log2 = vf_log_ds;
1237
1238        binary->online            = online;
1239        binary->input_format      = stream_format;
1240
1241        /* viewfinder output info */
1242        if ((vf_info != NULL) && (vf_info->res.width != 0)) {
1243                unsigned int vf_out_vecs, vf_out_width, vf_out_height;
1244                binary->vf_frame_info.format = vf_info->format;
1245                if (bin_out_info == NULL)
1246                        return IA_CSS_ERR_INTERNAL_ERROR;
1247                vf_out_vecs = __ISP_VF_OUTPUT_WIDTH_VECS(bin_out_info->padded_width,
1248                        vf_log_ds);
1249                vf_out_width = _ISP_VF_OUTPUT_WIDTH(vf_out_vecs);
1250                vf_out_height = _ISP_VF_OUTPUT_HEIGHT(bin_out_info->res.height,
1251                        vf_log_ds);
1252
1253                /* For preview mode, output pin is used instead of vf. */
1254                if (info->pipeline.mode == IA_CSS_BINARY_MODE_PREVIEW) {
1255                        binary->out_frame_info[0].res.width =
1256                                (bin_out_info->res.width >> vf_log_ds);
1257                        binary->out_frame_info[0].padded_width = vf_out_width;
1258                        binary->out_frame_info[0].res.height   = vf_out_height;
1259
1260                        binary->vf_frame_info.res.width    = 0;
1261                        binary->vf_frame_info.padded_width = 0;
1262                        binary->vf_frame_info.res.height   = 0;
1263                } else {
1264                        /* we also store the raw downscaled width. This is
1265                         * used for digital zoom in preview to zoom only on
1266                         * the width that we actually want to keep, not on
1267                         * the aligned width. */
1268                        binary->vf_frame_info.res.width =
1269                                (bin_out_info->res.width >> vf_log_ds);
1270                        binary->vf_frame_info.padded_width = vf_out_width;
1271                        binary->vf_frame_info.res.height   = vf_out_height;
1272                }
1273        } else {
1274                binary->vf_frame_info.res.width    = 0;
1275                binary->vf_frame_info.padded_width = 0;
1276                binary->vf_frame_info.res.height   = 0;
1277        }
1278
1279        if (info->enable.ca_gdc) {
1280                binary->morph_tbl_width =
1281                        _ISP_MORPH_TABLE_WIDTH(isp_internal_width);
1282                binary->morph_tbl_aligned_width  =
1283                        _ISP_MORPH_TABLE_ALIGNED_WIDTH(isp_internal_width);
1284                binary->morph_tbl_height =
1285                        _ISP_MORPH_TABLE_HEIGHT(isp_internal_height);
1286        } else {
1287                binary->morph_tbl_width  = 0;
1288                binary->morph_tbl_aligned_width  = 0;
1289                binary->morph_tbl_height = 0;
1290        }
1291
1292        sc_3a_dis_width = binary->in_frame_info.res.width;
1293        sc_3a_dis_padded_width = binary->in_frame_info.padded_width;
1294        sc_3a_dis_height = binary->in_frame_info.res.height;
1295        if (bds_out_info != NULL && in_info != NULL &&
1296                        bds_out_info->res.width != in_info->res.width) {
1297                /* TODO: Next, "internal_frame_info" should be derived from
1298                 * bds_out. So this part will change once it is in place! */
1299                sc_3a_dis_width = bds_out_info->res.width + info->pipeline.left_cropping;
1300                sc_3a_dis_padded_width = isp_internal_width;
1301                sc_3a_dis_height = isp_internal_height;
1302        }
1303
1304
1305        s3a_isp_width = _ISP_S3A_ELEMS_ISP_WIDTH(sc_3a_dis_padded_width,
1306                info->pipeline.left_cropping);
1307        if (info->s3a.fixed_s3a_deci_log) {
1308                s3a_log_deci = info->s3a.fixed_s3a_deci_log;
1309        } else {
1310                s3a_log_deci = binary_grid_deci_factor_log2(s3a_isp_width,
1311                                                            sc_3a_dis_height);
1312        }
1313        binary->deci_factor_log2  = s3a_log_deci;
1314
1315        if (info->enable.s3a) {
1316                binary->s3atbl_width  =
1317                        _ISP_S3ATBL_WIDTH(sc_3a_dis_width,
1318                                s3a_log_deci);
1319                binary->s3atbl_height =
1320                        _ISP_S3ATBL_HEIGHT(sc_3a_dis_height,
1321                                s3a_log_deci);
1322                binary->s3atbl_isp_width =
1323                        _ISP_S3ATBL_ISP_WIDTH(s3a_isp_width,
1324                                        s3a_log_deci);
1325                binary->s3atbl_isp_height =
1326                        _ISP_S3ATBL_ISP_HEIGHT(sc_3a_dis_height,
1327                                s3a_log_deci);
1328        } else {
1329                binary->s3atbl_width  = 0;
1330                binary->s3atbl_height = 0;
1331                binary->s3atbl_isp_width  = 0;
1332                binary->s3atbl_isp_height = 0;
1333        }
1334
1335        if (info->enable.sc) {
1336                binary->sctbl_width_per_color  =
1337#ifndef ISP2401
1338                        _ISP_SCTBL_WIDTH_PER_COLOR(sc_3a_dis_padded_width,
1339                                s3a_log_deci);
1340#else
1341                        _ISP_SCTBL_WIDTH_PER_COLOR(isp_internal_width, s3a_log_deci);
1342#endif
1343                binary->sctbl_aligned_width_per_color =
1344                        SH_CSS_MAX_SCTBL_ALIGNED_WIDTH_PER_COLOR;
1345                binary->sctbl_height =
1346#ifndef ISP2401
1347                        _ISP_SCTBL_HEIGHT(sc_3a_dis_height, s3a_log_deci);
1348#else
1349                        _ISP_SCTBL_HEIGHT(isp_internal_height, s3a_log_deci);
1350                binary->sctbl_legacy_width_per_color  =
1351                        _ISP_SCTBL_LEGACY_WIDTH_PER_COLOR(sc_3a_dis_padded_width, s3a_log_deci);
1352                binary->sctbl_legacy_height =
1353                        _ISP_SCTBL_LEGACY_HEIGHT(sc_3a_dis_height, s3a_log_deci);
1354#endif
1355        } else {
1356                binary->sctbl_width_per_color         = 0;
1357                binary->sctbl_aligned_width_per_color = 0;
1358                binary->sctbl_height                  = 0;
1359#ifdef ISP2401
1360                binary->sctbl_legacy_width_per_color  = 0;
1361                binary->sctbl_legacy_height           = 0;
1362#endif
1363        }
1364        ia_css_sdis_init_info(&binary->dis,
1365                                sc_3a_dis_width,
1366                                sc_3a_dis_padded_width,
1367                                sc_3a_dis_height,
1368                                info->pipeline.isp_pipe_version,
1369                                info->enable.dis);
1370        if (info->pipeline.left_cropping)
1371                binary->left_padding = 2 * ISP_VEC_NELEMS - info->pipeline.left_cropping;
1372        else
1373                binary->left_padding = 0;
1374
1375        return IA_CSS_SUCCESS;
1376}
1377
1378enum ia_css_err
1379ia_css_binary_find(struct ia_css_binary_descr *descr,
1380                   struct ia_css_binary *binary)
1381{
1382        int mode;
1383        bool online;
1384        bool two_ppc;
1385        enum atomisp_input_format stream_format;
1386        const struct ia_css_frame_info *req_in_info,
1387                                       *req_bds_out_info,
1388                                       *req_out_info[IA_CSS_BINARY_MAX_OUTPUT_PORTS],
1389                                       *req_bin_out_info = NULL,
1390                                       *req_vf_info;
1391
1392        struct ia_css_binary_xinfo *xcandidate;
1393#ifndef ISP2401
1394        bool need_ds, need_dz, need_dvs, need_xnr, need_dpc;
1395#else
1396        bool need_ds, need_dz, need_dvs, need_xnr, need_dpc, need_tnr;
1397#endif
1398        bool striped;
1399        bool enable_yuv_ds;
1400        bool enable_high_speed;
1401        bool enable_dvs_6axis;
1402        bool enable_reduced_pipe;
1403        bool enable_capture_pp_bli;
1404#ifdef ISP2401
1405        bool enable_luma_only;
1406#endif
1407        enum ia_css_err err = IA_CSS_ERR_INTERNAL_ERROR;
1408        bool continuous;
1409        unsigned int isp_pipe_version;
1410        struct ia_css_resolution dvs_env, internal_res;
1411        unsigned int i;
1412
1413        assert(descr != NULL);
1414        /* MW: used after an error check, may accept NULL, but doubtfull */
1415        assert(binary != NULL);
1416
1417        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1418                "ia_css_binary_find() enter: descr=%p, (mode=%d), binary=%p\n",
1419                descr, descr->mode,
1420                binary);
1421
1422        mode = descr->mode;
1423        online = descr->online;
1424        two_ppc = descr->two_ppc;
1425        stream_format = descr->stream_format;
1426        req_in_info = descr->in_info;
1427        req_bds_out_info = descr->bds_out_info;
1428        for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++) {
1429                req_out_info[i] = descr->out_info[i];
1430                if (req_out_info[i] && (req_out_info[i]->res.width != 0))
1431                        req_bin_out_info = req_out_info[i];
1432        }
1433        if (req_bin_out_info == NULL)
1434                return IA_CSS_ERR_INTERNAL_ERROR;
1435#ifndef ISP2401
1436        req_vf_info = descr->vf_info;
1437#else
1438
1439        if ((descr->vf_info != NULL) && (descr->vf_info->res.width == 0))
1440                /* width==0 means that there is no vf pin (e.g. in SkyCam preview case) */
1441                req_vf_info = NULL;
1442        else
1443                req_vf_info = descr->vf_info;
1444#endif
1445
1446        need_xnr = descr->enable_xnr;
1447        need_ds = descr->enable_fractional_ds;
1448        need_dz = false;
1449        need_dvs = false;
1450        need_dpc = descr->enable_dpc;
1451#ifdef ISP2401
1452        need_tnr = descr->enable_tnr;
1453#endif
1454        enable_yuv_ds = descr->enable_yuv_ds;
1455        enable_high_speed = descr->enable_high_speed;
1456        enable_dvs_6axis  = descr->enable_dvs_6axis;
1457        enable_reduced_pipe = descr->enable_reduced_pipe;
1458        enable_capture_pp_bli = descr->enable_capture_pp_bli;
1459#ifdef ISP2401
1460        enable_luma_only = descr->enable_luma_only;
1461#endif
1462        continuous = descr->continuous;
1463        striped = descr->striped;
1464        isp_pipe_version = descr->isp_pipe_version;
1465
1466        dvs_env.width = 0;
1467        dvs_env.height = 0;
1468        internal_res.width = 0;
1469        internal_res.height = 0;
1470
1471
1472        if (mode == IA_CSS_BINARY_MODE_VIDEO) {
1473                dvs_env = descr->dvs_env;
1474                need_dz = descr->enable_dz;
1475                /* Video is the only mode that has a nodz variant. */
1476                need_dvs = dvs_env.width || dvs_env.height;
1477        }
1478
1479        /* print a map of the binary file */
1480        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "BINARY INFO:\n");
1481        for (i = 0; i < IA_CSS_BINARY_NUM_MODES; i++) {
1482                xcandidate = binary_infos[i];
1483                if (xcandidate) {
1484                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "%d:\n", i);
1485                        while (xcandidate) {
1486                                ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, " Name:%s Type:%d Cont:%d\n",
1487                                                xcandidate->blob->name, xcandidate->type,
1488                                                xcandidate->sp.enable.continuous);
1489                                xcandidate = xcandidate->next;
1490                        }
1491                }
1492        }
1493
1494        /* printf("sh_css_binary_find: pipe version %d\n", isp_pipe_version); */
1495        for (xcandidate = binary_infos[mode]; xcandidate;
1496             xcandidate = xcandidate->next) {
1497                struct ia_css_binary_info *candidate = &xcandidate->sp;
1498                /* printf("sh_css_binary_find: evaluating candidate:
1499                 * %d\n",candidate->id); */
1500                ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1501                        "ia_css_binary_find() candidate = %p, mode = %d ID = %d\n",
1502                        candidate, candidate->pipeline.mode, candidate->id);
1503
1504                /*
1505                 * MW: Only a limited set of jointly configured binaries can
1506                 * be used in a continuous preview/video mode unless it is
1507                 * the copy mode and runs on SP.
1508                */
1509                if (!candidate->enable.continuous &&
1510                    continuous && (mode != IA_CSS_BINARY_MODE_COPY)) {
1511                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1512                                "ia_css_binary_find() [%d] continue: !%d && %d && (%d != %d)\n",
1513                                        __LINE__, candidate->enable.continuous,
1514                                        continuous, mode,
1515                                        IA_CSS_BINARY_MODE_COPY);
1516                        continue;
1517                }
1518                if (striped && candidate->iterator.num_stripes == 1) {
1519                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1520                                "ia_css_binary_find() [%d] continue: binary is not striped\n",
1521                                        __LINE__);
1522                        continue;
1523                }
1524
1525                if (candidate->pipeline.isp_pipe_version != isp_pipe_version &&
1526                    (mode != IA_CSS_BINARY_MODE_COPY) &&
1527                    (mode != IA_CSS_BINARY_MODE_CAPTURE_PP) &&
1528                    (mode != IA_CSS_BINARY_MODE_VF_PP)) {
1529                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1530                                "ia_css_binary_find() [%d] continue: (%d != %d)\n",
1531                                __LINE__,
1532                                candidate->pipeline.isp_pipe_version, isp_pipe_version);
1533                        continue;
1534                }
1535                if (!candidate->enable.reduced_pipe && enable_reduced_pipe) {
1536                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1537                                "ia_css_binary_find() [%d] continue: !%d && %d\n",
1538                                __LINE__,
1539                                candidate->enable.reduced_pipe,
1540                                enable_reduced_pipe);
1541                        continue;
1542                }
1543                if (!candidate->enable.dvs_6axis && enable_dvs_6axis) {
1544                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1545                                "ia_css_binary_find() [%d] continue: !%d && %d\n",
1546                                __LINE__,
1547                                candidate->enable.dvs_6axis,
1548                                enable_dvs_6axis);
1549                        continue;
1550                }
1551                if (candidate->enable.high_speed && !enable_high_speed) {
1552                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1553                                "ia_css_binary_find() [%d] continue: %d && !%d\n",
1554                                __LINE__,
1555                                candidate->enable.high_speed,
1556                                enable_high_speed);
1557                        continue;
1558                }
1559                if (!candidate->enable.xnr && need_xnr) {
1560                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1561                                "ia_css_binary_find() [%d] continue: %d && !%d\n",
1562                                __LINE__,
1563                                candidate->enable.xnr,
1564                                need_xnr);
1565                        continue;
1566                }
1567                if (!(candidate->enable.ds & 2) && enable_yuv_ds) {
1568                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1569                                "ia_css_binary_find() [%d] continue: !%d && %d\n",
1570                                __LINE__,
1571                                ((candidate->enable.ds & 2) != 0),
1572                                enable_yuv_ds);
1573                        continue;
1574                }
1575                if ((candidate->enable.ds & 2) && !enable_yuv_ds) {
1576                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1577                                "ia_css_binary_find() [%d] continue: %d && !%d\n",
1578                                __LINE__,
1579                                ((candidate->enable.ds & 2) != 0),
1580                                enable_yuv_ds);
1581                        continue;
1582                }
1583
1584                if (mode == IA_CSS_BINARY_MODE_VIDEO &&
1585                        candidate->enable.ds && need_ds)
1586                        need_dz = false;
1587
1588                /* when we require vf output, we need to have vf_veceven */
1589                if ((req_vf_info != NULL) && !(candidate->enable.vf_veceven ||
1590                                /* or variable vf vec even */
1591                                candidate->vf_dec.is_variable ||
1592                                /* or more than one output pin. */
1593                                xcandidate->num_output_pins > 1)) {
1594                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1595                                "ia_css_binary_find() [%d] continue: (%p != NULL) && !(%d || %d || (%d >%d))\n",
1596                                __LINE__, req_vf_info,
1597                                candidate->enable.vf_veceven,
1598                                candidate->vf_dec.is_variable,
1599                                xcandidate->num_output_pins, 1);
1600                        continue;
1601                }
1602                if (!candidate->enable.dvs_envelope && need_dvs) {
1603                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1604                                "ia_css_binary_find() [%d] continue: !%d && %d\n",
1605                                __LINE__,
1606                                candidate->enable.dvs_envelope, (int)need_dvs);
1607                        continue;
1608                }
1609                /* internal_res check considers input, output, and dvs envelope sizes */
1610                ia_css_binary_internal_res(req_in_info, req_bds_out_info,
1611                                           req_bin_out_info, &dvs_env, candidate, &internal_res);
1612                if (internal_res.width > candidate->internal.max_width) {
1613                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1614                        "ia_css_binary_find() [%d] continue: (%d > %d)\n",
1615                        __LINE__, internal_res.width,
1616                        candidate->internal.max_width);
1617                        continue;
1618                }
1619                if (internal_res.height > candidate->internal.max_height) {
1620                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1621                        "ia_css_binary_find() [%d] continue: (%d > %d)\n",
1622                        __LINE__, internal_res.height,
1623                        candidate->internal.max_height);
1624                        continue;
1625                }
1626                if (!candidate->enable.ds && need_ds && !(xcandidate->num_output_pins > 1)) {
1627                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1628                                "ia_css_binary_find() [%d] continue: !%d && %d\n",
1629                                __LINE__, candidate->enable.ds, (int)need_ds);
1630                        continue;
1631                }
1632                if (!candidate->enable.uds && !candidate->enable.dvs_6axis && need_dz) {
1633                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1634                                "ia_css_binary_find() [%d] continue: !%d && !%d && %d\n",
1635                                __LINE__, candidate->enable.uds,
1636                                candidate->enable.dvs_6axis, (int)need_dz);
1637                        continue;
1638                }
1639                if (online && candidate->input.source == IA_CSS_BINARY_INPUT_MEMORY) {
1640                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1641                                "ia_css_binary_find() [%d] continue: %d && (%d == %d)\n",
1642                                __LINE__, online, candidate->input.source,
1643                                IA_CSS_BINARY_INPUT_MEMORY);
1644                        continue;
1645                }
1646                if (!online && candidate->input.source == IA_CSS_BINARY_INPUT_SENSOR) {
1647                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1648                                "ia_css_binary_find() [%d] continue: !%d && (%d == %d)\n",
1649                                __LINE__, online, candidate->input.source,
1650                                IA_CSS_BINARY_INPUT_SENSOR);
1651                        continue;
1652                }
1653                if (req_bin_out_info->res.width < candidate->output.min_width ||
1654                    req_bin_out_info->res.width > candidate->output.max_width) {
1655                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1656                                "ia_css_binary_find() [%d] continue: (%d > %d) || (%d < %d)\n",
1657                                __LINE__,
1658                                req_bin_out_info->padded_width,
1659                                candidate->output.min_width,
1660                                req_bin_out_info->padded_width,
1661                                candidate->output.max_width);
1662                        continue;
1663                }
1664                if (xcandidate->num_output_pins > 1 && /* in case we have a second output pin, */
1665                     req_vf_info) { /* and we need vf output. */
1666                        if (req_vf_info->res.width > candidate->output.max_width) {
1667                                ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1668                                        "ia_css_binary_find() [%d] continue: (%d < %d)\n",
1669                                        __LINE__,
1670                                        req_vf_info->res.width,
1671                                        candidate->output.max_width);
1672                                continue;
1673                        }
1674                }
1675                if (req_in_info->padded_width > candidate->input.max_width) {
1676                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1677                                "ia_css_binary_find() [%d] continue: (%d > %d)\n",
1678                                __LINE__, req_in_info->padded_width,
1679                                candidate->input.max_width);
1680                        continue;
1681                }
1682                if (!binary_supports_output_format(xcandidate, req_bin_out_info->format)) {
1683                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1684                                "ia_css_binary_find() [%d] continue: !%d\n",
1685                                __LINE__,
1686                                binary_supports_output_format(xcandidate, req_bin_out_info->format));
1687                        continue;
1688                }
1689#ifdef ISP2401
1690                if (!binary_supports_input_format(xcandidate, descr->stream_format)) {
1691                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1692                                            "ia_css_binary_find() [%d] continue: !%d\n",
1693                                            __LINE__,
1694                                            binary_supports_input_format(xcandidate, req_in_info->format));
1695                        continue;
1696                }
1697#endif
1698                if (xcandidate->num_output_pins > 1 && /* in case we have a second output pin, */
1699                    req_vf_info                   && /* and we need vf output. */
1700                                                      /* check if the required vf format
1701                                                         is supported. */
1702                    !binary_supports_output_format(xcandidate, req_vf_info->format)) {
1703                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1704                                "ia_css_binary_find() [%d] continue: (%d > %d) && (%p != NULL) && !%d\n",
1705                                __LINE__, xcandidate->num_output_pins, 1,
1706                                req_vf_info,
1707                                binary_supports_output_format(xcandidate, req_vf_info->format));
1708                        continue;
1709                }
1710
1711                /* Check if vf_veceven supports the requested vf format */
1712                if (xcandidate->num_output_pins == 1 &&
1713                    req_vf_info && candidate->enable.vf_veceven &&
1714                    !binary_supports_vf_format(xcandidate, req_vf_info->format)) {
1715                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1716                                "ia_css_binary_find() [%d] continue: (%d == %d) && (%p != NULL) && %d && !%d\n",
1717                                __LINE__, xcandidate->num_output_pins, 1,
1718                                req_vf_info, candidate->enable.vf_veceven,
1719                                binary_supports_vf_format(xcandidate, req_vf_info->format));
1720                        continue;
1721                }
1722
1723                /* Check if vf_veceven supports the requested vf width */
1724                if (xcandidate->num_output_pins == 1 &&
1725                    req_vf_info && candidate->enable.vf_veceven) { /* and we need vf output. */
1726                        if (req_vf_info->res.width > candidate->output.max_width) {
1727                                ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1728                                        "ia_css_binary_find() [%d] continue: (%d < %d)\n",
1729                                        __LINE__,
1730                                        req_vf_info->res.width,
1731                                        candidate->output.max_width);
1732                                continue;
1733                        }
1734                }
1735
1736                if (!supports_bds_factor(candidate->bds.supported_bds_factors,
1737                    descr->required_bds_factor)) {
1738                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1739                                "ia_css_binary_find() [%d] continue: 0x%x & 0x%x)\n",
1740                                __LINE__, candidate->bds.supported_bds_factors,
1741                                descr->required_bds_factor);
1742                        continue;
1743                }
1744
1745                if (!candidate->enable.dpc && need_dpc) {
1746                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1747                                "ia_css_binary_find() [%d] continue: 0x%x & 0x%x)\n",
1748                                __LINE__, candidate->enable.dpc,
1749                                descr->enable_dpc);
1750                        continue;
1751                }
1752
1753                if (candidate->uds.use_bci && enable_capture_pp_bli) {
1754                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1755                                "ia_css_binary_find() [%d] continue: 0x%x & 0x%x)\n",
1756                                __LINE__, candidate->uds.use_bci,
1757                                descr->enable_capture_pp_bli);
1758                        continue;
1759                }
1760
1761#ifdef ISP2401
1762                if (candidate->enable.luma_only != enable_luma_only) {
1763                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1764                                "ia_css_binary_find() [%d] continue: %d != %d\n",
1765                                __LINE__, candidate->enable.luma_only,
1766                                descr->enable_luma_only);
1767                        continue;
1768                }
1769
1770                if(!candidate->enable.tnr && need_tnr) {
1771                        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1772                                "ia_css_binary_find() [%d] continue: !%d && %d\n",
1773                                __LINE__, candidate->enable.tnr,
1774                                descr->enable_tnr);
1775                        continue;
1776                }
1777
1778#endif
1779                /* reconfigure any variable properties of the binary */
1780                err = ia_css_binary_fill_info(xcandidate, online, two_ppc,
1781                                       stream_format, req_in_info,
1782                                       req_bds_out_info,
1783                                       req_out_info, req_vf_info,
1784                                       binary, &dvs_env,
1785                                       descr->stream_config_left_padding,
1786                                       false);
1787
1788                if (err != IA_CSS_SUCCESS)
1789                        break;
1790                binary_init_metrics(&binary->metrics, &binary->info->sp);
1791                break;
1792        }
1793
1794        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1795                "ia_css_binary_find() selected = %p, mode = %d ID = %d\n",
1796                xcandidate, xcandidate ? xcandidate->sp.pipeline.mode : 0, xcandidate ? xcandidate->sp.id : 0);
1797
1798        ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1799                "ia_css_binary_find() leave: return_err=%d\n", err);
1800
1801        return err;
1802}
1803
1804unsigned
1805ia_css_binary_max_vf_width(void)
1806{
1807        /* This is (should be) true for IPU1 and IPU2 */
1808        /* For IPU3 (SkyCam) this pointer is guarenteed to be NULL simply because such a binary does not exist  */
1809        if (binary_infos[IA_CSS_BINARY_MODE_VF_PP])
1810                return binary_infos[IA_CSS_BINARY_MODE_VF_PP]->sp.output.max_width;
1811        return 0;
1812}
1813
1814void
1815ia_css_binary_destroy_isp_parameters(struct ia_css_binary *binary)
1816{
1817        if (binary) {
1818                ia_css_isp_param_destroy_isp_parameters(&binary->mem_params,
1819                                                        &binary->css_params);
1820        }
1821}
1822
1823void
1824ia_css_binary_get_isp_binaries(struct ia_css_binary_xinfo **binaries,
1825        uint32_t *num_isp_binaries)
1826{
1827        assert(binaries != NULL);
1828
1829        if (num_isp_binaries)
1830                *num_isp_binaries = 0;
1831
1832        *binaries = all_binaries;
1833        if (all_binaries && num_isp_binaries) {
1834                /* -1 to account for sp binary which is not stored in all_binaries */
1835                if (sh_css_num_binaries > 0)
1836                        *num_isp_binaries = sh_css_num_binaries - 1;
1837        }
1838}
1839