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
893