linux/drivers/staging/media/atomisp/pci/atomisp2/css2400/isp/kernels/sdis/sdis_1.0/ia_css_sdis.host.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 "memory_access.h"
  16#include "assert_support.h"
  17#include "ia_css_debug.h"
  18#include "ia_css_sdis_types.h"
  19#include "sdis/common/ia_css_sdis_common.host.h"
  20#include "ia_css_sdis.host.h"
  21
  22const struct ia_css_dvs_coefficients default_sdis_config = {
  23        .grid = { 0, 0, 0, 0, 0, 0, 0, 0 },
  24        .hor_coefs = NULL,
  25        .ver_coefs = NULL
  26};
  27
  28static void
  29fill_row(short *private, const short *public, unsigned width, unsigned padding)
  30{
  31        assert((int)width >= 0);
  32        assert((int)padding >= 0);
  33        memcpy (private, public, width*sizeof(short));
  34        memset (&private[width], 0, padding*sizeof(short));
  35}
  36
  37void ia_css_sdis_horicoef_vmem_encode (
  38        struct sh_css_isp_sdis_hori_coef_tbl *to,
  39        const struct ia_css_dvs_coefficients *from,
  40        unsigned size)
  41{
  42        unsigned aligned_width = from->grid.aligned_width * from->grid.bqs_per_grid_cell;
  43        unsigned width         = from->grid.num_hor_coefs;
  44        int      padding       = aligned_width-width;
  45        unsigned stride        = size/IA_CSS_DVS_NUM_COEF_TYPES/sizeof(short);
  46        unsigned total_bytes   = aligned_width*IA_CSS_DVS_NUM_COEF_TYPES*sizeof(short);
  47        short   *public        = from->hor_coefs;
  48        short   *private       = (short*)to;
  49        unsigned type;
  50
  51        /* Copy the table, add padding */
  52        assert(padding >= 0);
  53        assert(total_bytes <= size);
  54        assert(size % (IA_CSS_DVS_NUM_COEF_TYPES*ISP_VEC_NELEMS*sizeof(short)) == 0);
  55
  56        for (type = 0; type < IA_CSS_DVS_NUM_COEF_TYPES; type++) {
  57                fill_row(&private[type*stride], &public[type*width], width, padding);
  58        }
  59}
  60
  61void ia_css_sdis_vertcoef_vmem_encode (
  62        struct sh_css_isp_sdis_vert_coef_tbl *to,
  63        const struct ia_css_dvs_coefficients *from,
  64        unsigned size)
  65{
  66        unsigned aligned_height = from->grid.aligned_height * from->grid.bqs_per_grid_cell;
  67        unsigned height         = from->grid.num_ver_coefs;
  68        int      padding        = aligned_height-height;
  69        unsigned stride         = size/IA_CSS_DVS_NUM_COEF_TYPES/sizeof(short);
  70        unsigned total_bytes    = aligned_height*IA_CSS_DVS_NUM_COEF_TYPES*sizeof(short);
  71        short   *public         = from->ver_coefs;
  72        short   *private        = (short*)to;
  73        unsigned type;
  74
  75        /* Copy the table, add padding */
  76        assert(padding >= 0);
  77        assert(total_bytes <= size);
  78        assert(size % (IA_CSS_DVS_NUM_COEF_TYPES*ISP_VEC_NELEMS*sizeof(short)) == 0);
  79
  80        for (type = 0; type < IA_CSS_DVS_NUM_COEF_TYPES; type++) {
  81                fill_row(&private[type*stride], &public[type*height], height, padding);
  82        }
  83}
  84
  85void ia_css_sdis_horiproj_encode (
  86        struct sh_css_isp_sdis_hori_proj_tbl *to,
  87        const struct ia_css_dvs_coefficients *from,
  88        unsigned size)
  89{
  90        (void)to;
  91        (void)from;
  92        (void)size;
  93}
  94
  95void ia_css_sdis_vertproj_encode (
  96        struct sh_css_isp_sdis_vert_proj_tbl *to,
  97        const struct ia_css_dvs_coefficients *from,
  98        unsigned size)
  99{
 100        (void)to;
 101        (void)from;
 102        (void)size;
 103}
 104
 105void ia_css_get_isp_dis_coefficients(
 106        struct ia_css_stream *stream,
 107        short *horizontal_coefficients,
 108        short *vertical_coefficients)
 109{
 110        struct ia_css_isp_parameters *params;
 111        unsigned int hor_num_isp, ver_num_isp;
 112        unsigned int hor_num_3a,  ver_num_3a;
 113        int i;
 114        struct ia_css_binary *dvs_binary;
 115
 116        IA_CSS_ENTER("void");
 117
 118        assert(horizontal_coefficients != NULL);
 119        assert(vertical_coefficients != NULL);
 120
 121        params = stream->isp_params_configs;
 122
 123        /* Only video pipe supports DVS */
 124        dvs_binary = ia_css_stream_get_dvs_binary(stream);
 125        if (!dvs_binary)
 126                return;
 127
 128        hor_num_isp = dvs_binary->dis.coef.pad.width;
 129        ver_num_isp = dvs_binary->dis.coef.pad.height;
 130        hor_num_3a  = dvs_binary->dis.coef.dim.width;
 131        ver_num_3a  = dvs_binary->dis.coef.dim.height;
 132
 133        for (i = 0; i < IA_CSS_DVS_NUM_COEF_TYPES; i++) {
 134                fill_row(&horizontal_coefficients[i*hor_num_isp],
 135                         &params->dvs_coefs.hor_coefs[i*hor_num_3a], hor_num_3a, hor_num_isp-hor_num_3a);
 136        }
 137        for (i = 0; i < SH_CSS_DIS_VER_NUM_COEF_TYPES(dvs_binary); i++) {
 138                fill_row(&vertical_coefficients[i*ver_num_isp],
 139                         &params->dvs_coefs.ver_coefs[i*ver_num_3a], ver_num_3a, ver_num_isp-ver_num_3a);
 140        }
 141
 142        IA_CSS_LEAVE("void");
 143}
 144
 145size_t
 146ia_css_sdis_hor_coef_tbl_bytes(
 147        const struct ia_css_binary *binary)
 148{
 149        if (binary->info->sp.pipeline.isp_pipe_version == 1)
 150                return sizeof(short) * IA_CSS_DVS_NUM_COEF_TYPES  * binary->dis.coef.pad.width;
 151        else
 152                return sizeof(short) * IA_CSS_DVS2_NUM_COEF_TYPES * binary->dis.coef.pad.width;
 153}
 154
 155size_t
 156ia_css_sdis_ver_coef_tbl_bytes(
 157        const struct ia_css_binary *binary)
 158{
 159        return sizeof(short) * SH_CSS_DIS_VER_NUM_COEF_TYPES(binary) * binary->dis.coef.pad.height;
 160}
 161
 162void
 163ia_css_sdis_init_info(
 164        struct ia_css_sdis_info *dis,
 165        unsigned sc_3a_dis_width,
 166        unsigned sc_3a_dis_padded_width,
 167        unsigned sc_3a_dis_height,
 168        unsigned isp_pipe_version,
 169        unsigned enabled)
 170{
 171        if (!enabled) {
 172                *dis = (struct ia_css_sdis_info) { };
 173                return;
 174        }
 175
 176        dis->deci_factor_log2 = SH_CSS_DIS_DECI_FACTOR_LOG2;
 177
 178        dis->grid.dim.width  =
 179                        _ISP_BQS(sc_3a_dis_width) >> SH_CSS_DIS_DECI_FACTOR_LOG2;
 180        dis->grid.dim.height =
 181                        _ISP_BQS(sc_3a_dis_height) >> SH_CSS_DIS_DECI_FACTOR_LOG2;
 182        dis->grid.pad.width  =
 183                        CEIL_SHIFT(_ISP_BQS(sc_3a_dis_padded_width), SH_CSS_DIS_DECI_FACTOR_LOG2);
 184        dis->grid.pad.height =
 185                        CEIL_SHIFT(_ISP_BQS(sc_3a_dis_height), SH_CSS_DIS_DECI_FACTOR_LOG2);
 186
 187        dis->coef.dim.width  =
 188                        (_ISP_BQS(sc_3a_dis_width)  >> SH_CSS_DIS_DECI_FACTOR_LOG2) << SH_CSS_DIS_DECI_FACTOR_LOG2;
 189        dis->coef.dim.height =
 190                        (_ISP_BQS(sc_3a_dis_height) >> SH_CSS_DIS_DECI_FACTOR_LOG2) << SH_CSS_DIS_DECI_FACTOR_LOG2;
 191        dis->coef.pad.width  =
 192                        __ISP_SDIS_HOR_COEF_NUM_VECS(sc_3a_dis_padded_width) * ISP_VEC_NELEMS;
 193        dis->coef.pad.height =
 194                        __ISP_SDIS_VER_COEF_NUM_VECS(sc_3a_dis_height) * ISP_VEC_NELEMS;
 195        if (isp_pipe_version == 1) {
 196                dis->proj.dim.width  =
 197                        _ISP_BQS(sc_3a_dis_height) >> SH_CSS_DIS_DECI_FACTOR_LOG2;
 198                dis->proj.dim.height =
 199                        _ISP_BQS(sc_3a_dis_width)  >> SH_CSS_DIS_DECI_FACTOR_LOG2;
 200        } else {
 201                dis->proj.dim.width  =
 202                        (_ISP_BQS(sc_3a_dis_width)  >> SH_CSS_DIS_DECI_FACTOR_LOG2) *
 203                        (_ISP_BQS(sc_3a_dis_height) >> SH_CSS_DIS_DECI_FACTOR_LOG2);
 204                dis->proj.dim.height =
 205                        (_ISP_BQS(sc_3a_dis_width)  >> SH_CSS_DIS_DECI_FACTOR_LOG2) *
 206                        (_ISP_BQS(sc_3a_dis_height) >> SH_CSS_DIS_DECI_FACTOR_LOG2);
 207        }
 208        dis->proj.pad.width  =
 209                        __ISP_SDIS_HOR_PROJ_NUM_ISP(sc_3a_dis_padded_width,
 210                                sc_3a_dis_height,
 211                                SH_CSS_DIS_DECI_FACTOR_LOG2,
 212                                isp_pipe_version);
 213        dis->proj.pad.height =
 214                        __ISP_SDIS_VER_PROJ_NUM_ISP(sc_3a_dis_padded_width,
 215                                SH_CSS_DIS_DECI_FACTOR_LOG2);
 216}
 217
 218void ia_css_sdis_clear_coefficients(
 219        struct ia_css_dvs_coefficients *dvs_coefs)
 220{
 221        dvs_coefs->hor_coefs = NULL;
 222        dvs_coefs->ver_coefs = NULL;
 223}
 224
 225enum ia_css_err
 226ia_css_get_dvs_statistics(
 227        struct ia_css_dvs_statistics           *host_stats,
 228        const struct ia_css_isp_dvs_statistics *isp_stats)
 229{
 230        struct ia_css_isp_dvs_statistics_map *map;
 231        enum ia_css_err ret = IA_CSS_SUCCESS;
 232
 233        IA_CSS_ENTER("host_stats=%p, isp_stats=%p", host_stats, isp_stats);
 234
 235        assert(host_stats != NULL);
 236        assert(isp_stats != NULL);
 237
 238        map = ia_css_isp_dvs_statistics_map_allocate(isp_stats, NULL);
 239        if (map) {
 240                mmgr_load(isp_stats->data_ptr, map->data_ptr, isp_stats->size);
 241                ia_css_translate_dvs_statistics(host_stats, map);
 242                ia_css_isp_dvs_statistics_map_free(map);
 243        } else {
 244                IA_CSS_ERROR("out of memory");
 245                ret = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
 246        }
 247
 248        IA_CSS_LEAVE_ERR(ret);
 249        return ret;
 250}
 251
 252void
 253ia_css_translate_dvs_statistics(
 254        struct ia_css_dvs_statistics               *host_stats,
 255        const struct ia_css_isp_dvs_statistics_map *isp_stats)
 256{
 257        unsigned int hor_num_isp, ver_num_isp, hor_num_dvs, ver_num_dvs, i;
 258        int32_t *hor_ptr_dvs, *ver_ptr_dvs, *hor_ptr_isp, *ver_ptr_isp;
 259
 260        assert(host_stats != NULL);
 261        assert(host_stats->hor_proj != NULL);
 262        assert(host_stats->ver_proj != NULL);
 263        assert(isp_stats != NULL);
 264        assert(isp_stats->hor_proj != NULL);
 265        assert(isp_stats->ver_proj != NULL);
 266
 267        IA_CSS_ENTER("hproj=%p, vproj=%p, haddr=%p, vaddr=%p",
 268                     host_stats->hor_proj, host_stats->ver_proj,
 269                     isp_stats->hor_proj, isp_stats->ver_proj);
 270
 271        hor_num_isp = host_stats->grid.aligned_height;
 272        ver_num_isp = host_stats->grid.aligned_width;
 273        hor_ptr_isp = isp_stats->hor_proj;
 274        ver_ptr_isp = isp_stats->ver_proj;
 275        hor_num_dvs = host_stats->grid.height;
 276        ver_num_dvs = host_stats->grid.width;
 277        hor_ptr_dvs = host_stats->hor_proj;
 278        ver_ptr_dvs = host_stats->ver_proj;
 279
 280        for (i = 0; i < IA_CSS_DVS_NUM_COEF_TYPES; i++) {
 281                memcpy(hor_ptr_dvs, hor_ptr_isp, hor_num_dvs * sizeof(int32_t));
 282                hor_ptr_isp += hor_num_isp;
 283                hor_ptr_dvs += hor_num_dvs;
 284
 285                memcpy(ver_ptr_dvs, ver_ptr_isp, ver_num_dvs * sizeof(int32_t));
 286                ver_ptr_isp += ver_num_isp;
 287                ver_ptr_dvs += ver_num_dvs;
 288        }
 289
 290        IA_CSS_LEAVE("void");
 291}
 292
 293struct ia_css_isp_dvs_statistics *
 294ia_css_isp_dvs_statistics_allocate(
 295        const struct ia_css_dvs_grid_info *grid)
 296{
 297        struct ia_css_isp_dvs_statistics *me;
 298        int hor_size, ver_size;
 299
 300        assert(grid != NULL);
 301
 302        IA_CSS_ENTER("grid=%p", grid);
 303
 304        if (!grid->enable)
 305                return NULL;
 306
 307        me = sh_css_calloc(1,sizeof(*me));
 308        if (!me)
 309                goto err;
 310
 311        hor_size = CEIL_MUL(sizeof(int) * IA_CSS_DVS_NUM_COEF_TYPES * grid->aligned_height,
 312                            HIVE_ISP_DDR_WORD_BYTES);
 313        ver_size = CEIL_MUL(sizeof(int) * IA_CSS_DVS_NUM_COEF_TYPES * grid->aligned_width,
 314                            HIVE_ISP_DDR_WORD_BYTES);
 315
 316
 317        me->size = hor_size + ver_size;
 318        me->data_ptr = mmgr_malloc(me->size);
 319        if (me->data_ptr == mmgr_NULL)
 320                goto err;
 321        me->hor_size = hor_size;
 322        me->hor_proj = me->data_ptr;
 323        me->ver_size = ver_size;
 324        me->ver_proj = me->data_ptr + hor_size;
 325
 326        IA_CSS_LEAVE("return=%p", me);
 327
 328        return me;
 329err:
 330        ia_css_isp_dvs_statistics_free(me);
 331
 332        IA_CSS_LEAVE("return=%p", NULL);
 333
 334        return NULL;
 335}
 336
 337struct ia_css_isp_dvs_statistics_map *
 338ia_css_isp_dvs_statistics_map_allocate(
 339        const struct ia_css_isp_dvs_statistics *isp_stats,
 340        void *data_ptr)
 341{
 342        struct ia_css_isp_dvs_statistics_map *me;
 343        /* Windows compiler does not like adding sizes to a void *
 344         * so we use a local char * instead. */
 345        char *base_ptr;
 346
 347        me = sh_css_malloc(sizeof(*me));
 348        if (!me) {
 349                IA_CSS_LOG("cannot allocate memory");
 350                goto err;
 351        }
 352
 353        me->data_ptr = data_ptr;
 354        me->data_allocated = data_ptr == NULL;
 355
 356        if (!me->data_ptr) {
 357                me->data_ptr = sh_css_malloc(isp_stats->size);
 358                if (!me->data_ptr) {
 359                        IA_CSS_LOG("cannot allocate memory");
 360                        goto err;
 361                }
 362        }
 363        base_ptr = me->data_ptr;
 364
 365        me->size = isp_stats->size;
 366        /* GCC complains when we assign a char * to a void *, so these
 367         * casts are necessary unfortunately. */
 368        me->hor_proj = (void*)base_ptr;
 369        me->ver_proj = (void*)(base_ptr + isp_stats->hor_size);
 370
 371        return me;
 372err:
 373        if (me)
 374                sh_css_free(me);
 375        return NULL;
 376}
 377
 378void
 379ia_css_isp_dvs_statistics_map_free(struct ia_css_isp_dvs_statistics_map *me)
 380{
 381        if (me) {
 382                if (me->data_allocated)
 383                        sh_css_free(me->data_ptr);
 384                sh_css_free(me);
 385        }
 386}
 387
 388void
 389ia_css_isp_dvs_statistics_free(struct ia_css_isp_dvs_statistics *me)
 390{
 391        if (me != NULL) {
 392                hmm_free(me->data_ptr);
 393                sh_css_free(me);
 394        }
 395}
 396
 397void ia_css_sdis_horicoef_debug_dtrace(
 398        const struct ia_css_dvs_coefficients *config, unsigned level)
 399{
 400        (void)config;
 401        (void)level;
 402}
 403
 404void ia_css_sdis_vertcoef_debug_dtrace(
 405        const struct ia_css_dvs_coefficients *config, unsigned level)
 406{
 407        (void)config;
 408        (void)level;
 409}
 410
 411void ia_css_sdis_horiproj_debug_dtrace(
 412        const struct ia_css_dvs_coefficients *config, unsigned level)
 413{
 414        (void)config;
 415        (void)level;
 416}
 417
 418void ia_css_sdis_vertproj_debug_dtrace(
 419        const struct ia_css_dvs_coefficients *config, unsigned level)
 420{
 421        (void)config;
 422        (void)level;
 423}
 424