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