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