linux/drivers/staging/media/atomisp/pci/isp/kernels/ctc/ctc2/ia_css_ctc2.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 "ia_css_types.h"
  17#include "sh_css_defs.h"
  18#include "assert_support.h"
  19
  20#include "ia_css_ctc2.host.h"
  21
  22#define INEFFECTIVE_VAL 4096
  23#define BASIC_VAL 819
  24
  25/*Default configuration of parameters for Ctc2*/
  26const struct ia_css_ctc2_config default_ctc2_config = {
  27        INEFFECTIVE_VAL, INEFFECTIVE_VAL, INEFFECTIVE_VAL,
  28        INEFFECTIVE_VAL, INEFFECTIVE_VAL, INEFFECTIVE_VAL,
  29        BASIC_VAL * 2, BASIC_VAL * 4, BASIC_VAL * 6,
  30        BASIC_VAL * 8, INEFFECTIVE_VAL, INEFFECTIVE_VAL,
  31        BASIC_VAL >> 1, BASIC_VAL
  32};
  33
  34/* (dydx) = ctc2_slope(y1, y0, x1, x0)
  35 * -----------------------------------------------
  36 * Calculation of the Slope of a Line = ((y1 - y0) >> 8)/(x1 - x0)
  37 *
  38 * Note: y1, y0 , x1 & x0 must lie within the range 0 <-> 8191
  39 */
  40static int ctc2_slope(int y1, int y0, int x1, int x0)
  41{
  42        const int shift_val = 8;
  43        const int max_slope = (1 << IA_CSS_CTC_COEF_SHIFT) - 1;
  44        int dy = y1 - y0;
  45        int dx = x1 - x0;
  46        int rounding = (dx + 1) >> 1;
  47        int dy_shift = dy << shift_val;
  48        int slope, dydx;
  49
  50        /*Protection for parameter values, & avoiding zero divisions*/
  51        assert(y0 >= 0 && y0 <= max_slope);
  52        assert(y1 >= 0 && y1 <= max_slope);
  53        assert(x0 >= 0 && x0 <= max_slope);
  54        assert(x1 > 0 && x1 <= max_slope);
  55        assert(dx > 0);
  56
  57        if (dy < 0)
  58                rounding = -rounding;
  59        slope = (int)(dy_shift + rounding) / dx;
  60
  61        /*the slope must lie within the range
  62          (-max_slope-1) >= (dydx) >= (max_slope)
  63        */
  64        if (slope <= -max_slope - 1) {
  65                dydx = -max_slope - 1;
  66        } else if (slope >= max_slope) {
  67                dydx = max_slope;
  68        } else {
  69                dydx = slope;
  70        }
  71
  72        return dydx;
  73}
  74
  75/* (void) = ia_css_ctc2_vmem_encode(*to, *from)
  76 * -----------------------------------------------
  77 * VMEM Encode Function to translate Y parameters from userspace into ISP space
  78 */
  79void ia_css_ctc2_vmem_encode(struct ia_css_isp_ctc2_vmem_params *to,
  80                             const struct ia_css_ctc2_config *from,
  81                             size_t size)
  82{
  83        unsigned int i, j;
  84        const unsigned int shffl_blck = 4;
  85        const unsigned int length_zeros = 11;
  86        short dydx0, dydx1, dydx2, dydx3, dydx4;
  87
  88        (void)size;
  89        /*
  90        *  Calculation of slopes of lines interconnecting
  91        *  0.0 -> y_x1 -> y_x2 -> y _x3 -> y_x4 -> 1.0
  92        */
  93        dydx0 = ctc2_slope(from->y_y1, from->y_y0,
  94                           from->y_x1, 0);
  95        dydx1 = ctc2_slope(from->y_y2, from->y_y1,
  96                           from->y_x2, from->y_x1);
  97        dydx2 = ctc2_slope(from->y_y3, from->y_y2,
  98                           from->y_x3, from->y_x2);
  99        dydx3 = ctc2_slope(from->y_y4, from->y_y3,
 100                           from->y_x4, from->y_x3);
 101        dydx4 = ctc2_slope(from->y_y5, from->y_y4,
 102                           SH_CSS_BAYER_MAXVAL, from->y_x4);
 103
 104        /*Fill 3 arrays with:
 105         * - Luma input gain values y_y0, y_y1, y_y2, y_3, y_y4
 106         * - Luma kneepoints 0, y_x1, y_x2, y_x3, y_x4
 107         * - Calculated slopes dydx0, dyxd1, dydx2, dydx3, dydx4
 108         *
 109         * - Each 64-element array is divided in blocks of 16 elements:
 110         *   the 5 parameters + zeros in the remaining 11 positions
 111         * - All blocks of the same array will contain the same data
 112         */
 113        for (i = 0; i < shffl_blck; i++) {
 114                to->y_x[0][(i << shffl_blck)]     = 0;
 115                to->y_x[0][(i << shffl_blck) + 1] = from->y_x1;
 116                to->y_x[0][(i << shffl_blck) + 2] = from->y_x2;
 117                to->y_x[0][(i << shffl_blck) + 3] = from->y_x3;
 118                to->y_x[0][(i << shffl_blck) + 4] = from->y_x4;
 119
 120                to->y_y[0][(i << shffl_blck)]     = from->y_y0;
 121                to->y_y[0][(i << shffl_blck) + 1] = from->y_y1;
 122                to->y_y[0][(i << shffl_blck) + 2] = from->y_y2;
 123                to->y_y[0][(i << shffl_blck) + 3] = from->y_y3;
 124                to->y_y[0][(i << shffl_blck) + 4] = from->y_y4;
 125
 126                to->e_y_slope[0][(i << shffl_blck)]    = dydx0;
 127                to->e_y_slope[0][(i << shffl_blck) + 1] = dydx1;
 128                to->e_y_slope[0][(i << shffl_blck) + 2] = dydx2;
 129                to->e_y_slope[0][(i << shffl_blck) + 3] = dydx3;
 130                to->e_y_slope[0][(i << shffl_blck) + 4] = dydx4;
 131
 132                for (j = 0; j < length_zeros; j++) {
 133                        to->y_x[0][(i << shffl_blck) + 5 + j] = 0;
 134                        to->y_y[0][(i << shffl_blck) + 5 + j] = 0;
 135                        to->e_y_slope[0][(i << shffl_blck) + 5 + j] = 0;
 136                }
 137        }
 138}
 139
 140/* (void) = ia_css_ctc2_encode(*to, *from)
 141 * -----------------------------------------------
 142 * DMEM Encode Function to translate UV parameters from userspace into ISP space
 143 */
 144void ia_css_ctc2_encode(struct ia_css_isp_ctc2_dmem_params *to,
 145                        struct ia_css_ctc2_config *from,
 146                        size_t size)
 147{
 148        (void)size;
 149
 150        to->uv_y0 = from->uv_y0;
 151        to->uv_y1 = from->uv_y1;
 152        to->uv_x0 = from->uv_x0;
 153        to->uv_x1 = from->uv_x1;
 154
 155        /*Slope Calculation*/
 156        to->uv_dydx = ctc2_slope(from->uv_y1, from->uv_y0,
 157                                 from->uv_x1, from->uv_x0);
 158}
 159