GNU Linux-libre 4.14.259-gnu1
[releases.git] / drivers / staging / media / atomisp / pci / atomisp2 / css2400 / runtime / isys / src / virtual_isys.c
1 #ifndef ISP2401
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 #else
16 /**
17 Support for Intel Camera Imaging ISP subsystem.
18 Copyright (c) 2010 - 2015, Intel Corporation.
19
20 This program is free software; you can redistribute it and/or modify it
21 under the terms and conditions of the GNU General Public License,
22 version 2, as published by the Free Software Foundation.
23
24 This program is distributed in the hope it will be useful, but WITHOUT
25 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
26 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
27 more details.
28 */
29 #endif
30
31 #include "system_global.h"
32
33 #ifdef USE_INPUT_SYSTEM_VERSION_2401
34
35 #include "ia_css_isys.h"
36 #include "ia_css_debug.h"
37 #include "math_support.h"
38 #include "string_support.h"
39 #include "virtual_isys.h"
40 #include "isp.h"
41 #include "sh_css_defs.h"
42
43 /*************************************************
44  *
45  * Forwarded Declaration
46  *
47  *************************************************/
48 #ifndef ISP2401
49
50 #endif
51 static bool create_input_system_channel(
52         input_system_cfg_t      *cfg,
53         bool                    metadata,
54         input_system_channel_t  *channel);
55
56 static void destroy_input_system_channel(
57         input_system_channel_t  *channel);
58
59 static bool create_input_system_input_port(
60         input_system_cfg_t              *cfg,
61         input_system_input_port_t       *input_port);
62
63 static void destroy_input_system_input_port(
64         input_system_input_port_t       *input_port);
65
66 static bool calculate_input_system_channel_cfg(
67         input_system_channel_t          *channel,
68         input_system_input_port_t       *input_port,
69         input_system_cfg_t              *isys_cfg,
70         input_system_channel_cfg_t      *channel_cfg,
71         bool metadata);
72
73 static bool calculate_input_system_input_port_cfg(
74         input_system_channel_t          *channel,
75         input_system_input_port_t       *input_port,
76         input_system_cfg_t              *isys_cfg,
77         input_system_input_port_cfg_t   *input_port_cfg);
78
79 static bool acquire_sid(
80         stream2mmio_ID_t        stream2mmio,
81         stream2mmio_sid_ID_t    *sid);
82
83 static void release_sid(
84         stream2mmio_ID_t        stream2mmio,
85         stream2mmio_sid_ID_t    *sid);
86
87 static bool acquire_ib_buffer(
88         int32_t bits_per_pixel,
89         int32_t pixels_per_line,
90         int32_t lines_per_frame,
91         int32_t align_in_bytes,
92         bool online,
93         ib_buffer_t *buf);
94
95 static void release_ib_buffer(
96         ib_buffer_t *buf);
97
98 static bool acquire_dma_channel(
99         isys2401_dma_ID_t       dma_id,
100         isys2401_dma_channel    *channel);
101
102 static void release_dma_channel(
103         isys2401_dma_ID_t       dma_id,
104         isys2401_dma_channel    *channel);
105
106 static bool acquire_be_lut_entry(
107         csi_rx_backend_ID_t             backend,
108         csi_mipi_packet_type_t          packet_type,
109         csi_rx_backend_lut_entry_t      *entry);
110
111 static void release_be_lut_entry(
112         csi_rx_backend_ID_t             backend,
113         csi_mipi_packet_type_t          packet_type,
114         csi_rx_backend_lut_entry_t      *entry);
115
116 static bool calculate_tpg_cfg(
117         input_system_channel_t          *channel,
118         input_system_input_port_t       *input_port,
119         input_system_cfg_t              *isys_cfg,
120         pixelgen_tpg_cfg_t              *cfg);
121
122 static bool calculate_prbs_cfg(
123         input_system_channel_t          *channel,
124         input_system_input_port_t       *input_port,
125         input_system_cfg_t              *isys_cfg,
126         pixelgen_prbs_cfg_t             *cfg);
127
128 static bool calculate_fe_cfg(
129         const input_system_cfg_t        *isys_cfg,
130         csi_rx_frontend_cfg_t           *cfg);
131
132 static bool calculate_be_cfg(
133         const input_system_input_port_t *input_port,
134         const input_system_cfg_t        *isys_cfg,
135         bool                            metadata,
136         csi_rx_backend_cfg_t            *cfg);
137
138 static bool calculate_stream2mmio_cfg(
139         const input_system_cfg_t        *isys_cfg,
140         bool                            metadata,
141         stream2mmio_cfg_t               *cfg);
142
143 static bool calculate_ibuf_ctrl_cfg(
144         const input_system_channel_t    *channel,
145         const input_system_input_port_t *input_port,
146         const input_system_cfg_t        *isys_cfg,
147         ibuf_ctrl_cfg_t                 *cfg);
148
149 static bool calculate_isys2401_dma_cfg(
150         const input_system_channel_t    *channel,
151         const input_system_cfg_t        *isys_cfg,
152         isys2401_dma_cfg_t              *cfg);
153
154 static bool calculate_isys2401_dma_port_cfg(
155         const input_system_cfg_t        *isys_cfg,
156         bool                            raw_packed,
157         bool                            metadata,
158         isys2401_dma_port_cfg_t         *cfg);
159
160 static csi_mipi_packet_type_t get_csi_mipi_packet_type(
161         int32_t data_type);
162
163 static int32_t calculate_stride(
164         int32_t bits_per_pixel,
165         int32_t pixels_per_line,
166         bool    raw_packed,
167         int32_t align_in_bytes);
168
169 /** end of Forwarded Declaration */
170
171 /**************************************************
172  *
173  * Public Methods
174  *
175  **************************************************/
176 ia_css_isys_error_t ia_css_isys_stream_create(
177         ia_css_isys_descr_t     *isys_stream_descr,
178         ia_css_isys_stream_h    isys_stream,
179         uint32_t isys_stream_id)
180 {
181         ia_css_isys_error_t rc;
182
183         if (isys_stream_descr == NULL || isys_stream == NULL ||
184                 isys_stream_id >= SH_CSS_MAX_ISYS_CHANNEL_NODES)
185                 return  false;
186
187         ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
188                 "ia_css_isys_stream_create() enter:\n");
189
190         /*Reset isys_stream to 0*/
191         memset(isys_stream, 0, sizeof(*isys_stream));
192         isys_stream->enable_metadata = isys_stream_descr->metadata.enable;
193         isys_stream->id = isys_stream_id;
194
195         isys_stream->linked_isys_stream_id = isys_stream_descr->linked_isys_stream_id;
196         rc = create_input_system_input_port(isys_stream_descr, &(isys_stream->input_port));
197         if (rc == false)
198                 return false;
199
200         rc = create_input_system_channel(isys_stream_descr, false, &(isys_stream->channel));
201         if (rc == false) {
202                 destroy_input_system_input_port(&isys_stream->input_port);
203                 return false;
204         }
205
206 #ifdef ISP2401
207         /*
208          * Early polling is required for timestamp accuracy in certain cause.
209          * The ISYS HW polling is started on
210          * ia_css_isys_stream_capture_indication() instead of
211          * ia_css_pipeline_sp_wait_for_isys_stream_N() as isp processing of
212          * capture takes longer than getting an ISYS frame
213          */
214         isys_stream->polling_mode = isys_stream_descr->polling_mode;
215
216 #endif
217         /* create metadata channel */
218         if (isys_stream_descr->metadata.enable) {
219                 rc = create_input_system_channel(isys_stream_descr, true, &isys_stream->md_channel);
220                 if (rc == false) {
221                         destroy_input_system_input_port(&isys_stream->input_port);
222                         destroy_input_system_channel(&isys_stream->channel);
223                         return false;
224                 }
225         }
226         ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
227                 "ia_css_isys_stream_create() leave:\n");
228
229         return true;
230 }
231
232 void ia_css_isys_stream_destroy(
233         ia_css_isys_stream_h    isys_stream)
234 {
235         destroy_input_system_input_port(&isys_stream->input_port);
236         destroy_input_system_channel(&(isys_stream->channel));
237         if (isys_stream->enable_metadata) {
238                 /* Destroy metadata channel only if its allocated*/
239                 destroy_input_system_channel(&isys_stream->md_channel);
240         }
241 }
242
243 ia_css_isys_error_t ia_css_isys_stream_calculate_cfg(
244         ia_css_isys_stream_h            isys_stream,
245         ia_css_isys_descr_t             *isys_stream_descr,
246         ia_css_isys_stream_cfg_t        *isys_stream_cfg)
247 {
248         ia_css_isys_error_t rc;
249
250         if (isys_stream_cfg == NULL             ||
251                 isys_stream_descr == NULL       ||
252                 isys_stream == NULL)
253                 return false;
254
255         ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
256                 "ia_css_isys_stream_calculate_cfg() enter:\n");
257
258         rc  = calculate_input_system_channel_cfg(
259                         &(isys_stream->channel),
260                         &(isys_stream->input_port),
261                         isys_stream_descr,
262                         &(isys_stream_cfg->channel_cfg),
263                         false);
264         if (rc == false)
265                 return false;
266
267         /* configure metadata channel */
268         if (isys_stream_descr->metadata.enable) {
269                 isys_stream_cfg->enable_metadata = true;
270                 rc  = calculate_input_system_channel_cfg(
271                                 &isys_stream->md_channel,
272                                 &isys_stream->input_port,
273                                 isys_stream_descr,
274                                 &isys_stream_cfg->md_channel_cfg,
275                                 true);
276                 if (rc == false)
277                         return false;
278         }
279
280         rc = calculate_input_system_input_port_cfg(
281                         &(isys_stream->channel),
282                         &(isys_stream->input_port),
283                         isys_stream_descr,
284                         &(isys_stream_cfg->input_port_cfg));
285         if (rc == false)
286                 return false;
287
288         isys_stream->valid = 1;
289         isys_stream_cfg->valid = 1;
290         ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
291                 "ia_css_isys_stream_calculate_cfg() leave:\n");
292         return rc;
293 }
294
295 /** end of Public Methods */
296
297 /**************************************************
298  *
299  * Private Methods
300  *
301  **************************************************/
302 static bool create_input_system_channel(
303         input_system_cfg_t      *cfg,
304         bool                    metadata,
305         input_system_channel_t  *me)
306 {
307         bool rc = true;
308
309         me->dma_id = ISYS2401_DMA0_ID;
310
311         switch (cfg->input_port_id) {
312         case INPUT_SYSTEM_CSI_PORT0_ID:
313         case INPUT_SYSTEM_PIXELGEN_PORT0_ID:
314                 me->stream2mmio_id = STREAM2MMIO0_ID;
315                 me->ibuf_ctrl_id = IBUF_CTRL0_ID;
316                 break;
317
318         case INPUT_SYSTEM_CSI_PORT1_ID:
319         case INPUT_SYSTEM_PIXELGEN_PORT1_ID:
320                 me->stream2mmio_id = STREAM2MMIO1_ID;
321                 me->ibuf_ctrl_id = IBUF_CTRL1_ID;
322                 break;
323
324         case INPUT_SYSTEM_CSI_PORT2_ID:
325         case INPUT_SYSTEM_PIXELGEN_PORT2_ID:
326                 me->stream2mmio_id = STREAM2MMIO2_ID;
327                 me->ibuf_ctrl_id = IBUF_CTRL2_ID;
328                 break;
329         default:
330                 rc = false;
331                 break;
332         }
333
334         if (rc == false)
335                 return false;
336
337         if (!acquire_sid(me->stream2mmio_id, &(me->stream2mmio_sid_id))) {
338                 return false;
339         }
340
341         if (!acquire_ib_buffer(
342                         metadata ? cfg->metadata.bits_per_pixel : cfg->input_port_resolution.bits_per_pixel,
343                         metadata ? cfg->metadata.pixels_per_line : cfg->input_port_resolution.pixels_per_line,
344                         metadata ? cfg->metadata.lines_per_frame : cfg->input_port_resolution.lines_per_frame,
345                         metadata ? cfg->metadata.align_req_in_bytes : cfg->input_port_resolution.align_req_in_bytes,
346                         cfg->online,
347                         &(me->ib_buffer))) {
348                 release_sid(me->stream2mmio_id, &(me->stream2mmio_sid_id));
349                 return false;
350         }
351
352         if (!acquire_dma_channel(me->dma_id, &(me->dma_channel))) {
353                 release_sid(me->stream2mmio_id, &(me->stream2mmio_sid_id));
354                 release_ib_buffer(&(me->ib_buffer));
355                 return false;
356         }
357
358         return true;
359 }
360
361 static void destroy_input_system_channel(
362         input_system_channel_t  *me)
363 {
364         release_sid(me->stream2mmio_id,
365                 &(me->stream2mmio_sid_id));
366
367         release_ib_buffer(&(me->ib_buffer));
368
369         release_dma_channel(me->dma_id, &(me->dma_channel));
370 }
371
372 static bool create_input_system_input_port(
373         input_system_cfg_t              *cfg,
374         input_system_input_port_t       *me)
375 {
376         csi_mipi_packet_type_t packet_type;
377         bool rc = true;
378
379         switch (cfg->input_port_id) {
380         case INPUT_SYSTEM_CSI_PORT0_ID:
381                 me->csi_rx.frontend_id = CSI_RX_FRONTEND0_ID;
382                 me->csi_rx.backend_id = CSI_RX_BACKEND0_ID;
383
384                 packet_type = get_csi_mipi_packet_type(cfg->csi_port_attr.fmt_type);
385                 me->csi_rx.packet_type = packet_type;
386
387                 rc = acquire_be_lut_entry(
388                                 me->csi_rx.backend_id,
389                                 packet_type,
390                                 &(me->csi_rx.backend_lut_entry));
391                 break;
392         case INPUT_SYSTEM_PIXELGEN_PORT0_ID:
393                 me->pixelgen.pixelgen_id = PIXELGEN0_ID;
394                 break;
395         case INPUT_SYSTEM_CSI_PORT1_ID:
396                 me->csi_rx.frontend_id = CSI_RX_FRONTEND1_ID;
397                 me->csi_rx.backend_id = CSI_RX_BACKEND1_ID;
398
399                 packet_type = get_csi_mipi_packet_type(cfg->csi_port_attr.fmt_type);
400                 me->csi_rx.packet_type = packet_type;
401
402                 rc = acquire_be_lut_entry(
403                                 me->csi_rx.backend_id,
404                                 packet_type,
405                                 &(me->csi_rx.backend_lut_entry));
406                 break;
407         case INPUT_SYSTEM_PIXELGEN_PORT1_ID:
408                 me->pixelgen.pixelgen_id = PIXELGEN1_ID;
409
410                 break;
411         case INPUT_SYSTEM_CSI_PORT2_ID:
412                 me->csi_rx.frontend_id = CSI_RX_FRONTEND2_ID;
413                 me->csi_rx.backend_id = CSI_RX_BACKEND2_ID;
414
415                 packet_type = get_csi_mipi_packet_type(cfg->csi_port_attr.fmt_type);
416                 me->csi_rx.packet_type = packet_type;
417
418                 rc = acquire_be_lut_entry(
419                                 me->csi_rx.backend_id,
420                                 packet_type,
421                                 &(me->csi_rx.backend_lut_entry));
422                 break;
423         case INPUT_SYSTEM_PIXELGEN_PORT2_ID:
424                 me->pixelgen.pixelgen_id = PIXELGEN2_ID;
425                 break;
426         default:
427                 rc = false;
428                 break;
429         }
430
431         me->source_type = cfg->mode;
432
433         /* for metadata */
434         me->metadata.packet_type = CSI_MIPI_PACKET_TYPE_UNDEFINED;
435         if (rc && cfg->metadata.enable) {
436                 me->metadata.packet_type = get_csi_mipi_packet_type(
437                                 cfg->metadata.fmt_type);
438                 rc = acquire_be_lut_entry(
439                                 me->csi_rx.backend_id,
440                                 me->metadata.packet_type,
441                                 &me->metadata.backend_lut_entry);
442         }
443
444         return rc;
445 }
446
447 static void destroy_input_system_input_port(
448         input_system_input_port_t       *me)
449 {
450         if (me->source_type == INPUT_SYSTEM_SOURCE_TYPE_SENSOR) {
451                 release_be_lut_entry(
452                                 me->csi_rx.backend_id,
453                                 me->csi_rx.packet_type,
454                                 &me->csi_rx.backend_lut_entry);
455         }
456
457         if (me->metadata.packet_type != CSI_MIPI_PACKET_TYPE_UNDEFINED) {
458                 /*Free the backend lut allocated for metadata*/
459                 release_be_lut_entry(
460                                 me->csi_rx.backend_id,
461                                 me->metadata.packet_type,
462                                 &me->metadata.backend_lut_entry);
463         }
464 }
465
466 static bool calculate_input_system_channel_cfg(
467         input_system_channel_t          *channel,
468         input_system_input_port_t       *input_port,
469         input_system_cfg_t              *isys_cfg,
470         input_system_channel_cfg_t      *channel_cfg,
471         bool metadata)
472 {
473         bool rc;
474
475         rc = calculate_stream2mmio_cfg(isys_cfg, metadata,
476                         &(channel_cfg->stream2mmio_cfg));
477         if (rc == false)
478                 return false;
479
480         rc = calculate_ibuf_ctrl_cfg(
481                         channel,
482                         input_port,
483                         isys_cfg,
484                         &(channel_cfg->ibuf_ctrl_cfg));
485         if (rc == false)
486                 return false;
487         if (metadata)
488                 channel_cfg->ibuf_ctrl_cfg.stores_per_frame = isys_cfg->metadata.lines_per_frame;
489
490         rc = calculate_isys2401_dma_cfg(
491                         channel,
492                         isys_cfg,
493                         &(channel_cfg->dma_cfg));
494         if (rc == false)
495                 return false;
496
497         rc = calculate_isys2401_dma_port_cfg(
498                         isys_cfg,
499                         false,
500                         metadata,
501                         &(channel_cfg->dma_src_port_cfg));
502         if (rc == false)
503                 return false;
504
505         rc = calculate_isys2401_dma_port_cfg(
506                         isys_cfg,
507                         isys_cfg->raw_packed,
508                         metadata,
509                         &(channel_cfg->dma_dest_port_cfg));
510         if (rc == false)
511                 return false;
512
513         return true;
514 }
515
516 static bool calculate_input_system_input_port_cfg(
517         input_system_channel_t          *channel,
518         input_system_input_port_t       *input_port,
519         input_system_cfg_t              *isys_cfg,
520         input_system_input_port_cfg_t   *input_port_cfg)
521 {
522         bool rc;
523
524         switch (input_port->source_type) {
525         case INPUT_SYSTEM_SOURCE_TYPE_SENSOR:
526                 rc  = calculate_fe_cfg(
527                                 isys_cfg,
528                                 &(input_port_cfg->csi_rx_cfg.frontend_cfg));
529
530                 rc &= calculate_be_cfg(
531                                 input_port,
532                                 isys_cfg,
533                                 false,
534                                 &(input_port_cfg->csi_rx_cfg.backend_cfg));
535
536                 if (rc && isys_cfg->metadata.enable)
537                         rc &= calculate_be_cfg(input_port, isys_cfg, true,
538                                         &input_port_cfg->csi_rx_cfg.md_backend_cfg);
539                 break;
540         case INPUT_SYSTEM_SOURCE_TYPE_TPG:
541                 rc = calculate_tpg_cfg(
542                                 channel,
543                                 input_port,
544                                 isys_cfg,
545                                 &(input_port_cfg->pixelgen_cfg.tpg_cfg));
546                 break;
547         case INPUT_SYSTEM_SOURCE_TYPE_PRBS:
548                 rc = calculate_prbs_cfg(
549                                 channel,
550                                 input_port,
551                                 isys_cfg,
552                                 &(input_port_cfg->pixelgen_cfg.prbs_cfg));
553                 break;
554         default:
555                 rc = false;
556                 break;
557         }
558
559         return rc;
560 }
561
562 static bool acquire_sid(
563         stream2mmio_ID_t        stream2mmio,
564         stream2mmio_sid_ID_t    *sid)
565 {
566         return ia_css_isys_stream2mmio_sid_rmgr_acquire(stream2mmio, sid);
567 }
568
569 static void release_sid(
570         stream2mmio_ID_t        stream2mmio,
571         stream2mmio_sid_ID_t    *sid)
572 {
573         ia_css_isys_stream2mmio_sid_rmgr_release(stream2mmio, sid);
574 }
575
576 /* See also: ia_css_dma_configure_from_info() */
577 static int32_t calculate_stride(
578         int32_t bits_per_pixel,
579         int32_t pixels_per_line,
580         bool    raw_packed,
581         int32_t align_in_bytes)
582 {
583         int32_t bytes_per_line;
584         int32_t pixels_per_word;
585         int32_t words_per_line;
586         int32_t pixels_per_line_padded;
587
588         pixels_per_line_padded = CEIL_MUL(pixels_per_line, align_in_bytes);
589
590         if (!raw_packed)
591                 bits_per_pixel = CEIL_MUL(bits_per_pixel, 8);
592
593         pixels_per_word = HIVE_ISP_DDR_WORD_BITS / bits_per_pixel;
594         words_per_line  = ceil_div(pixels_per_line_padded, pixels_per_word);
595         bytes_per_line  = HIVE_ISP_DDR_WORD_BYTES * words_per_line;
596
597         return bytes_per_line;
598 }
599
600 static bool acquire_ib_buffer(
601         int32_t bits_per_pixel,
602         int32_t pixels_per_line,
603         int32_t lines_per_frame,
604         int32_t align_in_bytes,
605         bool online,
606         ib_buffer_t *buf)
607 {
608         buf->stride = calculate_stride(bits_per_pixel, pixels_per_line, false, align_in_bytes);
609         if (online)
610                 buf->lines = 4; /* use double buffering for online usecases */
611         else
612                 buf->lines = 2;
613
614         (void)(lines_per_frame);
615         return ia_css_isys_ibuf_rmgr_acquire(buf->stride * buf->lines, &buf->start_addr);
616 }
617
618 static void release_ib_buffer(
619         ib_buffer_t *buf)
620 {
621         ia_css_isys_ibuf_rmgr_release(&buf->start_addr);
622 }
623
624 static bool acquire_dma_channel(
625         isys2401_dma_ID_t       dma_id,
626         isys2401_dma_channel    *channel)
627 {
628         return ia_css_isys_dma_channel_rmgr_acquire(dma_id, channel);
629 }
630
631 static void release_dma_channel(
632         isys2401_dma_ID_t       dma_id,
633         isys2401_dma_channel    *channel)
634 {
635         ia_css_isys_dma_channel_rmgr_release(dma_id, channel);
636 }
637
638 static bool acquire_be_lut_entry(
639         csi_rx_backend_ID_t             backend,
640         csi_mipi_packet_type_t          packet_type,
641         csi_rx_backend_lut_entry_t      *entry)
642 {
643         return ia_css_isys_csi_rx_lut_rmgr_acquire(backend, packet_type, entry);
644 }
645
646 static void release_be_lut_entry(
647         csi_rx_backend_ID_t             backend,
648         csi_mipi_packet_type_t          packet_type,
649         csi_rx_backend_lut_entry_t      *entry)
650 {
651         ia_css_isys_csi_rx_lut_rmgr_release(backend, packet_type, entry);
652 }
653
654 static bool calculate_tpg_cfg(
655         input_system_channel_t          *channel,
656         input_system_input_port_t       *input_port,
657         input_system_cfg_t              *isys_cfg,
658         pixelgen_tpg_cfg_t              *cfg)
659 {
660         (void)channel;
661         (void)input_port;
662
663         memcpy_s(
664                 (void *)cfg,
665                 sizeof(pixelgen_tpg_cfg_t),
666                 (void *)(&(isys_cfg->tpg_port_attr)),
667                 sizeof(pixelgen_tpg_cfg_t));
668         return true;
669 }
670
671 static bool calculate_prbs_cfg(
672         input_system_channel_t          *channel,
673         input_system_input_port_t       *input_port,
674         input_system_cfg_t              *isys_cfg,
675         pixelgen_prbs_cfg_t             *cfg)
676 {
677         (void)channel;
678         (void)input_port;
679
680         memcpy_s(
681                 (void *)cfg,
682                 sizeof(pixelgen_prbs_cfg_t),
683                 (void *)(&(isys_cfg->prbs_port_attr)),
684                 sizeof(pixelgen_prbs_cfg_t));
685         return true;
686 }
687
688 static bool calculate_fe_cfg(
689         const input_system_cfg_t        *isys_cfg,
690         csi_rx_frontend_cfg_t           *cfg)
691 {
692         cfg->active_lanes = isys_cfg->csi_port_attr.active_lanes;
693         return true;
694 }
695
696 static bool calculate_be_cfg(
697         const input_system_input_port_t *input_port,
698         const input_system_cfg_t        *isys_cfg,
699         bool                            metadata,
700         csi_rx_backend_cfg_t            *cfg)
701 {
702
703         memcpy_s(
704                 (void *)(&cfg->lut_entry),
705                 sizeof(csi_rx_backend_lut_entry_t),
706                 metadata ? (void *)(&input_port->metadata.backend_lut_entry) :
707                         (void *)(&input_port->csi_rx.backend_lut_entry),
708                 sizeof(csi_rx_backend_lut_entry_t));
709
710         cfg->csi_mipi_cfg.virtual_channel = isys_cfg->csi_port_attr.ch_id;
711         if (metadata) {
712                 cfg->csi_mipi_packet_type = get_csi_mipi_packet_type(isys_cfg->metadata.fmt_type);
713                 cfg->csi_mipi_cfg.comp_enable = false;
714                 cfg->csi_mipi_cfg.data_type = isys_cfg->metadata.fmt_type;
715         }
716         else {
717                 cfg->csi_mipi_packet_type = get_csi_mipi_packet_type(isys_cfg->csi_port_attr.fmt_type);
718                 cfg->csi_mipi_cfg.data_type = isys_cfg->csi_port_attr.fmt_type;
719                 cfg->csi_mipi_cfg.comp_enable = isys_cfg->csi_port_attr.comp_enable;
720                 cfg->csi_mipi_cfg.comp_scheme = isys_cfg->csi_port_attr.comp_scheme;
721                 cfg->csi_mipi_cfg.comp_predictor = isys_cfg->csi_port_attr.comp_predictor;
722                 cfg->csi_mipi_cfg.comp_bit_idx = cfg->csi_mipi_cfg.data_type - MIPI_FORMAT_CUSTOM0;
723         }
724
725         return true;
726 }
727
728 static bool calculate_stream2mmio_cfg(
729         const input_system_cfg_t        *isys_cfg,
730         bool                            metadata,
731         stream2mmio_cfg_t               *cfg
732 )
733 {
734         cfg->bits_per_pixel = metadata ? isys_cfg->metadata.bits_per_pixel :
735                 isys_cfg->input_port_resolution.bits_per_pixel;
736
737         cfg->enable_blocking =
738                 ((isys_cfg->mode == INPUT_SYSTEM_SOURCE_TYPE_TPG) ||
739                  (isys_cfg->mode == INPUT_SYSTEM_SOURCE_TYPE_PRBS));
740
741         return true;
742 }
743
744 static bool calculate_ibuf_ctrl_cfg(
745         const input_system_channel_t    *channel,
746         const input_system_input_port_t *input_port,
747         const input_system_cfg_t        *isys_cfg,
748         ibuf_ctrl_cfg_t                 *cfg)
749 {
750         const int32_t bits_per_byte = 8;
751         int32_t bits_per_pixel;
752         int32_t bytes_per_pixel;
753         int32_t left_padding;
754
755         (void)input_port;
756
757         bits_per_pixel = isys_cfg->input_port_resolution.bits_per_pixel;
758         bytes_per_pixel = ceil_div(bits_per_pixel, bits_per_byte);
759
760         left_padding = CEIL_MUL(isys_cfg->output_port_attr.left_padding, ISP_VEC_NELEMS)
761                         * bytes_per_pixel;
762
763         cfg->online     = isys_cfg->online;
764
765         cfg->dma_cfg.channel    = channel->dma_channel;
766         cfg->dma_cfg.cmd        = _DMA_V2_MOVE_A2B_NO_SYNC_CHK_COMMAND;
767
768         cfg->dma_cfg.shift_returned_items       = 0;
769         cfg->dma_cfg.elems_per_word_in_ibuf     = 0;
770         cfg->dma_cfg.elems_per_word_in_dest     = 0;
771
772         cfg->ib_buffer.start_addr               = channel->ib_buffer.start_addr;
773         cfg->ib_buffer.stride                   = channel->ib_buffer.stride;
774         cfg->ib_buffer.lines                    = channel->ib_buffer.lines;
775
776         /*
777 #ifndef ISP2401
778          * zhengjie.lu@intel.com:
779 #endif
780          * "dest_buf_cfg" should be part of the input system output
781          * port configuration.
782          *
783          * TODO: move "dest_buf_cfg" to the input system output
784          * port configuration.
785          */
786
787         /* input_buf addr only available in sched mode;
788            this buffer is allocated in isp, crun mode addr
789            can be passed by after ISP allocation */
790         if (cfg->online) {
791                 cfg->dest_buf_cfg.start_addr    = ISP_INPUT_BUF_START_ADDR + left_padding;
792                 cfg->dest_buf_cfg.stride        = bytes_per_pixel
793                         * isys_cfg->output_port_attr.max_isp_input_width;
794                 cfg->dest_buf_cfg.lines         = LINES_OF_ISP_INPUT_BUF;
795         } else if (isys_cfg->raw_packed) {
796                 cfg->dest_buf_cfg.stride        = calculate_stride(bits_per_pixel,
797                                                         isys_cfg->input_port_resolution.pixels_per_line,
798                                                         isys_cfg->raw_packed,
799                                                         isys_cfg->input_port_resolution.align_req_in_bytes);
800         } else {
801                 cfg->dest_buf_cfg.stride        = channel->ib_buffer.stride;
802         }
803
804         /*
805 #ifndef ISP2401
806          * zhengjie.lu@intel.com:
807 #endif
808          * "items_per_store" is hard coded as "1", which is ONLY valid
809          * when the CSI-MIPI long packet is transferred.
810          *
811          * TODO: After the 1st stage of MERR+,  make the proper solution to
812          * configure "items_per_store" so that it can also handle the CSI-MIPI
813          * short packet.
814          */
815         cfg->items_per_store            = 1;
816
817         cfg->stores_per_frame           = isys_cfg->input_port_resolution.lines_per_frame;
818
819
820         cfg->stream2mmio_cfg.sync_cmd   = _STREAM2MMIO_CMD_TOKEN_SYNC_FRAME;
821
822         /* TODO: Define conditions as when to use store words vs store packets */
823         cfg->stream2mmio_cfg.store_cmd  = _STREAM2MMIO_CMD_TOKEN_STORE_PACKETS;
824
825         return true;
826 }
827
828 static bool calculate_isys2401_dma_cfg(
829         const input_system_channel_t    *channel,
830         const input_system_cfg_t        *isys_cfg,
831         isys2401_dma_cfg_t              *cfg)
832 {
833         cfg->channel    = channel->dma_channel;
834
835         /* only online/sensor mode goto vmem
836            offline/buffered_sensor, tpg and prbs will go to ddr */
837         if (isys_cfg->online)
838                 cfg->connection = isys2401_dma_ibuf_to_vmem_connection;
839         else
840                 cfg->connection = isys2401_dma_ibuf_to_ddr_connection;
841
842         cfg->extension  = isys2401_dma_zero_extension;
843         cfg->height     = 1;
844
845         return true;
846 }
847
848 /* See also: ia_css_dma_configure_from_info() */
849 static bool calculate_isys2401_dma_port_cfg(
850         const input_system_cfg_t        *isys_cfg,
851         bool                            raw_packed,
852         bool                            metadata,
853         isys2401_dma_port_cfg_t         *cfg)
854 {
855         int32_t bits_per_pixel;
856         int32_t pixels_per_line;
857         int32_t align_req_in_bytes;
858
859         /* TODO: Move metadata away from isys_cfg to application layer */
860         if (metadata) {
861                 bits_per_pixel = isys_cfg->metadata.bits_per_pixel;
862                 pixels_per_line = isys_cfg->metadata.pixels_per_line;
863                 align_req_in_bytes = isys_cfg->metadata.align_req_in_bytes;
864         } else {
865                 bits_per_pixel = isys_cfg->input_port_resolution.bits_per_pixel;
866                 pixels_per_line = isys_cfg->input_port_resolution.pixels_per_line;
867                 align_req_in_bytes = isys_cfg->input_port_resolution.align_req_in_bytes;
868         }
869
870         cfg->stride     = calculate_stride(bits_per_pixel, pixels_per_line, raw_packed, align_req_in_bytes);
871
872         if (!raw_packed)
873                 bits_per_pixel = CEIL_MUL(bits_per_pixel, 8);
874
875         cfg->elements   = HIVE_ISP_DDR_WORD_BITS / bits_per_pixel;
876         cfg->cropping   = 0;
877         cfg->width      = CEIL_DIV(cfg->stride, HIVE_ISP_DDR_WORD_BYTES);
878
879         return true;
880 }
881
882 static csi_mipi_packet_type_t get_csi_mipi_packet_type(
883         int32_t data_type)
884 {
885         csi_mipi_packet_type_t packet_type;
886
887         packet_type = CSI_MIPI_PACKET_TYPE_RESERVED;
888
889         if (data_type >= 0 && data_type <= MIPI_FORMAT_SHORT8)
890                 packet_type = CSI_MIPI_PACKET_TYPE_SHORT;
891
892         if (data_type > MIPI_FORMAT_SHORT8 && data_type <= N_MIPI_FORMAT)
893                 packet_type = CSI_MIPI_PACKET_TYPE_LONG;
894
895         return packet_type;
896 }
897 /** end of Private Methods */
898 #endif