linux/drivers/staging/media/atomisp/pci/isp/kernels/sdis/sdis_2/ia_css_sdis2.host.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Support for Intel Camera Imaging ISP subsystem.
   4 * Copyright (c) 2015, Intel Corporation.
   5 *
   6 * This program is free software; you can redistribute it and/or modify it
   7 * under the terms and conditions of the GNU General Public License,
   8 * version 2, as published by the Free Software Foundation.
   9 *
  10 * This program is distributed in the hope it will be useful, but WITHOUT
  11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  13 * more details.
  14 */
  15
  16#include "hmm.h"
  17
  18#include <assert_support.h>
  19#include "ia_css_debug.h"
  20#include "ia_css_sdis2.host.h"
  21
  22const struct ia_css_dvs2_coefficients default_sdis2_config = {
  23        .grid = { 0, 0, 0, 0, 0, 0, 0, 0 },
  24        .hor_coefs = { NULL, NULL, NULL, NULL },
  25        .ver_coefs = { NULL, NULL, NULL, NULL },
  26};
  27
  28static void
  29fill_row(short *private, const short *public, unsigned int width,
  30         unsigned int padding)
  31{
  32        memcpy(private, public, width * sizeof(short));
  33        memset(&private[width], 0, padding * sizeof(short));
  34}
  35
  36void ia_css_sdis2_horicoef_vmem_encode(
  37    struct sh_css_isp_sdis_hori_coef_tbl *to,
  38    const struct ia_css_dvs2_coefficients *from,
  39    unsigned int size)
  40{
  41        unsigned int aligned_width = from->grid.aligned_width *
  42                                     from->grid.bqs_per_grid_cell;
  43        unsigned int width         = from->grid.num_hor_coefs;
  44        int      padding       = aligned_width - width;
  45        unsigned int stride        = size / IA_CSS_DVS2_NUM_COEF_TYPES / sizeof(short);
  46        unsigned int total_bytes   = aligned_width * IA_CSS_DVS2_NUM_COEF_TYPES *
  47                                     sizeof(short);
  48        short   *private       = (short *)to;
  49
  50        /* Copy the table, add padding */
  51        assert(padding >= 0);
  52        assert(total_bytes <= size);
  53        assert(size % (IA_CSS_DVS2_NUM_COEF_TYPES * ISP_VEC_NELEMS * sizeof(
  54                           short)) == 0);
  55        fill_row(&private[0 * stride], from->hor_coefs.odd_real,  width, padding);
  56        fill_row(&private[1 * stride], from->hor_coefs.odd_imag,  width, padding);
  57        fill_row(&private[2 * stride], from->hor_coefs.even_real, width, padding);
  58        fill_row(&private[3 * stride], from->hor_coefs.even_imag, width, padding);
  59}
  60
  61void ia_css_sdis2_vertcoef_vmem_encode(
  62    struct sh_css_isp_sdis_vert_coef_tbl *to,
  63    const struct ia_css_dvs2_coefficients *from,
  64    unsigned int size)
  65{
  66        unsigned int aligned_height = from->grid.aligned_height *
  67                                      from->grid.bqs_per_grid_cell;
  68        unsigned int height         = from->grid.num_ver_coefs;
  69        int      padding        = aligned_height - height;
  70        unsigned int stride         = size / IA_CSS_DVS2_NUM_COEF_TYPES / sizeof(short);
  71        unsigned int total_bytes    = aligned_height * IA_CSS_DVS2_NUM_COEF_TYPES *
  72                                      sizeof(short);
  73        short   *private        = (short *)to;
  74
  75        /* Copy the table, add padding */
  76        assert(padding >= 0);
  77        assert(total_bytes <= size);
  78        assert(size % (IA_CSS_DVS2_NUM_COEF_TYPES * ISP_VEC_NELEMS * sizeof(
  79                           short)) == 0);
  80        fill_row(&private[0 * stride], from->ver_coefs.odd_real,  height, padding);
  81        fill_row(&private[1 * stride], from->ver_coefs.odd_imag,  height, padding);
  82        fill_row(&private[2 * stride], from->ver_coefs.even_real, height, padding);
  83        fill_row(&private[3 * stride], from->ver_coefs.even_imag, height, padding);
  84}
  85
  86void ia_css_sdis2_horiproj_encode(
  87    struct sh_css_isp_sdis_hori_proj_tbl *to,
  88    const struct ia_css_dvs2_coefficients *from,
  89    unsigned int size)
  90{
  91        (void)to;
  92        (void)from;
  93        (void)size;
  94}
  95
  96void ia_css_sdis2_vertproj_encode(
  97    struct sh_css_isp_sdis_vert_proj_tbl *to,
  98    const struct ia_css_dvs2_coefficients *from,
  99    unsigned int size)
 100{
 101        (void)to;
 102        (void)from;
 103        (void)size;
 104}
 105
 106void ia_css_get_isp_dvs2_coefficients(
 107    struct ia_css_stream *stream,
 108    short *hor_coefs_odd_real,
 109    short *hor_coefs_odd_imag,
 110    short *hor_coefs_even_real,
 111    short *hor_coefs_even_imag,
 112    short *ver_coefs_odd_real,
 113    short *ver_coefs_odd_imag,
 114    short *ver_coefs_even_real,
 115    short *ver_coefs_even_imag)
 116{
 117        struct ia_css_isp_parameters *params;
 118        unsigned int hor_num_3a, ver_num_3a;
 119        struct ia_css_binary *dvs_binary;
 120
 121        IA_CSS_ENTER("void");
 122
 123        assert(stream);
 124        assert(hor_coefs_odd_real);
 125        assert(hor_coefs_odd_imag);
 126        assert(hor_coefs_even_real);
 127        assert(hor_coefs_even_imag);
 128        assert(ver_coefs_odd_real);
 129        assert(ver_coefs_odd_imag);
 130        assert(ver_coefs_even_real);
 131        assert(ver_coefs_even_imag);
 132
 133        params = stream->isp_params_configs;
 134
 135        /* Only video pipe supports DVS */
 136        dvs_binary = ia_css_stream_get_dvs_binary(stream);
 137        if (!dvs_binary)
 138                return;
 139
 140        hor_num_3a  = dvs_binary->dis.coef.dim.width;
 141        ver_num_3a  = dvs_binary->dis.coef.dim.height;
 142
 143        memcpy(hor_coefs_odd_real,  params->dvs2_coefs.hor_coefs.odd_real,
 144               hor_num_3a * sizeof(short));
 145        memcpy(hor_coefs_odd_imag,  params->dvs2_coefs.hor_coefs.odd_imag,
 146               hor_num_3a * sizeof(short));
 147        memcpy(hor_coefs_even_real, params->dvs2_coefs.hor_coefs.even_real,
 148               hor_num_3a * sizeof(short));
 149        memcpy(hor_coefs_even_imag, params->dvs2_coefs.hor_coefs.even_imag,
 150               hor_num_3a * sizeof(short));
 151        memcpy(ver_coefs_odd_real,  params->dvs2_coefs.ver_coefs.odd_real,
 152               ver_num_3a * sizeof(short));
 153        memcpy(ver_coefs_odd_imag,  params->dvs2_coefs.ver_coefs.odd_imag,
 154               ver_num_3a * sizeof(short));
 155        memcpy(ver_coefs_even_real, params->dvs2_coefs.ver_coefs.even_real,
 156               ver_num_3a * sizeof(short));
 157        memcpy(ver_coefs_even_imag, params->dvs2_coefs.ver_coefs.even_imag,
 158               ver_num_3a * sizeof(short));
 159
 160        IA_CSS_LEAVE("void");
 161}
 162
 163void ia_css_sdis2_clear_coefficients(
 164    struct ia_css_dvs2_coefficients *dvs2_coefs)
 165{
 166        dvs2_coefs->hor_coefs.odd_real  = NULL;
 167        dvs2_coefs->hor_coefs.odd_imag  = NULL;
 168        dvs2_coefs->hor_coefs.even_real = NULL;
 169        dvs2_coefs->hor_coefs.even_imag = NULL;
 170        dvs2_coefs->ver_coefs.odd_real  = NULL;
 171        dvs2_coefs->ver_coefs.odd_imag  = NULL;
 172        dvs2_coefs->ver_coefs.even_real = NULL;
 173        dvs2_coefs->ver_coefs.even_imag = NULL;
 174}
 175
 176int
 177ia_css_get_dvs2_statistics(
 178    struct ia_css_dvs2_statistics          *host_stats,
 179    const struct ia_css_isp_dvs_statistics *isp_stats) {
 180        struct ia_css_isp_dvs_statistics_map *map;
 181        int ret = 0;
 182
 183        IA_CSS_ENTER("host_stats=%p, isp_stats=%p", host_stats, isp_stats);
 184
 185        assert(host_stats);
 186        assert(isp_stats);
 187
 188        map = ia_css_isp_dvs_statistics_map_allocate(isp_stats, NULL);
 189        if (map)
 190        {
 191                hmm_load(isp_stats->data_ptr, map->data_ptr, isp_stats->size);
 192                ia_css_translate_dvs2_statistics(host_stats, map);
 193                ia_css_isp_dvs_statistics_map_free(map);
 194        } else
 195        {
 196                IA_CSS_ERROR("out of memory");
 197                ret = -ENOMEM;
 198        }
 199
 200        IA_CSS_LEAVE_ERR(ret);
 201        return ret;
 202}
 203
 204void
 205ia_css_translate_dvs2_statistics(
 206    struct ia_css_dvs2_statistics                  *host_stats,
 207    const struct ia_css_isp_dvs_statistics_map *isp_stats)
 208{
 209        unsigned int size_bytes, table_width, table_size, height;
 210        unsigned int src_offset = 0, dst_offset = 0;
 211        s32 *htemp_ptr, *vtemp_ptr;
 212
 213        assert(host_stats);
 214        assert(host_stats->hor_prod.odd_real);
 215        assert(host_stats->hor_prod.odd_imag);
 216        assert(host_stats->hor_prod.even_real);
 217        assert(host_stats->hor_prod.even_imag);
 218        assert(host_stats->ver_prod.odd_real);
 219        assert(host_stats->ver_prod.odd_imag);
 220        assert(host_stats->ver_prod.even_real);
 221        assert(host_stats->ver_prod.even_imag);
 222        assert(isp_stats);
 223        assert(isp_stats->hor_proj);
 224        assert(isp_stats->ver_proj);
 225
 226        IA_CSS_ENTER("hor_coefs.odd_real=%p, hor_coefs.odd_imag=%p, hor_coefs.even_real=%p, hor_coefs.even_imag=%p, ver_coefs.odd_real=%p, ver_coefs.odd_imag=%p, ver_coefs.even_real=%p, ver_coefs.even_imag=%p, haddr=%p, vaddr=%p",
 227                     host_stats->hor_prod.odd_real, host_stats->hor_prod.odd_imag,
 228                     host_stats->hor_prod.even_real, host_stats->hor_prod.even_imag,
 229                     host_stats->ver_prod.odd_real, host_stats->ver_prod.odd_imag,
 230                     host_stats->ver_prod.even_real, host_stats->ver_prod.even_imag,
 231                     isp_stats->hor_proj, isp_stats->ver_proj);
 232
 233        /* Host side: reflecting the true width in bytes */
 234        size_bytes = host_stats->grid.aligned_width * sizeof(*htemp_ptr);
 235
 236        /* DDR side: need to be aligned to the system bus width */
 237        /* statistics table width in terms of 32-bit words*/
 238        table_width = CEIL_MUL(size_bytes,
 239                               HIVE_ISP_DDR_WORD_BYTES) / sizeof(*htemp_ptr);
 240        table_size = table_width * host_stats->grid.aligned_height;
 241
 242        htemp_ptr = isp_stats->hor_proj; /* horizontal stats */
 243        vtemp_ptr = isp_stats->ver_proj; /* vertical stats */
 244        for (height = 0; height < host_stats->grid.aligned_height; height++) {
 245                /* hor stats */
 246                memcpy(host_stats->hor_prod.odd_real + dst_offset,
 247                       &htemp_ptr[0 * table_size + src_offset], size_bytes);
 248                memcpy(host_stats->hor_prod.odd_imag + dst_offset,
 249                       &htemp_ptr[1 * table_size + src_offset], size_bytes);
 250                memcpy(host_stats->hor_prod.even_real + dst_offset,
 251                       &htemp_ptr[2 * table_size + src_offset], size_bytes);
 252                memcpy(host_stats->hor_prod.even_imag + dst_offset,
 253                       &htemp_ptr[3 * table_size + src_offset], size_bytes);
 254
 255                /* ver stats */
 256                memcpy(host_stats->ver_prod.odd_real + dst_offset,
 257                       &vtemp_ptr[0 * table_size + src_offset], size_bytes);
 258                memcpy(host_stats->ver_prod.odd_imag + dst_offset,
 259                       &vtemp_ptr[1 * table_size + src_offset], size_bytes);
 260                memcpy(host_stats->ver_prod.even_real + dst_offset,
 261                       &vtemp_ptr[2 * table_size + src_offset], size_bytes);
 262                memcpy(host_stats->ver_prod.even_imag + dst_offset,
 263                       &vtemp_ptr[3 * table_size + src_offset], size_bytes);
 264
 265                src_offset += table_width; /* aligned table width */
 266                dst_offset += host_stats->grid.aligned_width;
 267        }
 268
 269        IA_CSS_LEAVE("void");
 270}
 271
 272struct ia_css_isp_dvs_statistics *
 273ia_css_isp_dvs2_statistics_allocate(
 274    const struct ia_css_dvs_grid_info *grid)
 275{
 276        struct ia_css_isp_dvs_statistics *me;
 277        int size;
 278
 279        assert(grid);
 280
 281        IA_CSS_ENTER("grid=%p", grid);
 282
 283        if (!grid->enable)
 284                return NULL;
 285
 286        me = kvcalloc(1, sizeof(*me), GFP_KERNEL);
 287        if (!me)
 288                goto err;
 289
 290        /* on ISP 2 SDIS DMA model, every row of projection table width must be
 291           aligned to HIVE_ISP_DDR_WORD_BYTES
 292        */
 293        size = CEIL_MUL(sizeof(int) * grid->aligned_width, HIVE_ISP_DDR_WORD_BYTES)
 294               * grid->aligned_height * IA_CSS_DVS2_NUM_COEF_TYPES;
 295
 296        me->size = 2 * size;
 297        me->data_ptr = hmm_alloc(me->size, HMM_BO_PRIVATE, 0, NULL, 0);
 298        if (me->data_ptr == mmgr_NULL)
 299                goto err;
 300        me->hor_proj = me->data_ptr;
 301        me->hor_size = size;
 302        me->ver_proj = me->data_ptr + size;
 303        me->ver_size = size;
 304
 305        IA_CSS_LEAVE("return=%p", me);
 306        return me;
 307err:
 308        ia_css_isp_dvs2_statistics_free(me);
 309        IA_CSS_LEAVE("return=%p", NULL);
 310
 311        return NULL;
 312}
 313
 314void
 315ia_css_isp_dvs2_statistics_free(struct ia_css_isp_dvs_statistics *me)
 316{
 317        if (me) {
 318                hmm_free(me->data_ptr);
 319                kvfree(me);
 320        }
 321}
 322
 323void ia_css_sdis2_horicoef_debug_dtrace(
 324    const struct ia_css_dvs2_coefficients *config, unsigned int level)
 325{
 326        (void)config;
 327        (void)level;
 328}
 329
 330void ia_css_sdis2_vertcoef_debug_dtrace(
 331    const struct ia_css_dvs2_coefficients *config, unsigned int level)
 332{
 333        (void)config;
 334        (void)level;
 335}
 336
 337void ia_css_sdis2_horiproj_debug_dtrace(
 338    const struct ia_css_dvs2_coefficients *config, unsigned int level)
 339{
 340        (void)config;
 341        (void)level;
 342}
 343
 344void ia_css_sdis2_vertproj_debug_dtrace(
 345    const struct ia_css_dvs2_coefficients *config, unsigned int level)
 346{
 347        (void)config;
 348        (void)level;
 349}
 350