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 	/* create metadata channel */
193 	if (isys_stream_descr->metadata.enable) {
194 		rc = create_input_system_channel(isys_stream_descr, true,
195 						 &isys_stream->md_channel);
196 		if (!rc) {
197 			destroy_input_system_input_port(&isys_stream->input_port);
198 			destroy_input_system_channel(&isys_stream->channel);
199 			return false;
200 		}
201 	}
202 	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
203 			    "ia_css_isys_stream_create() leave:\n");
204 
205 	return true;
206 }
207 
ia_css_isys_stream_destroy(ia_css_isys_stream_h isys_stream)208 void ia_css_isys_stream_destroy(
209     ia_css_isys_stream_h	isys_stream)
210 {
211 	destroy_input_system_input_port(&isys_stream->input_port);
212 	destroy_input_system_channel(&isys_stream->channel);
213 	if (isys_stream->enable_metadata) {
214 		/* Destroy metadata channel only if its allocated*/
215 		destroy_input_system_channel(&isys_stream->md_channel);
216 	}
217 }
218 
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)219 ia_css_isys_error_t ia_css_isys_stream_calculate_cfg(
220     ia_css_isys_stream_h		isys_stream,
221     ia_css_isys_descr_t		*isys_stream_descr,
222     ia_css_isys_stream_cfg_t	*isys_stream_cfg)
223 {
224 	ia_css_isys_error_t rc;
225 
226 	if (!isys_stream_cfg		||
227 	    !isys_stream_descr	||
228 	    !isys_stream)
229 		return false;
230 
231 	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
232 			    "ia_css_isys_stream_calculate_cfg() enter:\n");
233 
234 	rc  = calculate_input_system_channel_cfg(
235 		  &isys_stream->channel,
236 		  &isys_stream->input_port,
237 		  isys_stream_descr,
238 		  &isys_stream_cfg->channel_cfg,
239 		  false);
240 	if (!rc)
241 		return false;
242 
243 	/* configure metadata channel */
244 	if (isys_stream_descr->metadata.enable) {
245 		isys_stream_cfg->enable_metadata = true;
246 		rc  = calculate_input_system_channel_cfg(
247 			  &isys_stream->md_channel,
248 			  &isys_stream->input_port,
249 			  isys_stream_descr,
250 			  &isys_stream_cfg->md_channel_cfg,
251 			  true);
252 		if (!rc)
253 			return false;
254 	}
255 
256 	rc = calculate_input_system_input_port_cfg(
257 		 &isys_stream->channel,
258 		 &isys_stream->input_port,
259 		 isys_stream_descr,
260 		 &isys_stream_cfg->input_port_cfg);
261 	if (!rc)
262 		return false;
263 
264 	isys_stream->valid = 1;
265 	isys_stream_cfg->valid = 1;
266 	ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
267 			    "ia_css_isys_stream_calculate_cfg() leave:\n");
268 	return rc;
269 }
270 
271 /* end of Public Methods */
272 
273 /**************************************************
274  *
275  * Private Methods
276  *
277  **************************************************/
create_input_system_channel(isp2401_input_system_cfg_t * cfg,bool metadata,input_system_channel_t * me)278 static bool create_input_system_channel(
279     isp2401_input_system_cfg_t	*cfg,
280     bool			metadata,
281     input_system_channel_t	*me)
282 {
283 	bool rc = true;
284 
285 	me->dma_id = ISYS2401_DMA0_ID;
286 
287 	switch (cfg->input_port_id) {
288 	case INPUT_SYSTEM_CSI_PORT0_ID:
289 	case INPUT_SYSTEM_PIXELGEN_PORT0_ID:
290 		me->stream2mmio_id = STREAM2MMIO0_ID;
291 		me->ibuf_ctrl_id = IBUF_CTRL0_ID;
292 		break;
293 
294 	case INPUT_SYSTEM_CSI_PORT1_ID:
295 	case INPUT_SYSTEM_PIXELGEN_PORT1_ID:
296 		me->stream2mmio_id = STREAM2MMIO1_ID;
297 		me->ibuf_ctrl_id = IBUF_CTRL1_ID;
298 		break;
299 
300 	case INPUT_SYSTEM_CSI_PORT2_ID:
301 	case INPUT_SYSTEM_PIXELGEN_PORT2_ID:
302 		me->stream2mmio_id = STREAM2MMIO2_ID;
303 		me->ibuf_ctrl_id = IBUF_CTRL2_ID;
304 		break;
305 	default:
306 		rc = false;
307 		break;
308 	}
309 
310 	if (!rc)
311 		return false;
312 
313 	if (!acquire_sid(me->stream2mmio_id, &me->stream2mmio_sid_id)) {
314 		return false;
315 	}
316 
317 	if (!acquire_ib_buffer(
318 		metadata ? cfg->metadata.bits_per_pixel :
319 		cfg->input_port_resolution.bits_per_pixel,
320 		metadata ? cfg->metadata.pixels_per_line :
321 		cfg->input_port_resolution.pixels_per_line,
322 		metadata ? cfg->metadata.lines_per_frame :
323 		cfg->input_port_resolution.lines_per_frame,
324 		metadata ? cfg->metadata.align_req_in_bytes :
325 		cfg->input_port_resolution.align_req_in_bytes,
326 		cfg->online,
327 		&me->ib_buffer)) {
328 		release_sid(me->stream2mmio_id, &me->stream2mmio_sid_id);
329 		return false;
330 	}
331 
332 	if (!acquire_dma_channel(me->dma_id, &me->dma_channel)) {
333 		release_sid(me->stream2mmio_id, &me->stream2mmio_sid_id);
334 		release_ib_buffer(&me->ib_buffer);
335 		return false;
336 	}
337 
338 	return true;
339 }
340 
destroy_input_system_channel(input_system_channel_t * me)341 static void destroy_input_system_channel(
342     input_system_channel_t	*me)
343 {
344 	release_sid(me->stream2mmio_id,
345 		    &me->stream2mmio_sid_id);
346 
347 	release_ib_buffer(&me->ib_buffer);
348 
349 	release_dma_channel(me->dma_id, &me->dma_channel);
350 }
351 
create_input_system_input_port(isp2401_input_system_cfg_t * cfg,input_system_input_port_t * me)352 static bool create_input_system_input_port(
353     isp2401_input_system_cfg_t		*cfg,
354     input_system_input_port_t	*me)
355 {
356 	csi_mipi_packet_type_t packet_type;
357 	bool rc = true;
358 
359 	switch (cfg->input_port_id) {
360 	case INPUT_SYSTEM_CSI_PORT0_ID:
361 		me->csi_rx.frontend_id = CSI_RX_FRONTEND0_ID;
362 		me->csi_rx.backend_id = CSI_RX_BACKEND0_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_PORT0_ID:
373 		me->pixelgen.pixelgen_id = PIXELGEN0_ID;
374 		break;
375 	case INPUT_SYSTEM_CSI_PORT1_ID:
376 		me->csi_rx.frontend_id = CSI_RX_FRONTEND1_ID;
377 		me->csi_rx.backend_id = CSI_RX_BACKEND1_ID;
378 
379 		packet_type = get_csi_mipi_packet_type(cfg->csi_port_attr.fmt_type);
380 		me->csi_rx.packet_type = packet_type;
381 
382 		rc = acquire_be_lut_entry(
383 			 me->csi_rx.backend_id,
384 			 packet_type,
385 			 &me->csi_rx.backend_lut_entry);
386 		break;
387 	case INPUT_SYSTEM_PIXELGEN_PORT1_ID:
388 		me->pixelgen.pixelgen_id = PIXELGEN1_ID;
389 
390 		break;
391 	case INPUT_SYSTEM_CSI_PORT2_ID:
392 		me->csi_rx.frontend_id = CSI_RX_FRONTEND2_ID;
393 		me->csi_rx.backend_id = CSI_RX_BACKEND2_ID;
394 
395 		packet_type = get_csi_mipi_packet_type(cfg->csi_port_attr.fmt_type);
396 		me->csi_rx.packet_type = packet_type;
397 
398 		rc = acquire_be_lut_entry(
399 			 me->csi_rx.backend_id,
400 			 packet_type,
401 			 &me->csi_rx.backend_lut_entry);
402 		break;
403 	case INPUT_SYSTEM_PIXELGEN_PORT2_ID:
404 		me->pixelgen.pixelgen_id = PIXELGEN2_ID;
405 		break;
406 	default:
407 		rc = false;
408 		break;
409 	}
410 
411 	me->source_type = cfg->mode;
412 
413 	/* for metadata */
414 	me->metadata.packet_type = CSI_MIPI_PACKET_TYPE_UNDEFINED;
415 	if (rc && cfg->metadata.enable) {
416 		me->metadata.packet_type = get_csi_mipi_packet_type(
417 					       cfg->metadata.fmt_type);
418 		rc = acquire_be_lut_entry(
419 			 me->csi_rx.backend_id,
420 			 me->metadata.packet_type,
421 			 &me->metadata.backend_lut_entry);
422 	}
423 
424 	return rc;
425 }
426 
destroy_input_system_input_port(input_system_input_port_t * me)427 static void destroy_input_system_input_port(
428     input_system_input_port_t	*me)
429 {
430 	if (me->source_type == INPUT_SYSTEM_SOURCE_TYPE_SENSOR) {
431 		release_be_lut_entry(
432 		    me->csi_rx.backend_id,
433 		    me->csi_rx.packet_type,
434 		    &me->csi_rx.backend_lut_entry);
435 	}
436 
437 	if (me->metadata.packet_type != CSI_MIPI_PACKET_TYPE_UNDEFINED) {
438 		/*Free the backend lut allocated for metadata*/
439 		release_be_lut_entry(
440 		    me->csi_rx.backend_id,
441 		    me->metadata.packet_type,
442 		    &me->metadata.backend_lut_entry);
443 	}
444 }
445 
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)446 static bool calculate_input_system_channel_cfg(
447     input_system_channel_t		*channel,
448     input_system_input_port_t	*input_port,
449     isp2401_input_system_cfg_t		*isys_cfg,
450     input_system_channel_cfg_t	*channel_cfg,
451     bool metadata)
452 {
453 	bool rc;
454 
455 	rc = calculate_stream2mmio_cfg(isys_cfg, metadata,
456 				       &channel_cfg->stream2mmio_cfg);
457 	if (!rc)
458 		return false;
459 
460 	rc = calculate_ibuf_ctrl_cfg(
461 		 channel,
462 		 input_port,
463 		 isys_cfg,
464 		 &channel_cfg->ibuf_ctrl_cfg);
465 	if (!rc)
466 		return false;
467 	if (metadata)
468 		channel_cfg->ibuf_ctrl_cfg.stores_per_frame =
469 		    isys_cfg->metadata.lines_per_frame;
470 
471 	rc = calculate_isys2401_dma_cfg(
472 		 channel,
473 		 isys_cfg,
474 		 &channel_cfg->dma_cfg);
475 	if (!rc)
476 		return false;
477 
478 	rc = calculate_isys2401_dma_port_cfg(
479 		 isys_cfg,
480 		 false,
481 		 metadata,
482 		 &channel_cfg->dma_src_port_cfg);
483 	if (!rc)
484 		return false;
485 
486 	rc = calculate_isys2401_dma_port_cfg(
487 		 isys_cfg,
488 		 isys_cfg->raw_packed,
489 		 metadata,
490 		 &channel_cfg->dma_dest_port_cfg);
491 	if (!rc)
492 		return false;
493 
494 	return true;
495 }
496 
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)497 static bool calculate_input_system_input_port_cfg(
498     input_system_channel_t		*channel,
499     input_system_input_port_t	*input_port,
500     isp2401_input_system_cfg_t		*isys_cfg,
501     input_system_input_port_cfg_t	*input_port_cfg)
502 {
503 	bool rc;
504 
505 	switch (input_port->source_type) {
506 	case INPUT_SYSTEM_SOURCE_TYPE_SENSOR:
507 		rc  = calculate_fe_cfg(
508 			  isys_cfg,
509 			  &input_port_cfg->csi_rx_cfg.frontend_cfg);
510 
511 		rc &= calculate_be_cfg(
512 			  input_port,
513 			  isys_cfg,
514 			  false,
515 			  &input_port_cfg->csi_rx_cfg.backend_cfg);
516 
517 		if (rc && isys_cfg->metadata.enable)
518 			rc &= calculate_be_cfg(input_port, isys_cfg, true,
519 					       &input_port_cfg->csi_rx_cfg.md_backend_cfg);
520 		break;
521 	case INPUT_SYSTEM_SOURCE_TYPE_TPG:
522 		rc = calculate_tpg_cfg(
523 			 channel,
524 			 input_port,
525 			 isys_cfg,
526 			 &input_port_cfg->pixelgen_cfg.tpg_cfg);
527 		break;
528 	case INPUT_SYSTEM_SOURCE_TYPE_PRBS:
529 		rc = calculate_prbs_cfg(
530 			 channel,
531 			 input_port,
532 			 isys_cfg,
533 			 &input_port_cfg->pixelgen_cfg.prbs_cfg);
534 		break;
535 	default:
536 		rc = false;
537 		break;
538 	}
539 
540 	return rc;
541 }
542 
acquire_sid(stream2mmio_ID_t stream2mmio,stream2mmio_sid_ID_t * sid)543 static bool acquire_sid(
544     stream2mmio_ID_t	stream2mmio,
545     stream2mmio_sid_ID_t	*sid)
546 {
547 	return ia_css_isys_stream2mmio_sid_rmgr_acquire(stream2mmio, sid);
548 }
549 
release_sid(stream2mmio_ID_t stream2mmio,stream2mmio_sid_ID_t * sid)550 static void release_sid(
551     stream2mmio_ID_t	stream2mmio,
552     stream2mmio_sid_ID_t	*sid)
553 {
554 	ia_css_isys_stream2mmio_sid_rmgr_release(stream2mmio, sid);
555 }
556 
557 /* 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)558 static int32_t calculate_stride(
559     s32 bits_per_pixel,
560     s32 pixels_per_line,
561     bool	raw_packed,
562     int32_t align_in_bytes)
563 {
564 	s32 bytes_per_line;
565 	s32 pixels_per_word;
566 	s32 words_per_line;
567 	s32 pixels_per_line_padded;
568 
569 	pixels_per_line_padded = CEIL_MUL(pixels_per_line, align_in_bytes);
570 
571 	if (!raw_packed)
572 		bits_per_pixel = CEIL_MUL(bits_per_pixel, 8);
573 
574 	pixels_per_word = HIVE_ISP_DDR_WORD_BITS / bits_per_pixel;
575 	words_per_line  = ceil_div(pixels_per_line_padded, pixels_per_word);
576 	bytes_per_line  = HIVE_ISP_DDR_WORD_BYTES * words_per_line;
577 
578 	return bytes_per_line;
579 }
580 
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)581 static bool acquire_ib_buffer(
582     s32 bits_per_pixel,
583     s32 pixels_per_line,
584     s32 lines_per_frame,
585     s32 align_in_bytes,
586     bool online,
587     isp2401_ib_buffer_t *buf)
588 {
589 	buf->stride = calculate_stride(bits_per_pixel, pixels_per_line, false,
590 				       align_in_bytes);
591 	if (online)
592 		buf->lines = 4; /* use double buffering for online usecases */
593 	else
594 		buf->lines = 2;
595 
596 	(void)(lines_per_frame);
597 	return ia_css_isys_ibuf_rmgr_acquire(buf->stride * buf->lines,
598 					     &buf->start_addr);
599 }
600 
release_ib_buffer(isp2401_ib_buffer_t * buf)601 static void release_ib_buffer(
602     isp2401_ib_buffer_t *buf)
603 {
604 	ia_css_isys_ibuf_rmgr_release(&buf->start_addr);
605 }
606 
acquire_dma_channel(isys2401_dma_ID_t dma_id,isys2401_dma_channel * channel)607 static bool acquire_dma_channel(
608     isys2401_dma_ID_t	dma_id,
609     isys2401_dma_channel	*channel)
610 {
611 	return ia_css_isys_dma_channel_rmgr_acquire(dma_id, channel);
612 }
613 
release_dma_channel(isys2401_dma_ID_t dma_id,isys2401_dma_channel * channel)614 static void release_dma_channel(
615     isys2401_dma_ID_t	dma_id,
616     isys2401_dma_channel	*channel)
617 {
618 	ia_css_isys_dma_channel_rmgr_release(dma_id, channel);
619 }
620 
acquire_be_lut_entry(csi_rx_backend_ID_t backend,csi_mipi_packet_type_t packet_type,csi_rx_backend_lut_entry_t * entry)621 static bool acquire_be_lut_entry(
622     csi_rx_backend_ID_t		backend,
623     csi_mipi_packet_type_t		packet_type,
624     csi_rx_backend_lut_entry_t	*entry)
625 {
626 	return ia_css_isys_csi_rx_lut_rmgr_acquire(backend, packet_type, entry);
627 }
628 
release_be_lut_entry(csi_rx_backend_ID_t backend,csi_mipi_packet_type_t packet_type,csi_rx_backend_lut_entry_t * entry)629 static void release_be_lut_entry(
630     csi_rx_backend_ID_t		backend,
631     csi_mipi_packet_type_t		packet_type,
632     csi_rx_backend_lut_entry_t	*entry)
633 {
634 	ia_css_isys_csi_rx_lut_rmgr_release(backend, packet_type, entry);
635 }
636 
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)637 static bool calculate_tpg_cfg(
638     input_system_channel_t		*channel,
639     input_system_input_port_t	*input_port,
640     isp2401_input_system_cfg_t		*isys_cfg,
641     pixelgen_tpg_cfg_t		*cfg)
642 {
643 	memcpy(cfg, &isys_cfg->tpg_port_attr, sizeof(pixelgen_tpg_cfg_t));
644 
645 	return true;
646 }
647 
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)648 static bool calculate_prbs_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_prbs_cfg_t		*cfg)
653 {
654 	memcpy(cfg, &isys_cfg->prbs_port_attr, sizeof(pixelgen_prbs_cfg_t));
655 
656 	return true;
657 }
658 
calculate_fe_cfg(const isp2401_input_system_cfg_t * isys_cfg,csi_rx_frontend_cfg_t * cfg)659 static bool calculate_fe_cfg(
660     const isp2401_input_system_cfg_t	*isys_cfg,
661     csi_rx_frontend_cfg_t		*cfg)
662 {
663 	cfg->active_lanes = isys_cfg->csi_port_attr.active_lanes;
664 	return true;
665 }
666 
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)667 static bool calculate_be_cfg(
668     const input_system_input_port_t	*input_port,
669     const isp2401_input_system_cfg_t	*isys_cfg,
670     bool				metadata,
671     csi_rx_backend_cfg_t		*cfg)
672 {
673 	memcpy(&cfg->lut_entry,
674 	      metadata ? &input_port->metadata.backend_lut_entry :
675 			 &input_port->csi_rx.backend_lut_entry,
676 	      sizeof(csi_rx_backend_lut_entry_t));
677 
678 	cfg->csi_mipi_cfg.virtual_channel = isys_cfg->csi_port_attr.ch_id;
679 	if (metadata) {
680 		cfg->csi_mipi_packet_type = get_csi_mipi_packet_type(
681 						isys_cfg->metadata.fmt_type);
682 		cfg->csi_mipi_cfg.comp_enable = false;
683 		cfg->csi_mipi_cfg.data_type = isys_cfg->metadata.fmt_type;
684 	} else {
685 		cfg->csi_mipi_packet_type = get_csi_mipi_packet_type(
686 						isys_cfg->csi_port_attr.fmt_type);
687 		cfg->csi_mipi_cfg.data_type = isys_cfg->csi_port_attr.fmt_type;
688 		cfg->csi_mipi_cfg.comp_enable = isys_cfg->csi_port_attr.comp_enable;
689 		cfg->csi_mipi_cfg.comp_scheme = isys_cfg->csi_port_attr.comp_scheme;
690 		cfg->csi_mipi_cfg.comp_predictor = isys_cfg->csi_port_attr.comp_predictor;
691 		cfg->csi_mipi_cfg.comp_bit_idx = cfg->csi_mipi_cfg.data_type -
692 						 MIPI_FORMAT_CUSTOM0;
693 	}
694 
695 	return true;
696 }
697 
calculate_stream2mmio_cfg(const isp2401_input_system_cfg_t * isys_cfg,bool metadata,stream2mmio_cfg_t * cfg)698 static bool calculate_stream2mmio_cfg(
699     const isp2401_input_system_cfg_t	*isys_cfg,
700     bool				metadata,
701     stream2mmio_cfg_t		*cfg
702 )
703 {
704 	cfg->bits_per_pixel = metadata ? isys_cfg->metadata.bits_per_pixel :
705 			      isys_cfg->input_port_resolution.bits_per_pixel;
706 
707 	cfg->enable_blocking =
708 	    ((isys_cfg->mode == INPUT_SYSTEM_SOURCE_TYPE_TPG) ||
709 	     (isys_cfg->mode == INPUT_SYSTEM_SOURCE_TYPE_PRBS));
710 
711 	return true;
712 }
713 
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)714 static bool calculate_ibuf_ctrl_cfg(
715     const input_system_channel_t	*channel,
716     const input_system_input_port_t	*input_port,
717     const isp2401_input_system_cfg_t	*isys_cfg,
718     ibuf_ctrl_cfg_t			*cfg)
719 {
720 	const s32 bits_per_byte = 8;
721 	s32 bits_per_pixel;
722 	s32 bytes_per_pixel;
723 	s32 left_padding;
724 
725 	(void)input_port;
726 
727 	bits_per_pixel = isys_cfg->input_port_resolution.bits_per_pixel;
728 	bytes_per_pixel = ceil_div(bits_per_pixel, bits_per_byte);
729 
730 	left_padding = CEIL_MUL(isys_cfg->output_port_attr.left_padding, ISP_VEC_NELEMS)
731 		       * bytes_per_pixel;
732 
733 	cfg->online	= isys_cfg->online;
734 
735 	cfg->dma_cfg.channel	= channel->dma_channel;
736 	cfg->dma_cfg.cmd	= _DMA_V2_MOVE_A2B_NO_SYNC_CHK_COMMAND;
737 
738 	cfg->dma_cfg.shift_returned_items	= 0;
739 	cfg->dma_cfg.elems_per_word_in_ibuf	= 0;
740 	cfg->dma_cfg.elems_per_word_in_dest	= 0;
741 
742 	cfg->ib_buffer.start_addr		= channel->ib_buffer.start_addr;
743 	cfg->ib_buffer.stride			= channel->ib_buffer.stride;
744 	cfg->ib_buffer.lines			= channel->ib_buffer.lines;
745 
746 	/*
747 	#ifndef ISP2401
748 	 * zhengjie.lu@intel.com:
749 	#endif
750 	 * "dest_buf_cfg" should be part of the input system output
751 	 * port configuration.
752 	 *
753 	 * TODO: move "dest_buf_cfg" to the input system output
754 	 * port configuration.
755 	 */
756 
757 	/* input_buf addr only available in sched mode;
758 	   this buffer is allocated in isp, crun mode addr
759 	   can be passed by after ISP allocation */
760 	if (cfg->online) {
761 		cfg->dest_buf_cfg.start_addr	= ISP_INPUT_BUF_START_ADDR + left_padding;
762 		cfg->dest_buf_cfg.stride	= bytes_per_pixel
763 					      * isys_cfg->output_port_attr.max_isp_input_width;
764 		cfg->dest_buf_cfg.lines		= LINES_OF_ISP_INPUT_BUF;
765 	} else if (isys_cfg->raw_packed) {
766 		cfg->dest_buf_cfg.stride	= calculate_stride(bits_per_pixel,
767 					      isys_cfg->input_port_resolution.pixels_per_line,
768 					      isys_cfg->raw_packed,
769 					      isys_cfg->input_port_resolution.align_req_in_bytes);
770 	} else {
771 		cfg->dest_buf_cfg.stride	= channel->ib_buffer.stride;
772 	}
773 
774 	/*
775 	#ifndef ISP2401
776 	 * zhengjie.lu@intel.com:
777 	#endif
778 	 * "items_per_store" is hard coded as "1", which is ONLY valid
779 	 * when the CSI-MIPI long packet is transferred.
780 	 *
781 	 * TODO: After the 1st stage of MERR+,  make the proper solution to
782 	 * configure "items_per_store" so that it can also handle the CSI-MIPI
783 	 * short packet.
784 	 */
785 	cfg->items_per_store		= 1;
786 
787 	cfg->stores_per_frame		= isys_cfg->input_port_resolution.lines_per_frame;
788 
789 	cfg->stream2mmio_cfg.sync_cmd	= _STREAM2MMIO_CMD_TOKEN_SYNC_FRAME;
790 
791 	/* TODO: Define conditions as when to use store words vs store packets */
792 	cfg->stream2mmio_cfg.store_cmd	= _STREAM2MMIO_CMD_TOKEN_STORE_PACKETS;
793 
794 	return true;
795 }
796 
calculate_isys2401_dma_cfg(const input_system_channel_t * channel,const isp2401_input_system_cfg_t * isys_cfg,isys2401_dma_cfg_t * cfg)797 static bool calculate_isys2401_dma_cfg(
798     const input_system_channel_t	*channel,
799     const isp2401_input_system_cfg_t	*isys_cfg,
800     isys2401_dma_cfg_t		*cfg)
801 {
802 	cfg->channel	= channel->dma_channel;
803 
804 	/* only online/sensor mode goto vmem
805 	   offline/buffered_sensor, tpg and prbs will go to ddr */
806 	if (isys_cfg->online)
807 		cfg->connection = isys2401_dma_ibuf_to_vmem_connection;
808 	else
809 		cfg->connection = isys2401_dma_ibuf_to_ddr_connection;
810 
811 	cfg->extension	= isys2401_dma_zero_extension;
812 	cfg->height	= 1;
813 
814 	return true;
815 }
816 
817 /* 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)818 static bool calculate_isys2401_dma_port_cfg(
819     const isp2401_input_system_cfg_t	*isys_cfg,
820     bool				raw_packed,
821     bool				metadata,
822     isys2401_dma_port_cfg_t		*cfg)
823 {
824 	s32 bits_per_pixel;
825 	s32 pixels_per_line;
826 	s32 align_req_in_bytes;
827 
828 	/* TODO: Move metadata away from isys_cfg to application layer */
829 	if (metadata) {
830 		bits_per_pixel = isys_cfg->metadata.bits_per_pixel;
831 		pixels_per_line = isys_cfg->metadata.pixels_per_line;
832 		align_req_in_bytes = isys_cfg->metadata.align_req_in_bytes;
833 	} else {
834 		bits_per_pixel = isys_cfg->input_port_resolution.bits_per_pixel;
835 		pixels_per_line = isys_cfg->input_port_resolution.pixels_per_line;
836 		align_req_in_bytes = isys_cfg->input_port_resolution.align_req_in_bytes;
837 	}
838 
839 	cfg->stride	= calculate_stride(bits_per_pixel, pixels_per_line, raw_packed,
840 				       align_req_in_bytes);
841 
842 	if (!raw_packed)
843 		bits_per_pixel = CEIL_MUL(bits_per_pixel, 8);
844 
845 	cfg->elements	= HIVE_ISP_DDR_WORD_BITS / bits_per_pixel;
846 	cfg->cropping	= 0;
847 	cfg->width	= CEIL_DIV(cfg->stride, HIVE_ISP_DDR_WORD_BYTES);
848 
849 	return true;
850 }
851 
get_csi_mipi_packet_type(int32_t data_type)852 static csi_mipi_packet_type_t get_csi_mipi_packet_type(
853     int32_t data_type)
854 {
855 	csi_mipi_packet_type_t packet_type;
856 
857 	packet_type = CSI_MIPI_PACKET_TYPE_RESERVED;
858 
859 	if (data_type >= 0 && data_type <= MIPI_FORMAT_SHORT8)
860 		packet_type = CSI_MIPI_PACKET_TYPE_SHORT;
861 
862 	if (data_type > MIPI_FORMAT_SHORT8 && data_type <= N_MIPI_FORMAT)
863 		packet_type = CSI_MIPI_PACKET_TYPE_LONG;
864 
865 	return packet_type;
866 }
867 
868 /* end of Private Methods */
869 #endif
870