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