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