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