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