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