usb: chipidea: imx: get available runtime dr mode for wakeup setting
[linux-block.git] / drivers / staging / media / atomisp / pci / isp / kernels / eed1_8 / ia_css_eed1_8.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 #ifndef IA_CSS_NO_DEBUG
16 #include "ia_css_debug.h"
17 #endif
18
19 #include "type_support.h"
20 #include "assert_support.h"
21 #include "math_support.h" /* for min and max */
22
23 #include "ia_css_eed1_8.host.h"
24
25 /* WARNING1: Number of inv points should be less or equal to 16,
26  * due to implementation limitation. See kernel design document
27  * for more details.
28  * WARNING2: Do not modify the number of inv points without correcting
29  * the EED1_8 kernel implementation assumptions.
30  */
31 #define NUMBER_OF_CHGRINV_POINTS 15
32 #define NUMBER_OF_TCINV_POINTS 9
33 #define NUMBER_OF_FCINV_POINTS 9
34
35 static const s16 chgrinv_x[NUMBER_OF_CHGRINV_POINTS] = {
36         0, 16, 64, 144, 272, 448, 672, 976,
37         1376, 1888, 2528, 3312, 4256, 5376, 6688
38 };
39
40 static const s16 chgrinv_a[NUMBER_OF_CHGRINV_POINTS] = {
41         -7171, -256, -29, -3456, -1071, -475, -189, -102,
42             -48, -38, -10, -9, -7, -6, 0
43     };
44
45 static const s16 chgrinv_b[NUMBER_OF_CHGRINV_POINTS] = {
46         8191, 1021, 256, 114, 60, 37, 24, 17,
47         12, 9, 6, 5, 4, 3, 2
48 };
49
50 static const s16 chgrinv_c[NUMBER_OF_CHGRINV_POINTS] = {
51         1, 1, 1, 0, 0, 0, 0, 0,
52         0, 0, 0, 0, 0, 0, 0
53 };
54
55 static const s16 tcinv_x[NUMBER_OF_TCINV_POINTS] = {
56         0, 4, 11, 23, 42, 68, 102, 148, 205
57 };
58
59 static const s16 tcinv_a[NUMBER_OF_TCINV_POINTS] = {
60         -6364, -631, -126, -34, -13, -6, -4452, -2156, 0
61     };
62
63 static const s16 tcinv_b[NUMBER_OF_TCINV_POINTS] = {
64         8191, 1828, 726, 352, 197, 121, 80, 55, 40
65 };
66
67 static const s16 tcinv_c[NUMBER_OF_TCINV_POINTS] = {
68         1, 1, 1, 1, 1, 1, 0, 0, 0
69 };
70
71 static const s16 fcinv_x[NUMBER_OF_FCINV_POINTS] = {
72         0, 80, 216, 456, 824, 1344, 2040, 2952, 4096
73 };
74
75 static const s16 fcinv_a[NUMBER_OF_FCINV_POINTS] = {
76         -5244, -486, -86, -2849, -961, -400, -180, -86, 0
77     };
78
79 static const s16 fcinv_b[NUMBER_OF_FCINV_POINTS] = {
80         8191, 1637, 607, 287, 159, 98, 64, 44, 32
81 };
82
83 static const s16 fcinv_c[NUMBER_OF_FCINV_POINTS] = {
84         1, 1, 1, 0, 0, 0, 0, 0, 0
85 };
86
87 void
88 ia_css_eed1_8_vmem_encode(
89     struct eed1_8_vmem_params *to,
90     const struct ia_css_eed1_8_config *from,
91     size_t size)
92 {
93         unsigned int i, j, base;
94         const unsigned int total_blocks = 4;
95         const unsigned int shuffle_block = 16;
96
97         (void)size;
98
99         /* Init */
100         for (i = 0; i < ISP_VEC_NELEMS; i++) {
101                 to->e_dew_enh_x[0][i] = 0;
102                 to->e_dew_enh_y[0][i] = 0;
103                 to->e_dew_enh_a[0][i] = 0;
104                 to->e_dew_enh_f[0][i] = 0;
105                 to->chgrinv_x[0][i] = 0;
106                 to->chgrinv_a[0][i] = 0;
107                 to->chgrinv_b[0][i] = 0;
108                 to->chgrinv_c[0][i] = 0;
109                 to->tcinv_x[0][i] = 0;
110                 to->tcinv_a[0][i] = 0;
111                 to->tcinv_b[0][i] = 0;
112                 to->tcinv_c[0][i] = 0;
113                 to->fcinv_x[0][i] = 0;
114                 to->fcinv_a[0][i] = 0;
115                 to->fcinv_b[0][i] = 0;
116                 to->fcinv_c[0][i] = 0;
117         }
118
119         /* Constraints on dew_enhance_seg_x and dew_enhance_seg_y:
120          * - values should be greater or equal to 0.
121          * - values should be ascending.
122          * - value of index zero is equal to 0.
123          */
124
125         /* Checking constraints: */
126         /* TODO: investigate if an assert is the right way to report that
127          * the constraints are violated.
128          */
129         for (j = 0; j < IA_CSS_NUMBER_OF_DEW_ENHANCE_SEGMENTS; j++) {
130                 assert(from->dew_enhance_seg_x[j] > -1);
131                 assert(from->dew_enhance_seg_y[j] > -1);
132         }
133
134         for (j = 1; j < IA_CSS_NUMBER_OF_DEW_ENHANCE_SEGMENTS; j++) {
135                 assert(from->dew_enhance_seg_x[j] > from->dew_enhance_seg_x[j - 1]);
136                 assert(from->dew_enhance_seg_y[j] > from->dew_enhance_seg_y[j - 1]);
137         }
138
139         assert(from->dew_enhance_seg_x[0] == 0);
140         assert(from->dew_enhance_seg_y[0] == 0);
141
142         /* Constraints on chgrinv_x, tcinv_x and fcinv_x:
143          * - values should be greater or equal to 0.
144          * - values should be ascending.
145          * - value of index zero is equal to 0.
146          */
147         assert(chgrinv_x[0] == 0);
148         assert(tcinv_x[0] == 0);
149         assert(fcinv_x[0] == 0);
150
151         for (j = 1; j < NUMBER_OF_CHGRINV_POINTS; j++) {
152                 assert(chgrinv_x[j] > chgrinv_x[j - 1]);
153         }
154
155         for (j = 1; j < NUMBER_OF_TCINV_POINTS; j++) {
156                 assert(tcinv_x[j] > tcinv_x[j - 1]);
157         }
158
159         for (j = 1; j < NUMBER_OF_FCINV_POINTS; j++) {
160                 assert(fcinv_x[j] > fcinv_x[j - 1]);
161         }
162
163         /* The implementation of the calulating 1/x is based on the availability
164          * of the OP_vec_shuffle16 operation.
165          * A 64 element vector is split up in 4 blocks of 16 element. Each array is copied to
166          * a vector 4 times, (starting at 0, 16, 32 and 48). All array elements are copied or
167          * initialised as described in the KFS. The remaining elements of a vector are set to 0.
168          */
169         /* TODO: guard this code with above assumptions */
170         for (i = 0; i < total_blocks; i++) {
171                 base = shuffle_block * i;
172
173                 for (j = 0; j < IA_CSS_NUMBER_OF_DEW_ENHANCE_SEGMENTS; j++) {
174                         to->e_dew_enh_x[0][base + j] = min_t(int, max_t(int,
175                                                              from->dew_enhance_seg_x[j], 0),
176                                                              8191);
177                         to->e_dew_enh_y[0][base + j] = min_t(int, max_t(int,
178                                                              from->dew_enhance_seg_y[j], -8192),
179                                                              8191);
180                 }
181
182                 for (j = 0; j < (IA_CSS_NUMBER_OF_DEW_ENHANCE_SEGMENTS - 1); j++) {
183                         to->e_dew_enh_a[0][base + j] = min_t(int, max_t(int,
184                                                              from->dew_enhance_seg_slope[j],
185                                                              -8192), 8191);
186                         /* Convert dew_enhance_seg_exp to flag:
187                          * 0 -> 0
188                          * 1...13 -> 1
189                          */
190                         to->e_dew_enh_f[0][base + j] = (min_t(int, max_t(int,
191                                                               from->dew_enhance_seg_exp[j],
192                                                               0), 13) > 0);
193                 }
194
195                 /* Hard-coded to 0, in order to be able to handle out of
196                  * range input in the same way as the other segments.
197                  * See KFS for more details.
198                  */
199                 to->e_dew_enh_a[0][base + (IA_CSS_NUMBER_OF_DEW_ENHANCE_SEGMENTS - 1)] = 0;
200                 to->e_dew_enh_f[0][base + (IA_CSS_NUMBER_OF_DEW_ENHANCE_SEGMENTS - 1)] = 0;
201
202                 for (j = 0; j < NUMBER_OF_CHGRINV_POINTS; j++) {
203                         to->chgrinv_x[0][base + j] = chgrinv_x[j];
204                         to->chgrinv_a[0][base + j] = chgrinv_a[j];
205                         to->chgrinv_b[0][base + j] = chgrinv_b[j];
206                         to->chgrinv_c[0][base + j] = chgrinv_c[j];
207                 }
208
209                 for (j = 0; j < NUMBER_OF_TCINV_POINTS; j++) {
210                         to->tcinv_x[0][base + j] = tcinv_x[j];
211                         to->tcinv_a[0][base + j] = tcinv_a[j];
212                         to->tcinv_b[0][base + j] = tcinv_b[j];
213                         to->tcinv_c[0][base + j] = tcinv_c[j];
214                 }
215
216                 for (j = 0; j < NUMBER_OF_FCINV_POINTS; j++) {
217                         to->fcinv_x[0][base + j] = fcinv_x[j];
218                         to->fcinv_a[0][base + j] = fcinv_a[j];
219                         to->fcinv_b[0][base + j] = fcinv_b[j];
220                         to->fcinv_c[0][base + j] = fcinv_c[j];
221                 }
222         }
223 }
224
225 void
226 ia_css_eed1_8_encode(
227     struct eed1_8_dmem_params *to,
228     const struct ia_css_eed1_8_config *from,
229     size_t size)
230 {
231         int i;
232         int min_exp = 0;
233
234         (void)size;
235
236         to->rbzp_strength = from->rbzp_strength;
237
238         to->fcstrength = from->fcstrength;
239         to->fcthres_0 = from->fcthres_0;
240         to->fc_sat_coef = from->fc_sat_coef;
241         to->fc_coring_prm = from->fc_coring_prm;
242         to->fc_slope = from->fcthres_1 - from->fcthres_0;
243
244         to->aerel_thres0 = from->aerel_thres0;
245         to->aerel_gain0 = from->aerel_gain0;
246         to->aerel_thres_diff = from->aerel_thres1 - from->aerel_thres0;
247         to->aerel_gain_diff = from->aerel_gain1 - from->aerel_gain0;
248
249         to->derel_thres0 = from->derel_thres0;
250         to->derel_gain0 = from->derel_gain0;
251         to->derel_thres_diff = (from->derel_thres1 - from->derel_thres0);
252         to->derel_gain_diff = (from->derel_gain1 - from->derel_gain0);
253
254         to->coring_pos0 = from->coring_pos0;
255         to->coring_pos_diff = (from->coring_pos1 - from->coring_pos0);
256         to->coring_neg0 = from->coring_neg0;
257         to->coring_neg_diff = (from->coring_neg1 - from->coring_neg0);
258
259         /* Note: (ISP_VEC_ELEMBITS -1)
260          * TODO: currently the testbench does not support to use
261          * ISP_VEC_ELEMBITS. Investigate how to fix this
262          */
263         to->gain_exp = (13 - from->gain_exp);
264         to->gain_pos0 = from->gain_pos0;
265         to->gain_pos_diff = (from->gain_pos1 - from->gain_pos0);
266         to->gain_neg0 = from->gain_neg0;
267         to->gain_neg_diff = (from->gain_neg1 - from->gain_neg0);
268
269         to->margin_pos0 = from->pos_margin0;
270         to->margin_pos_diff = (from->pos_margin1 - from->pos_margin0);
271         to->margin_neg0 = from->neg_margin0;
272         to->margin_neg_diff = (from->neg_margin1 - from->neg_margin0);
273
274         /* Encode DEWEnhance exp (e_dew_enh_asr) */
275         for (i = 0; i < (IA_CSS_NUMBER_OF_DEW_ENHANCE_SEGMENTS - 1); i++) {
276                 min_exp = max(min_exp, from->dew_enhance_seg_exp[i]);
277         }
278         to->e_dew_enh_asr = 13 - min(max(min_exp, 0), 13);
279
280         to->dedgew_max = from->dedgew_max;
281 }
282
283 void
284 ia_css_init_eed1_8_state(
285     void *state,
286     size_t size)
287 {
288         memset(state, 0, size);
289 }
290
291 #ifndef IA_CSS_NO_DEBUG
292 void
293 ia_css_eed1_8_debug_dtrace(
294     const struct ia_css_eed1_8_config *eed,
295     unsigned int level)
296 {
297         if (!eed)
298                 return;
299
300         ia_css_debug_dtrace(level, "Edge Enhancing Demosaic 1.8:\n");
301         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "rbzp_strength",
302                             eed->rbzp_strength);
303         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "fcstrength", eed->fcstrength);
304         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "fcthres_0", eed->fcthres_0);
305         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "fcthres_1", eed->fcthres_1);
306         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "fc_sat_coef", eed->fc_sat_coef);
307         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "fc_coring_prm",
308                             eed->fc_coring_prm);
309
310         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "aerel_thres0", eed->aerel_thres0);
311         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "aerel_gain0", eed->aerel_gain0);
312         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "aerel_thres1", eed->aerel_thres1);
313         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "aerel_gain1", eed->aerel_gain1);
314
315         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "derel_thres0", eed->derel_thres0);
316         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "derel_gain0", eed->derel_gain0);
317         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "derel_thres1", eed->derel_thres1);
318         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "derel_gain1", eed->derel_gain1);
319
320         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "coring_pos0", eed->coring_pos0);
321         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "coring_pos1", eed->coring_pos1);
322         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "coring_neg0", eed->coring_neg0);
323         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "coring_neg1", eed->coring_neg1);
324
325         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "gain_exp", eed->gain_exp);
326         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "gain_pos0", eed->gain_pos0);
327         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "gain_pos1", eed->gain_pos1);
328         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "gain_neg0", eed->gain_neg0);
329         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "gain_neg1", eed->gain_neg1);
330
331         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "pos_margin0", eed->pos_margin0);
332         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "pos_margin1", eed->pos_margin1);
333         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "neg_margin0", eed->neg_margin0);
334         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "neg_margin1", eed->neg_margin1);
335
336         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "dedgew_max", eed->dedgew_max);
337 }
338 #endif