GNU Linux-libre 4.14.265-gnu1
[releases.git] / drivers / staging / media / atomisp / pci / atomisp2 / css2400 / isp / kernels / bnlm / ia_css_bnlm.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 "type_support.h"
16 #include "ia_css_bnlm.host.h"
17
18 #ifndef IA_CSS_NO_DEBUG
19 #include "ia_css_debug.h" /* ia_css_debug_dtrace() */
20 #endif
21 #include <assert_support.h>
22
23 #define BNLM_DIV_LUT_SIZE       (12)
24 static const int32_t div_lut_nearests[BNLM_DIV_LUT_SIZE] = {
25         0, 454, 948, 1484, 2070, 2710, 3412, 4184, 5035, 5978, 7025, 8191
26 };
27
28 static const int32_t div_lut_slopes[BNLM_DIV_LUT_SIZE] = {
29         -7760, -6960, -6216, -5536, -4912, -4344, -3832, -3360, -2936, -2552, -2208, -2208
30 };
31
32 static const int32_t div_lut_intercepts[BNLM_DIV_LUT_SIZE] = {
33         8184, 7752, 7336, 6928, 6536, 6152, 5776, 5416, 5064, 4728, 4408, 4408
34 };
35
36 /* Encodes a look-up table from BNLM public parameters to vmem parameters.
37  * Input:
38  *      lut     :       bnlm_lut struct containing encoded vmem parameters look-up table
39  *      lut_thr :       array containing threshold values for lut
40  *      lut_val :       array containing output values related to lut_thr
41  *      lut_size:       Size of lut_val array
42  */
43 static inline void
44 bnlm_lut_encode(struct bnlm_lut *lut, const int32_t *lut_thr, const int32_t *lut_val, const uint32_t lut_size)
45 {
46         u32 blk, i;
47         const u32 block_size = 16;
48         const u32 total_blocks = ISP_VEC_NELEMS / block_size;
49
50         /* Create VMEM LUTs from the threshold and value arrays.
51          *
52          * Min size of the LUT is 2 entries.
53          *
54          * Max size of the LUT is 16 entries, so that the LUT can fit into a
55          * single group of 16 elements inside a vector.
56          * Then these elements are copied into other groups inside the same
57          * vector. If the LUT size is less than 16, then remaining elements are
58          * set to 0.
59          */
60         assert((lut_size >= 2) && (lut_size <= block_size));
61         /* array lut_thr has (lut_size-1) entries */
62         for (i = 0; i < lut_size-2; i++) {
63                 /* Check if the lut_thr is monotonically increasing */
64                 assert(lut_thr[i] <= lut_thr[i+1]);
65         }
66
67         /* Initialize */
68         for (i = 0; i < total_blocks * block_size; i++) {
69                 lut->thr[0][i] = 0;
70                 lut->val[0][i] = 0;
71         }
72
73         /* Copy all data */
74         for (i = 0; i < lut_size - 1; i++) {
75                 lut->thr[0][i] = lut_thr[i];
76                 lut->val[0][i] = lut_val[i];
77         }
78         lut->val[0][i] = lut_val[i]; /* val has one more element than thr */
79
80         /* Copy data from first block to all blocks */
81         for (blk = 1; blk < total_blocks; blk++) {
82                 u32 blk_offset = blk * block_size;
83                 for (i = 1; i < lut_size; i++) {
84                         lut->thr[0][blk_offset + i] = lut->thr[0][i];
85                         lut->val[0][blk_offset + i] = lut->val[0][i];
86                 }
87         }
88 }
89
90 /*
91  * - Encodes BNLM public parameters into VMEM parameters
92  * - Generates VMEM parameters which will needed internally ISP
93  */
94 void
95 ia_css_bnlm_vmem_encode(
96                         struct bnlm_vmem_params *to,
97                         const struct ia_css_bnlm_config *from,
98                         size_t size)
99 {
100         int i;
101         (void)size;
102
103         /* Initialize LUTs in VMEM parameters */
104         bnlm_lut_encode(&to->mu_root_lut, from->mu_root_lut_thr, from->mu_root_lut_val, 16);
105         bnlm_lut_encode(&to->sad_norm_lut, from->sad_norm_lut_thr, from->sad_norm_lut_val, 16);
106         bnlm_lut_encode(&to->sig_detail_lut, from->sig_detail_lut_thr, from->sig_detail_lut_val, 16);
107         bnlm_lut_encode(&to->sig_rad_lut, from->sig_rad_lut_thr, from->sig_rad_lut_val, 16);
108         bnlm_lut_encode(&to->rad_pow_lut, from->rad_pow_lut_thr, from->rad_pow_lut_val, 16);
109         bnlm_lut_encode(&to->nl_0_lut, from->nl_0_lut_thr, from->nl_0_lut_val, 16);
110         bnlm_lut_encode(&to->nl_1_lut, from->nl_1_lut_thr, from->nl_1_lut_val, 16);
111         bnlm_lut_encode(&to->nl_2_lut, from->nl_2_lut_thr, from->nl_2_lut_val, 16);
112         bnlm_lut_encode(&to->nl_3_lut, from->nl_3_lut_thr, from->nl_3_lut_val, 16);
113
114         /* Initialize arrays in VMEM parameters */
115         memset(to->nl_th, 0, sizeof(to->nl_th));
116         to->nl_th[0][0] = from->nl_th[0];
117         to->nl_th[0][1] = from->nl_th[1];
118         to->nl_th[0][2] = from->nl_th[2];
119
120         memset(to->match_quality_max_idx, 0, sizeof(to->match_quality_max_idx));
121         to->match_quality_max_idx[0][0] = from->match_quality_max_idx[0];
122         to->match_quality_max_idx[0][1] = from->match_quality_max_idx[1];
123         to->match_quality_max_idx[0][2] = from->match_quality_max_idx[2];
124         to->match_quality_max_idx[0][3] = from->match_quality_max_idx[3];
125
126         bnlm_lut_encode(&to->div_lut, div_lut_nearests, div_lut_slopes, BNLM_DIV_LUT_SIZE);
127         memset(to->div_lut_intercepts, 0, sizeof(to->div_lut_intercepts));
128         for(i = 0; i < BNLM_DIV_LUT_SIZE; i++) {
129                 to->div_lut_intercepts[0][i] = div_lut_intercepts[i];
130         }
131
132         memset(to->power_of_2, 0, sizeof(to->power_of_2));
133         for (i = 0; i < (ISP_VEC_ELEMBITS-1); i++) {
134                 to->power_of_2[0][i] = 1 << i;
135         }
136 }
137
138 /* - Encodes BNLM public parameters into DMEM parameters */
139 void
140 ia_css_bnlm_encode(
141         struct bnlm_dmem_params *to,
142         const struct ia_css_bnlm_config *from,
143         size_t size)
144 {
145         (void)size;
146         to->rad_enable = from->rad_enable;
147         to->rad_x_origin = from->rad_x_origin;
148         to->rad_y_origin = from->rad_y_origin;
149         to->avg_min_th = from->avg_min_th;
150         to->max_min_th = from->max_min_th;
151
152         to->exp_coeff_a = from->exp_coeff_a;
153         to->exp_coeff_b = from->exp_coeff_b;
154         to->exp_coeff_c = from->exp_coeff_c;
155         to->exp_exponent = from->exp_exponent;
156 }
157
158 /* Prints debug traces for BNLM public parameters */
159 void
160 ia_css_bnlm_debug_trace(
161         const struct ia_css_bnlm_config *config,
162         unsigned level)
163 {
164         if (!config)
165                 return;
166
167 #ifndef IA_CSS_NO_DEBUG
168         ia_css_debug_dtrace(level, "BNLM:\n");
169         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "rad_enable", config->rad_enable);
170         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "rad_x_origin", config->rad_x_origin);
171         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "rad_y_origin", config->rad_y_origin);
172         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "avg_min_th", config->avg_min_th);
173         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "max_min_th", config->max_min_th);
174
175         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "exp_coeff_a", config->exp_coeff_a);
176         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "exp_coeff_b", config->exp_coeff_b);
177         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "exp_coeff_c", config->exp_coeff_c);
178         ia_css_debug_dtrace(level, "\t%-32s = %d\n", "exp_exponent", config->exp_exponent);
179
180         /* ToDo: print traces for LUTs */
181 #endif /* IA_CSS_NO_DEBUG */
182
183 }