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