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