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