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