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