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