1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16#include <linux/mm.h>
17#include <linux/slab.h>
18#include <linux/vmalloc.h>
19
20#include "ia_css.h"
21#include "sh_css_hrt.h"
22#include "ia_css_buffer.h"
23#include "ia_css_binary.h"
24#include "sh_css_internal.h"
25#include "sh_css_mipi.h"
26#include "sh_css_sp.h"
27#if !defined(HAS_NO_INPUT_SYSTEM)
28#include "ia_css_isys.h"
29#endif
30#include "ia_css_frame.h"
31#include "sh_css_defs.h"
32#include "sh_css_firmware.h"
33#include "sh_css_params.h"
34#include "sh_css_params_internal.h"
35#include "sh_css_param_shading.h"
36#include "ia_css_refcount.h"
37#include "ia_css_rmgr.h"
38#include "ia_css_debug.h"
39#include "ia_css_debug_pipe.h"
40#include "ia_css_device_access.h"
41#include "device_access.h"
42#include "sh_css_legacy.h"
43#include "ia_css_pipeline.h"
44#include "ia_css_stream.h"
45#include "sh_css_stream_format.h"
46#include "ia_css_pipe.h"
47#include "ia_css_util.h"
48#include "ia_css_pipe_util.h"
49#include "ia_css_pipe_binarydesc.h"
50#include "ia_css_pipe_stagedesc.h"
51#ifdef USE_INPUT_SYSTEM_VERSION_2
52#include "ia_css_isys.h"
53#endif
54
55#include "memory_access.h"
56#include "tag.h"
57#include "assert_support.h"
58#include "math_support.h"
59#include "sw_event_global.h"
60#if !defined(HAS_NO_INPUT_FORMATTER)
61#include "ia_css_ifmtr.h"
62#endif
63#if !defined(HAS_NO_INPUT_SYSTEM)
64#include "input_system.h"
65#endif
66#include "mmu_device.h"
67#include "ia_css_mmu_private.h"
68#include "gdc_device.h"
69#include "dma.h"
70#include "irq.h"
71#include "sp.h"
72#include "isp.h"
73#include "gp_device.h"
74#define __INLINE_GPIO__
75#include "gpio.h"
76#include "timed_ctrl.h"
77#include "platform_support.h"
78#include "ia_css_inputfifo.h"
79#define WITH_PC_MONITORING 0
80
81#define SH_CSS_VIDEO_BUFFER_ALIGNMENT 0
82
83#if WITH_PC_MONITORING
84#define MULTIPLE_SAMPLES 1
85#define NOF_SAMPLES 60
86#include "linux/kthread.h"
87#include "linux/sched.h"
88#include "linux/delay.h"
89#include "sh_css_metrics.h"
90static int thread_alive;
91#endif
92
93#include "ia_css_spctrl.h"
94#include "ia_css_version_data.h"
95#include "sh_css_struct.h"
96#include "ia_css_bufq.h"
97#include "ia_css_timer.h"
98
99#include "isp/modes/interface/input_buf.isp.h"
100
101
102#define SP_PROG_NAME "sp"
103
104#define REFCOUNT_SIZE 1000
105
106
107
108
109
110#define JPEG_BYTES (16 * 1024 * 1024)
111
112#define STATS_ENABLED(stage) (stage && stage->binary && stage->binary->info && \
113 (stage->binary->info->sp.enable.s3a || stage->binary->info->sp.enable.dis))
114
115struct sh_css my_css;
116
117int (*sh_css_printf) (const char *fmt, va_list args) = NULL;
118
119
120
121
122enum ia_sh_css_modes {
123 sh_css_mode_none = 0,
124 sh_css_mode_working,
125 sh_css_mode_suspend,
126 sh_css_mode_resume
127};
128
129
130
131
132struct sh_css_stream_seed {
133 struct ia_css_stream **orig_stream;
134 struct ia_css_stream *stream;
135 struct ia_css_stream_config stream_config;
136 int num_pipes;
137 struct ia_css_pipe *pipes[IA_CSS_PIPE_ID_NUM];
138 struct ia_css_pipe **orig_pipes[IA_CSS_PIPE_ID_NUM];
139 struct ia_css_pipe_config pipe_config[IA_CSS_PIPE_ID_NUM];
140};
141
142#define MAX_ACTIVE_STREAMS 5
143
144
145
146struct sh_css_save {
147 enum ia_sh_css_modes mode;
148 uint32_t mmu_base;
149 enum ia_css_irq_type irq_type;
150 struct sh_css_stream_seed stream_seeds[MAX_ACTIVE_STREAMS];
151 struct ia_css_fw *loaded_fw;
152 struct ia_css_env driver_env;
153};
154
155static bool my_css_save_initialized;
156static struct sh_css_save my_css_save;
157
158
159
160
161#define MAX_HMM_BUFFER_NUM \
162 (SH_CSS_MAX_NUM_QUEUES * (IA_CSS_NUM_ELEMS_SP2HOST_BUFFER_QUEUE + 2))
163
164struct sh_css_hmm_buffer_record {
165 bool in_use;
166 enum ia_css_buffer_type type;
167 struct ia_css_rmgr_vbuf_handle *h_vbuf;
168 hrt_address kernel_ptr;
169};
170
171static struct sh_css_hmm_buffer_record hmm_buffer_record[MAX_HMM_BUFFER_NUM];
172
173#define GPIO_FLASH_PIN_MASK (1 << HIVE_GPIO_STROBE_TRIGGER_PIN)
174
175static bool fw_explicitly_loaded = false;
176
177
178
179
180
181static enum ia_css_err
182allocate_delay_frames(struct ia_css_pipe *pipe);
183
184static enum ia_css_err
185sh_css_pipe_start(struct ia_css_stream *stream);
186
187#ifdef ISP2401
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205static enum ia_css_err
206sh_css_pipes_stop(struct ia_css_stream *stream);
207
208
209
210
211
212
213
214
215
216
217
218
219static bool
220sh_css_pipes_have_stopped(struct ia_css_stream *stream);
221
222static enum ia_css_err
223ia_css_pipe_check_format(struct ia_css_pipe *pipe, enum ia_css_frame_format format);
224
225static enum ia_css_err
226check_pipe_resolutions(const struct ia_css_pipe *pipe);
227
228#endif
229
230static enum ia_css_err
231ia_css_pipe_load_extension(struct ia_css_pipe *pipe,
232 struct ia_css_fw_info *firmware);
233
234static void
235ia_css_pipe_unload_extension(struct ia_css_pipe *pipe,
236 struct ia_css_fw_info *firmware);
237static void
238ia_css_reset_defaults(struct sh_css* css);
239
240static void
241sh_css_init_host_sp_control_vars(void);
242
243static enum ia_css_err set_num_primary_stages(unsigned int *num, enum ia_css_pipe_version version);
244
245static bool
246need_capture_pp(const struct ia_css_pipe *pipe);
247
248static bool
249need_yuv_scaler_stage(const struct ia_css_pipe *pipe);
250
251static enum ia_css_err ia_css_pipe_create_cas_scaler_desc_single_output(
252 struct ia_css_frame_info *cas_scaler_in_info,
253 struct ia_css_frame_info *cas_scaler_out_info,
254 struct ia_css_frame_info *cas_scaler_vf_info,
255 struct ia_css_cas_binary_descr *descr);
256
257static void ia_css_pipe_destroy_cas_scaler_desc(struct ia_css_cas_binary_descr *descr);
258
259static bool
260need_downscaling(const struct ia_css_resolution in_res,
261 const struct ia_css_resolution out_res);
262
263static bool need_capt_ldc(const struct ia_css_pipe *pipe);
264
265static enum ia_css_err
266sh_css_pipe_load_binaries(struct ia_css_pipe *pipe);
267
268static
269enum ia_css_err sh_css_pipe_get_viewfinder_frame_info(
270 struct ia_css_pipe *pipe,
271 struct ia_css_frame_info *info,
272 unsigned int idx);
273
274static enum ia_css_err
275sh_css_pipe_get_output_frame_info(struct ia_css_pipe *pipe,
276 struct ia_css_frame_info *info,
277 unsigned int idx);
278
279static enum ia_css_err
280capture_start(struct ia_css_pipe *pipe);
281
282static enum ia_css_err
283video_start(struct ia_css_pipe *pipe);
284
285static enum ia_css_err
286preview_start(struct ia_css_pipe *pipe);
287
288static enum ia_css_err
289yuvpp_start(struct ia_css_pipe *pipe);
290
291static bool copy_on_sp(struct ia_css_pipe *pipe);
292
293static enum ia_css_err
294init_vf_frameinfo_defaults(struct ia_css_pipe *pipe,
295 struct ia_css_frame *vf_frame, unsigned int idx);
296
297static enum ia_css_err
298init_in_frameinfo_memory_defaults(struct ia_css_pipe *pipe,
299 struct ia_css_frame *frame, enum ia_css_frame_format format);
300
301static enum ia_css_err
302init_out_frameinfo_defaults(struct ia_css_pipe *pipe,
303 struct ia_css_frame *out_frame, unsigned int idx);
304
305static enum ia_css_err
306sh_css_pipeline_add_acc_stage(struct ia_css_pipeline *pipeline,
307 const void *acc_fw);
308
309static enum ia_css_err
310alloc_continuous_frames(
311 struct ia_css_pipe *pipe, bool init_time);
312
313static void
314pipe_global_init(void);
315
316static enum ia_css_err
317pipe_generate_pipe_num(const struct ia_css_pipe *pipe, unsigned int *pipe_number);
318
319static void
320pipe_release_pipe_num(unsigned int pipe_num);
321
322static enum ia_css_err
323create_host_pipeline_structure(struct ia_css_stream *stream);
324
325static enum ia_css_err
326create_host_pipeline(struct ia_css_stream *stream);
327
328static enum ia_css_err
329create_host_preview_pipeline(struct ia_css_pipe *pipe);
330
331static enum ia_css_err
332create_host_video_pipeline(struct ia_css_pipe *pipe);
333
334static enum ia_css_err
335create_host_copy_pipeline(struct ia_css_pipe *pipe,
336 unsigned max_input_width,
337 struct ia_css_frame *out_frame);
338
339static enum ia_css_err
340create_host_isyscopy_capture_pipeline(struct ia_css_pipe *pipe);
341
342static enum ia_css_err
343create_host_capture_pipeline(struct ia_css_pipe *pipe);
344
345static enum ia_css_err
346create_host_yuvpp_pipeline(struct ia_css_pipe *pipe);
347
348static enum ia_css_err
349create_host_acc_pipeline(struct ia_css_pipe *pipe);
350
351static unsigned int
352sh_css_get_sw_interrupt_value(unsigned int irq);
353
354static struct ia_css_binary *ia_css_pipe_get_shading_correction_binary(const struct ia_css_pipe *pipe);
355
356static struct ia_css_binary *
357ia_css_pipe_get_s3a_binary(const struct ia_css_pipe *pipe);
358
359static struct ia_css_binary *
360ia_css_pipe_get_sdis_binary(const struct ia_css_pipe *pipe);
361
362static void
363sh_css_hmm_buffer_record_init(void);
364
365static void
366sh_css_hmm_buffer_record_uninit(void);
367
368static void
369sh_css_hmm_buffer_record_reset(struct sh_css_hmm_buffer_record *buffer_record);
370
371static struct sh_css_hmm_buffer_record
372*sh_css_hmm_buffer_record_acquire(struct ia_css_rmgr_vbuf_handle *h_vbuf,
373 enum ia_css_buffer_type type,
374 hrt_address kernel_ptr);
375
376static struct sh_css_hmm_buffer_record
377*sh_css_hmm_buffer_record_validate(hrt_vaddress ddr_buffer_addr,
378 enum ia_css_buffer_type type);
379
380void
381ia_css_get_acc_configs(
382 struct ia_css_pipe *pipe,
383 struct ia_css_isp_config *config);
384
385
386#if CONFIG_ON_FRAME_ENQUEUE()
387static enum ia_css_err set_config_on_frame_enqueue(struct ia_css_frame_info *info, struct frame_data_wrapper *frame);
388#endif
389
390#ifdef USE_INPUT_SYSTEM_VERSION_2401
391static unsigned int get_crop_lines_for_bayer_order(const struct ia_css_stream_config *config);
392static unsigned int get_crop_columns_for_bayer_order(const struct ia_css_stream_config *config);
393static void get_pipe_extra_pixel(struct ia_css_pipe *pipe,
394 unsigned int *extra_row, unsigned int *extra_column);
395#endif
396
397#ifdef ISP2401
398#ifdef USE_INPUT_SYSTEM_VERSION_2401
399static enum ia_css_err
400aspect_ratio_crop_init(struct ia_css_stream *curr_stream,
401 struct ia_css_pipe *pipes[],
402 bool *do_crop_status);
403
404static bool
405aspect_ratio_crop_check(bool enabled, struct ia_css_pipe *curr_pipe);
406
407static enum ia_css_err
408aspect_ratio_crop(struct ia_css_pipe *curr_pipe,
409 struct ia_css_resolution *effective_res);
410#endif
411
412#endif
413static void
414sh_css_pipe_free_shading_table(struct ia_css_pipe *pipe)
415{
416 assert(pipe != NULL);
417 if (pipe == NULL) {
418 IA_CSS_ERROR("NULL input parameter");
419 return;
420 }
421
422 if (pipe->shading_table)
423 ia_css_shading_table_free(pipe->shading_table);
424 pipe->shading_table = NULL;
425}
426
427static enum ia_css_frame_format yuv420_copy_formats[] = {
428 IA_CSS_FRAME_FORMAT_NV12,
429 IA_CSS_FRAME_FORMAT_NV21,
430 IA_CSS_FRAME_FORMAT_YV12,
431 IA_CSS_FRAME_FORMAT_YUV420,
432 IA_CSS_FRAME_FORMAT_YUV420_16,
433 IA_CSS_FRAME_FORMAT_CSI_MIPI_YUV420_8,
434 IA_CSS_FRAME_FORMAT_CSI_MIPI_LEGACY_YUV420_8
435};
436
437static enum ia_css_frame_format yuv422_copy_formats[] = {
438 IA_CSS_FRAME_FORMAT_NV12,
439 IA_CSS_FRAME_FORMAT_NV16,
440 IA_CSS_FRAME_FORMAT_NV21,
441 IA_CSS_FRAME_FORMAT_NV61,
442 IA_CSS_FRAME_FORMAT_YV12,
443 IA_CSS_FRAME_FORMAT_YV16,
444 IA_CSS_FRAME_FORMAT_YUV420,
445 IA_CSS_FRAME_FORMAT_YUV420_16,
446 IA_CSS_FRAME_FORMAT_YUV422,
447 IA_CSS_FRAME_FORMAT_YUV422_16,
448 IA_CSS_FRAME_FORMAT_UYVY,
449 IA_CSS_FRAME_FORMAT_YUYV
450};
451
452
453
454
455static enum ia_css_err
456verify_copy_out_frame_format(struct ia_css_pipe *pipe)
457{
458 enum ia_css_frame_format out_fmt = pipe->output_info[0].format;
459 unsigned int i, found = 0;
460
461 assert(pipe != NULL);
462 assert(pipe->stream != NULL);
463
464 switch (pipe->stream->config.input_config.format) {
465 case ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY:
466 case ATOMISP_INPUT_FORMAT_YUV420_8:
467 for (i=0; i<ARRAY_SIZE(yuv420_copy_formats) && !found; i++)
468 found = (out_fmt == yuv420_copy_formats[i]);
469 break;
470 case ATOMISP_INPUT_FORMAT_YUV420_10:
471 case ATOMISP_INPUT_FORMAT_YUV420_16:
472 found = (out_fmt == IA_CSS_FRAME_FORMAT_YUV420_16);
473 break;
474 case ATOMISP_INPUT_FORMAT_YUV422_8:
475 for (i=0; i<ARRAY_SIZE(yuv422_copy_formats) && !found; i++)
476 found = (out_fmt == yuv422_copy_formats[i]);
477 break;
478 case ATOMISP_INPUT_FORMAT_YUV422_10:
479 case ATOMISP_INPUT_FORMAT_YUV422_16:
480 found = (out_fmt == IA_CSS_FRAME_FORMAT_YUV422_16 ||
481 out_fmt == IA_CSS_FRAME_FORMAT_YUV420_16);
482 break;
483 case ATOMISP_INPUT_FORMAT_RGB_444:
484 case ATOMISP_INPUT_FORMAT_RGB_555:
485 case ATOMISP_INPUT_FORMAT_RGB_565:
486 found = (out_fmt == IA_CSS_FRAME_FORMAT_RGBA888 ||
487 out_fmt == IA_CSS_FRAME_FORMAT_RGB565);
488 break;
489 case ATOMISP_INPUT_FORMAT_RGB_666:
490 case ATOMISP_INPUT_FORMAT_RGB_888:
491 found = (out_fmt == IA_CSS_FRAME_FORMAT_RGBA888 ||
492 out_fmt == IA_CSS_FRAME_FORMAT_YUV420);
493 break;
494 case ATOMISP_INPUT_FORMAT_RAW_6:
495 case ATOMISP_INPUT_FORMAT_RAW_7:
496 case ATOMISP_INPUT_FORMAT_RAW_8:
497 case ATOMISP_INPUT_FORMAT_RAW_10:
498 case ATOMISP_INPUT_FORMAT_RAW_12:
499 case ATOMISP_INPUT_FORMAT_RAW_14:
500 case ATOMISP_INPUT_FORMAT_RAW_16:
501 found = (out_fmt == IA_CSS_FRAME_FORMAT_RAW) ||
502 (out_fmt == IA_CSS_FRAME_FORMAT_RAW_PACKED);
503 break;
504 case ATOMISP_INPUT_FORMAT_BINARY_8:
505 found = (out_fmt == IA_CSS_FRAME_FORMAT_BINARY_8);
506 break;
507 default:
508 break;
509 }
510 if (!found)
511 return IA_CSS_ERR_INVALID_ARGUMENTS;
512 return IA_CSS_SUCCESS;
513}
514
515unsigned int
516ia_css_stream_input_format_bits_per_pixel(struct ia_css_stream *stream)
517{
518 int bpp = 0;
519
520 if (stream != NULL)
521 bpp = ia_css_util_input_format_bpp(stream->config.input_config.format,
522 stream->config.pixels_per_clock == 2);
523
524 return bpp;
525}
526
527#if !defined(HAS_NO_INPUT_SYSTEM) && defined(USE_INPUT_SYSTEM_VERSION_2)
528static enum ia_css_err
529sh_css_config_input_network(struct ia_css_stream *stream)
530{
531 unsigned int fmt_type;
532 struct ia_css_pipe *pipe = stream->last_pipe;
533 struct ia_css_binary *binary = NULL;
534 enum ia_css_err err = IA_CSS_SUCCESS;
535
536 assert(stream != NULL);
537 assert(pipe != NULL);
538
539 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
540 "sh_css_config_input_network() enter:\n");
541
542 if (pipe->pipeline.stages)
543 binary = pipe->pipeline.stages->binary;
544
545 err = ia_css_isys_convert_stream_format_to_mipi_format(
546 stream->config.input_config.format,
547 stream->csi_rx_config.comp,
548 &fmt_type);
549 if (err != IA_CSS_SUCCESS)
550 return err;
551 sh_css_sp_program_input_circuit(fmt_type,
552 stream->config.channel_id,
553 stream->config.mode);
554
555 if ((binary && (binary->online || stream->config.continuous)) ||
556 pipe->config.mode == IA_CSS_PIPE_MODE_COPY) {
557 err = ia_css_ifmtr_configure(&stream->config,
558 binary);
559 if (err != IA_CSS_SUCCESS)
560 return err;
561 }
562
563 if (stream->config.mode == IA_CSS_INPUT_MODE_TPG ||
564 stream->config.mode == IA_CSS_INPUT_MODE_PRBS) {
565 unsigned int hblank_cycles = 100,
566 vblank_lines = 6,
567 width,
568 height,
569 vblank_cycles;
570 width = (stream->config.input_config.input_res.width) / (1 + (stream->config.pixels_per_clock == 2));
571 height = stream->config.input_config.input_res.height;
572 vblank_cycles = vblank_lines * (width + hblank_cycles);
573 sh_css_sp_configure_sync_gen(width, height, hblank_cycles,
574 vblank_cycles);
575#if defined(IS_ISP_2400_SYSTEM)
576 if (pipe->stream->config.mode == IA_CSS_INPUT_MODE_TPG) {
577
578 #define GP_ISEL_TPG_MODE 0x90058
579 ia_css_device_store_uint32(GP_ISEL_TPG_MODE, 0);
580 }
581#endif
582 }
583 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
584 "sh_css_config_input_network() leave:\n");
585 return IA_CSS_SUCCESS;
586}
587#elif !defined(HAS_NO_INPUT_SYSTEM) && defined(USE_INPUT_SYSTEM_VERSION_2401)
588static unsigned int csi2_protocol_calculate_max_subpixels_per_line(
589 enum atomisp_input_format format,
590 unsigned int pixels_per_line)
591{
592 unsigned int rval;
593
594 switch (format) {
595 case ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY:
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612 rval = pixels_per_line * 2;
613 break;
614 case ATOMISP_INPUT_FORMAT_YUV420_8:
615 case ATOMISP_INPUT_FORMAT_YUV420_10:
616 case ATOMISP_INPUT_FORMAT_YUV420_16:
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631 rval = pixels_per_line * 2;
632 break;
633 case ATOMISP_INPUT_FORMAT_YUV422_8:
634 case ATOMISP_INPUT_FORMAT_YUV422_10:
635 case ATOMISP_INPUT_FORMAT_YUV422_16:
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650 rval = pixels_per_line * 2;
651 break;
652 case ATOMISP_INPUT_FORMAT_RGB_444:
653 case ATOMISP_INPUT_FORMAT_RGB_555:
654 case ATOMISP_INPUT_FORMAT_RGB_565:
655 case ATOMISP_INPUT_FORMAT_RGB_666:
656 case ATOMISP_INPUT_FORMAT_RGB_888:
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671 rval = pixels_per_line * 4;
672 break;
673 case ATOMISP_INPUT_FORMAT_RAW_6:
674 case ATOMISP_INPUT_FORMAT_RAW_7:
675 case ATOMISP_INPUT_FORMAT_RAW_8:
676 case ATOMISP_INPUT_FORMAT_RAW_10:
677 case ATOMISP_INPUT_FORMAT_RAW_12:
678 case ATOMISP_INPUT_FORMAT_RAW_14:
679 case ATOMISP_INPUT_FORMAT_RAW_16:
680 case ATOMISP_INPUT_FORMAT_BINARY_8:
681 case ATOMISP_INPUT_FORMAT_USER_DEF1:
682 case ATOMISP_INPUT_FORMAT_USER_DEF2:
683 case ATOMISP_INPUT_FORMAT_USER_DEF3:
684 case ATOMISP_INPUT_FORMAT_USER_DEF4:
685 case ATOMISP_INPUT_FORMAT_USER_DEF5:
686 case ATOMISP_INPUT_FORMAT_USER_DEF6:
687 case ATOMISP_INPUT_FORMAT_USER_DEF7:
688 case ATOMISP_INPUT_FORMAT_USER_DEF8:
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703 rval = pixels_per_line;
704 break;
705 default:
706 rval = 0;
707 break;
708 }
709
710 return rval;
711}
712
713static bool sh_css_translate_stream_cfg_to_input_system_input_port_id(
714 struct ia_css_stream_config *stream_cfg,
715 ia_css_isys_descr_t *isys_stream_descr)
716{
717 bool rc;
718
719 rc = true;
720 switch (stream_cfg->mode) {
721 case IA_CSS_INPUT_MODE_TPG:
722
723 if (stream_cfg->source.tpg.id == IA_CSS_TPG_ID0) {
724 isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT0_ID;
725 } else if (stream_cfg->source.tpg.id == IA_CSS_TPG_ID1) {
726 isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT1_ID;
727 } else if (stream_cfg->source.tpg.id == IA_CSS_TPG_ID2) {
728 isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT2_ID;
729 }
730
731 break;
732 case IA_CSS_INPUT_MODE_PRBS:
733
734 if (stream_cfg->source.prbs.id == IA_CSS_PRBS_ID0) {
735 isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT0_ID;
736 } else if (stream_cfg->source.prbs.id == IA_CSS_PRBS_ID1) {
737 isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT1_ID;
738 } else if (stream_cfg->source.prbs.id == IA_CSS_PRBS_ID2) {
739 isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT2_ID;
740 }
741
742 break;
743 case IA_CSS_INPUT_MODE_BUFFERED_SENSOR:
744
745 if (stream_cfg->source.port.port == MIPI_PORT0_ID) {
746 isys_stream_descr->input_port_id = INPUT_SYSTEM_CSI_PORT0_ID;
747 } else if (stream_cfg->source.port.port == MIPI_PORT1_ID) {
748 isys_stream_descr->input_port_id = INPUT_SYSTEM_CSI_PORT1_ID;
749 } else if (stream_cfg->source.port.port == MIPI_PORT2_ID) {
750 isys_stream_descr->input_port_id = INPUT_SYSTEM_CSI_PORT2_ID;
751 }
752
753 break;
754 default:
755 rc = false;
756 break;
757 }
758
759 return rc;
760}
761
762static bool sh_css_translate_stream_cfg_to_input_system_input_port_type(
763 struct ia_css_stream_config *stream_cfg,
764 ia_css_isys_descr_t *isys_stream_descr)
765{
766 bool rc;
767
768 rc = true;
769 switch (stream_cfg->mode) {
770 case IA_CSS_INPUT_MODE_TPG:
771
772 isys_stream_descr->mode = INPUT_SYSTEM_SOURCE_TYPE_TPG;
773
774 break;
775 case IA_CSS_INPUT_MODE_PRBS:
776
777 isys_stream_descr->mode = INPUT_SYSTEM_SOURCE_TYPE_PRBS;
778
779 break;
780 case IA_CSS_INPUT_MODE_SENSOR:
781 case IA_CSS_INPUT_MODE_BUFFERED_SENSOR:
782
783 isys_stream_descr->mode = INPUT_SYSTEM_SOURCE_TYPE_SENSOR;
784 break;
785
786 default:
787 rc = false;
788 break;
789 }
790
791 return rc;
792}
793
794static bool sh_css_translate_stream_cfg_to_input_system_input_port_attr(
795 struct ia_css_stream_config *stream_cfg,
796 ia_css_isys_descr_t *isys_stream_descr,
797 int isys_stream_idx)
798{
799 bool rc;
800
801 rc = true;
802 switch (stream_cfg->mode) {
803 case IA_CSS_INPUT_MODE_TPG:
804 if (stream_cfg->source.tpg.mode == IA_CSS_TPG_MODE_RAMP) {
805 isys_stream_descr->tpg_port_attr.mode = PIXELGEN_TPG_MODE_RAMP;
806 } else if (stream_cfg->source.tpg.mode == IA_CSS_TPG_MODE_CHECKERBOARD) {
807 isys_stream_descr->tpg_port_attr.mode = PIXELGEN_TPG_MODE_CHBO;
808 } else if (stream_cfg->source.tpg.mode == IA_CSS_TPG_MODE_MONO) {
809 isys_stream_descr->tpg_port_attr.mode = PIXELGEN_TPG_MODE_MONO;
810 } else {
811 rc = false;
812 }
813
814
815
816
817
818 isys_stream_descr->tpg_port_attr.color_cfg.R1 = 51;
819 isys_stream_descr->tpg_port_attr.color_cfg.G1 = 102;
820 isys_stream_descr->tpg_port_attr.color_cfg.B1 = 255;
821 isys_stream_descr->tpg_port_attr.color_cfg.R2 = 0;
822 isys_stream_descr->tpg_port_attr.color_cfg.G2 = 100;
823 isys_stream_descr->tpg_port_attr.color_cfg.B2 = 160;
824
825 isys_stream_descr->tpg_port_attr.mask_cfg.h_mask = stream_cfg->source.tpg.x_mask;
826 isys_stream_descr->tpg_port_attr.mask_cfg.v_mask = stream_cfg->source.tpg.y_mask;
827 isys_stream_descr->tpg_port_attr.mask_cfg.hv_mask = stream_cfg->source.tpg.xy_mask;
828
829 isys_stream_descr->tpg_port_attr.delta_cfg.h_delta = stream_cfg->source.tpg.x_delta;
830 isys_stream_descr->tpg_port_attr.delta_cfg.v_delta = stream_cfg->source.tpg.y_delta;
831
832
833
834
835
836 isys_stream_descr->tpg_port_attr.sync_gen_cfg.hblank_cycles = 100;
837 isys_stream_descr->tpg_port_attr.sync_gen_cfg.vblank_cycles = 100;
838 isys_stream_descr->tpg_port_attr.sync_gen_cfg.pixels_per_clock = stream_cfg->pixels_per_clock;
839 isys_stream_descr->tpg_port_attr.sync_gen_cfg.nr_of_frames = (uint32_t) ~(0x0);
840 isys_stream_descr->tpg_port_attr.sync_gen_cfg.pixels_per_line = stream_cfg->isys_config[IA_CSS_STREAM_DEFAULT_ISYS_STREAM_IDX].input_res.width;
841 isys_stream_descr->tpg_port_attr.sync_gen_cfg.lines_per_frame = stream_cfg->isys_config[IA_CSS_STREAM_DEFAULT_ISYS_STREAM_IDX].input_res.height;
842
843 break;
844 case IA_CSS_INPUT_MODE_PRBS:
845
846 isys_stream_descr->prbs_port_attr.seed0 = stream_cfg->source.prbs.seed;
847 isys_stream_descr->prbs_port_attr.seed1 = stream_cfg->source.prbs.seed1;
848
849
850
851
852
853 isys_stream_descr->prbs_port_attr.sync_gen_cfg.hblank_cycles = 100;
854 isys_stream_descr->prbs_port_attr.sync_gen_cfg.vblank_cycles = 100;
855 isys_stream_descr->prbs_port_attr.sync_gen_cfg.pixels_per_clock = stream_cfg->pixels_per_clock;
856 isys_stream_descr->prbs_port_attr.sync_gen_cfg.nr_of_frames = (uint32_t) ~(0x0);
857 isys_stream_descr->prbs_port_attr.sync_gen_cfg.pixels_per_line = stream_cfg->isys_config[IA_CSS_STREAM_DEFAULT_ISYS_STREAM_IDX].input_res.width;
858 isys_stream_descr->prbs_port_attr.sync_gen_cfg.lines_per_frame = stream_cfg->isys_config[IA_CSS_STREAM_DEFAULT_ISYS_STREAM_IDX].input_res.height;
859
860 break;
861 case IA_CSS_INPUT_MODE_BUFFERED_SENSOR:
862 {
863 enum ia_css_err err;
864 unsigned int fmt_type;
865
866 err = ia_css_isys_convert_stream_format_to_mipi_format(
867 stream_cfg->isys_config[isys_stream_idx].format,
868 MIPI_PREDICTOR_NONE,
869 &fmt_type);
870 if (err != IA_CSS_SUCCESS)
871 rc = false;
872
873 isys_stream_descr->csi_port_attr.active_lanes = stream_cfg->source.port.num_lanes;
874 isys_stream_descr->csi_port_attr.fmt_type = fmt_type;
875 isys_stream_descr->csi_port_attr.ch_id = stream_cfg->channel_id;
876#ifdef USE_INPUT_SYSTEM_VERSION_2401
877 isys_stream_descr->online = stream_cfg->online;
878#endif
879 err |= ia_css_isys_convert_compressed_format(
880 &stream_cfg->source.port.compression,
881 isys_stream_descr);
882 if (err != IA_CSS_SUCCESS)
883 rc = false;
884
885
886 isys_stream_descr->metadata.enable = false;
887 if (stream_cfg->metadata_config.resolution.height > 0) {
888 err = ia_css_isys_convert_stream_format_to_mipi_format(
889 stream_cfg->metadata_config.data_type,
890 MIPI_PREDICTOR_NONE,
891 &fmt_type);
892 if (err != IA_CSS_SUCCESS)
893 rc = false;
894 isys_stream_descr->metadata.fmt_type = fmt_type;
895 isys_stream_descr->metadata.bits_per_pixel =
896 ia_css_util_input_format_bpp(stream_cfg->metadata_config.data_type, true);
897 isys_stream_descr->metadata.pixels_per_line = stream_cfg->metadata_config.resolution.width;
898 isys_stream_descr->metadata.lines_per_frame = stream_cfg->metadata_config.resolution.height;
899#ifdef USE_INPUT_SYSTEM_VERSION_2401
900
901
902 if (isys_stream_descr->metadata.lines_per_frame > 0)
903 isys_stream_descr->metadata.lines_per_frame +=
904 (isys_stream_descr->metadata.lines_per_frame & 1);
905#endif
906 isys_stream_descr->metadata.align_req_in_bytes =
907 ia_css_csi2_calculate_input_system_alignment(stream_cfg->metadata_config.data_type);
908 isys_stream_descr->metadata.enable = true;
909 }
910
911 break;
912 }
913 default:
914 rc = false;
915 break;
916 }
917
918 return rc;
919}
920
921static bool sh_css_translate_stream_cfg_to_input_system_input_port_resolution(
922 struct ia_css_stream_config *stream_cfg,
923 ia_css_isys_descr_t *isys_stream_descr,
924 int isys_stream_idx)
925{
926 unsigned int bits_per_subpixel;
927 unsigned int max_subpixels_per_line;
928 unsigned int lines_per_frame;
929 unsigned int align_req_in_bytes;
930 enum atomisp_input_format fmt_type;
931
932 fmt_type = stream_cfg->isys_config[isys_stream_idx].format;
933 if ((stream_cfg->mode == IA_CSS_INPUT_MODE_SENSOR ||
934 stream_cfg->mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR) &&
935 stream_cfg->source.port.compression.type != IA_CSS_CSI2_COMPRESSION_TYPE_NONE) {
936
937 if (stream_cfg->source.port.compression.uncompressed_bits_per_pixel ==
938 UNCOMPRESSED_BITS_PER_PIXEL_10) {
939 fmt_type = ATOMISP_INPUT_FORMAT_RAW_10;
940 }
941 else if (stream_cfg->source.port.compression.uncompressed_bits_per_pixel ==
942 UNCOMPRESSED_BITS_PER_PIXEL_12) {
943 fmt_type = ATOMISP_INPUT_FORMAT_RAW_12;
944 }
945 else
946 return false;
947 }
948
949 bits_per_subpixel =
950 sh_css_stream_format_2_bits_per_subpixel(fmt_type);
951 if (bits_per_subpixel == 0)
952 return false;
953
954 max_subpixels_per_line =
955 csi2_protocol_calculate_max_subpixels_per_line(fmt_type,
956 stream_cfg->isys_config[isys_stream_idx].input_res.width);
957 if (max_subpixels_per_line == 0)
958 return false;
959
960 lines_per_frame = stream_cfg->isys_config[isys_stream_idx].input_res.height;
961 if (lines_per_frame == 0)
962 return false;
963
964 align_req_in_bytes = ia_css_csi2_calculate_input_system_alignment(fmt_type);
965
966
967 isys_stream_descr->input_port_resolution.bits_per_pixel = bits_per_subpixel;
968 isys_stream_descr->input_port_resolution.pixels_per_line = max_subpixels_per_line;
969 isys_stream_descr->input_port_resolution.lines_per_frame = lines_per_frame;
970 isys_stream_descr->input_port_resolution.align_req_in_bytes = align_req_in_bytes;
971
972 return true;
973}
974
975static bool sh_css_translate_stream_cfg_to_isys_stream_descr(
976 struct ia_css_stream_config *stream_cfg,
977 bool early_polling,
978 ia_css_isys_descr_t *isys_stream_descr,
979 int isys_stream_idx)
980{
981 bool rc;
982
983 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
984 "sh_css_translate_stream_cfg_to_isys_stream_descr() enter:\n");
985 rc = sh_css_translate_stream_cfg_to_input_system_input_port_id(stream_cfg, isys_stream_descr);
986 rc &= sh_css_translate_stream_cfg_to_input_system_input_port_type(stream_cfg, isys_stream_descr);
987 rc &= sh_css_translate_stream_cfg_to_input_system_input_port_attr(stream_cfg, isys_stream_descr, isys_stream_idx);
988 rc &= sh_css_translate_stream_cfg_to_input_system_input_port_resolution(stream_cfg, isys_stream_descr, isys_stream_idx);
989
990 isys_stream_descr->raw_packed = stream_cfg->pack_raw_pixels;
991 isys_stream_descr->linked_isys_stream_id = (int8_t) stream_cfg->isys_config[isys_stream_idx].linked_isys_stream_id;
992
993
994
995
996
997
998
999
1000
1001 isys_stream_descr->polling_mode
1002 = early_polling ? INPUT_SYSTEM_POLL_ON_CAPTURE_REQUEST
1003 : INPUT_SYSTEM_POLL_ON_WAIT_FOR_FRAME;
1004 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
1005 "sh_css_translate_stream_cfg_to_isys_stream_descr() leave:\n");
1006
1007 return rc;
1008}
1009
1010static bool sh_css_translate_binary_info_to_input_system_output_port_attr(
1011 struct ia_css_binary *binary,
1012 ia_css_isys_descr_t *isys_stream_descr)
1013{
1014 if (!binary)
1015 return false;
1016
1017 isys_stream_descr->output_port_attr.left_padding = binary->left_padding;
1018 isys_stream_descr->output_port_attr.max_isp_input_width = binary->info->sp.input.max_width;
1019
1020 return true;
1021}
1022
1023static enum ia_css_err
1024sh_css_config_input_network(struct ia_css_stream *stream)
1025{
1026 bool rc;
1027 ia_css_isys_descr_t isys_stream_descr;
1028 unsigned int sp_thread_id;
1029 struct sh_css_sp_pipeline_terminal *sp_pipeline_input_terminal;
1030 struct ia_css_pipe *pipe = NULL;
1031 struct ia_css_binary *binary = NULL;
1032 int i;
1033 uint32_t isys_stream_id;
1034 bool early_polling = false;
1035
1036 assert(stream != NULL);
1037 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
1038 "sh_css_config_input_network() enter 0x%p:\n", stream);
1039
1040 if (stream->config.continuous == true) {
1041 if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_CAPTURE) {
1042 pipe = stream->last_pipe;
1043 } else if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_YUVPP) {
1044 pipe = stream->last_pipe;
1045 } else if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_PREVIEW) {
1046 pipe = stream->last_pipe->pipe_settings.preview.copy_pipe;
1047 } else if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_VIDEO) {
1048 pipe = stream->last_pipe->pipe_settings.video.copy_pipe;
1049 }
1050 } else {
1051 pipe = stream->last_pipe;
1052 if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_CAPTURE) {
1053
1054
1055
1056
1057
1058
1059
1060
1061 early_polling = true;
1062 }
1063 }
1064
1065 assert(pipe != NULL);
1066 if (pipe == NULL)
1067 return IA_CSS_ERR_INTERNAL_ERROR;
1068
1069 if (pipe->pipeline.stages != NULL)
1070 if (pipe->pipeline.stages->binary != NULL)
1071 binary = pipe->pipeline.stages->binary;
1072
1073
1074
1075 if (binary) {
1076
1077
1078
1079
1080 ia_css_get_crop_offsets(pipe, &binary->in_frame_info);
1081 }
1082
1083
1084 rc = ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &sp_thread_id);
1085 if (!rc)
1086 return IA_CSS_ERR_INTERNAL_ERROR;
1087
1088 sp_pipeline_input_terminal = &(sh_css_sp_group.pipe_io[sp_thread_id].input);
1089
1090 for (i = 0; i < IA_CSS_STREAM_MAX_ISYS_STREAM_PER_CH; i++) {
1091
1092 memset((void*)(&isys_stream_descr), 0, sizeof(ia_css_isys_descr_t));
1093 sp_pipeline_input_terminal->context.virtual_input_system_stream[i].valid = 0;
1094 sp_pipeline_input_terminal->ctrl.virtual_input_system_stream_cfg[i].valid = 0;
1095
1096 if (!stream->config.isys_config[i].valid)
1097 continue;
1098
1099
1100 rc = sh_css_translate_stream_cfg_to_isys_stream_descr(
1101 &(stream->config),
1102 early_polling,
1103 &(isys_stream_descr), i);
1104
1105 if (stream->config.online) {
1106 rc &= sh_css_translate_binary_info_to_input_system_output_port_attr(
1107 binary,
1108 &(isys_stream_descr));
1109 }
1110
1111 if (!rc)
1112 return IA_CSS_ERR_INTERNAL_ERROR;
1113
1114 isys_stream_id = ia_css_isys_generate_stream_id(sp_thread_id, i);
1115
1116
1117 rc = ia_css_isys_stream_create(
1118 &(isys_stream_descr),
1119 &(sp_pipeline_input_terminal->context.virtual_input_system_stream[i]),
1120 isys_stream_id);
1121 if (!rc)
1122 return IA_CSS_ERR_INTERNAL_ERROR;
1123
1124
1125 rc = ia_css_isys_stream_calculate_cfg(
1126 &(sp_pipeline_input_terminal->context.virtual_input_system_stream[i]),
1127 &(isys_stream_descr),
1128 &(sp_pipeline_input_terminal->ctrl.virtual_input_system_stream_cfg[i]));
1129 if (!rc) {
1130 ia_css_isys_stream_destroy(&(sp_pipeline_input_terminal->context.virtual_input_system_stream[i]));
1131 return IA_CSS_ERR_INTERNAL_ERROR;
1132 }
1133 }
1134
1135 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
1136 "sh_css_config_input_network() leave:\n");
1137
1138 return IA_CSS_SUCCESS;
1139}
1140
1141static inline struct ia_css_pipe *stream_get_last_pipe(
1142 struct ia_css_stream *stream)
1143{
1144 struct ia_css_pipe *last_pipe = NULL;
1145 if (stream != NULL)
1146 last_pipe = stream->last_pipe;
1147
1148 return last_pipe;
1149}
1150
1151static inline struct ia_css_pipe *stream_get_copy_pipe(
1152 struct ia_css_stream *stream)
1153{
1154 struct ia_css_pipe *copy_pipe = NULL;
1155 struct ia_css_pipe *last_pipe = NULL;
1156 enum ia_css_pipe_id pipe_id;
1157
1158 last_pipe = stream_get_last_pipe(stream);
1159
1160 if ((stream != NULL) &&
1161 (last_pipe != NULL) &&
1162 (stream->config.continuous)) {
1163
1164 pipe_id = last_pipe->mode;
1165 switch (pipe_id) {
1166 case IA_CSS_PIPE_ID_PREVIEW:
1167 copy_pipe = last_pipe->pipe_settings.preview.copy_pipe;
1168 break;
1169 case IA_CSS_PIPE_ID_VIDEO:
1170 copy_pipe = last_pipe->pipe_settings.video.copy_pipe;
1171 break;
1172 default:
1173 copy_pipe = NULL;
1174 break;
1175 }
1176 }
1177
1178 return copy_pipe;
1179}
1180
1181static inline struct ia_css_pipe *stream_get_target_pipe(
1182 struct ia_css_stream *stream)
1183{
1184 struct ia_css_pipe *target_pipe;
1185
1186
1187 if (stream->config.continuous) {
1188 target_pipe = stream_get_copy_pipe(stream);
1189 } else {
1190 target_pipe = stream_get_last_pipe(stream);
1191 }
1192
1193 return target_pipe;
1194}
1195
1196static enum ia_css_err stream_csi_rx_helper(
1197 struct ia_css_stream *stream,
1198 enum ia_css_err (*func)(enum mipi_port_id, uint32_t))
1199{
1200 enum ia_css_err retval = IA_CSS_ERR_INTERNAL_ERROR;
1201 uint32_t sp_thread_id, stream_id;
1202 bool rc;
1203 struct ia_css_pipe *target_pipe = NULL;
1204
1205 if ((stream == NULL) || (stream->config.mode != IA_CSS_INPUT_MODE_BUFFERED_SENSOR))
1206 goto exit;
1207
1208 target_pipe = stream_get_target_pipe(stream);
1209
1210 if (target_pipe == NULL)
1211 goto exit;
1212
1213 rc = ia_css_pipeline_get_sp_thread_id(
1214 ia_css_pipe_get_pipe_num(target_pipe),
1215 &sp_thread_id);
1216
1217 if (!rc)
1218 goto exit;
1219
1220
1221 stream_id = 0;
1222 do {
1223 if (stream->config.isys_config[stream_id].valid) {
1224 uint32_t isys_stream_id = ia_css_isys_generate_stream_id(sp_thread_id, stream_id);
1225 retval = func(stream->config.source.port.port, isys_stream_id);
1226 }
1227 stream_id++;
1228 } while ((retval == IA_CSS_SUCCESS) &&
1229 (stream_id < IA_CSS_STREAM_MAX_ISYS_STREAM_PER_CH));
1230
1231exit:
1232 return retval;
1233}
1234
1235static inline enum ia_css_err stream_register_with_csi_rx(
1236 struct ia_css_stream *stream)
1237{
1238 return stream_csi_rx_helper(stream, ia_css_isys_csi_rx_register_stream);
1239}
1240
1241static inline enum ia_css_err stream_unregister_with_csi_rx(
1242 struct ia_css_stream *stream)
1243{
1244 return stream_csi_rx_helper(stream, ia_css_isys_csi_rx_unregister_stream);
1245}
1246#endif
1247
1248#if WITH_PC_MONITORING
1249static struct task_struct *my_kthread;
1250static int sh_binary_running;
1251
1252static void print_pc_histo(char *core_name, struct sh_css_pc_histogram *hist)
1253{
1254 unsigned i;
1255 unsigned cnt_run = 0;
1256 unsigned cnt_stall = 0;
1257
1258 if (hist == NULL)
1259 return;
1260
1261 sh_css_print("%s histogram length = %d\n", core_name, hist->length);
1262 sh_css_print("%s PC\trun\tstall\n", core_name);
1263
1264 for (i = 0; i < hist->length; i++) {
1265 if ((hist->run[i] == 0) && (hist->run[i] == hist->stall[i]))
1266 continue;
1267 sh_css_print("%s %d\t%d\t%d\n",
1268 core_name, i, hist->run[i], hist->stall[i]);
1269 cnt_run += hist->run[i];
1270 cnt_stall += hist->stall[i];
1271 }
1272
1273 sh_css_print(" Statistics for %s, cnt_run = %d, cnt_stall = %d, "
1274 "hist->length = %d\n",
1275 core_name, cnt_run, cnt_stall, hist->length);
1276}
1277
1278static void print_pc_histogram(void)
1279{
1280 struct ia_css_binary_metrics *metrics;
1281
1282 for (metrics = sh_css_metrics.binary_metrics;
1283 metrics;
1284 metrics = metrics->next) {
1285 if (metrics->mode == IA_CSS_BINARY_MODE_PREVIEW ||
1286 metrics->mode == IA_CSS_BINARY_MODE_VF_PP) {
1287 sh_css_print("pc_histogram for binary %d is SKIPPED\n",
1288 metrics->id);
1289 continue;
1290 }
1291
1292 sh_css_print(" pc_histogram for binary %d\n", metrics->id);
1293 print_pc_histo(" ISP", &metrics->isp_histogram);
1294 print_pc_histo(" SP", &metrics->sp_histogram);
1295 sh_css_print("print_pc_histogram() done for binay->id = %d, "
1296 "done.\n", metrics->id);
1297 }
1298
1299 sh_css_print("PC_MONITORING:print_pc_histogram() -- DONE\n");
1300}
1301
1302static int pc_monitoring(void *data)
1303{
1304 int i = 0;
1305
1306 (void)data;
1307 while (true) {
1308 if (sh_binary_running) {
1309 sh_css_metrics_sample_pcs();
1310#if MULTIPLE_SAMPLES
1311 for (i = 0; i < NOF_SAMPLES; i++)
1312 sh_css_metrics_sample_pcs();
1313#endif
1314 }
1315 usleep_range(10, 50);
1316 }
1317 return 0;
1318}
1319
1320static void spying_thread_create(void)
1321{
1322 my_kthread = kthread_run(pc_monitoring, NULL, "sh_pc_monitor");
1323 sh_css_metrics_enable_pc_histogram(1);
1324}
1325
1326static void input_frame_info(struct ia_css_frame_info frame_info)
1327{
1328 sh_css_print("SH_CSS:input_frame_info() -- frame->info.res.width = %d, "
1329 "frame->info.res.height = %d, format = %d\n",
1330 frame_info.res.width, frame_info.res.height, frame_info.format);
1331}
1332#endif
1333
1334static void
1335start_binary(struct ia_css_pipe *pipe,
1336 struct ia_css_binary *binary)
1337{
1338 struct ia_css_stream *stream;
1339
1340 assert(pipe != NULL);
1341
1342
1343
1344 (void)binary;
1345
1346#if !defined(HAS_NO_INPUT_SYSTEM)
1347 stream = pipe->stream;
1348#else
1349 (void)pipe;
1350 (void)stream;
1351#endif
1352
1353 if (binary)
1354 sh_css_metrics_start_binary(&binary->metrics);
1355
1356#if WITH_PC_MONITORING
1357 sh_css_print("PC_MONITORING: %s() -- binary id = %d , "
1358 "enable_dvs_envelope = %d\n",
1359 __func__, binary->info->sp.id,
1360 binary->info->sp.enable.dvs_envelope);
1361 input_frame_info(binary->in_frame_info);
1362
1363 if (binary && binary->info->sp.pipeline.mode == IA_CSS_BINARY_MODE_VIDEO)
1364 sh_binary_running = true;
1365#endif
1366
1367#if !defined(HAS_NO_INPUT_SYSTEM) && !defined(USE_INPUT_SYSTEM_VERSION_2401)
1368 if (stream->reconfigure_css_rx) {
1369 ia_css_isys_rx_configure(&pipe->stream->csi_rx_config,
1370 pipe->stream->config.mode);
1371 stream->reconfigure_css_rx = false;
1372 }
1373#endif
1374}
1375
1376
1377static enum ia_css_err
1378start_copy_on_sp(struct ia_css_pipe *pipe,
1379 struct ia_css_frame *out_frame)
1380{
1381
1382 (void)out_frame;
1383 assert(pipe != NULL);
1384 assert(pipe->stream != NULL);
1385
1386 if ((pipe == NULL) || (pipe->stream == NULL))
1387 return IA_CSS_ERR_INVALID_ARGUMENTS;
1388
1389#if !defined(HAS_NO_INPUT_SYSTEM) && !defined(USE_INPUT_SYSTEM_VERSION_2401)
1390 if (pipe->stream->reconfigure_css_rx)
1391 ia_css_isys_rx_disable();
1392#endif
1393
1394 if (pipe->stream->config.input_config.format != ATOMISP_INPUT_FORMAT_BINARY_8)
1395 return IA_CSS_ERR_INTERNAL_ERROR;
1396 sh_css_sp_start_binary_copy(ia_css_pipe_get_pipe_num(pipe), out_frame, pipe->stream->config.pixels_per_clock == 2);
1397
1398#if !defined(HAS_NO_INPUT_SYSTEM) && !defined(USE_INPUT_SYSTEM_VERSION_2401)
1399 if (pipe->stream->reconfigure_css_rx) {
1400 ia_css_isys_rx_configure(&pipe->stream->csi_rx_config, pipe->stream->config.mode);
1401 pipe->stream->reconfigure_css_rx = false;
1402 }
1403#endif
1404
1405 return IA_CSS_SUCCESS;
1406}
1407
1408void sh_css_binary_args_reset(struct sh_css_binary_args *args)
1409{
1410 unsigned int i;
1411
1412#ifndef ISP2401
1413 for (i = 0; i < NUM_VIDEO_TNR_FRAMES; i++)
1414#else
1415 for (i = 0; i < NUM_TNR_FRAMES; i++)
1416#endif
1417 args->tnr_frames[i] = NULL;
1418 for (i = 0; i < MAX_NUM_VIDEO_DELAY_FRAMES; i++)
1419 args->delay_frames[i] = NULL;
1420 args->in_frame = NULL;
1421 for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
1422 args->out_frame[i] = NULL;
1423 args->out_vf_frame = NULL;
1424 args->copy_vf = false;
1425 args->copy_output = true;
1426 args->vf_downscale_log2 = 0;
1427}
1428
1429static void start_pipe(
1430 struct ia_css_pipe *me,
1431 enum sh_css_pipe_config_override copy_ovrd,
1432 enum ia_css_input_mode input_mode)
1433{
1434#if defined(HAS_NO_INPUT_SYSTEM)
1435 (void)input_mode;
1436#endif
1437
1438 IA_CSS_ENTER_PRIVATE("me = %p, copy_ovrd = %d, input_mode = %d",
1439 me, copy_ovrd, input_mode);
1440
1441 assert(me != NULL);
1442
1443 sh_css_sp_init_pipeline(&me->pipeline,
1444 me->mode,
1445 (uint8_t)ia_css_pipe_get_pipe_num(me),
1446 me->config.default_capture_config.enable_xnr != 0,
1447 me->stream->config.pixels_per_clock == 2,
1448 me->stream->config.continuous,
1449 false,
1450 me->required_bds_factor,
1451 copy_ovrd,
1452 input_mode,
1453 &me->stream->config.metadata_config,
1454 &me->stream->info.metadata_info
1455#if !defined(HAS_NO_INPUT_SYSTEM)
1456 ,(input_mode==IA_CSS_INPUT_MODE_MEMORY) ?
1457 (enum mipi_port_id)0 :
1458 me->stream->config.source.port.port
1459#endif
1460#ifdef ISP2401
1461 ,&me->config.internal_frame_origin_bqs_on_sctbl,
1462 me->stream->isp_params_configs
1463#endif
1464 );
1465
1466 if (me->config.mode != IA_CSS_PIPE_MODE_COPY) {
1467 struct ia_css_pipeline_stage *stage;
1468 stage = me->pipeline.stages;
1469 if (stage) {
1470 me->pipeline.current_stage = stage;
1471 start_binary(me, stage->binary);
1472 }
1473 }
1474 IA_CSS_LEAVE_PRIVATE("void");
1475}
1476
1477void
1478sh_css_invalidate_shading_tables(struct ia_css_stream *stream)
1479{
1480 int i;
1481 assert(stream != NULL);
1482
1483 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1484 "sh_css_invalidate_shading_tables() enter:\n");
1485
1486 for (i=0; i<stream->num_pipes; i++) {
1487 assert(stream->pipes[i] != NULL);
1488 sh_css_pipe_free_shading_table(stream->pipes[i]);
1489 }
1490
1491 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1492 "sh_css_invalidate_shading_tables() leave: return_void\n");
1493}
1494
1495#ifndef ISP2401
1496static void
1497enable_interrupts(enum ia_css_irq_type irq_type)
1498{
1499#ifdef USE_INPUT_SYSTEM_VERSION_2
1500 enum mipi_port_id port;
1501#endif
1502 bool enable_pulse = irq_type != IA_CSS_IRQ_TYPE_EDGE;
1503 IA_CSS_ENTER_PRIVATE("");
1504
1505
1506 cnd_sp_irq_enable(SP0_ID, true);
1507
1508 irq_enable_pulse(IRQ0_ID, enable_pulse);
1509
1510 cnd_virq_enable_channel(virq_sp, true);
1511
1512
1513 cnd_virq_enable_channel(
1514 (virq_id_t)(IRQ_SW_CHANNEL0_ID + IRQ_SW_CHANNEL_OFFSET),
1515 true);
1516
1517 cnd_virq_enable_channel(
1518 (virq_id_t)(IRQ_SW_CHANNEL1_ID + IRQ_SW_CHANNEL_OFFSET),
1519 true);
1520#if !defined(HAS_IRQ_MAP_VERSION_2)
1521
1522 cnd_virq_enable_channel(
1523 (virq_id_t)(IRQ_SW_CHANNEL2_ID + IRQ_SW_CHANNEL_OFFSET),
1524 true);
1525 virq_clear_all();
1526#endif
1527
1528#ifdef USE_INPUT_SYSTEM_VERSION_2
1529 for (port = 0; port < N_MIPI_PORT_ID; port++)
1530 ia_css_isys_rx_enable_all_interrupts(port);
1531#endif
1532
1533 IA_CSS_LEAVE_PRIVATE("");
1534}
1535
1536#endif
1537
1538static bool sh_css_setup_spctrl_config(const struct ia_css_fw_info *fw,
1539 const char * program,
1540 ia_css_spctrl_cfg *spctrl_cfg)
1541{
1542 if((fw == NULL)||(spctrl_cfg == NULL))
1543 return false;
1544 spctrl_cfg->sp_entry = 0;
1545 spctrl_cfg->program_name = (char *)(program);
1546
1547 spctrl_cfg->ddr_data_offset = fw->blob.data_source;
1548 spctrl_cfg->dmem_data_addr = fw->blob.data_target;
1549 spctrl_cfg->dmem_bss_addr = fw->blob.bss_target;
1550 spctrl_cfg->data_size = fw->blob.data_size ;
1551 spctrl_cfg->bss_size = fw->blob.bss_size;
1552
1553 spctrl_cfg->spctrl_config_dmem_addr = fw->info.sp.init_dmem_data;
1554 spctrl_cfg->spctrl_state_dmem_addr = fw->info.sp.sw_state;
1555
1556 spctrl_cfg->code_size = fw->blob.size;
1557 spctrl_cfg->code = fw->blob.code;
1558 spctrl_cfg->sp_entry = fw->info.sp.sp_entry;
1559
1560 return true;
1561}
1562void
1563ia_css_unload_firmware(void)
1564{
1565 if (sh_css_num_binaries)
1566 {
1567
1568 ia_css_binary_uninit();
1569 sh_css_unload_firmware();
1570 }
1571 fw_explicitly_loaded = false;
1572}
1573
1574static void
1575ia_css_reset_defaults(struct sh_css* css)
1576{
1577 struct sh_css default_css;
1578
1579
1580 memset(&default_css, 0, sizeof(default_css));
1581
1582
1583 default_css.check_system_idle = true;
1584 default_css.num_cont_raw_frames = NUM_CONTINUOUS_FRAMES;
1585
1586
1587
1588
1589
1590 default_css.irq_type = IA_CSS_IRQ_TYPE_EDGE;
1591
1592
1593 *css = default_css;
1594}
1595
1596bool
1597ia_css_check_firmware_version(const struct ia_css_fw *fw)
1598{
1599 bool retval = false;
1600
1601 if (fw != NULL) {
1602 retval = sh_css_check_firmware_version(fw->data);
1603 }
1604 return retval;
1605}
1606
1607enum ia_css_err
1608ia_css_load_firmware(const struct ia_css_env *env,
1609 const struct ia_css_fw *fw)
1610{
1611 enum ia_css_err err;
1612
1613 if (env == NULL)
1614 return IA_CSS_ERR_INVALID_ARGUMENTS;
1615 if (fw == NULL)
1616 return IA_CSS_ERR_INVALID_ARGUMENTS;
1617
1618 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_load_firmware() enter\n");
1619
1620
1621 if (my_css.flush != env->cpu_mem_env.flush) {
1622 ia_css_reset_defaults(&my_css);
1623 my_css.flush = env->cpu_mem_env.flush;
1624 }
1625
1626 ia_css_unload_firmware();
1627 err = sh_css_load_firmware(fw->data, fw->bytes);
1628 if (err == IA_CSS_SUCCESS) {
1629 err = ia_css_binary_init_infos();
1630 if (err == IA_CSS_SUCCESS)
1631 fw_explicitly_loaded = true;
1632 }
1633
1634 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_load_firmware() leave \n");
1635 return err;
1636}
1637
1638enum ia_css_err
1639ia_css_init(const struct ia_css_env *env,
1640 const struct ia_css_fw *fw,
1641 uint32_t mmu_l1_base,
1642 enum ia_css_irq_type irq_type)
1643{
1644 enum ia_css_err err;
1645 ia_css_spctrl_cfg spctrl_cfg;
1646
1647 void (*flush_func)(struct ia_css_acc_fw *fw);
1648 hrt_data select, enable;
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667 COMPILATION_ERROR_IF( sizeof(struct sh_css_ddr_address_map) != SIZE_OF_SH_CSS_DDR_ADDRESS_MAP_STRUCT );
1668
1669 COMPILATION_ERROR_IF( sizeof(struct host_sp_queues) != SIZE_OF_HOST_SP_QUEUES_STRUCT );
1670 COMPILATION_ERROR_IF( sizeof(struct ia_css_circbuf_desc_s) != SIZE_OF_IA_CSS_CIRCBUF_DESC_S_STRUCT );
1671 COMPILATION_ERROR_IF( sizeof(struct ia_css_circbuf_elem_s) != SIZE_OF_IA_CSS_CIRCBUF_ELEM_S_STRUCT );
1672
1673
1674 COMPILATION_ERROR_IF( sizeof(struct host_sp_communication) != SIZE_OF_HOST_SP_COMMUNICATION_STRUCT );
1675 COMPILATION_ERROR_IF( sizeof(struct sh_css_event_irq_mask) != SIZE_OF_SH_CSS_EVENT_IRQ_MASK_STRUCT );
1676
1677
1678 COMPILATION_ERROR_IF( sizeof(struct sh_css_hmm_buffer) != SIZE_OF_SH_CSS_HMM_BUFFER_STRUCT );
1679 COMPILATION_ERROR_IF( sizeof(struct ia_css_isp_3a_statistics) != SIZE_OF_IA_CSS_ISP_3A_STATISTICS_STRUCT );
1680 COMPILATION_ERROR_IF( sizeof(struct ia_css_isp_dvs_statistics) != SIZE_OF_IA_CSS_ISP_DVS_STATISTICS_STRUCT );
1681 COMPILATION_ERROR_IF( sizeof(struct ia_css_metadata) != SIZE_OF_IA_CSS_METADATA_STRUCT );
1682
1683
1684 COMPILATION_ERROR_IF( sizeof(struct ia_css_sp_init_dmem_cfg) != SIZE_OF_IA_CSS_SP_INIT_DMEM_CFG_STRUCT );
1685
1686 if (fw == NULL && !fw_explicitly_loaded)
1687 return IA_CSS_ERR_INVALID_ARGUMENTS;
1688 if (env == NULL)
1689 return IA_CSS_ERR_INVALID_ARGUMENTS;
1690
1691 sh_css_printf = env->print_env.debug_print;
1692
1693 IA_CSS_ENTER("void");
1694
1695 flush_func = env->cpu_mem_env.flush;
1696
1697 pipe_global_init();
1698 ia_css_pipeline_init();
1699 ia_css_queue_map_init();
1700
1701 ia_css_device_access_init(&env->hw_access_env);
1702
1703 select = gpio_reg_load(GPIO0_ID, _gpio_block_reg_do_select)
1704 & (~GPIO_FLASH_PIN_MASK);
1705 enable = gpio_reg_load(GPIO0_ID, _gpio_block_reg_do_e)
1706 | GPIO_FLASH_PIN_MASK;
1707 sh_css_mmu_set_page_table_base_index(mmu_l1_base);
1708#ifndef ISP2401
1709 my_css_save.mmu_base = mmu_l1_base;
1710#else
1711 ia_css_save_mmu_base_addr(mmu_l1_base);
1712#endif
1713
1714 ia_css_reset_defaults(&my_css);
1715
1716 my_css_save.driver_env = *env;
1717 my_css.flush = flush_func;
1718
1719 err = ia_css_rmgr_init();
1720 if (err != IA_CSS_SUCCESS) {
1721 IA_CSS_LEAVE_ERR(err);
1722 return err;
1723 }
1724
1725#ifndef ISP2401
1726 IA_CSS_LOG("init: %d", my_css_save_initialized);
1727#else
1728 ia_css_save_restore_data_init();
1729#endif
1730
1731#ifndef ISP2401
1732 if (!my_css_save_initialized)
1733 {
1734 my_css_save_initialized = true;
1735 my_css_save.mode = sh_css_mode_working;
1736 memset(my_css_save.stream_seeds, 0, sizeof(struct sh_css_stream_seed) * MAX_ACTIVE_STREAMS);
1737 IA_CSS_LOG("init: %d mode=%d", my_css_save_initialized, my_css_save.mode);
1738 }
1739#endif
1740 mipi_init();
1741
1742#ifndef ISP2401
1743
1744
1745 my_css.page_table_base_index = mmu_get_page_table_base_index(MMU0_ID);
1746
1747#endif
1748 my_css.irq_type = irq_type;
1749#ifndef ISP2401
1750 my_css_save.irq_type = irq_type;
1751#else
1752 ia_css_save_irq_type(irq_type);
1753#endif
1754 enable_interrupts(my_css.irq_type);
1755
1756
1757 gpio_reg_store(GPIO0_ID, _gpio_block_reg_do_select, select);
1758 gpio_reg_store(GPIO0_ID, _gpio_block_reg_do_e, enable);
1759 gpio_reg_store(GPIO0_ID, _gpio_block_reg_do_0, 0);
1760
1761 err = ia_css_refcount_init(REFCOUNT_SIZE);
1762 if (err != IA_CSS_SUCCESS) {
1763 IA_CSS_LEAVE_ERR(err);
1764 return err;
1765 }
1766 err = sh_css_params_init();
1767 if (err != IA_CSS_SUCCESS) {
1768 IA_CSS_LEAVE_ERR(err);
1769 return err;
1770 }
1771 if (fw)
1772 {
1773 ia_css_unload_firmware();
1774 err = sh_css_load_firmware(fw->data, fw->bytes);
1775 if (err != IA_CSS_SUCCESS) {
1776 IA_CSS_LEAVE_ERR(err);
1777 return err;
1778 }
1779 err = ia_css_binary_init_infos();
1780 if (err != IA_CSS_SUCCESS) {
1781 IA_CSS_LEAVE_ERR(err);
1782 return err;
1783 }
1784 fw_explicitly_loaded = false;
1785#ifndef ISP2401
1786 my_css_save.loaded_fw = (struct ia_css_fw *)fw;
1787#endif
1788 }
1789 if(!sh_css_setup_spctrl_config(&sh_css_sp_fw,SP_PROG_NAME,&spctrl_cfg))
1790 return IA_CSS_ERR_INTERNAL_ERROR;
1791
1792 err = ia_css_spctrl_load_fw(SP0_ID, &spctrl_cfg);
1793 if (err != IA_CSS_SUCCESS) {
1794 IA_CSS_LEAVE_ERR(err);
1795 return err;
1796 }
1797
1798#if WITH_PC_MONITORING
1799 if (!thread_alive) {
1800 thread_alive++;
1801 sh_css_print("PC_MONITORING: %s() -- create thread DISABLED\n",
1802 __func__);
1803 spying_thread_create();
1804 }
1805#endif
1806 if (!sh_css_hrt_system_is_idle()) {
1807 IA_CSS_LEAVE_ERR(IA_CSS_ERR_SYSTEM_NOT_IDLE);
1808 return IA_CSS_ERR_SYSTEM_NOT_IDLE;
1809 }
1810
1811
1812
1813
1814
1815
1816
1817#if defined(HAS_INPUT_SYSTEM_VERSION_2) && defined(HAS_INPUT_SYSTEM_VERSION_2401)
1818#if defined(USE_INPUT_SYSTEM_VERSION_2)
1819 gp_device_reg_store(GP_DEVICE0_ID, _REG_GP_SWITCH_ISYS2401_ADDR, 0);
1820#elif defined (USE_INPUT_SYSTEM_VERSION_2401)
1821 gp_device_reg_store(GP_DEVICE0_ID, _REG_GP_SWITCH_ISYS2401_ADDR, 1);
1822#endif
1823#endif
1824
1825#if !defined(HAS_NO_INPUT_SYSTEM)
1826 dma_set_max_burst_size(DMA0_ID, HIVE_DMA_BUS_DDR_CONN,
1827 ISP_DMA_MAX_BURST_LENGTH);
1828
1829 if(ia_css_isys_init() != INPUT_SYSTEM_ERR_NO_ERROR)
1830 err = IA_CSS_ERR_INVALID_ARGUMENTS;
1831#endif
1832
1833 sh_css_params_map_and_store_default_gdc_lut();
1834
1835 IA_CSS_LEAVE_ERR(err);
1836 return err;
1837}
1838
1839enum ia_css_err ia_css_suspend(void)
1840{
1841 int i;
1842 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_suspend() enter\n");
1843 my_css_save.mode = sh_css_mode_suspend;
1844 for(i=0;i<MAX_ACTIVE_STREAMS;i++)
1845 if (my_css_save.stream_seeds[i].stream != NULL)
1846 {
1847 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "==*> unloading seed %d (%p)\n", i, my_css_save.stream_seeds[i].stream);
1848 ia_css_stream_unload(my_css_save.stream_seeds[i].stream);
1849 }
1850 my_css_save.mode = sh_css_mode_working;
1851 ia_css_stop_sp();
1852 ia_css_uninit();
1853 for(i=0;i<MAX_ACTIVE_STREAMS;i++)
1854 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "==*> after 1: seed %d (%p)\n", i, my_css_save.stream_seeds[i].stream);
1855 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_suspend() leave\n");
1856 return IA_CSS_SUCCESS;
1857}
1858
1859enum ia_css_err
1860ia_css_resume(void)
1861{
1862 int i, j;
1863 enum ia_css_err err;
1864 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_resume() enter: void\n");
1865
1866 err = ia_css_init(&(my_css_save.driver_env), my_css_save.loaded_fw, my_css_save.mmu_base, my_css_save.irq_type);
1867 if (err != IA_CSS_SUCCESS)
1868 return err;
1869 err = ia_css_start_sp();
1870 if (err != IA_CSS_SUCCESS)
1871 return err;
1872 my_css_save.mode = sh_css_mode_resume;
1873 for(i=0;i<MAX_ACTIVE_STREAMS;i++)
1874 {
1875 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "==*> seed stream %p\n", my_css_save.stream_seeds[i].stream);
1876 if (my_css_save.stream_seeds[i].stream != NULL)
1877 {
1878 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "==*> loading seed %d\n", i);
1879 err = ia_css_stream_load(my_css_save.stream_seeds[i].stream);
1880 if (err != IA_CSS_SUCCESS)
1881 {
1882 if (i)
1883 for(j=0;j<i;j++)
1884 ia_css_stream_unload(my_css_save.stream_seeds[j].stream);
1885 return err;
1886 }
1887 err = ia_css_stream_start(my_css_save.stream_seeds[i].stream);
1888 if (err != IA_CSS_SUCCESS)
1889 {
1890 for(j=0;j<=i;j++)
1891 {
1892 ia_css_stream_stop(my_css_save.stream_seeds[j].stream);
1893 ia_css_stream_unload(my_css_save.stream_seeds[j].stream);
1894 }
1895 return err;
1896 }
1897 *my_css_save.stream_seeds[i].orig_stream = my_css_save.stream_seeds[i].stream;
1898 for(j=0;j<my_css_save.stream_seeds[i].num_pipes;j++)
1899 *(my_css_save.stream_seeds[i].orig_pipes[j]) = my_css_save.stream_seeds[i].pipes[j];
1900 }
1901 }
1902 my_css_save.mode = sh_css_mode_working;
1903 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_resume() leave: return_void\n");
1904 return IA_CSS_SUCCESS;
1905}
1906
1907enum ia_css_err
1908ia_css_enable_isys_event_queue(bool enable)
1909{
1910 if (sh_css_sp_is_running())
1911 return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
1912 sh_css_sp_enable_isys_event_queue(enable);
1913 return IA_CSS_SUCCESS;
1914}
1915
1916void *sh_css_malloc(size_t size)
1917{
1918 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "sh_css_malloc() enter: size=%zu\n",size);
1919
1920 if (size == 0)
1921 return NULL;
1922 if (size > PAGE_SIZE)
1923 return vmalloc(size);
1924 return kmalloc(size, GFP_KERNEL);
1925}
1926
1927void *sh_css_calloc(size_t N, size_t size)
1928{
1929 void *p;
1930
1931 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "sh_css_calloc() enter: N=%zu, size=%zu\n",N,size);
1932
1933
1934 if (size > 0) {
1935 p = sh_css_malloc(N*size);
1936 if (p)
1937 memset(p, 0, size);
1938 return p;
1939 }
1940 return NULL;
1941}
1942
1943void sh_css_free(void *ptr)
1944{
1945 if (is_vmalloc_addr(ptr))
1946 vfree(ptr);
1947 else
1948 kfree(ptr);
1949}
1950
1951
1952void
1953sh_css_flush(struct ia_css_acc_fw *fw)
1954{
1955 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "sh_css_flush() enter:\n");
1956 if ((fw != NULL) && (my_css.flush != NULL))
1957 my_css.flush(fw);
1958}
1959
1960
1961
1962
1963
1964static enum ia_css_err
1965map_sp_threads(struct ia_css_stream *stream, bool map)
1966{
1967 struct ia_css_pipe *main_pipe = NULL;
1968 struct ia_css_pipe *copy_pipe = NULL;
1969 struct ia_css_pipe *capture_pipe = NULL;
1970 struct ia_css_pipe *acc_pipe = NULL;
1971 enum ia_css_err err = IA_CSS_SUCCESS;
1972 enum ia_css_pipe_id pipe_id;
1973
1974 assert(stream != NULL);
1975 IA_CSS_ENTER_PRIVATE("stream = %p, map = %s",
1976 stream, map ? "true" : "false");
1977
1978 if (stream == NULL) {
1979 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
1980 return IA_CSS_ERR_INVALID_ARGUMENTS;
1981 }
1982
1983 main_pipe = stream->last_pipe;
1984 pipe_id = main_pipe->mode;
1985
1986 ia_css_pipeline_map(main_pipe->pipe_num, map);
1987
1988 switch (pipe_id) {
1989 case IA_CSS_PIPE_ID_PREVIEW:
1990 copy_pipe = main_pipe->pipe_settings.preview.copy_pipe;
1991 capture_pipe = main_pipe->pipe_settings.preview.capture_pipe;
1992 acc_pipe = main_pipe->pipe_settings.preview.acc_pipe;
1993 break;
1994
1995 case IA_CSS_PIPE_ID_VIDEO:
1996 copy_pipe = main_pipe->pipe_settings.video.copy_pipe;
1997 capture_pipe = main_pipe->pipe_settings.video.capture_pipe;
1998 break;
1999
2000 case IA_CSS_PIPE_ID_CAPTURE:
2001 case IA_CSS_PIPE_ID_ACC:
2002 default:
2003 break;
2004 }
2005
2006 if (acc_pipe) {
2007 ia_css_pipeline_map(acc_pipe->pipe_num, map);
2008 }
2009
2010 if(capture_pipe) {
2011 ia_css_pipeline_map(capture_pipe->pipe_num, map);
2012 }
2013
2014
2015 if(copy_pipe) {
2016 ia_css_pipeline_map(copy_pipe->pipe_num, map);
2017 }
2018
2019 if (!stream->config.continuous) {
2020 int i;
2021 for (i = 1; i < stream->num_pipes; i++)
2022 ia_css_pipeline_map(stream->pipes[i]->pipe_num, map);
2023 }
2024
2025 IA_CSS_LEAVE_ERR_PRIVATE(err);
2026 return err;
2027}
2028
2029
2030
2031static enum ia_css_err
2032create_host_pipeline_structure(struct ia_css_stream *stream)
2033{
2034 struct ia_css_pipe *copy_pipe = NULL, *capture_pipe = NULL;
2035 struct ia_css_pipe *acc_pipe = NULL;
2036 enum ia_css_pipe_id pipe_id;
2037 struct ia_css_pipe *main_pipe = NULL;
2038 enum ia_css_err err = IA_CSS_SUCCESS;
2039 unsigned int copy_pipe_delay = 0,
2040 capture_pipe_delay = 0;
2041
2042 assert(stream != NULL);
2043 IA_CSS_ENTER_PRIVATE("stream = %p", stream);
2044
2045 if (stream == NULL) {
2046 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
2047 return IA_CSS_ERR_INVALID_ARGUMENTS;
2048 }
2049
2050 main_pipe = stream->last_pipe;
2051 assert(main_pipe != NULL);
2052 if (main_pipe == NULL) {
2053 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
2054 return IA_CSS_ERR_INVALID_ARGUMENTS;
2055 }
2056
2057 pipe_id = main_pipe->mode;
2058
2059 switch (pipe_id) {
2060 case IA_CSS_PIPE_ID_PREVIEW:
2061 copy_pipe = main_pipe->pipe_settings.preview.copy_pipe;
2062 copy_pipe_delay = main_pipe->dvs_frame_delay;
2063 capture_pipe = main_pipe->pipe_settings.preview.capture_pipe;
2064 capture_pipe_delay = IA_CSS_FRAME_DELAY_0;
2065 acc_pipe = main_pipe->pipe_settings.preview.acc_pipe;
2066 err = ia_css_pipeline_create(&main_pipe->pipeline, main_pipe->mode, main_pipe->pipe_num, main_pipe->dvs_frame_delay);
2067 break;
2068
2069 case IA_CSS_PIPE_ID_VIDEO:
2070 copy_pipe = main_pipe->pipe_settings.video.copy_pipe;
2071 copy_pipe_delay = main_pipe->dvs_frame_delay;
2072 capture_pipe = main_pipe->pipe_settings.video.capture_pipe;
2073 capture_pipe_delay = IA_CSS_FRAME_DELAY_0;
2074 err = ia_css_pipeline_create(&main_pipe->pipeline, main_pipe->mode, main_pipe->pipe_num, main_pipe->dvs_frame_delay);
2075 break;
2076
2077 case IA_CSS_PIPE_ID_CAPTURE:
2078 capture_pipe = main_pipe;
2079 capture_pipe_delay = main_pipe->dvs_frame_delay;
2080 break;
2081
2082 case IA_CSS_PIPE_ID_YUVPP:
2083 err = ia_css_pipeline_create(&main_pipe->pipeline, main_pipe->mode,
2084 main_pipe->pipe_num, main_pipe->dvs_frame_delay);
2085 break;
2086
2087 case IA_CSS_PIPE_ID_ACC:
2088 err = ia_css_pipeline_create(&main_pipe->pipeline, main_pipe->mode, main_pipe->pipe_num, main_pipe->dvs_frame_delay);
2089 break;
2090
2091 default:
2092 err = IA_CSS_ERR_INVALID_ARGUMENTS;
2093 }
2094
2095 if ((IA_CSS_SUCCESS == err) && copy_pipe) {
2096 err = ia_css_pipeline_create(©_pipe->pipeline,
2097 copy_pipe->mode,
2098 copy_pipe->pipe_num,
2099 copy_pipe_delay);
2100 }
2101
2102 if ((IA_CSS_SUCCESS == err) && capture_pipe) {
2103 err = ia_css_pipeline_create(&capture_pipe->pipeline,
2104 capture_pipe->mode,
2105 capture_pipe->pipe_num,
2106 capture_pipe_delay);
2107 }
2108
2109 if ((IA_CSS_SUCCESS == err) && acc_pipe) {
2110 err = ia_css_pipeline_create(&acc_pipe->pipeline, acc_pipe->mode, acc_pipe->pipe_num, main_pipe->dvs_frame_delay);
2111 }
2112
2113
2114 if (!stream->config.continuous) {
2115 int i;
2116 for (i = 1; i < stream->num_pipes && IA_CSS_SUCCESS == err; i++) {
2117 main_pipe = stream->pipes[i];
2118 err = ia_css_pipeline_create(&main_pipe->pipeline,
2119 main_pipe->mode,
2120 main_pipe->pipe_num,
2121 main_pipe->dvs_frame_delay);
2122 }
2123 }
2124
2125 IA_CSS_LEAVE_ERR_PRIVATE(err);
2126 return err;
2127}
2128
2129
2130
2131static enum ia_css_err
2132create_host_pipeline(struct ia_css_stream *stream)
2133{
2134 struct ia_css_pipe *copy_pipe = NULL, *capture_pipe = NULL;
2135 struct ia_css_pipe *acc_pipe = NULL;
2136 enum ia_css_pipe_id pipe_id;
2137 struct ia_css_pipe *main_pipe = NULL;
2138 enum ia_css_err err = IA_CSS_SUCCESS;
2139 unsigned max_input_width = 0;
2140
2141 IA_CSS_ENTER_PRIVATE("stream = %p", stream);
2142 if (stream == NULL) {
2143 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
2144 return IA_CSS_ERR_INVALID_ARGUMENTS;
2145 }
2146
2147 main_pipe = stream->last_pipe;
2148 pipe_id = main_pipe->mode;
2149
2150
2151
2152 if ((pipe_id == IA_CSS_PIPE_ID_PREVIEW) ||
2153 (pipe_id == IA_CSS_PIPE_ID_VIDEO)) {
2154
2155
2156
2157
2158
2159
2160 if (stream->config.continuous ||
2161 (pipe_id == IA_CSS_PIPE_ID_PREVIEW && stream->config.mode != IA_CSS_INPUT_MODE_MEMORY)) {
2162 err = alloc_continuous_frames(main_pipe, true);
2163 if (err != IA_CSS_SUCCESS)
2164 goto ERR;
2165 }
2166
2167 }
2168
2169#if defined(USE_INPUT_SYSTEM_VERSION_2)
2170
2171 if (pipe_id != IA_CSS_PIPE_ID_ACC) {
2172 err = allocate_mipi_frames(main_pipe, &stream->info);
2173 if (err != IA_CSS_SUCCESS)
2174 goto ERR;
2175 }
2176#elif defined(USE_INPUT_SYSTEM_VERSION_2401)
2177 if ((pipe_id != IA_CSS_PIPE_ID_ACC) &&
2178 (main_pipe->config.mode != IA_CSS_PIPE_MODE_COPY)) {
2179 err = allocate_mipi_frames(main_pipe, &stream->info);
2180 if (err != IA_CSS_SUCCESS)
2181 goto ERR;
2182 }
2183#endif
2184
2185 switch (pipe_id) {
2186 case IA_CSS_PIPE_ID_PREVIEW:
2187 copy_pipe = main_pipe->pipe_settings.preview.copy_pipe;
2188 capture_pipe = main_pipe->pipe_settings.preview.capture_pipe;
2189 acc_pipe = main_pipe->pipe_settings.preview.acc_pipe;
2190 max_input_width =
2191 main_pipe->pipe_settings.preview.preview_binary.info->sp.input.max_width;
2192
2193 err = create_host_preview_pipeline(main_pipe);
2194 if (err != IA_CSS_SUCCESS)
2195 goto ERR;
2196
2197 break;
2198
2199 case IA_CSS_PIPE_ID_VIDEO:
2200 copy_pipe = main_pipe->pipe_settings.video.copy_pipe;
2201 capture_pipe = main_pipe->pipe_settings.video.capture_pipe;
2202 max_input_width =
2203 main_pipe->pipe_settings.video.video_binary.info->sp.input.max_width;
2204
2205 err = create_host_video_pipeline(main_pipe);
2206 if (err != IA_CSS_SUCCESS)
2207 goto ERR;
2208
2209 break;
2210
2211 case IA_CSS_PIPE_ID_CAPTURE:
2212 capture_pipe = main_pipe;
2213
2214 break;
2215
2216 case IA_CSS_PIPE_ID_YUVPP:
2217 err = create_host_yuvpp_pipeline(main_pipe);
2218 if (err != IA_CSS_SUCCESS)
2219 goto ERR;
2220
2221 break;
2222
2223 case IA_CSS_PIPE_ID_ACC:
2224 err = create_host_acc_pipeline(main_pipe);
2225 if (err != IA_CSS_SUCCESS)
2226 goto ERR;
2227
2228 break;
2229 default:
2230 err = IA_CSS_ERR_INVALID_ARGUMENTS;
2231 }
2232 if (err != IA_CSS_SUCCESS)
2233 goto ERR;
2234
2235 if(copy_pipe) {
2236 err = create_host_copy_pipeline(copy_pipe, max_input_width,
2237 main_pipe->continuous_frames[0]);
2238 if (err != IA_CSS_SUCCESS)
2239 goto ERR;
2240 }
2241
2242 if(capture_pipe) {
2243 err = create_host_capture_pipeline(capture_pipe);
2244 if (err != IA_CSS_SUCCESS)
2245 goto ERR;
2246 }
2247
2248 if (acc_pipe) {
2249 err = create_host_acc_pipeline(acc_pipe);
2250 if (err != IA_CSS_SUCCESS)
2251 goto ERR;
2252 }
2253
2254
2255 if (!stream->config.continuous) {
2256 int i;
2257 for (i = 1; i < stream->num_pipes && IA_CSS_SUCCESS == err; i++) {
2258 switch (stream->pipes[i]->mode) {
2259 case IA_CSS_PIPE_ID_PREVIEW:
2260 err = create_host_preview_pipeline(stream->pipes[i]);
2261 break;
2262 case IA_CSS_PIPE_ID_VIDEO:
2263 err = create_host_video_pipeline(stream->pipes[i]);
2264 break;
2265 case IA_CSS_PIPE_ID_CAPTURE:
2266 err = create_host_capture_pipeline(stream->pipes[i]);
2267 break;
2268 case IA_CSS_PIPE_ID_YUVPP:
2269 err = create_host_yuvpp_pipeline(stream->pipes[i]);
2270 break;
2271 case IA_CSS_PIPE_ID_ACC:
2272 err = create_host_acc_pipeline(stream->pipes[i]);
2273 break;
2274 default:
2275 err = IA_CSS_ERR_INVALID_ARGUMENTS;
2276 }
2277 if (err != IA_CSS_SUCCESS)
2278 goto ERR;
2279 }
2280 }
2281
2282ERR:
2283 IA_CSS_LEAVE_ERR_PRIVATE(err);
2284 return err;
2285}
2286
2287static enum ia_css_err
2288init_pipe_defaults(enum ia_css_pipe_mode mode,
2289 struct ia_css_pipe *pipe,
2290 bool copy_pipe)
2291{
2292 if (pipe == NULL) {
2293 IA_CSS_ERROR("NULL pipe parameter");
2294 return IA_CSS_ERR_INVALID_ARGUMENTS;
2295 }
2296
2297
2298 *pipe = IA_CSS_DEFAULT_PIPE;
2299
2300
2301 switch (mode) {
2302 case IA_CSS_PIPE_MODE_PREVIEW:
2303 pipe->mode = IA_CSS_PIPE_ID_PREVIEW;
2304 pipe->pipe_settings.preview = IA_CSS_DEFAULT_PREVIEW_SETTINGS;
2305 break;
2306 case IA_CSS_PIPE_MODE_CAPTURE:
2307 if (copy_pipe) {
2308 pipe->mode = IA_CSS_PIPE_ID_COPY;
2309 } else {
2310 pipe->mode = IA_CSS_PIPE_ID_CAPTURE;
2311 }
2312 pipe->pipe_settings.capture = IA_CSS_DEFAULT_CAPTURE_SETTINGS;
2313 break;
2314 case IA_CSS_PIPE_MODE_VIDEO:
2315 pipe->mode = IA_CSS_PIPE_ID_VIDEO;
2316 pipe->pipe_settings.video = IA_CSS_DEFAULT_VIDEO_SETTINGS;
2317 break;
2318 case IA_CSS_PIPE_MODE_ACC:
2319 pipe->mode = IA_CSS_PIPE_ID_ACC;
2320 break;
2321 case IA_CSS_PIPE_MODE_COPY:
2322 pipe->mode = IA_CSS_PIPE_ID_CAPTURE;
2323 break;
2324 case IA_CSS_PIPE_MODE_YUVPP:
2325 pipe->mode = IA_CSS_PIPE_ID_YUVPP;
2326 pipe->pipe_settings.yuvpp = IA_CSS_DEFAULT_YUVPP_SETTINGS;
2327 break;
2328 default:
2329 return IA_CSS_ERR_INVALID_ARGUMENTS;
2330 }
2331
2332 return IA_CSS_SUCCESS;
2333}
2334
2335static void
2336pipe_global_init(void)
2337{
2338 uint8_t i;
2339
2340 my_css.pipe_counter = 0;
2341 for (i = 0; i < IA_CSS_PIPELINE_NUM_MAX; i++) {
2342 my_css.all_pipes[i] = NULL;
2343 }
2344}
2345
2346static enum ia_css_err
2347pipe_generate_pipe_num(const struct ia_css_pipe *pipe, unsigned int *pipe_number)
2348{
2349 const uint8_t INVALID_PIPE_NUM = (uint8_t)~(0);
2350 uint8_t pipe_num = INVALID_PIPE_NUM;
2351 uint8_t i;
2352
2353 if (pipe == NULL) {
2354 IA_CSS_ERROR("NULL pipe parameter");
2355 return IA_CSS_ERR_INVALID_ARGUMENTS;
2356 }
2357
2358
2359 for (i = 0; i < IA_CSS_PIPELINE_NUM_MAX; i++) {
2360 if (my_css.all_pipes[i] == NULL) {
2361
2362 my_css.all_pipes[i] = (struct ia_css_pipe *)pipe;
2363 pipe_num = i;
2364 break;
2365 }
2366 }
2367 if (pipe_num == INVALID_PIPE_NUM) {
2368
2369 IA_CSS_ERROR("Max number of pipes already created");
2370 return IA_CSS_ERR_RESOURCE_EXHAUSTED;
2371 }
2372
2373 my_css.pipe_counter++;
2374
2375 IA_CSS_LOG("pipe_num (%d)", pipe_num);
2376
2377 *pipe_number = pipe_num;
2378 return IA_CSS_SUCCESS;
2379}
2380
2381static void
2382pipe_release_pipe_num(unsigned int pipe_num)
2383{
2384 my_css.all_pipes[pipe_num] = NULL;
2385 my_css.pipe_counter--;
2386 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
2387 "pipe_release_pipe_num (%d)\n", pipe_num);
2388}
2389
2390static enum ia_css_err
2391create_pipe(enum ia_css_pipe_mode mode,
2392 struct ia_css_pipe **pipe,
2393 bool copy_pipe)
2394{
2395 enum ia_css_err err = IA_CSS_SUCCESS;
2396 struct ia_css_pipe *me;
2397
2398 if (pipe == NULL) {
2399 IA_CSS_ERROR("NULL pipe parameter");
2400 return IA_CSS_ERR_INVALID_ARGUMENTS;
2401 }
2402
2403 me = kmalloc(sizeof(*me), GFP_KERNEL);
2404 if (!me)
2405 return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
2406
2407 err = init_pipe_defaults(mode, me, copy_pipe);
2408 if (err != IA_CSS_SUCCESS) {
2409 kfree(me);
2410 return err;
2411 }
2412
2413 err = pipe_generate_pipe_num(me, &(me->pipe_num));
2414 if (err != IA_CSS_SUCCESS) {
2415 kfree(me);
2416 return err;
2417 }
2418
2419 *pipe = me;
2420 return IA_CSS_SUCCESS;
2421}
2422
2423struct ia_css_pipe *
2424find_pipe_by_num(uint32_t pipe_num)
2425{
2426 unsigned int i;
2427 for (i = 0; i < IA_CSS_PIPELINE_NUM_MAX; i++){
2428 if (my_css.all_pipes[i] &&
2429 ia_css_pipe_get_pipe_num(my_css.all_pipes[i]) == pipe_num) {
2430 return my_css.all_pipes[i];
2431 }
2432 }
2433 return NULL;
2434}
2435
2436static void sh_css_pipe_free_acc_binaries (
2437 struct ia_css_pipe *pipe)
2438{
2439 struct ia_css_pipeline *pipeline;
2440 struct ia_css_pipeline_stage *stage;
2441
2442 assert(pipe != NULL);
2443 if (pipe == NULL) {
2444 IA_CSS_ERROR("NULL input pointer");
2445 return;
2446 }
2447 pipeline = &pipe->pipeline;
2448
2449
2450 for (stage = pipeline->stages; stage; stage = stage->next) {
2451 struct ia_css_fw_info *firmware = (struct ia_css_fw_info *)
2452 stage->firmware;
2453 if (firmware)
2454 ia_css_pipe_unload_extension(pipe, firmware);
2455 }
2456}
2457
2458enum ia_css_err
2459ia_css_pipe_destroy(struct ia_css_pipe *pipe)
2460{
2461 enum ia_css_err err = IA_CSS_SUCCESS;
2462 IA_CSS_ENTER("pipe = %p", pipe);
2463
2464 if (pipe == NULL) {
2465 IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
2466 return IA_CSS_ERR_INVALID_ARGUMENTS;
2467 }
2468
2469 if (pipe->stream != NULL) {
2470 IA_CSS_LOG("ia_css_stream_destroy not called!");
2471 IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
2472 return IA_CSS_ERR_INVALID_ARGUMENTS;
2473 }
2474
2475 switch (pipe->config.mode) {
2476 case IA_CSS_PIPE_MODE_PREVIEW:
2477
2478
2479 if (pipe->mode == IA_CSS_PIPE_ID_PREVIEW) {
2480 ia_css_frame_free_multiple(NUM_CONTINUOUS_FRAMES,
2481 pipe->continuous_frames);
2482 ia_css_metadata_free_multiple(NUM_CONTINUOUS_FRAMES,
2483 pipe->cont_md_buffers);
2484 if (pipe->pipe_settings.preview.copy_pipe) {
2485 err = ia_css_pipe_destroy(pipe->pipe_settings.preview.copy_pipe);
2486 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_pipe_destroy(): "
2487 "destroyed internal copy pipe err=%d\n", err);
2488 }
2489 }
2490 break;
2491 case IA_CSS_PIPE_MODE_VIDEO:
2492 if (pipe->mode == IA_CSS_PIPE_ID_VIDEO) {
2493 ia_css_frame_free_multiple(NUM_CONTINUOUS_FRAMES,
2494 pipe->continuous_frames);
2495 ia_css_metadata_free_multiple(NUM_CONTINUOUS_FRAMES,
2496 pipe->cont_md_buffers);
2497 if (pipe->pipe_settings.video.copy_pipe) {
2498 err = ia_css_pipe_destroy(pipe->pipe_settings.video.copy_pipe);
2499 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_pipe_destroy(): "
2500 "destroyed internal copy pipe err=%d\n", err);
2501 }
2502 }
2503#ifndef ISP2401
2504 ia_css_frame_free_multiple(NUM_VIDEO_TNR_FRAMES, pipe->pipe_settings.video.tnr_frames);
2505#else
2506 ia_css_frame_free_multiple(NUM_TNR_FRAMES, pipe->pipe_settings.video.tnr_frames);
2507#endif
2508 ia_css_frame_free_multiple(MAX_NUM_VIDEO_DELAY_FRAMES, pipe->pipe_settings.video.delay_frames);
2509 break;
2510 case IA_CSS_PIPE_MODE_CAPTURE:
2511 ia_css_frame_free_multiple(MAX_NUM_VIDEO_DELAY_FRAMES, pipe->pipe_settings.capture.delay_frames);
2512 break;
2513 case IA_CSS_PIPE_MODE_ACC:
2514 sh_css_pipe_free_acc_binaries(pipe);
2515 break;
2516 case IA_CSS_PIPE_MODE_COPY:
2517 break;
2518 case IA_CSS_PIPE_MODE_YUVPP:
2519 break;
2520 }
2521
2522 sh_css_params_free_gdc_lut(pipe->scaler_pp_lut);
2523 pipe->scaler_pp_lut = mmgr_NULL;
2524
2525 my_css.active_pipes[ia_css_pipe_get_pipe_num(pipe)] = NULL;
2526 sh_css_pipe_free_shading_table(pipe);
2527
2528 ia_css_pipeline_destroy(&pipe->pipeline);
2529 pipe_release_pipe_num(ia_css_pipe_get_pipe_num(pipe));
2530
2531
2532 if (pipe->config.acc_extension) {
2533 ia_css_pipe_unload_extension(pipe, pipe->config.acc_extension);
2534 }
2535 kfree(pipe);
2536 IA_CSS_LEAVE("err = %d", err);
2537 return err;
2538}
2539
2540void
2541ia_css_uninit(void)
2542{
2543 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_uninit() enter: void\n");
2544#if WITH_PC_MONITORING
2545 sh_css_print("PC_MONITORING: %s() -- started\n", __func__);
2546 print_pc_histogram();
2547#endif
2548
2549 sh_css_params_free_default_gdc_lut();
2550
2551
2552
2553
2554
2555 sh_css_params_uninit();
2556 ia_css_refcount_uninit();
2557
2558 ia_css_rmgr_uninit();
2559
2560#if !defined(HAS_NO_INPUT_FORMATTER)
2561
2562 ifmtr_set_if_blocking_mode_reset = true;
2563#endif
2564
2565 if (!fw_explicitly_loaded) {
2566 ia_css_unload_firmware();
2567 }
2568 ia_css_spctrl_unload_fw(SP0_ID);
2569 sh_css_sp_set_sp_running(false);
2570#if defined(USE_INPUT_SYSTEM_VERSION_2) || defined(USE_INPUT_SYSTEM_VERSION_2401)
2571
2572 free_mipi_frames(NULL);
2573#endif
2574
2575 sh_css_sp_reset_global_vars();
2576
2577#if !defined(HAS_NO_INPUT_SYSTEM)
2578 ia_css_isys_uninit();
2579#endif
2580
2581 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_uninit() leave: return_void\n");
2582}
2583
2584#if defined(HAS_IRQ_MAP_VERSION_2)
2585enum ia_css_err ia_css_irq_translate(
2586 unsigned int *irq_infos)
2587{
2588 virq_id_t irq;
2589 enum hrt_isp_css_irq_status status = hrt_isp_css_irq_status_more_irqs;
2590 unsigned int infos = 0;
2591
2592
2593
2594 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_irq_translate() enter: irq_infos=%p\n",irq_infos);
2595
2596 while (status == hrt_isp_css_irq_status_more_irqs) {
2597 status = virq_get_channel_id(&irq);
2598 if (status == hrt_isp_css_irq_status_error)
2599 return IA_CSS_ERR_INTERNAL_ERROR;
2600
2601#if WITH_PC_MONITORING
2602 sh_css_print("PC_MONITORING: %s() irq = %d, "
2603 "sh_binary_running set to 0\n", __func__, irq);
2604 sh_binary_running = 0 ;
2605#endif
2606
2607 switch (irq) {
2608 case virq_sp:
2609
2610
2611 infos |= IA_CSS_IRQ_INFO_EVENTS_READY;
2612 break;
2613 case virq_isp:
2614 break;
2615#if !defined(HAS_NO_INPUT_SYSTEM)
2616 case virq_isys_sof:
2617 infos |= IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF;
2618 break;
2619 case virq_isys_eof:
2620 infos |= IA_CSS_IRQ_INFO_CSS_RECEIVER_EOF;
2621 break;
2622 case virq_isys_csi:
2623 infos |= IA_CSS_IRQ_INFO_INPUT_SYSTEM_ERROR;
2624 break;
2625#endif
2626#if !defined(HAS_NO_INPUT_FORMATTER)
2627 case virq_ifmt0_id:
2628 infos |= IA_CSS_IRQ_INFO_IF_ERROR;
2629 break;
2630#endif
2631 case virq_dma:
2632 infos |= IA_CSS_IRQ_INFO_DMA_ERROR;
2633 break;
2634 case virq_sw_pin_0:
2635 infos |= sh_css_get_sw_interrupt_value(0);
2636 break;
2637 case virq_sw_pin_1:
2638 infos |= sh_css_get_sw_interrupt_value(1);
2639
2640 break;
2641 default:
2642 break;
2643 }
2644 }
2645
2646 if (irq_infos)
2647 *irq_infos = infos;
2648
2649 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_irq_translate() "
2650 "leave: irq_infos=%u\n", infos);
2651
2652 return IA_CSS_SUCCESS;
2653}
2654
2655enum ia_css_err ia_css_irq_enable(
2656 enum ia_css_irq_info info,
2657 bool enable)
2658{
2659 virq_id_t irq = N_virq_id;
2660 IA_CSS_ENTER("info=%d, enable=%d", info, enable);
2661
2662 switch (info) {
2663#if !defined(HAS_NO_INPUT_FORMATTER)
2664 case IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF:
2665 irq = virq_isys_sof;
2666 break;
2667 case IA_CSS_IRQ_INFO_CSS_RECEIVER_EOF:
2668 irq = virq_isys_eof;
2669 break;
2670 case IA_CSS_IRQ_INFO_INPUT_SYSTEM_ERROR:
2671 irq = virq_isys_csi;
2672 break;
2673#endif
2674#if !defined(HAS_NO_INPUT_FORMATTER)
2675 case IA_CSS_IRQ_INFO_IF_ERROR:
2676 irq = virq_ifmt0_id;
2677 break;
2678#endif
2679 case IA_CSS_IRQ_INFO_DMA_ERROR:
2680 irq = virq_dma;
2681 break;
2682 case IA_CSS_IRQ_INFO_SW_0:
2683 irq = virq_sw_pin_0;
2684 break;
2685 case IA_CSS_IRQ_INFO_SW_1:
2686 irq = virq_sw_pin_1;
2687 break;
2688 default:
2689 IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
2690 return IA_CSS_ERR_INVALID_ARGUMENTS;
2691 }
2692
2693 cnd_virq_enable_channel(irq, enable);
2694
2695 IA_CSS_LEAVE_ERR(IA_CSS_SUCCESS);
2696 return IA_CSS_SUCCESS;
2697}
2698
2699#else
2700#error "sh_css.c: IRQ MAP must be one of \
2701 {IRQ_MAP_VERSION_2}"
2702#endif
2703
2704static unsigned int
2705sh_css_get_sw_interrupt_value(unsigned int irq)
2706{
2707 unsigned int irq_value;
2708 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "sh_css_get_sw_interrupt_value() enter: irq=%d\n",irq);
2709 irq_value = sh_css_sp_get_sw_interrupt_value(irq);
2710 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "sh_css_get_sw_interrupt_value() leave: irq_value=%d\n",irq_value);
2711 return irq_value;
2712}
2713
2714
2715
2716static enum ia_css_err load_copy_binary(
2717 struct ia_css_pipe *pipe,
2718 struct ia_css_binary *copy_binary,
2719 struct ia_css_binary *next_binary)
2720{
2721 struct ia_css_frame_info copy_out_info, copy_in_info, copy_vf_info;
2722 unsigned int left_padding;
2723 enum ia_css_err err;
2724 struct ia_css_binary_descr copy_descr;
2725
2726
2727 assert(pipe != NULL);
2728 assert(copy_binary != NULL);
2729 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
2730 "load_copy_binary() enter:\n");
2731
2732 if (next_binary != NULL) {
2733 copy_out_info = next_binary->in_frame_info;
2734 left_padding = next_binary->left_padding;
2735 } else {
2736 copy_out_info = pipe->output_info[0];
2737 copy_vf_info = pipe->vf_output_info[0];
2738 ia_css_frame_info_set_format(©_vf_info, IA_CSS_FRAME_FORMAT_YUV_LINE);
2739 left_padding = 0;
2740 }
2741
2742 ia_css_pipe_get_copy_binarydesc(pipe, ©_descr,
2743 ©_in_info, ©_out_info, (next_binary != NULL) ? NULL : NULL);
2744 err = ia_css_binary_find(©_descr, copy_binary);
2745 if (err != IA_CSS_SUCCESS)
2746 return err;
2747 copy_binary->left_padding = left_padding;
2748 return IA_CSS_SUCCESS;
2749}
2750
2751static enum ia_css_err
2752alloc_continuous_frames(
2753 struct ia_css_pipe *pipe, bool init_time)
2754{
2755 enum ia_css_err err = IA_CSS_SUCCESS;
2756 struct ia_css_frame_info ref_info;
2757 enum ia_css_pipe_id pipe_id;
2758 bool continuous;
2759 unsigned int i, idx;
2760 unsigned int num_frames;
2761 struct ia_css_pipe *capture_pipe = NULL;
2762
2763 IA_CSS_ENTER_PRIVATE("pipe = %p, init_time = %d", pipe, init_time);
2764
2765 if ((pipe == NULL) || (pipe->stream == NULL)) {
2766 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
2767 return IA_CSS_ERR_INVALID_ARGUMENTS;
2768 }
2769
2770 pipe_id = pipe->mode;
2771 continuous = pipe->stream->config.continuous;
2772
2773 if (continuous) {
2774 if (init_time) {
2775 num_frames = pipe->stream->config.init_num_cont_raw_buf;
2776 pipe->stream->continuous_pipe = pipe;
2777 } else
2778 num_frames = pipe->stream->config.target_num_cont_raw_buf;
2779 } else {
2780 num_frames = NUM_ONLINE_INIT_CONTINUOUS_FRAMES;
2781 }
2782
2783 if (pipe_id == IA_CSS_PIPE_ID_PREVIEW) {
2784 ref_info = pipe->pipe_settings.preview.preview_binary.in_frame_info;
2785 } else if (pipe_id == IA_CSS_PIPE_ID_VIDEO) {
2786 ref_info = pipe->pipe_settings.video.video_binary.in_frame_info;
2787 }
2788 else {
2789
2790 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INTERNAL_ERROR);
2791 return IA_CSS_ERR_INTERNAL_ERROR;
2792 }
2793
2794#if defined(USE_INPUT_SYSTEM_VERSION_2401)
2795
2796 ref_info.res.width = pipe->stream->config.input_config.input_res.width;
2797 ref_info.res.height = pipe->stream->config.input_config.input_res.height;
2798
2799
2800 ref_info.padded_width = CEIL_MUL(ref_info.res.width, 2 * ISP_VEC_NELEMS);
2801#endif
2802
2803#if !defined(HAS_NO_PACKED_RAW_PIXELS)
2804 if (pipe->stream->config.pack_raw_pixels) {
2805 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
2806 "alloc_continuous_frames() IA_CSS_FRAME_FORMAT_RAW_PACKED\n");
2807 ref_info.format = IA_CSS_FRAME_FORMAT_RAW_PACKED;
2808 } else
2809#endif
2810 {
2811 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
2812 "alloc_continuous_frames() IA_CSS_FRAME_FORMAT_RAW\n");
2813 ref_info.format = IA_CSS_FRAME_FORMAT_RAW;
2814 }
2815
2816
2817 if (pipe_id == IA_CSS_PIPE_ID_PREVIEW) {
2818 pipe->pipe_settings.preview.preview_binary.in_frame_info.format = ref_info.format;
2819 capture_pipe = pipe->pipe_settings.preview.capture_pipe;
2820 } else if (pipe_id == IA_CSS_PIPE_ID_VIDEO) {
2821 pipe->pipe_settings.video.video_binary.in_frame_info.format = ref_info.format;
2822 capture_pipe = pipe->pipe_settings.video.capture_pipe;
2823 } else {
2824
2825 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INTERNAL_ERROR);
2826 return IA_CSS_ERR_INTERNAL_ERROR;
2827 }
2828
2829 if (init_time)
2830 idx = 0;
2831 else
2832 idx = pipe->stream->config.init_num_cont_raw_buf;
2833
2834 for (i = idx; i < NUM_CONTINUOUS_FRAMES; i++) {
2835
2836 if (pipe->continuous_frames[i]) {
2837 ia_css_frame_free(pipe->continuous_frames[i]);
2838 pipe->continuous_frames[i] = NULL;
2839 }
2840
2841 ia_css_metadata_free(pipe->cont_md_buffers[i]);
2842 pipe->cont_md_buffers[i] = NULL;
2843
2844
2845 if (i < num_frames) {
2846
2847 err = ia_css_frame_allocate_from_info(
2848 &pipe->continuous_frames[i],
2849 &ref_info);
2850 if (err != IA_CSS_SUCCESS) {
2851 IA_CSS_LEAVE_ERR_PRIVATE(err);
2852 return err;
2853 }
2854
2855 pipe->cont_md_buffers[i] = ia_css_metadata_allocate(
2856 &pipe->stream->info.metadata_info);
2857 }
2858 }
2859 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
2860 return IA_CSS_SUCCESS;
2861}
2862
2863enum ia_css_err
2864ia_css_alloc_continuous_frame_remain(struct ia_css_stream *stream)
2865{
2866 if (stream == NULL)
2867 return IA_CSS_ERR_INVALID_ARGUMENTS;
2868 return alloc_continuous_frames(stream->continuous_pipe, false);
2869}
2870
2871static enum ia_css_err
2872load_preview_binaries(struct ia_css_pipe *pipe)
2873{
2874 struct ia_css_frame_info prev_in_info,
2875 prev_bds_out_info,
2876 prev_out_info,
2877 prev_vf_info;
2878 struct ia_css_binary_descr preview_descr;
2879 bool online;
2880 enum ia_css_err err = IA_CSS_SUCCESS;
2881 bool continuous, need_vf_pp = false;
2882 bool need_isp_copy_binary = false;
2883#ifdef USE_INPUT_SYSTEM_VERSION_2401
2884 bool sensor = false;
2885#endif
2886
2887 struct ia_css_frame_info *pipe_out_info = &pipe->output_info[0];
2888 struct ia_css_preview_settings *mycs = &pipe->pipe_settings.preview;
2889
2890 IA_CSS_ENTER_PRIVATE("");
2891 assert(pipe != NULL);
2892 assert(pipe->stream != NULL);
2893 assert(pipe->mode == IA_CSS_PIPE_ID_PREVIEW);
2894
2895 online = pipe->stream->config.online;
2896 continuous = pipe->stream->config.continuous;
2897#ifdef USE_INPUT_SYSTEM_VERSION_2401
2898 sensor = pipe->stream->config.mode == IA_CSS_INPUT_MODE_SENSOR;
2899#endif
2900
2901 if (mycs->preview_binary.info)
2902 return IA_CSS_SUCCESS;
2903
2904 err = ia_css_util_check_input(&pipe->stream->config, false, false);
2905 if (err != IA_CSS_SUCCESS)
2906 return err;
2907 err = ia_css_frame_check_info(pipe_out_info);
2908 if (err != IA_CSS_SUCCESS)
2909 return err;
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925 need_vf_pp = pipe->config.enable_dz;
2926 need_vf_pp |= pipe_out_info->format != IA_CSS_FRAME_FORMAT_YUV_LINE &&
2927 !(pipe_out_info->format == IA_CSS_FRAME_FORMAT_NV12 ||
2928 pipe_out_info->format == IA_CSS_FRAME_FORMAT_NV12_16 ||
2929 pipe_out_info->format == IA_CSS_FRAME_FORMAT_NV12_TILEY);
2930
2931
2932 if (pipe->vf_yuv_ds_input_info.res.width)
2933 prev_vf_info = pipe->vf_yuv_ds_input_info;
2934 else
2935 prev_vf_info = *pipe_out_info;
2936
2937
2938
2939
2940
2941 if (need_vf_pp)
2942 ia_css_frame_info_set_format(&prev_vf_info,
2943 IA_CSS_FRAME_FORMAT_YUV_LINE);
2944
2945 err = ia_css_pipe_get_preview_binarydesc(
2946 pipe,
2947 &preview_descr,
2948 &prev_in_info,
2949 &prev_bds_out_info,
2950 &prev_out_info,
2951 &prev_vf_info);
2952 if (err != IA_CSS_SUCCESS)
2953 return err;
2954 err = ia_css_binary_find(&preview_descr, &mycs->preview_binary);
2955 if (err != IA_CSS_SUCCESS)
2956 return err;
2957
2958#ifdef ISP2401
2959
2960
2961 pipe->num_invalid_frames = pipe->dvs_frame_delay;
2962 pipe->info.num_invalid_frames = pipe->num_invalid_frames;
2963
2964 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
2965 "load_preview_binaries() num_invalid_frames=%d dvs_frame_delay=%d\n",
2966 pipe->num_invalid_frames, pipe->dvs_frame_delay);
2967
2968#endif
2969
2970 need_vf_pp |= mycs->preview_binary.out_frame_info[0].res.width != pipe_out_info->res.width;
2971 need_vf_pp |= mycs->preview_binary.out_frame_info[0].res.height != pipe_out_info->res.height;
2972
2973
2974
2975
2976
2977 if (need_vf_pp &&
2978 (mycs->preview_binary.out_frame_info[0].format != IA_CSS_FRAME_FORMAT_YUV_LINE)) {
2979
2980
2981 if (pipe->vf_yuv_ds_input_info.res.width)
2982 prev_vf_info = pipe->vf_yuv_ds_input_info;
2983 else
2984 prev_vf_info = *pipe_out_info;
2985
2986 ia_css_frame_info_set_format(&prev_vf_info,
2987 IA_CSS_FRAME_FORMAT_YUV_LINE);
2988
2989 err = ia_css_pipe_get_preview_binarydesc(
2990 pipe,
2991 &preview_descr,
2992 &prev_in_info,
2993 &prev_bds_out_info,
2994 &prev_out_info,
2995 &prev_vf_info);
2996 if (err != IA_CSS_SUCCESS)
2997 return err;
2998 err = ia_css_binary_find(&preview_descr,
2999 &mycs->preview_binary);
3000 if (err != IA_CSS_SUCCESS)
3001 return err;
3002 }
3003
3004 if (need_vf_pp) {
3005 struct ia_css_binary_descr vf_pp_descr;
3006
3007
3008 ia_css_pipe_get_vfpp_binarydesc(pipe, &vf_pp_descr,
3009 &mycs->preview_binary.out_frame_info[0],
3010 pipe_out_info);
3011 err = ia_css_binary_find(&vf_pp_descr,
3012 &mycs->vf_pp_binary);
3013 if (err != IA_CSS_SUCCESS)
3014 return err;
3015 }
3016
3017#ifdef USE_INPUT_SYSTEM_VERSION_2401
3018
3019
3020
3021 need_isp_copy_binary = !online && sensor;
3022#else
3023#ifndef ISP2401
3024 need_isp_copy_binary = !online && !continuous;
3025#else
3026
3027
3028
3029
3030
3031 need_isp_copy_binary = !online && !continuous && !(pipe->stream->config.mode == IA_CSS_INPUT_MODE_MEMORY);
3032#endif
3033#endif
3034
3035
3036 if (need_isp_copy_binary) {
3037 err = load_copy_binary(pipe,
3038 &mycs->copy_binary,
3039 &mycs->preview_binary);
3040 if (err != IA_CSS_SUCCESS)
3041 return err;
3042 }
3043
3044 if (pipe->shading_table) {
3045 ia_css_shading_table_free(pipe->shading_table);
3046 pipe->shading_table = NULL;
3047 }
3048
3049 return IA_CSS_SUCCESS;
3050}
3051
3052static void
3053ia_css_binary_unload(struct ia_css_binary *binary)
3054{
3055 ia_css_binary_destroy_isp_parameters(binary);
3056}
3057
3058static enum ia_css_err
3059unload_preview_binaries(struct ia_css_pipe *pipe)
3060{
3061 IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
3062
3063 if ((pipe == NULL) || (pipe->mode != IA_CSS_PIPE_ID_PREVIEW)) {
3064 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
3065 return IA_CSS_ERR_INVALID_ARGUMENTS;
3066 }
3067 ia_css_binary_unload(&pipe->pipe_settings.preview.copy_binary);
3068 ia_css_binary_unload(&pipe->pipe_settings.preview.preview_binary);
3069 ia_css_binary_unload(&pipe->pipe_settings.preview.vf_pp_binary);
3070
3071 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
3072 return IA_CSS_SUCCESS;
3073}
3074
3075static const struct ia_css_fw_info *last_output_firmware(
3076 const struct ia_css_fw_info *fw)
3077{
3078 const struct ia_css_fw_info *last_fw = NULL;
3079
3080 IA_CSS_ENTER_LEAVE_PRIVATE("");
3081
3082 for (; fw; fw = fw->next) {
3083 const struct ia_css_fw_info *info = fw;
3084 if (info->info.isp.sp.enable.output)
3085 last_fw = fw;
3086 }
3087 return last_fw;
3088}
3089
3090static enum ia_css_err add_firmwares(
3091 struct ia_css_pipeline *me,
3092 struct ia_css_binary *binary,
3093 const struct ia_css_fw_info *fw,
3094 const struct ia_css_fw_info *last_fw,
3095 unsigned int binary_mode,
3096 struct ia_css_frame *in_frame,
3097 struct ia_css_frame *out_frame,
3098 struct ia_css_frame *vf_frame,
3099 struct ia_css_pipeline_stage **my_stage,
3100 struct ia_css_pipeline_stage **vf_stage)
3101{
3102 enum ia_css_err err = IA_CSS_SUCCESS;
3103 struct ia_css_pipeline_stage *extra_stage = NULL;
3104 struct ia_css_pipeline_stage_desc stage_desc;
3105
3106
3107 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
3108 "add_firmwares() enter:\n");
3109
3110 for (; fw; fw = fw->next) {
3111 struct ia_css_frame *out[IA_CSS_BINARY_MAX_OUTPUT_PORTS] = {NULL};
3112 struct ia_css_frame *in = NULL;
3113 struct ia_css_frame *vf = NULL;
3114 if ((fw == last_fw) && (fw->info.isp.sp.enable.out_frame != 0)) {
3115 out[0] = out_frame;
3116 }
3117 if (fw->info.isp.sp.enable.in_frame != 0) {
3118 in = in_frame;
3119 }
3120 if (fw->info.isp.sp.enable.out_frame != 0) {
3121 vf = vf_frame;
3122 }
3123 ia_css_pipe_get_firmwares_stage_desc(&stage_desc, binary,
3124 out, in, vf, fw, binary_mode);
3125 err = ia_css_pipeline_create_and_add_stage(me,
3126 &stage_desc,
3127 &extra_stage);
3128 if (err != IA_CSS_SUCCESS)
3129 return err;
3130 if (fw->info.isp.sp.enable.output != 0)
3131 in_frame = extra_stage->args.out_frame[0];
3132 if (my_stage && !*my_stage && extra_stage)
3133 *my_stage = extra_stage;
3134 if (vf_stage && !*vf_stage && extra_stage &&
3135 fw->info.isp.sp.enable.vf_veceven)
3136 *vf_stage = extra_stage;
3137 }
3138 return err;
3139}
3140
3141static enum ia_css_err add_vf_pp_stage(
3142 struct ia_css_pipe *pipe,
3143 struct ia_css_frame *in_frame,
3144 struct ia_css_frame *out_frame,
3145 struct ia_css_binary *vf_pp_binary,
3146 struct ia_css_pipeline_stage **vf_pp_stage)
3147{
3148
3149 struct ia_css_pipeline *me = NULL;
3150 const struct ia_css_fw_info *last_fw = NULL;
3151 enum ia_css_err err = IA_CSS_SUCCESS;
3152 struct ia_css_frame *out_frames[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
3153 struct ia_css_pipeline_stage_desc stage_desc;
3154
3155
3156
3157 if (pipe == NULL)
3158 return IA_CSS_ERR_INVALID_ARGUMENTS;
3159 if (in_frame == NULL)
3160 return IA_CSS_ERR_INVALID_ARGUMENTS;
3161 if (vf_pp_binary == NULL)
3162 return IA_CSS_ERR_INVALID_ARGUMENTS;
3163 if (vf_pp_stage == NULL)
3164 return IA_CSS_ERR_INVALID_ARGUMENTS;
3165
3166 ia_css_pipe_util_create_output_frames(out_frames);
3167 me = &pipe->pipeline;
3168
3169 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
3170 "add_vf_pp_stage() enter:\n");
3171
3172 *vf_pp_stage = NULL;
3173
3174 last_fw = last_output_firmware(pipe->vf_stage);
3175 if (!pipe->extra_config.disable_vf_pp) {
3176 if (last_fw) {
3177 ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
3178 ia_css_pipe_get_generic_stage_desc(&stage_desc, vf_pp_binary,
3179 out_frames, in_frame, NULL);
3180 } else{
3181 ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
3182 ia_css_pipe_get_generic_stage_desc(&stage_desc, vf_pp_binary,
3183 out_frames, in_frame, NULL);
3184 }
3185 err = ia_css_pipeline_create_and_add_stage(me, &stage_desc, vf_pp_stage);
3186 if (err != IA_CSS_SUCCESS)
3187 return err;
3188 in_frame = (*vf_pp_stage)->args.out_frame[0];
3189 }
3190 err = add_firmwares(me, vf_pp_binary, pipe->vf_stage, last_fw,
3191 IA_CSS_BINARY_MODE_VF_PP,
3192 in_frame, out_frame, NULL,
3193 vf_pp_stage, NULL);
3194 return err;
3195}
3196
3197static enum ia_css_err add_yuv_scaler_stage(
3198 struct ia_css_pipe *pipe,
3199 struct ia_css_pipeline *me,
3200 struct ia_css_frame *in_frame,
3201 struct ia_css_frame *out_frame,
3202 struct ia_css_frame *internal_out_frame,
3203 struct ia_css_binary *yuv_scaler_binary,
3204 struct ia_css_pipeline_stage **pre_vf_pp_stage)
3205{
3206 const struct ia_css_fw_info *last_fw;
3207 enum ia_css_err err = IA_CSS_SUCCESS;
3208 struct ia_css_frame *vf_frame = NULL;
3209 struct ia_css_frame *out_frames[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
3210 struct ia_css_pipeline_stage_desc stage_desc;
3211
3212
3213 assert(in_frame != NULL);
3214 assert(pipe != NULL);
3215 assert(me != NULL);
3216 assert(yuv_scaler_binary != NULL);
3217 assert(pre_vf_pp_stage != NULL);
3218 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
3219 "add_yuv_scaler_stage() enter:\n");
3220
3221 *pre_vf_pp_stage = NULL;
3222 ia_css_pipe_util_create_output_frames(out_frames);
3223
3224 last_fw = last_output_firmware(pipe->output_stage);
3225
3226 if(last_fw) {
3227 ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
3228 ia_css_pipe_get_generic_stage_desc(&stage_desc,
3229 yuv_scaler_binary, out_frames, in_frame, vf_frame);
3230 } else {
3231 ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
3232 ia_css_pipe_util_set_output_frames(out_frames, 1, internal_out_frame);
3233 ia_css_pipe_get_generic_stage_desc(&stage_desc,
3234 yuv_scaler_binary, out_frames, in_frame, vf_frame);
3235 }
3236 err = ia_css_pipeline_create_and_add_stage(me,
3237 &stage_desc,
3238 pre_vf_pp_stage);
3239 if (err != IA_CSS_SUCCESS)
3240 return err;
3241 in_frame = (*pre_vf_pp_stage)->args.out_frame[0];
3242
3243 err = add_firmwares(me, yuv_scaler_binary, pipe->output_stage, last_fw,
3244 IA_CSS_BINARY_MODE_CAPTURE_PP,
3245 in_frame, out_frame, vf_frame,
3246 NULL, pre_vf_pp_stage);
3247
3248 (*pre_vf_pp_stage)->args.vf_downscale_log2 = yuv_scaler_binary->vf_downscale_log2;
3249
3250 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
3251 "add_yuv_scaler_stage() leave:\n");
3252 return err;
3253}
3254
3255static enum ia_css_err add_capture_pp_stage(
3256 struct ia_css_pipe *pipe,
3257 struct ia_css_pipeline *me,
3258 struct ia_css_frame *in_frame,
3259 struct ia_css_frame *out_frame,
3260 struct ia_css_binary *capture_pp_binary,
3261 struct ia_css_pipeline_stage **capture_pp_stage)
3262{
3263 const struct ia_css_fw_info *last_fw = NULL;
3264 enum ia_css_err err = IA_CSS_SUCCESS;
3265 struct ia_css_frame *vf_frame = NULL;
3266 struct ia_css_frame *out_frames[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
3267 struct ia_css_pipeline_stage_desc stage_desc;
3268
3269
3270 assert(in_frame != NULL);
3271 assert(pipe != NULL);
3272 assert(me != NULL);
3273 assert(capture_pp_binary != NULL);
3274 assert(capture_pp_stage != NULL);
3275 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
3276 "add_capture_pp_stage() enter:\n");
3277
3278 *capture_pp_stage = NULL;
3279 ia_css_pipe_util_create_output_frames(out_frames);
3280
3281 last_fw = last_output_firmware(pipe->output_stage);
3282 err = ia_css_frame_allocate_from_info(&vf_frame,
3283 &capture_pp_binary->vf_frame_info);
3284 if (err != IA_CSS_SUCCESS)
3285 return err;
3286 if(last_fw) {
3287 ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
3288 ia_css_pipe_get_generic_stage_desc(&stage_desc,
3289 capture_pp_binary, out_frames, NULL, vf_frame);
3290 } else {
3291 ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
3292 ia_css_pipe_get_generic_stage_desc(&stage_desc,
3293 capture_pp_binary, out_frames, NULL, vf_frame);
3294 }
3295 err = ia_css_pipeline_create_and_add_stage(me,
3296 &stage_desc,
3297 capture_pp_stage);
3298 if (err != IA_CSS_SUCCESS)
3299 return err;
3300 err = add_firmwares(me, capture_pp_binary, pipe->output_stage, last_fw,
3301 IA_CSS_BINARY_MODE_CAPTURE_PP,
3302 in_frame, out_frame, vf_frame,
3303 NULL, capture_pp_stage);
3304
3305 if (*capture_pp_stage) {
3306 (*capture_pp_stage)->args.vf_downscale_log2 =
3307 capture_pp_binary->vf_downscale_log2;
3308 }
3309 return err;
3310}
3311
3312static void sh_css_setup_queues(void)
3313{
3314 const struct ia_css_fw_info *fw;
3315 unsigned int HIVE_ADDR_host_sp_queues_initialized;
3316
3317 sh_css_hmm_buffer_record_init();
3318
3319 sh_css_event_init_irq_mask();
3320
3321 fw = &sh_css_sp_fw;
3322 HIVE_ADDR_host_sp_queues_initialized =
3323 fw->info.sp.host_sp_queues_initialized;
3324
3325 ia_css_bufq_init();
3326
3327
3328 sp_dmem_store_uint32(SP0_ID,
3329 (unsigned int)sp_address_of(host_sp_queues_initialized),
3330 (uint32_t)(1));
3331 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "sh_css_setup_queues() leave:\n");
3332}
3333
3334static enum ia_css_err
3335init_vf_frameinfo_defaults(struct ia_css_pipe *pipe,
3336 struct ia_css_frame *vf_frame, unsigned int idx)
3337{
3338 enum ia_css_err err = IA_CSS_SUCCESS;
3339 unsigned int thread_id;
3340 enum sh_css_queue_id queue_id;
3341
3342 assert(vf_frame != NULL);
3343
3344 sh_css_pipe_get_viewfinder_frame_info(pipe, &vf_frame->info, idx);
3345 vf_frame->contiguous = false;
3346 vf_frame->flash_state = IA_CSS_FRAME_FLASH_STATE_NONE;
3347 ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
3348 ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME + idx, thread_id, &queue_id);
3349 vf_frame->dynamic_queue_id = queue_id;
3350 vf_frame->buf_type = IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME + idx;
3351
3352 err = ia_css_frame_init_planes(vf_frame);
3353 return err;
3354}
3355
3356#ifdef USE_INPUT_SYSTEM_VERSION_2401
3357static unsigned int
3358get_crop_lines_for_bayer_order (
3359 const struct ia_css_stream_config *config)
3360{
3361 assert(config != NULL);
3362 if ((IA_CSS_BAYER_ORDER_BGGR == config->input_config.bayer_order)
3363 || (IA_CSS_BAYER_ORDER_GBRG == config->input_config.bayer_order))
3364 return 1;
3365
3366 return 0;
3367}
3368
3369static unsigned int
3370get_crop_columns_for_bayer_order (
3371 const struct ia_css_stream_config *config)
3372{
3373 assert(config != NULL);
3374 if ((IA_CSS_BAYER_ORDER_RGGB == config->input_config.bayer_order)
3375 || (IA_CSS_BAYER_ORDER_GBRG == config->input_config.bayer_order))
3376 return 1;
3377
3378 return 0;
3379}
3380
3381
3382
3383static void get_pipe_extra_pixel(struct ia_css_pipe *pipe,
3384 unsigned int *extra_row, unsigned int *extra_column)
3385{
3386 enum ia_css_pipe_id pipe_id = pipe->mode;
3387 unsigned int left_cropping = 0, top_cropping = 0;
3388 unsigned int i;
3389 struct ia_css_resolution dvs_env = pipe->config.dvs_envelope;
3390
3391
3392
3393
3394
3395 switch (pipe_id) {
3396 case IA_CSS_PIPE_ID_PREVIEW:
3397 if (pipe->pipe_settings.preview.preview_binary.info) {
3398 left_cropping = pipe->pipe_settings.preview.preview_binary.info->sp.pipeline.left_cropping;
3399 top_cropping = pipe->pipe_settings.preview.preview_binary.info->sp.pipeline.top_cropping;
3400 }
3401 dvs_env = pipe->pipe_settings.preview.preview_binary.dvs_envelope;
3402 break;
3403 case IA_CSS_PIPE_ID_VIDEO:
3404 if (pipe->pipe_settings.video.video_binary.info) {
3405 left_cropping = pipe->pipe_settings.video.video_binary.info->sp.pipeline.left_cropping;
3406 top_cropping = pipe->pipe_settings.video.video_binary.info->sp.pipeline.top_cropping;
3407 }
3408 dvs_env = pipe->pipe_settings.video.video_binary.dvs_envelope;
3409 break;
3410 case IA_CSS_PIPE_ID_CAPTURE:
3411 for (i = 0; i < pipe->pipe_settings.capture.num_primary_stage; i++) {
3412 if (pipe->pipe_settings.capture.primary_binary[i].info) {
3413 left_cropping += pipe->pipe_settings.capture.primary_binary[i].info->sp.pipeline.left_cropping;
3414 top_cropping += pipe->pipe_settings.capture.primary_binary[i].info->sp.pipeline.top_cropping;
3415 }
3416 dvs_env.width += pipe->pipe_settings.capture.primary_binary[i].dvs_envelope.width;
3417 dvs_env.height += pipe->pipe_settings.capture.primary_binary[i].dvs_envelope.height;
3418 }
3419 break;
3420 default:
3421 break;
3422 }
3423
3424 *extra_row = top_cropping + dvs_env.height;
3425 *extra_column = left_cropping + dvs_env.width;
3426}
3427
3428void
3429ia_css_get_crop_offsets (
3430 struct ia_css_pipe *pipe,
3431 struct ia_css_frame_info *in_frame)
3432{
3433 unsigned int row = 0;
3434 unsigned int column = 0;
3435 struct ia_css_resolution *input_res;
3436 struct ia_css_resolution *effective_res;
3437 unsigned int extra_row = 0, extra_col = 0;
3438 unsigned int min_reqd_height, min_reqd_width;
3439
3440 assert(pipe != NULL);
3441 assert(pipe->stream != NULL);
3442 assert(in_frame != NULL);
3443
3444 IA_CSS_ENTER_PRIVATE("pipe = %p effective_wd = %u effective_ht = %u",
3445 pipe, pipe->config.input_effective_res.width,
3446 pipe->config.input_effective_res.height);
3447
3448 input_res = &pipe->stream->config.input_config.input_res;
3449#ifndef ISP2401
3450 effective_res = &pipe->stream->config.input_config.effective_res;
3451#else
3452 effective_res = &pipe->config.input_effective_res;
3453#endif
3454
3455 get_pipe_extra_pixel(pipe, &extra_row, &extra_col);
3456
3457 in_frame->raw_bayer_order = pipe->stream->config.input_config.bayer_order;
3458
3459 min_reqd_height = effective_res->height + extra_row;
3460 min_reqd_width = effective_res->width + extra_col;
3461
3462 if (input_res->height > min_reqd_height) {
3463 row = (input_res->height - min_reqd_height) / 2;
3464 row &= ~0x1;
3465 }
3466 if (input_res->width > min_reqd_width) {
3467 column = (input_res->width - min_reqd_width) / 2;
3468 column &= ~0x1;
3469 }
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480 column += get_crop_columns_for_bayer_order(&pipe->stream->config);
3481 row += get_crop_lines_for_bayer_order(&pipe->stream->config);
3482
3483 in_frame->crop_info.start_column = column;
3484 in_frame->crop_info.start_line = row;
3485
3486 IA_CSS_LEAVE_PRIVATE("void start_col: %u start_row: %u", column, row);
3487
3488 return;
3489}
3490#endif
3491
3492static enum ia_css_err
3493init_in_frameinfo_memory_defaults(struct ia_css_pipe *pipe,
3494 struct ia_css_frame *frame, enum ia_css_frame_format format)
3495{
3496 struct ia_css_frame *in_frame;
3497 enum ia_css_err err = IA_CSS_SUCCESS;
3498 unsigned int thread_id;
3499 enum sh_css_queue_id queue_id;
3500
3501 assert(frame != NULL);
3502 in_frame = frame;
3503
3504 in_frame->info.format = format;
3505
3506#ifdef USE_INPUT_SYSTEM_VERSION_2401
3507 if (format == IA_CSS_FRAME_FORMAT_RAW)
3508 in_frame->info.format = (pipe->stream->config.pack_raw_pixels) ?
3509 IA_CSS_FRAME_FORMAT_RAW_PACKED : IA_CSS_FRAME_FORMAT_RAW;
3510#endif
3511
3512
3513 in_frame->info.res.width = pipe->stream->config.input_config.input_res.width;
3514 in_frame->info.res.height = pipe->stream->config.input_config.input_res.height;
3515 in_frame->info.raw_bit_depth =
3516 ia_css_pipe_util_pipe_input_format_bpp(pipe);
3517 ia_css_frame_info_set_width(&in_frame->info, pipe->stream->config.input_config.input_res.width, 0);
3518 in_frame->contiguous = false;
3519 in_frame->flash_state = IA_CSS_FRAME_FLASH_STATE_NONE;
3520 ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
3521 ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_INPUT_FRAME, thread_id, &queue_id);
3522 in_frame->dynamic_queue_id = queue_id;
3523 in_frame->buf_type = IA_CSS_BUFFER_TYPE_INPUT_FRAME;
3524#ifdef USE_INPUT_SYSTEM_VERSION_2401
3525 ia_css_get_crop_offsets(pipe, &in_frame->info);
3526#endif
3527 err = ia_css_frame_init_planes(in_frame);
3528
3529 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
3530 "init_in_frameinfo_memory_defaults() bayer_order = %d:\n", in_frame->info.raw_bayer_order);
3531
3532 return err;
3533}
3534
3535static enum ia_css_err
3536init_out_frameinfo_defaults(struct ia_css_pipe *pipe,
3537 struct ia_css_frame *out_frame, unsigned int idx)
3538{
3539 enum ia_css_err err = IA_CSS_SUCCESS;
3540 unsigned int thread_id;
3541 enum sh_css_queue_id queue_id;
3542
3543 assert(out_frame != NULL);
3544
3545 sh_css_pipe_get_output_frame_info(pipe, &out_frame->info, idx);
3546 out_frame->contiguous = false;
3547 out_frame->flash_state = IA_CSS_FRAME_FLASH_STATE_NONE;
3548 ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
3549 ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_OUTPUT_FRAME + idx, thread_id, &queue_id);
3550 out_frame->dynamic_queue_id = queue_id;
3551 out_frame->buf_type = IA_CSS_BUFFER_TYPE_OUTPUT_FRAME + idx;
3552 err = ia_css_frame_init_planes(out_frame);
3553
3554 return err;
3555}
3556
3557
3558static enum ia_css_err create_host_video_pipeline(struct ia_css_pipe *pipe)
3559{
3560 struct ia_css_pipeline_stage_desc stage_desc;
3561 struct ia_css_binary *copy_binary, *video_binary,
3562 *yuv_scaler_binary, *vf_pp_binary;
3563 struct ia_css_pipeline_stage *copy_stage = NULL;
3564 struct ia_css_pipeline_stage *video_stage = NULL;
3565 struct ia_css_pipeline_stage *yuv_scaler_stage = NULL;
3566 struct ia_css_pipeline_stage *vf_pp_stage = NULL;
3567 struct ia_css_pipeline *me;
3568 struct ia_css_frame *in_frame = NULL;
3569 struct ia_css_frame *out_frame;
3570 struct ia_css_frame *out_frames[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
3571 struct ia_css_frame *vf_frame = NULL;
3572 enum ia_css_err err = IA_CSS_SUCCESS;
3573 bool need_copy = false;
3574 bool need_vf_pp = false;
3575 bool need_yuv_pp = false;
3576 unsigned num_output_pins;
3577 bool need_in_frameinfo_memory = false;
3578
3579 unsigned int i, num_yuv_scaler;
3580 bool *is_output_stage = NULL;
3581
3582 IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
3583 if ((pipe == NULL) || (pipe->stream == NULL) || (pipe->mode != IA_CSS_PIPE_ID_VIDEO)) {
3584 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
3585 return IA_CSS_ERR_INVALID_ARGUMENTS;
3586 }
3587 ia_css_pipe_util_create_output_frames(out_frames);
3588 out_frame = &pipe->out_frame_struct;
3589
3590
3591 me = &pipe->pipeline;
3592 ia_css_pipeline_clean(me);
3593
3594 me->dvs_frame_delay = pipe->dvs_frame_delay;
3595
3596#ifdef USE_INPUT_SYSTEM_VERSION_2401
3597
3598
3599
3600 need_in_frameinfo_memory = !(pipe->stream->config.online || pipe->stream->config.continuous);
3601#else
3602
3603 need_in_frameinfo_memory = pipe->stream->config.mode == IA_CSS_INPUT_MODE_MEMORY;
3604#endif
3605
3606
3607 if (need_in_frameinfo_memory) {
3608 in_frame = &pipe->in_frame_struct;
3609 err = init_in_frameinfo_memory_defaults(pipe, in_frame, IA_CSS_FRAME_FORMAT_RAW);
3610 if (err != IA_CSS_SUCCESS)
3611 goto ERR;
3612 }
3613
3614 out_frame->data = 0;
3615 err = init_out_frameinfo_defaults(pipe, out_frame, 0);
3616 if (err != IA_CSS_SUCCESS)
3617 goto ERR;
3618
3619 if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0]) {
3620 vf_frame = &pipe->vf_frame_struct;
3621 vf_frame->data = 0;
3622 err = init_vf_frameinfo_defaults(pipe, vf_frame, 0);
3623 if (err != IA_CSS_SUCCESS)
3624 goto ERR;
3625 }
3626
3627 copy_binary = &pipe->pipe_settings.video.copy_binary;
3628 video_binary = &pipe->pipe_settings.video.video_binary;
3629 vf_pp_binary = &pipe->pipe_settings.video.vf_pp_binary;
3630 num_output_pins = video_binary->info->num_output_pins;
3631
3632 yuv_scaler_binary = pipe->pipe_settings.video.yuv_scaler_binary;
3633 num_yuv_scaler = pipe->pipe_settings.video.num_yuv_scaler;
3634 is_output_stage = pipe->pipe_settings.video.is_output_stage;
3635
3636 need_copy = (copy_binary != NULL && copy_binary->info != NULL);
3637 need_vf_pp = (vf_pp_binary != NULL && vf_pp_binary->info != NULL);
3638 need_yuv_pp = (yuv_scaler_binary != NULL && yuv_scaler_binary->info != NULL);
3639
3640 if (need_copy) {
3641 ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
3642 ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary,
3643 out_frames, NULL, NULL);
3644 err = ia_css_pipeline_create_and_add_stage(me,
3645 &stage_desc,
3646 ©_stage);
3647 if (err != IA_CSS_SUCCESS)
3648 goto ERR;
3649 in_frame = me->stages->args.out_frame[0];
3650 } else if (pipe->stream->config.continuous) {
3651#ifdef USE_INPUT_SYSTEM_VERSION_2401
3652
3653
3654
3655 in_frame = pipe->stream->last_pipe->continuous_frames[0];
3656#else
3657 in_frame = pipe->continuous_frames[0];
3658#endif
3659 }
3660
3661 ia_css_pipe_util_set_output_frames(out_frames, 0, need_yuv_pp ? NULL : out_frame);
3662
3663
3664
3665 if(need_vf_pp) {
3666 ia_css_pipe_get_generic_stage_desc(&stage_desc, video_binary,
3667 out_frames, in_frame, NULL);
3668 } else {
3669 ia_css_pipe_get_generic_stage_desc(&stage_desc, video_binary,
3670 out_frames, in_frame, vf_frame);
3671 }
3672 err = ia_css_pipeline_create_and_add_stage(me,
3673 &stage_desc,
3674 &video_stage);
3675 if (err != IA_CSS_SUCCESS)
3676 goto ERR;
3677
3678
3679 if(video_stage) {
3680 video_stage->args.copy_vf =
3681 video_binary->info->sp.pipeline.mode == IA_CSS_BINARY_MODE_COPY;
3682 video_stage->args.copy_output = video_stage->args.copy_vf;
3683 }
3684
3685
3686
3687 if (need_vf_pp && video_stage) {
3688 in_frame = video_stage->args.out_vf_frame;
3689 err = add_vf_pp_stage(pipe, in_frame, vf_frame, vf_pp_binary,
3690 &vf_pp_stage);
3691 if (err != IA_CSS_SUCCESS)
3692 goto ERR;
3693 }
3694 if (video_stage) {
3695 int frm;
3696#ifndef ISP2401
3697 for (frm = 0; frm < NUM_VIDEO_TNR_FRAMES; frm++) {
3698#else
3699 for (frm = 0; frm < NUM_TNR_FRAMES; frm++) {
3700#endif
3701 video_stage->args.tnr_frames[frm] =
3702 pipe->pipe_settings.video.tnr_frames[frm];
3703 }
3704 for (frm = 0; frm < MAX_NUM_VIDEO_DELAY_FRAMES; frm++) {
3705 video_stage->args.delay_frames[frm] =
3706 pipe->pipe_settings.video.delay_frames[frm];
3707 }
3708 }
3709
3710
3711 if (!need_vf_pp && video_stage && pipe->config.acc_extension &&
3712 (pipe->config.acc_extension->info.isp.type == IA_CSS_ACC_OUTPUT))
3713 {
3714 struct ia_css_frame *out = NULL;
3715 struct ia_css_frame *in = NULL;
3716
3717 if ((pipe->config.acc_extension->info.isp.sp.enable.output) &&
3718 (pipe->config.acc_extension->info.isp.sp.enable.in_frame) &&
3719 (pipe->config.acc_extension->info.isp.sp.enable.out_frame)) {
3720
3721
3722 out = video_stage->args.out_frame[0];
3723 err = ia_css_frame_allocate_from_info(&in, &(pipe->output_info[0]));
3724 if (err != IA_CSS_SUCCESS)
3725 goto ERR;
3726 video_stage->args.out_frame[0] = in;
3727 }
3728
3729 err = add_firmwares( me, video_binary, pipe->output_stage,
3730 last_output_firmware(pipe->output_stage),
3731 IA_CSS_BINARY_MODE_VIDEO,
3732 in, out, NULL, &video_stage, NULL);
3733 if (err != IA_CSS_SUCCESS)
3734 goto ERR;
3735 }
3736
3737 if (need_yuv_pp && video_stage) {
3738 struct ia_css_frame *tmp_in_frame = video_stage->args.out_frame[0];
3739 struct ia_css_frame *tmp_out_frame = NULL;
3740
3741 for (i = 0; i < num_yuv_scaler; i++) {
3742 if (is_output_stage[i] == true) {
3743 tmp_out_frame = out_frame;
3744 } else {
3745 tmp_out_frame = NULL;
3746 }
3747 err = add_yuv_scaler_stage(pipe, me, tmp_in_frame, tmp_out_frame,
3748 NULL,
3749 &yuv_scaler_binary[i],
3750 &yuv_scaler_stage);
3751
3752 if (err != IA_CSS_SUCCESS) {
3753 IA_CSS_LEAVE_ERR_PRIVATE(err);
3754 return err;
3755 }
3756
3757 if (yuv_scaler_stage)
3758 tmp_in_frame = yuv_scaler_stage->args.out_frame[1];
3759 }
3760 }
3761
3762 pipe->pipeline.acquire_isp_each_stage = false;
3763 ia_css_pipeline_finalize_stages(&pipe->pipeline, pipe->stream->config.continuous);
3764
3765ERR:
3766 IA_CSS_LEAVE_ERR_PRIVATE(err);
3767 return err;
3768}
3769
3770static enum ia_css_err
3771create_host_acc_pipeline(struct ia_css_pipe *pipe)
3772{
3773 enum ia_css_err err = IA_CSS_SUCCESS;
3774 const struct ia_css_fw_info *fw;
3775 unsigned int i;
3776
3777 IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
3778 if ((pipe == NULL) || (pipe->stream == NULL)) {
3779 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
3780 return IA_CSS_ERR_INVALID_ARGUMENTS;
3781 }
3782
3783 pipe->pipeline.num_execs = pipe->config.acc_num_execs;
3784
3785 if (pipe->config.acc_extension)
3786 pipe->pipeline.pipe_qos_config = 0;
3787
3788 fw = pipe->vf_stage;
3789 for (i = 0; fw; fw = fw->next){
3790 err = sh_css_pipeline_add_acc_stage(&pipe->pipeline, fw);
3791 if (err != IA_CSS_SUCCESS)
3792 goto ERR;
3793 }
3794
3795 for (i=0; i<pipe->config.num_acc_stages; i++) {
3796 struct ia_css_fw_info *fw = pipe->config.acc_stages[i];
3797 err = sh_css_pipeline_add_acc_stage(&pipe->pipeline, fw);
3798 if (err != IA_CSS_SUCCESS)
3799 goto ERR;
3800 }
3801
3802 ia_css_pipeline_finalize_stages(&pipe->pipeline, pipe->stream->config.continuous);
3803
3804ERR:
3805 IA_CSS_LEAVE_ERR_PRIVATE(err);
3806 return err;
3807}
3808
3809
3810static enum ia_css_err
3811create_host_preview_pipeline(struct ia_css_pipe *pipe)
3812{
3813 struct ia_css_pipeline_stage *copy_stage = NULL;
3814 struct ia_css_pipeline_stage *preview_stage = NULL;
3815 struct ia_css_pipeline_stage *vf_pp_stage = NULL;
3816 struct ia_css_pipeline_stage_desc stage_desc;
3817 struct ia_css_pipeline *me = NULL;
3818 struct ia_css_binary *copy_binary, *preview_binary, *vf_pp_binary = NULL;
3819 struct ia_css_frame *in_frame = NULL;
3820 enum ia_css_err err = IA_CSS_SUCCESS;
3821 struct ia_css_frame *out_frame;
3822 struct ia_css_frame *out_frames[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
3823 bool need_in_frameinfo_memory = false;
3824#ifdef USE_INPUT_SYSTEM_VERSION_2401
3825 bool sensor = false;
3826 bool buffered_sensor = false;
3827 bool online = false;
3828 bool continuous = false;
3829#endif
3830
3831 IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
3832 if ((pipe == NULL) || (pipe->stream == NULL) || (pipe->mode != IA_CSS_PIPE_ID_PREVIEW)) {
3833 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
3834 return IA_CSS_ERR_INVALID_ARGUMENTS;
3835 }
3836
3837
3838 ia_css_pipe_util_create_output_frames(out_frames);
3839
3840 me = &pipe->pipeline;
3841 ia_css_pipeline_clean(me);
3842
3843#ifdef USE_INPUT_SYSTEM_VERSION_2401
3844
3845
3846
3847
3848
3849
3850
3851 sensor = (pipe->stream->config.mode == IA_CSS_INPUT_MODE_SENSOR);
3852 buffered_sensor = (pipe->stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR);
3853 online = pipe->stream->config.online;
3854 continuous = pipe->stream->config.continuous;
3855 need_in_frameinfo_memory =
3856 !((sensor && (online || continuous)) || (buffered_sensor && (online || continuous)));
3857#else
3858
3859 need_in_frameinfo_memory = pipe->stream->config.mode == IA_CSS_INPUT_MODE_MEMORY;
3860#endif
3861 if (need_in_frameinfo_memory) {
3862 err = init_in_frameinfo_memory_defaults(pipe, &me->in_frame, IA_CSS_FRAME_FORMAT_RAW);
3863 if (err != IA_CSS_SUCCESS)
3864 goto ERR;
3865
3866 in_frame = &me->in_frame;
3867 } else {
3868 in_frame = NULL;
3869 }
3870
3871 err = init_out_frameinfo_defaults(pipe, &me->out_frame[0], 0);
3872 if (err != IA_CSS_SUCCESS)
3873 goto ERR;
3874 out_frame = &me->out_frame[0];
3875
3876 copy_binary = &pipe->pipe_settings.preview.copy_binary;
3877 preview_binary = &pipe->pipe_settings.preview.preview_binary;
3878 if (pipe->pipe_settings.preview.vf_pp_binary.info)
3879 vf_pp_binary = &pipe->pipe_settings.preview.vf_pp_binary;
3880
3881 if (pipe->pipe_settings.preview.copy_binary.info) {
3882 ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
3883 ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary,
3884 out_frames, NULL, NULL);
3885 err = ia_css_pipeline_create_and_add_stage(me,
3886 &stage_desc,
3887 ©_stage);
3888 if (err != IA_CSS_SUCCESS)
3889 goto ERR;
3890 in_frame = me->stages->args.out_frame[0];
3891#ifndef ISP2401
3892 } else {
3893#else
3894 } else if (pipe->stream->config.continuous) {
3895#endif
3896#ifdef USE_INPUT_SYSTEM_VERSION_2401
3897
3898
3899
3900 if (continuous || !online){
3901 in_frame = pipe->stream->last_pipe->continuous_frames[0];
3902 }
3903#else
3904 in_frame = pipe->continuous_frames[0];
3905#endif
3906 }
3907
3908 if (vf_pp_binary) {
3909 ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
3910 ia_css_pipe_get_generic_stage_desc(&stage_desc, preview_binary,
3911 out_frames, in_frame, NULL);
3912 } else {
3913 ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
3914 ia_css_pipe_get_generic_stage_desc(&stage_desc, preview_binary,
3915 out_frames, in_frame, NULL);
3916 }
3917 err = ia_css_pipeline_create_and_add_stage(me,
3918 &stage_desc,
3919 &preview_stage);
3920 if (err != IA_CSS_SUCCESS)
3921 goto ERR;
3922
3923 preview_stage->args.copy_vf =
3924 preview_binary->info->sp.pipeline.mode == IA_CSS_BINARY_MODE_COPY;
3925 preview_stage->args.copy_output = !preview_stage->args.copy_vf;
3926 if (preview_stage->args.copy_vf && !preview_stage->args.out_vf_frame) {
3927
3928 preview_stage->args.out_vf_frame =
3929 preview_stage->args.out_frame[0];
3930 }
3931 if (vf_pp_binary) {
3932 if (preview_binary->info->sp.pipeline.mode == IA_CSS_BINARY_MODE_COPY)
3933 in_frame = preview_stage->args.out_vf_frame;
3934 else
3935 in_frame = preview_stage->args.out_frame[0];
3936 err = add_vf_pp_stage(pipe, in_frame, out_frame, vf_pp_binary,
3937 &vf_pp_stage);
3938 if (err != IA_CSS_SUCCESS)
3939 goto ERR;
3940 }
3941
3942 pipe->pipeline.acquire_isp_each_stage = false;
3943 ia_css_pipeline_finalize_stages(&pipe->pipeline, pipe->stream->config.continuous);
3944
3945ERR:
3946 IA_CSS_LEAVE_ERR_PRIVATE(err);
3947 return err;
3948}
3949
3950static void send_raw_frames(struct ia_css_pipe *pipe)
3951{
3952 if (pipe->stream->config.continuous) {
3953 unsigned int i;
3954
3955 sh_css_update_host2sp_cont_num_raw_frames
3956 (pipe->stream->config.init_num_cont_raw_buf, true);
3957 sh_css_update_host2sp_cont_num_raw_frames
3958 (pipe->stream->config.target_num_cont_raw_buf, false);
3959
3960
3961 for (i = 0; i < pipe->stream->config.init_num_cont_raw_buf; i++) {
3962 sh_css_update_host2sp_offline_frame(i,
3963 pipe->continuous_frames[i], pipe->cont_md_buffers[i]);
3964 }
3965 }
3966
3967 return;
3968}
3969
3970static enum ia_css_err
3971preview_start(struct ia_css_pipe *pipe)
3972{
3973 struct ia_css_pipeline *me ;
3974 struct ia_css_binary *copy_binary, *preview_binary, *vf_pp_binary = NULL;
3975 enum ia_css_err err = IA_CSS_SUCCESS;
3976 struct ia_css_pipe *copy_pipe, *capture_pipe;
3977 struct ia_css_pipe *acc_pipe;
3978 enum sh_css_pipe_config_override copy_ovrd;
3979 enum ia_css_input_mode preview_pipe_input_mode;
3980
3981 IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
3982 if ((pipe == NULL) || (pipe->stream == NULL) || (pipe->mode != IA_CSS_PIPE_ID_PREVIEW)) {
3983 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
3984 return IA_CSS_ERR_INVALID_ARGUMENTS;
3985 }
3986
3987 me = &pipe->pipeline;
3988
3989 preview_pipe_input_mode = pipe->stream->config.mode;
3990
3991 copy_pipe = pipe->pipe_settings.preview.copy_pipe;
3992 capture_pipe = pipe->pipe_settings.preview.capture_pipe;
3993 acc_pipe = pipe->pipe_settings.preview.acc_pipe;
3994
3995 copy_binary = &pipe->pipe_settings.preview.copy_binary;
3996 preview_binary = &pipe->pipe_settings.preview.preview_binary;
3997 if (pipe->pipe_settings.preview.vf_pp_binary.info)
3998 vf_pp_binary = &pipe->pipe_settings.preview.vf_pp_binary;
3999
4000 sh_css_metrics_start_frame();
4001
4002#if defined(USE_INPUT_SYSTEM_VERSION_2) || defined(USE_INPUT_SYSTEM_VERSION_2401)
4003
4004 err = send_mipi_frames(pipe);
4005 if (err != IA_CSS_SUCCESS)
4006 goto ERR;
4007#endif
4008 send_raw_frames(pipe);
4009
4010 {
4011 unsigned int thread_id;
4012
4013 ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
4014 copy_ovrd = 1 << thread_id;
4015
4016 if (pipe->stream->cont_capt) {
4017 ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(capture_pipe), &thread_id);
4018 copy_ovrd |= 1 << thread_id;
4019 }
4020 }
4021
4022
4023 if (pipe->stream->config.continuous) {
4024 sh_css_sp_init_pipeline(©_pipe->pipeline,
4025 IA_CSS_PIPE_ID_COPY,
4026 (uint8_t)ia_css_pipe_get_pipe_num(copy_pipe),
4027 false,
4028 pipe->stream->config.pixels_per_clock == 2, false,
4029 false, pipe->required_bds_factor,
4030 copy_ovrd,
4031 pipe->stream->config.mode,
4032 &pipe->stream->config.metadata_config,
4033#ifndef ISP2401
4034 &pipe->stream->info.metadata_info
4035#else
4036 &pipe->stream->info.metadata_info,
4037#endif
4038#if !defined(HAS_NO_INPUT_SYSTEM)
4039#ifndef ISP2401
4040 , pipe->stream->config.source.port.port
4041#else
4042 pipe->stream->config.source.port.port,
4043#endif
4044#endif
4045#ifndef ISP2401
4046 );
4047#else
4048 &pipe->config.internal_frame_origin_bqs_on_sctbl,
4049 pipe->stream->isp_params_configs);
4050#endif
4051
4052
4053
4054 preview_pipe_input_mode = IA_CSS_INPUT_MODE_MEMORY;
4055 }
4056
4057
4058 if (pipe->stream->cont_capt) {
4059 sh_css_sp_init_pipeline(&capture_pipe->pipeline,
4060 IA_CSS_PIPE_ID_CAPTURE,
4061 (uint8_t)ia_css_pipe_get_pipe_num(capture_pipe),
4062 capture_pipe->config.default_capture_config.enable_xnr != 0,
4063 capture_pipe->stream->config.pixels_per_clock == 2,
4064 true,
4065 false,
4066 capture_pipe->required_bds_factor,
4067 0,
4068 IA_CSS_INPUT_MODE_MEMORY,
4069 &pipe->stream->config.metadata_config,
4070#ifndef ISP2401
4071 &pipe->stream->info.metadata_info
4072#else
4073 &pipe->stream->info.metadata_info,
4074#endif
4075#if !defined(HAS_NO_INPUT_SYSTEM)
4076#ifndef ISP2401
4077 , (enum mipi_port_id)0
4078#else
4079 (enum mipi_port_id)0,
4080#endif
4081#endif
4082#ifndef ISP2401
4083 );
4084#else
4085 &capture_pipe->config.internal_frame_origin_bqs_on_sctbl,
4086 capture_pipe->stream->isp_params_configs);
4087#endif
4088 }
4089
4090 if (acc_pipe) {
4091 sh_css_sp_init_pipeline(&acc_pipe->pipeline,
4092 IA_CSS_PIPE_ID_ACC,
4093 (uint8_t) ia_css_pipe_get_pipe_num(acc_pipe),
4094 false,
4095 pipe->stream->config.pixels_per_clock == 2,
4096 false,
4097 false,
4098 pipe->required_bds_factor,
4099 0,
4100 IA_CSS_INPUT_MODE_MEMORY,
4101 NULL,
4102#ifndef ISP2401
4103 NULL
4104#else
4105 NULL,
4106#endif
4107#if !defined(HAS_NO_INPUT_SYSTEM)
4108#ifndef ISP2401
4109 , (enum mipi_port_id) 0
4110#else
4111 (enum mipi_port_id) 0,
4112#endif
4113#endif
4114#ifndef ISP2401
4115 );
4116#else
4117 &pipe->config.internal_frame_origin_bqs_on_sctbl,
4118 pipe->stream->isp_params_configs);
4119#endif
4120 }
4121
4122 start_pipe(pipe, copy_ovrd, preview_pipe_input_mode);
4123
4124#if defined(USE_INPUT_SYSTEM_VERSION_2) || defined(USE_INPUT_SYSTEM_VERSION_2401)
4125ERR:
4126#endif
4127 IA_CSS_LEAVE_ERR_PRIVATE(err);
4128 return err;
4129}
4130
4131enum ia_css_err
4132ia_css_pipe_enqueue_buffer(struct ia_css_pipe *pipe,
4133 const struct ia_css_buffer *buffer)
4134{
4135 enum ia_css_err return_err = IA_CSS_SUCCESS;
4136 unsigned int thread_id;
4137 enum sh_css_queue_id queue_id;
4138 struct ia_css_pipeline *pipeline;
4139 struct ia_css_pipeline_stage *stage;
4140 struct ia_css_rmgr_vbuf_handle p_vbuf;
4141 struct ia_css_rmgr_vbuf_handle *h_vbuf;
4142 struct sh_css_hmm_buffer ddr_buffer;
4143 enum ia_css_buffer_type buf_type;
4144 enum ia_css_pipe_id pipe_id;
4145 bool ret_err;
4146
4147 IA_CSS_ENTER("pipe=%p, buffer=%p", pipe, buffer);
4148
4149 if ((pipe == NULL) || (buffer == NULL)) {
4150 IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
4151 return IA_CSS_ERR_INVALID_ARGUMENTS;
4152 }
4153
4154 buf_type = buffer->type;
4155
4156
4157#if 0
4158 if (buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME) {
4159 bool found_pipe = false;
4160 for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) {
4161 if ((buffer->data.frame->info.res.width == pipe->output_info[i].res.width) &&
4162 (buffer->data.frame->info.res.height == pipe->output_info[i].res.height)) {
4163 buf_type += i;
4164 found_pipe = true;
4165 break;
4166 }
4167 }
4168 if (!found_pipe)
4169 return IA_CSS_ERR_INVALID_ARGUMENTS;
4170 }
4171 if (buf_type == IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME) {
4172 bool found_pipe = false;
4173 for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) {
4174 if ((buffer->data.frame->info.res.width == pipe->vf_output_info[i].res.width) &&
4175 (buffer->data.frame->info.res.height == pipe->vf_output_info[i].res.height)) {
4176 buf_type += i;
4177 found_pipe = true;
4178 break;
4179 }
4180 }
4181 if (!found_pipe)
4182 return IA_CSS_ERR_INVALID_ARGUMENTS;
4183 }
4184#endif
4185 pipe_id = pipe->mode;
4186
4187 IA_CSS_LOG("pipe_id=%d, buf_type=%d", pipe_id, buf_type);
4188
4189
4190 assert(pipe_id < IA_CSS_PIPE_ID_NUM);
4191 assert(buf_type < IA_CSS_NUM_DYNAMIC_BUFFER_TYPE);
4192 if ((buf_type == IA_CSS_BUFFER_TYPE_INVALID) ||
4193 (buf_type >= IA_CSS_NUM_DYNAMIC_BUFFER_TYPE) ||
4194 (pipe_id >= IA_CSS_PIPE_ID_NUM)) {
4195 IA_CSS_LEAVE_ERR(IA_CSS_ERR_INTERNAL_ERROR);
4196 return IA_CSS_ERR_INTERNAL_ERROR;
4197 }
4198
4199 ret_err = ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
4200 if (!ret_err) {
4201 IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
4202 return IA_CSS_ERR_INVALID_ARGUMENTS;
4203 }
4204
4205 ret_err = ia_css_query_internal_queue_id(buf_type, thread_id, &queue_id);
4206 if (!ret_err) {
4207 IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
4208 return IA_CSS_ERR_INVALID_ARGUMENTS;
4209 }
4210
4211 if ((queue_id <= SH_CSS_INVALID_QUEUE_ID) || (queue_id >= SH_CSS_MAX_NUM_QUEUES)) {
4212 IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
4213 return IA_CSS_ERR_INVALID_ARGUMENTS;
4214 }
4215
4216 if (!sh_css_sp_is_running()) {
4217 IA_CSS_LOG("SP is not running!");
4218 IA_CSS_LEAVE_ERR(IA_CSS_ERR_RESOURCE_NOT_AVAILABLE);
4219
4220 return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
4221 }
4222
4223
4224 pipeline = &pipe->pipeline;
4225
4226 assert(pipeline != NULL ||
4227 pipe_id == IA_CSS_PIPE_ID_COPY ||
4228 pipe_id == IA_CSS_PIPE_ID_ACC);
4229
4230 assert(sizeof(NULL) <= sizeof(ddr_buffer.kernel_ptr));
4231 ddr_buffer.kernel_ptr = HOST_ADDRESS(NULL);
4232 ddr_buffer.cookie_ptr = buffer->driver_cookie;
4233 ddr_buffer.timing_data = buffer->timing_data;
4234
4235 if (buf_type == IA_CSS_BUFFER_TYPE_3A_STATISTICS) {
4236 if (buffer->data.stats_3a == NULL) {
4237 IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
4238 return IA_CSS_ERR_INVALID_ARGUMENTS;
4239 }
4240 ddr_buffer.kernel_ptr = HOST_ADDRESS(buffer->data.stats_3a);
4241 ddr_buffer.payload.s3a = *buffer->data.stats_3a;
4242 } else if (buf_type == IA_CSS_BUFFER_TYPE_DIS_STATISTICS) {
4243 if (buffer->data.stats_dvs == NULL) {
4244 IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
4245 return IA_CSS_ERR_INVALID_ARGUMENTS;
4246 }
4247 ddr_buffer.kernel_ptr = HOST_ADDRESS(buffer->data.stats_dvs);
4248 ddr_buffer.payload.dis = *buffer->data.stats_dvs;
4249 } else if (buf_type == IA_CSS_BUFFER_TYPE_METADATA) {
4250 if (buffer->data.metadata == NULL) {
4251 IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
4252 return IA_CSS_ERR_INVALID_ARGUMENTS;
4253 }
4254 ddr_buffer.kernel_ptr = HOST_ADDRESS(buffer->data.metadata);
4255 ddr_buffer.payload.metadata = *buffer->data.metadata;
4256 } else if ((buf_type == IA_CSS_BUFFER_TYPE_INPUT_FRAME)
4257 || (buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME)
4258 || (buf_type == IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME)
4259 || (buf_type == IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME)
4260 || (buf_type == IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME)) {
4261 if (buffer->data.frame == NULL) {
4262 IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
4263 return IA_CSS_ERR_INVALID_ARGUMENTS;
4264 }
4265 ddr_buffer.kernel_ptr = HOST_ADDRESS(buffer->data.frame);
4266 ddr_buffer.payload.frame.frame_data = buffer->data.frame->data;
4267 ddr_buffer.payload.frame.flashed = 0;
4268
4269 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
4270 "ia_css_pipe_enqueue_buffer() buf_type=%d, data(DDR address)=0x%x\n",
4271 buf_type, buffer->data.frame->data);
4272
4273
4274#if CONFIG_ON_FRAME_ENQUEUE()
4275 return_err = set_config_on_frame_enqueue(
4276 &buffer->data.frame->info,
4277 &ddr_buffer.payload.frame);
4278 if (IA_CSS_SUCCESS != return_err) {
4279 IA_CSS_LEAVE_ERR(return_err);
4280 return return_err;
4281 }
4282#endif
4283 }
4284
4285
4286 p_vbuf.vptr = 0;
4287 p_vbuf.count = 0;
4288 p_vbuf.size = sizeof(struct sh_css_hmm_buffer);
4289 h_vbuf = &p_vbuf;
4290
4291 ia_css_rmgr_acq_vbuf(hmm_buffer_pool, &h_vbuf);
4292
4293 assert(h_vbuf != NULL);
4294 assert(h_vbuf->vptr != 0x0);
4295
4296 if ((h_vbuf == NULL) || (h_vbuf->vptr == 0x0)) {
4297 IA_CSS_LEAVE_ERR(IA_CSS_ERR_INTERNAL_ERROR);
4298 return IA_CSS_ERR_INTERNAL_ERROR;
4299 }
4300
4301 mmgr_store(h_vbuf->vptr,
4302 (void *)(&ddr_buffer),
4303 sizeof(struct sh_css_hmm_buffer));
4304 if ((buf_type == IA_CSS_BUFFER_TYPE_3A_STATISTICS)
4305 || (buf_type == IA_CSS_BUFFER_TYPE_DIS_STATISTICS)
4306 || (buf_type == IA_CSS_BUFFER_TYPE_LACE_STATISTICS)) {
4307 if (pipeline == NULL) {
4308 ia_css_rmgr_rel_vbuf(hmm_buffer_pool, &h_vbuf);
4309 IA_CSS_LOG("pipeline is empty!");
4310 IA_CSS_LEAVE_ERR(IA_CSS_ERR_INTERNAL_ERROR);
4311 return IA_CSS_ERR_INTERNAL_ERROR;
4312 }
4313
4314 for (stage = pipeline->stages; stage; stage = stage->next) {
4315
4316
4317 if (STATS_ENABLED(stage)) {
4318
4319 return_err = ia_css_bufq_enqueue_buffer(thread_id,
4320 queue_id,
4321 (uint32_t)h_vbuf->vptr);
4322 }
4323 }
4324 } else if ((buf_type == IA_CSS_BUFFER_TYPE_INPUT_FRAME)
4325 || (buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME)
4326 || (buf_type == IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME)
4327 || (buf_type == IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME)
4328 || (buf_type == IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME)
4329 || (buf_type == IA_CSS_BUFFER_TYPE_METADATA)) {
4330
4331 return_err = ia_css_bufq_enqueue_buffer(thread_id,
4332 queue_id,
4333 (uint32_t)h_vbuf->vptr);
4334#if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS)
4335 if ((return_err == IA_CSS_SUCCESS) && (IA_CSS_BUFFER_TYPE_OUTPUT_FRAME == buf_type)) {
4336 IA_CSS_LOG("pfp: enqueued OF %d to q %d thread %d",
4337 ddr_buffer.payload.frame.frame_data,
4338 queue_id, thread_id);
4339 }
4340#endif
4341
4342 }
4343
4344 if (return_err == IA_CSS_SUCCESS) {
4345 if (sh_css_hmm_buffer_record_acquire(
4346 h_vbuf, buf_type,
4347 HOST_ADDRESS(ddr_buffer.kernel_ptr))) {
4348 IA_CSS_LOG("send vbuf=%p", h_vbuf);
4349 } else {
4350 return_err = IA_CSS_ERR_INTERNAL_ERROR;
4351 IA_CSS_ERROR("hmm_buffer_record[]: no available slots\n");
4352 }
4353 }
4354
4355
4356
4357
4358
4359 if (return_err == IA_CSS_SUCCESS) {
4360 if (!sh_css_sp_is_running()) {
4361
4362 IA_CSS_LOG("SP is not running!");
4363 IA_CSS_LEAVE_ERR(IA_CSS_ERR_RESOURCE_NOT_AVAILABLE);
4364 return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
4365 }
4366 return_err = ia_css_bufq_enqueue_psys_event(
4367 IA_CSS_PSYS_SW_EVENT_BUFFER_ENQUEUED,
4368 (uint8_t)thread_id,
4369 queue_id,
4370 0);
4371 } else {
4372 ia_css_rmgr_rel_vbuf(hmm_buffer_pool, &h_vbuf);
4373 IA_CSS_ERROR("buffer not enqueued");
4374 }
4375
4376 IA_CSS_LEAVE("return value = %d", return_err);
4377
4378 return return_err;
4379}
4380
4381
4382
4383
4384enum ia_css_err
4385ia_css_pipe_dequeue_buffer(struct ia_css_pipe *pipe,
4386 struct ia_css_buffer *buffer)
4387{
4388 enum ia_css_err return_err;
4389 enum sh_css_queue_id queue_id;
4390 hrt_vaddress ddr_buffer_addr = (hrt_vaddress)0;
4391 struct sh_css_hmm_buffer ddr_buffer;
4392 enum ia_css_buffer_type buf_type;
4393 enum ia_css_pipe_id pipe_id;
4394 unsigned int thread_id;
4395 hrt_address kernel_ptr = 0;
4396 bool ret_err;
4397
4398 IA_CSS_ENTER("pipe=%p, buffer=%p", pipe, buffer);
4399
4400 if ((pipe == NULL) || (buffer == NULL)) {
4401 IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
4402 return IA_CSS_ERR_INVALID_ARGUMENTS;
4403 }
4404
4405 pipe_id = pipe->mode;
4406
4407 buf_type = buffer->type;
4408
4409 IA_CSS_LOG("pipe_id=%d, buf_type=%d", pipe_id, buf_type);
4410
4411 ddr_buffer.kernel_ptr = 0;
4412
4413 ret_err = ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
4414 if (!ret_err) {
4415 IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
4416 return IA_CSS_ERR_INVALID_ARGUMENTS;
4417 }
4418
4419 ret_err = ia_css_query_internal_queue_id(buf_type, thread_id, &queue_id);
4420 if (!ret_err) {
4421 IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
4422 return IA_CSS_ERR_INVALID_ARGUMENTS;
4423 }
4424
4425 if ((queue_id <= SH_CSS_INVALID_QUEUE_ID) || (queue_id >= SH_CSS_MAX_NUM_QUEUES)) {
4426 IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
4427 return IA_CSS_ERR_INVALID_ARGUMENTS;
4428 }
4429
4430 if (!sh_css_sp_is_running()) {
4431 IA_CSS_LOG("SP is not running!");
4432 IA_CSS_LEAVE_ERR(IA_CSS_ERR_RESOURCE_NOT_AVAILABLE);
4433
4434 return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
4435 }
4436
4437 return_err = ia_css_bufq_dequeue_buffer(queue_id,
4438 (uint32_t *)&ddr_buffer_addr);
4439
4440 if (return_err == IA_CSS_SUCCESS) {
4441 struct ia_css_frame *frame;
4442 struct sh_css_hmm_buffer_record *hmm_buffer_record = NULL;
4443
4444 IA_CSS_LOG("receive vbuf=%x", (int)ddr_buffer_addr);
4445
4446
4447 hmm_buffer_record = sh_css_hmm_buffer_record_validate(
4448 ddr_buffer_addr, buf_type);
4449 if (hmm_buffer_record != NULL) {
4450
4451
4452
4453
4454 kernel_ptr = hmm_buffer_record->kernel_ptr;
4455 ia_css_rmgr_rel_vbuf(hmm_buffer_pool, &hmm_buffer_record->h_vbuf);
4456 sh_css_hmm_buffer_record_reset(hmm_buffer_record);
4457 } else {
4458 IA_CSS_ERROR("hmm_buffer_record not found (0x%u) buf_type(%d)",
4459 ddr_buffer_addr, buf_type);
4460 IA_CSS_LEAVE_ERR(IA_CSS_ERR_INTERNAL_ERROR);
4461 return IA_CSS_ERR_INTERNAL_ERROR;
4462 }
4463
4464 mmgr_load(ddr_buffer_addr,
4465 &ddr_buffer,
4466 sizeof(struct sh_css_hmm_buffer));
4467
4468
4469
4470
4471 if ((ddr_buffer.kernel_ptr == 0) ||
4472 (kernel_ptr != HOST_ADDRESS(ddr_buffer.kernel_ptr))) {
4473 IA_CSS_ERROR("kernel_ptr invalid");
4474 IA_CSS_ERROR("expected: (0x%llx)", (u64)kernel_ptr);
4475 IA_CSS_ERROR("actual: (0x%llx)", (u64)HOST_ADDRESS(ddr_buffer.kernel_ptr));
4476 IA_CSS_ERROR("buf_type: %d\n", buf_type);
4477 IA_CSS_LEAVE_ERR(IA_CSS_ERR_INTERNAL_ERROR);
4478 return IA_CSS_ERR_INTERNAL_ERROR;
4479 }
4480
4481 if (ddr_buffer.kernel_ptr != 0) {
4482
4483
4484 buffer->exp_id = 0;
4485 buffer->driver_cookie = ddr_buffer.cookie_ptr;
4486 buffer->timing_data = ddr_buffer.timing_data;
4487
4488 if ((buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME) ||
4489 (buf_type == IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME)) {
4490 buffer->isys_eof_clock_tick.ticks = ddr_buffer.isys_eof_clock_tick;
4491 }
4492
4493 switch (buf_type) {
4494 case IA_CSS_BUFFER_TYPE_INPUT_FRAME:
4495 case IA_CSS_BUFFER_TYPE_OUTPUT_FRAME:
4496 case IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME:
4497 if ((pipe) && (pipe->stop_requested == true))
4498 {
4499
4500#if defined(USE_INPUT_SYSTEM_VERSION_2)
4501
4502
4503
4504 return_err = free_mipi_frames(pipe);
4505 if (return_err != IA_CSS_SUCCESS) {
4506 IA_CSS_LOG("free_mipi_frames() failed");
4507 IA_CSS_LEAVE_ERR(return_err);
4508 return return_err;
4509 }
4510#endif
4511 pipe->stop_requested = false;
4512 }
4513 case IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME:
4514 case IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME:
4515 frame = (struct ia_css_frame*)HOST_ADDRESS(ddr_buffer.kernel_ptr);
4516 buffer->data.frame = frame;
4517 buffer->exp_id = ddr_buffer.payload.frame.exp_id;
4518 frame->exp_id = ddr_buffer.payload.frame.exp_id;
4519 frame->isp_config_id = ddr_buffer.payload.frame.isp_parameters_id;
4520 if (ddr_buffer.payload.frame.flashed == 1)
4521 frame->flash_state =
4522 IA_CSS_FRAME_FLASH_STATE_PARTIAL;
4523 if (ddr_buffer.payload.frame.flashed == 2)
4524 frame->flash_state =
4525 IA_CSS_FRAME_FLASH_STATE_FULL;
4526 frame->valid = pipe->num_invalid_frames == 0;
4527 if (!frame->valid)
4528 pipe->num_invalid_frames--;
4529
4530 if (frame->info.format == IA_CSS_FRAME_FORMAT_BINARY_8) {
4531#ifdef USE_INPUT_SYSTEM_VERSION_2401
4532 frame->planes.binary.size = frame->data_bytes;
4533#else
4534 frame->planes.binary.size =
4535 sh_css_sp_get_binary_copy_size();
4536#endif
4537 }
4538#if defined(SH_CSS_ENABLE_PER_FRAME_PARAMS)
4539 if (IA_CSS_BUFFER_TYPE_OUTPUT_FRAME == buf_type) {
4540 IA_CSS_LOG("pfp: dequeued OF %d with config id %d thread %d",
4541 frame->data, frame->isp_config_id, thread_id);
4542 }
4543#endif
4544
4545 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
4546 "ia_css_pipe_dequeue_buffer() buf_type=%d, data(DDR address)=0x%x\n",
4547 buf_type, buffer->data.frame->data);
4548
4549 break;
4550 case IA_CSS_BUFFER_TYPE_3A_STATISTICS:
4551 buffer->data.stats_3a =
4552 (struct ia_css_isp_3a_statistics*)HOST_ADDRESS(ddr_buffer.kernel_ptr);
4553 buffer->exp_id = ddr_buffer.payload.s3a.exp_id;
4554 buffer->data.stats_3a->exp_id = ddr_buffer.payload.s3a.exp_id;
4555 buffer->data.stats_3a->isp_config_id = ddr_buffer.payload.s3a.isp_config_id;
4556 break;
4557 case IA_CSS_BUFFER_TYPE_DIS_STATISTICS:
4558 buffer->data.stats_dvs =
4559 (struct ia_css_isp_dvs_statistics*)
4560 HOST_ADDRESS(ddr_buffer.kernel_ptr);
4561 buffer->exp_id = ddr_buffer.payload.dis.exp_id;
4562 buffer->data.stats_dvs->exp_id = ddr_buffer.payload.dis.exp_id;
4563 break;
4564 case IA_CSS_BUFFER_TYPE_LACE_STATISTICS:
4565 break;
4566 case IA_CSS_BUFFER_TYPE_METADATA:
4567 buffer->data.metadata =
4568 (struct ia_css_metadata*)HOST_ADDRESS(ddr_buffer.kernel_ptr);
4569 buffer->exp_id = ddr_buffer.payload.metadata.exp_id;
4570 buffer->data.metadata->exp_id = ddr_buffer.payload.metadata.exp_id;
4571 break;
4572 default:
4573 return_err = IA_CSS_ERR_INTERNAL_ERROR;
4574 break;
4575 }
4576 }
4577 }
4578
4579
4580
4581
4582
4583 if (return_err == IA_CSS_SUCCESS){
4584 if (!sh_css_sp_is_running()) {
4585 IA_CSS_LOG("SP is not running!");
4586 IA_CSS_LEAVE_ERR(IA_CSS_ERR_RESOURCE_NOT_AVAILABLE);
4587
4588 return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
4589 }
4590 ia_css_bufq_enqueue_psys_event(
4591 IA_CSS_PSYS_SW_EVENT_BUFFER_DEQUEUED,
4592 0,
4593 queue_id,
4594 0);
4595 }
4596 IA_CSS_LEAVE("buffer=%p", buffer);
4597
4598 return return_err;
4599}
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611static enum ia_css_event_type convert_event_sp_to_host_domain[] = {
4612 IA_CSS_EVENT_TYPE_OUTPUT_FRAME_DONE,
4613 IA_CSS_EVENT_TYPE_SECOND_OUTPUT_FRAME_DONE,
4614 IA_CSS_EVENT_TYPE_VF_OUTPUT_FRAME_DONE,
4615 IA_CSS_EVENT_TYPE_SECOND_VF_OUTPUT_FRAME_DONE,
4616 IA_CSS_EVENT_TYPE_3A_STATISTICS_DONE,
4617 IA_CSS_EVENT_TYPE_DIS_STATISTICS_DONE,
4618 IA_CSS_EVENT_TYPE_PIPELINE_DONE,
4619 IA_CSS_EVENT_TYPE_FRAME_TAGGED,
4620 IA_CSS_EVENT_TYPE_INPUT_FRAME_DONE,
4621 IA_CSS_EVENT_TYPE_METADATA_DONE,
4622 IA_CSS_EVENT_TYPE_LACE_STATISTICS_DONE,
4623 IA_CSS_EVENT_TYPE_ACC_STAGE_COMPLETE,
4624 IA_CSS_EVENT_TYPE_TIMER,
4625 IA_CSS_EVENT_TYPE_PORT_EOF,
4626 IA_CSS_EVENT_TYPE_FW_WARNING,
4627 IA_CSS_EVENT_TYPE_FW_ASSERT,
4628 0,
4629};
4630
4631enum ia_css_err
4632ia_css_dequeue_event(struct ia_css_event *event)
4633{
4634 return ia_css_dequeue_psys_event(event);
4635}
4636
4637enum ia_css_err
4638ia_css_dequeue_psys_event(struct ia_css_event *event)
4639{
4640 enum ia_css_pipe_id pipe_id = 0;
4641 uint8_t payload[4] = {0,0,0,0};
4642 enum ia_css_err ret_err;
4643
4644
4645
4646
4647
4648
4649
4650
4651 if (event == NULL)
4652 return IA_CSS_ERR_INVALID_ARGUMENTS;
4653
4654 if (!sh_css_sp_is_running()) {
4655
4656 return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
4657 }
4658
4659
4660 ret_err = ia_css_bufq_dequeue_psys_event(payload);
4661 if (ret_err != IA_CSS_SUCCESS)
4662 return ret_err;
4663
4664 IA_CSS_LOG("event dequeued from psys event queue");
4665
4666
4667 ia_css_bufq_enqueue_psys_event(
4668 IA_CSS_PSYS_SW_EVENT_EVENT_DEQUEUED, 0, 0, 0);
4669
4670
4671
4672
4673 event->type = convert_event_sp_to_host_domain[payload[0]];
4674
4675 event->pipe = NULL;
4676 event->port = MIPI_PORT0_ID;
4677 event->exp_id = 0;
4678 event->fw_warning = IA_CSS_FW_WARNING_NONE;
4679 event->fw_handle = 0;
4680 event->timer_data = 0;
4681 event->timer_code = 0;
4682 event->timer_subcode = 0;
4683
4684 if (event->type == IA_CSS_EVENT_TYPE_TIMER) {
4685
4686 uint32_t tmp_data;
4687
4688 event->timer_data = ((payload[1] & 0xFF) | ((payload[3] & 0xFF) << 8));
4689 event->timer_code = payload[2];
4690 payload[0] = payload[1] = payload[2] = payload[3] = 0;
4691 ret_err = ia_css_bufq_dequeue_psys_event(payload);
4692 if (ret_err != IA_CSS_SUCCESS) {
4693
4694
4695
4696 IA_CSS_WARNING("Timer: Error de-queuing the 2nd TIMER event!!!\n");
4697 return ret_err;
4698 }
4699 ia_css_bufq_enqueue_psys_event(
4700 IA_CSS_PSYS_SW_EVENT_EVENT_DEQUEUED, 0, 0, 0);
4701 event->type = convert_event_sp_to_host_domain[payload[0]];
4702
4703 if (event->type == IA_CSS_EVENT_TYPE_TIMER) {
4704
4705 tmp_data = ((payload[1] & 0xFF) | ((payload[3] & 0xFF) << 8));
4706 event->timer_data |= (tmp_data << 16);
4707 event->timer_subcode = payload[2];
4708 }
4709
4710
4711
4712
4713
4714 else {
4715 event->timer_data = 0;
4716 event->timer_code = 0;
4717 event->timer_subcode = 0;
4718 IA_CSS_ERROR("Missing 2nd timer event. Timer event discarded");
4719 }
4720 }
4721 if (event->type == IA_CSS_EVENT_TYPE_PORT_EOF) {
4722 event->port = (enum mipi_port_id)payload[1];
4723 event->exp_id = payload[3];
4724 } else if (event->type == IA_CSS_EVENT_TYPE_FW_WARNING) {
4725 event->fw_warning = (enum ia_css_fw_warning)payload[1];
4726
4727 if (event->fw_warning == IA_CSS_FW_WARNING_EXP_ID_LOCKED ||
4728 event->fw_warning == IA_CSS_FW_WARNING_TAG_EXP_ID_FAILED)
4729 event->exp_id = payload[3];
4730 } else if (event->type == IA_CSS_EVENT_TYPE_FW_ASSERT) {
4731 event->fw_assert_module_id = payload[1];
4732 event->fw_assert_line_no = (payload[2] << 8) + payload[3];
4733
4734 } else if (event->type != IA_CSS_EVENT_TYPE_TIMER) {
4735
4736
4737
4738 event->pipe = find_pipe_by_num(payload[1]);
4739 pipe_id = (enum ia_css_pipe_id)payload[2];
4740
4741 if (!event->pipe)
4742 return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
4743
4744 if (event->type == IA_CSS_EVENT_TYPE_FRAME_TAGGED) {
4745
4746 int i, n;
4747 n = event->pipe->stream->num_pipes;
4748 for (i = 0; i < n; i++) {
4749 struct ia_css_pipe *p =
4750 event->pipe->stream->pipes[i];
4751 if (p->config.mode == IA_CSS_PIPE_MODE_CAPTURE) {
4752 event->pipe = p;
4753 break;
4754 }
4755 }
4756 event->exp_id = payload[3];
4757 }
4758 if (event->type == IA_CSS_EVENT_TYPE_ACC_STAGE_COMPLETE) {
4759
4760 uint32_t stage_num = (uint32_t)payload[3];
4761 ret_err = ia_css_pipeline_get_fw_from_stage(
4762 &(event->pipe->pipeline),
4763 stage_num,
4764 &(event->fw_handle));
4765 if (ret_err != IA_CSS_SUCCESS) {
4766 IA_CSS_ERROR("Invalid stage num received for ACC event. stage_num:%u",
4767 stage_num);
4768 return ret_err;
4769 }
4770 }
4771 }
4772
4773 if (event->pipe)
4774 IA_CSS_LEAVE("event_id=%d, pipe_id=%d", event->type, pipe_id);
4775 else
4776 IA_CSS_LEAVE("event_id=%d", event->type);
4777
4778 return IA_CSS_SUCCESS;
4779}
4780
4781enum ia_css_err
4782ia_css_dequeue_isys_event(struct ia_css_event *event)
4783{
4784 uint8_t payload[4] = {0, 0, 0, 0};
4785 enum ia_css_err err = IA_CSS_SUCCESS;
4786
4787
4788
4789
4790 if (event == NULL)
4791 return IA_CSS_ERR_INVALID_ARGUMENTS;
4792
4793 if (!sh_css_sp_is_running()) {
4794
4795 return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
4796 }
4797
4798 err = ia_css_bufq_dequeue_isys_event(payload);
4799 if (err != IA_CSS_SUCCESS)
4800 return err;
4801
4802 IA_CSS_LOG("event dequeued from isys event queue");
4803
4804
4805 ia_css_bufq_enqueue_isys_event(IA_CSS_ISYS_SW_EVENT_EVENT_DEQUEUED);
4806
4807
4808 event->type = IA_CSS_EVENT_TYPE_PORT_EOF;
4809
4810 event->pipe = NULL;
4811 event->port = payload[1];
4812 event->exp_id = payload[3];
4813
4814 IA_CSS_LEAVE_ERR(err);
4815 return err;
4816}
4817
4818static void
4819acc_start(struct ia_css_pipe *pipe)
4820{
4821 assert(pipe != NULL);
4822 assert(pipe->stream != NULL);
4823
4824 start_pipe(pipe, SH_CSS_PIPE_CONFIG_OVRD_NO_OVRD,
4825 pipe->stream->config.mode);
4826}
4827
4828static enum ia_css_err
4829sh_css_pipe_start(struct ia_css_stream *stream)
4830{
4831 enum ia_css_err err = IA_CSS_SUCCESS;
4832
4833 struct ia_css_pipe *pipe;
4834 enum ia_css_pipe_id pipe_id;
4835 unsigned int thread_id;
4836
4837 IA_CSS_ENTER_PRIVATE("stream = %p", stream);
4838
4839 if (stream == NULL) {
4840 IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
4841 return IA_CSS_ERR_INVALID_ARGUMENTS;
4842 }
4843 pipe = stream->last_pipe;
4844 if (pipe == NULL) {
4845 IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
4846 return IA_CSS_ERR_INVALID_ARGUMENTS;
4847 }
4848
4849 pipe_id = pipe->mode;
4850
4851 if(stream->started == true) {
4852 IA_CSS_WARNING("Cannot start stream that is already started");
4853 IA_CSS_LEAVE_ERR(err);
4854 return err;
4855 }
4856
4857 pipe->stop_requested = false;
4858
4859 switch (pipe_id) {
4860 case IA_CSS_PIPE_ID_PREVIEW:
4861 err = preview_start(pipe);
4862 break;
4863 case IA_CSS_PIPE_ID_VIDEO:
4864 err = video_start(pipe);
4865 break;
4866 case IA_CSS_PIPE_ID_CAPTURE:
4867 err = capture_start(pipe);
4868 break;
4869 case IA_CSS_PIPE_ID_YUVPP:
4870 err = yuvpp_start(pipe);
4871 break;
4872 case IA_CSS_PIPE_ID_ACC:
4873 acc_start(pipe);
4874 break;
4875 default:
4876 err = IA_CSS_ERR_INVALID_ARGUMENTS;
4877 }
4878
4879 if (!stream->config.continuous) {
4880 int i;
4881 for (i = 1; i < stream->num_pipes && IA_CSS_SUCCESS == err ; i++) {
4882 switch (stream->pipes[i]->mode) {
4883 case IA_CSS_PIPE_ID_PREVIEW:
4884 stream->pipes[i]->stop_requested = false;
4885 err = preview_start(stream->pipes[i]);
4886 break;
4887 case IA_CSS_PIPE_ID_VIDEO:
4888 stream->pipes[i]->stop_requested = false;
4889 err = video_start(stream->pipes[i]);
4890 break;
4891 case IA_CSS_PIPE_ID_CAPTURE:
4892 stream->pipes[i]->stop_requested = false;
4893 err = capture_start(stream->pipes[i]);
4894 break;
4895 case IA_CSS_PIPE_ID_YUVPP:
4896 stream->pipes[i]->stop_requested = false;
4897 err = yuvpp_start(stream->pipes[i]);
4898 break;
4899 case IA_CSS_PIPE_ID_ACC:
4900 stream->pipes[i]->stop_requested = false;
4901 acc_start(stream->pipes[i]);
4902 break;
4903 default:
4904 err = IA_CSS_ERR_INVALID_ARGUMENTS;
4905 }
4906 }
4907 }
4908 if (err != IA_CSS_SUCCESS) {
4909 IA_CSS_LEAVE_ERR_PRIVATE(err);
4910 return err;
4911 }
4912
4913
4914
4915
4916
4917
4918 if (!copy_on_sp(pipe)) {
4919 sh_css_invalidate_params(stream);
4920 err = sh_css_param_update_isp_params(pipe,
4921 stream->isp_params_configs, true, NULL);
4922 if (err != IA_CSS_SUCCESS) {
4923 IA_CSS_LEAVE_ERR_PRIVATE(err);
4924 return err;
4925 }
4926 }
4927
4928 ia_css_debug_pipe_graph_dump_epilogue();
4929
4930 ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
4931
4932 if (!sh_css_sp_is_running()) {
4933 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_RESOURCE_NOT_AVAILABLE);
4934
4935 return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
4936 }
4937 ia_css_bufq_enqueue_psys_event(IA_CSS_PSYS_SW_EVENT_START_STREAM,
4938 (uint8_t)thread_id, 0, 0);
4939
4940
4941 if (!stream->config.continuous) {
4942 int i;
4943 for (i = 1; i < stream->num_pipes; i++) {
4944 ia_css_pipeline_get_sp_thread_id(
4945 ia_css_pipe_get_pipe_num(stream->pipes[i]),
4946 &thread_id);
4947 ia_css_bufq_enqueue_psys_event(
4948 IA_CSS_PSYS_SW_EVENT_START_STREAM,
4949 (uint8_t)thread_id, 0, 0);
4950 }
4951 }
4952
4953
4954 if (pipe->stream->config.continuous) {
4955 struct ia_css_pipe *copy_pipe = NULL;
4956
4957 if (pipe_id == IA_CSS_PIPE_ID_PREVIEW)
4958 copy_pipe = pipe->pipe_settings.preview.copy_pipe;
4959 else if (pipe_id == IA_CSS_PIPE_ID_VIDEO)
4960 copy_pipe = pipe->pipe_settings.video.copy_pipe;
4961
4962 if (copy_pipe == NULL) {
4963 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INTERNAL_ERROR);
4964 return IA_CSS_ERR_INTERNAL_ERROR;
4965 }
4966 ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(copy_pipe), &thread_id);
4967
4968 ia_css_bufq_enqueue_psys_event(
4969 IA_CSS_PSYS_SW_EVENT_START_STREAM,
4970 (uint8_t)thread_id, 0, 0);
4971 }
4972 if (pipe->stream->cont_capt) {
4973 struct ia_css_pipe *capture_pipe = NULL;
4974 if (pipe_id == IA_CSS_PIPE_ID_PREVIEW)
4975 capture_pipe = pipe->pipe_settings.preview.capture_pipe;
4976 else if (pipe_id == IA_CSS_PIPE_ID_VIDEO)
4977 capture_pipe = pipe->pipe_settings.video.capture_pipe;
4978
4979 if (capture_pipe == NULL) {
4980 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INTERNAL_ERROR);
4981 return IA_CSS_ERR_INTERNAL_ERROR;
4982 }
4983 ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(capture_pipe), &thread_id);
4984
4985 ia_css_bufq_enqueue_psys_event(
4986 IA_CSS_PSYS_SW_EVENT_START_STREAM,
4987 (uint8_t)thread_id, 0, 0);
4988 }
4989
4990
4991 if (pipe_id == IA_CSS_PIPE_ID_PREVIEW) {
4992 struct ia_css_pipe *acc_pipe = NULL;
4993 acc_pipe = pipe->pipe_settings.preview.acc_pipe;
4994
4995 if (acc_pipe){
4996 ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(acc_pipe), &thread_id);
4997
4998 ia_css_bufq_enqueue_psys_event(
4999 IA_CSS_PSYS_SW_EVENT_START_STREAM,
5000 (uint8_t) thread_id, 0, 0);
5001 }
5002 }
5003
5004 stream->started = true;
5005
5006 IA_CSS_LEAVE_ERR_PRIVATE(err);
5007 return err;
5008}
5009
5010#ifndef ISP2401
5011void
5012sh_css_enable_cont_capt(bool enable, bool stop_copy_preview)
5013{
5014 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
5015 "sh_css_enable_cont_capt() enter: enable=%d\n", enable);
5016
5017 my_css.stop_copy_preview = stop_copy_preview;
5018}
5019
5020bool
5021sh_css_continuous_is_enabled(uint8_t pipe_num)
5022#else
5023
5024
5025
5026
5027
5028
5029static enum ia_css_err
5030sh_css_pipes_stop(struct ia_css_stream *stream)
5031#endif
5032{
5033#ifndef ISP2401
5034 struct ia_css_pipe *pipe;
5035 bool continuous;
5036#else
5037 enum ia_css_err err = IA_CSS_SUCCESS;
5038 struct ia_css_pipe *main_pipe;
5039 enum ia_css_pipe_id main_pipe_id;
5040 int i;
5041#endif
5042
5043#ifndef ISP2401
5044 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "sh_css_continuous_is_enabled() enter: pipe_num=%d\n", pipe_num);
5045#else
5046 assert(stream != NULL);
5047 if (stream == NULL) {
5048 IA_CSS_LOG("stream does NOT exist!");
5049 err = IA_CSS_ERR_INTERNAL_ERROR;
5050 goto ERR;
5051 }
5052#endif
5053
5054#ifndef ISP2401
5055 pipe = find_pipe_by_num(pipe_num);
5056 continuous = pipe && pipe->stream->config.continuous;
5057 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
5058 "sh_css_continuous_is_enabled() leave: enable=%d\n",
5059 continuous);
5060 return continuous;
5061}
5062#else
5063 main_pipe = stream->last_pipe;
5064 assert(main_pipe != NULL);
5065 if (main_pipe == NULL) {
5066 IA_CSS_LOG("main_pipe does NOT exist!");
5067 err = IA_CSS_ERR_INTERNAL_ERROR;
5068 goto ERR;
5069 }
5070#endif
5071
5072#ifndef ISP2401
5073enum ia_css_err
5074ia_css_stream_get_max_buffer_depth(struct ia_css_stream *stream, int *buffer_depth)
5075{
5076 if (buffer_depth == NULL)
5077 return IA_CSS_ERR_INVALID_ARGUMENTS;
5078 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_get_max_buffer_depth() enter: void\n");
5079 (void)stream;
5080 *buffer_depth = NUM_CONTINUOUS_FRAMES;
5081 return IA_CSS_SUCCESS;
5082}
5083#else
5084 main_pipe_id = main_pipe->mode;
5085 IA_CSS_ENTER_PRIVATE("main_pipe_id=%d", main_pipe_id);
5086#endif
5087
5088#ifndef ISP2401
5089enum ia_css_err
5090ia_css_stream_set_buffer_depth(struct ia_css_stream *stream, int buffer_depth)
5091{
5092 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_set_buffer_depth() enter: num_frames=%d\n",buffer_depth);
5093 (void)stream;
5094 if (buffer_depth > NUM_CONTINUOUS_FRAMES || buffer_depth < 1)
5095 return IA_CSS_ERR_INVALID_ARGUMENTS;
5096
5097 stream->config.target_num_cont_raw_buf = buffer_depth;
5098
5099 return IA_CSS_SUCCESS;
5100}
5101#else
5102
5103
5104
5105
5106 for (i = 0; i < stream->num_pipes; i++) {
5107
5108 IA_CSS_LOG("Send the stop-request to the pipe: pipe_id=%d",
5109 stream->pipes[i]->pipeline.pipe_id);
5110 err = ia_css_pipeline_request_stop(&stream->pipes[i]->pipeline);
5111#endif
5112
5113#ifndef ISP2401
5114enum ia_css_err
5115ia_css_stream_get_buffer_depth(struct ia_css_stream *stream, int *buffer_depth)
5116{
5117 if (buffer_depth == NULL)
5118 return IA_CSS_ERR_INVALID_ARGUMENTS;
5119 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_get_buffer_depth() enter: void\n");
5120#else
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136 if (err != IA_CSS_SUCCESS) {
5137 goto ERR;
5138 }
5139 }
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150 if (main_pipe->stream->config.continuous) {
5151 struct ia_css_pipe *copy_pipe = NULL;
5152
5153
5154 if (main_pipe_id == IA_CSS_PIPE_ID_PREVIEW)
5155 copy_pipe = main_pipe->pipe_settings.preview.copy_pipe;
5156 else if (main_pipe_id == IA_CSS_PIPE_ID_VIDEO)
5157 copy_pipe = main_pipe->pipe_settings.video.copy_pipe;
5158
5159
5160 assert(copy_pipe != NULL);
5161 if (copy_pipe == NULL) {
5162 IA_CSS_LOG("Copy Pipe does NOT exist!");
5163 err = IA_CSS_ERR_INTERNAL_ERROR;
5164 goto ERR;
5165 }
5166
5167
5168 IA_CSS_LOG("Send the stop-request to the pipe: pipe_id=%d",
5169 copy_pipe->pipeline.pipe_id);
5170 err = ia_css_pipeline_request_stop(©_pipe->pipeline);
5171 }
5172
5173ERR:
5174 IA_CSS_LEAVE_ERR_PRIVATE(err);
5175 return err;
5176}
5177
5178
5179
5180
5181
5182
5183
5184static bool
5185sh_css_pipes_have_stopped(struct ia_css_stream *stream)
5186{
5187 bool rval = true;
5188
5189 struct ia_css_pipe *main_pipe;
5190 enum ia_css_pipe_id main_pipe_id;
5191
5192 int i;
5193
5194 assert(stream != NULL);
5195 if (stream == NULL) {
5196 IA_CSS_LOG("stream does NOT exist!");
5197 rval = false;
5198 goto RET;
5199 }
5200
5201 main_pipe = stream->last_pipe;
5202 assert(main_pipe != NULL);
5203
5204 if (main_pipe == NULL) {
5205 IA_CSS_LOG("main_pipe does NOT exist!");
5206 rval = false;
5207 goto RET;
5208 }
5209
5210 main_pipe_id = main_pipe->mode;
5211 IA_CSS_ENTER_PRIVATE("main_pipe_id=%d", main_pipe_id);
5212
5213
5214
5215
5216
5217 for (i = 0; i < stream->num_pipes; i++) {
5218 rval = rval && ia_css_pipeline_has_stopped(&stream->pipes[i]->pipeline);
5219 IA_CSS_LOG("Pipe has stopped: pipe_id=%d, stopped=%d",
5220 stream->pipes[i]->pipeline.pipe_id,
5221 rval);
5222 }
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233 if (main_pipe->stream->config.continuous) {
5234 struct ia_css_pipe *copy_pipe = NULL;
5235
5236
5237 if (main_pipe_id == IA_CSS_PIPE_ID_PREVIEW)
5238 copy_pipe = main_pipe->pipe_settings.preview.copy_pipe;
5239 else if (main_pipe_id == IA_CSS_PIPE_ID_VIDEO)
5240 copy_pipe = main_pipe->pipe_settings.video.copy_pipe;
5241
5242
5243 assert(copy_pipe != NULL);
5244 if (copy_pipe == NULL) {
5245 IA_CSS_LOG("Copy Pipe does NOT exist!");
5246
5247 rval = false;
5248 goto RET;
5249 }
5250
5251
5252 rval = rval && ia_css_pipeline_has_stopped(©_pipe->pipeline);
5253 IA_CSS_LOG("Pipe has stopped: pipe_id=%d, stopped=%d",
5254 copy_pipe->pipeline.pipe_id,
5255 rval);
5256 }
5257
5258RET:
5259 IA_CSS_LEAVE_PRIVATE("rval=%d", rval);
5260 return rval;
5261}
5262
5263bool
5264sh_css_continuous_is_enabled(uint8_t pipe_num)
5265{
5266 struct ia_css_pipe *pipe;
5267 bool continuous;
5268
5269 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "sh_css_continuous_is_enabled() enter: pipe_num=%d\n", pipe_num);
5270
5271 pipe = find_pipe_by_num(pipe_num);
5272 continuous = pipe && pipe->stream->config.continuous;
5273 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
5274 "sh_css_continuous_is_enabled() leave: enable=%d\n",
5275 continuous);
5276 return continuous;
5277}
5278
5279enum ia_css_err
5280ia_css_stream_get_max_buffer_depth(struct ia_css_stream *stream, int *buffer_depth)
5281{
5282 if (buffer_depth == NULL)
5283 return IA_CSS_ERR_INVALID_ARGUMENTS;
5284 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_get_max_buffer_depth() enter: void\n");
5285 (void)stream;
5286 *buffer_depth = NUM_CONTINUOUS_FRAMES;
5287 return IA_CSS_SUCCESS;
5288}
5289
5290enum ia_css_err
5291ia_css_stream_set_buffer_depth(struct ia_css_stream *stream, int buffer_depth)
5292{
5293 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_set_buffer_depth() enter: num_frames=%d\n",buffer_depth);
5294 (void)stream;
5295 if (buffer_depth > NUM_CONTINUOUS_FRAMES || buffer_depth < 1)
5296 return IA_CSS_ERR_INVALID_ARGUMENTS;
5297
5298 stream->config.target_num_cont_raw_buf = buffer_depth;
5299
5300 return IA_CSS_SUCCESS;
5301}
5302
5303enum ia_css_err
5304ia_css_stream_get_buffer_depth(struct ia_css_stream *stream, int *buffer_depth)
5305{
5306 if (buffer_depth == NULL)
5307 return IA_CSS_ERR_INVALID_ARGUMENTS;
5308 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_get_buffer_depth() enter: void\n");
5309#endif
5310 (void)stream;
5311 *buffer_depth = stream->config.target_num_cont_raw_buf;
5312 return IA_CSS_SUCCESS;
5313}
5314
5315#if !defined(HAS_NO_INPUT_SYSTEM) && defined(USE_INPUT_SYSTEM_VERSION_2)
5316unsigned int
5317sh_css_get_mipi_sizes_for_check(const unsigned int port, const unsigned int idx)
5318{
5319 OP___assert(port < N_CSI_PORTS);
5320 OP___assert(idx < IA_CSS_MIPI_SIZE_CHECK_MAX_NOF_ENTRIES_PER_PORT);
5321 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "sh_css_get_mipi_sizes_for_check(port %d, idx %d): %d\n",
5322 port, idx, my_css.mipi_sizes_for_check[port][idx]);
5323 return my_css.mipi_sizes_for_check[port][idx];
5324}
5325#endif
5326
5327static enum ia_css_err sh_css_pipe_configure_output(
5328 struct ia_css_pipe *pipe,
5329 unsigned int width,
5330 unsigned int height,
5331 unsigned int padded_width,
5332 enum ia_css_frame_format format,
5333 unsigned int idx)
5334{
5335 enum ia_css_err err = IA_CSS_SUCCESS;
5336
5337 IA_CSS_ENTER_PRIVATE("pipe = %p, width = %d, height = %d, paddaed width = %d, format = %d, idx = %d",
5338 pipe, width, height, padded_width, format, idx);
5339 if (pipe == NULL) {
5340 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
5341 return IA_CSS_ERR_INVALID_ARGUMENTS;
5342 }
5343
5344 err = ia_css_util_check_res(width, height);
5345 if (err != IA_CSS_SUCCESS) {
5346 IA_CSS_LEAVE_ERR_PRIVATE(err);
5347 return err;
5348 }
5349 if (pipe->output_info[idx].res.width != width ||
5350 pipe->output_info[idx].res.height != height ||
5351 pipe->output_info[idx].format != format)
5352 {
5353 ia_css_frame_info_init(
5354 &pipe->output_info[idx],
5355 width,
5356 height,
5357 format,
5358 padded_width);
5359 }
5360 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
5361 return IA_CSS_SUCCESS;
5362}
5363
5364static enum ia_css_err
5365sh_css_pipe_get_shading_info(struct ia_css_pipe *pipe,
5366#ifndef ISP2401
5367 struct ia_css_shading_info *info)
5368#else
5369 struct ia_css_shading_info *shading_info,
5370 struct ia_css_pipe_config *pipe_config)
5371#endif
5372{
5373 enum ia_css_err err = IA_CSS_SUCCESS;
5374 struct ia_css_binary *binary = NULL;
5375
5376 assert(pipe != NULL);
5377#ifndef ISP2401
5378 assert(info != NULL);
5379#else
5380 assert(shading_info != NULL);
5381 assert(pipe_config != NULL);
5382#endif
5383 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
5384 "sh_css_pipe_get_shading_info() enter:\n");
5385
5386 binary = ia_css_pipe_get_shading_correction_binary(pipe);
5387
5388 if (binary) {
5389 err = ia_css_binary_get_shading_info(binary,
5390 IA_CSS_SHADING_CORRECTION_TYPE_1,
5391 pipe->required_bds_factor,
5392 (const struct ia_css_stream_config *)&pipe->stream->config,
5393#ifndef ISP2401
5394 info);
5395#else
5396 shading_info, pipe_config);
5397#endif
5398
5399
5400
5401 } else {
5402
5403
5404
5405
5406
5407#ifndef ISP2401
5408 memset(info, 0, sizeof(*info));
5409#else
5410 memset(shading_info, 0, sizeof(*shading_info));
5411#endif
5412 }
5413 return err;
5414}
5415
5416static enum ia_css_err
5417sh_css_pipe_get_grid_info(struct ia_css_pipe *pipe,
5418 struct ia_css_grid_info *info)
5419{
5420 enum ia_css_err err = IA_CSS_SUCCESS;
5421 struct ia_css_binary *binary = NULL;
5422
5423 assert(pipe != NULL);
5424 assert(info != NULL);
5425
5426 IA_CSS_ENTER_PRIVATE("");
5427
5428 binary = ia_css_pipe_get_s3a_binary(pipe);
5429
5430 if (binary) {
5431 err = ia_css_binary_3a_grid_info(binary, info, pipe);
5432 if (err != IA_CSS_SUCCESS)
5433 goto ERR;
5434 } else
5435 memset(&info->s3a_grid, 0, sizeof(info->s3a_grid));
5436
5437 binary = ia_css_pipe_get_sdis_binary(pipe);
5438
5439 if (binary) {
5440 ia_css_binary_dvs_grid_info(binary, info, pipe);
5441 ia_css_binary_dvs_stat_grid_info(binary, info, pipe);
5442 } else {
5443 memset(&info->dvs_grid.dvs_grid_info, 0,
5444 sizeof(info->dvs_grid.dvs_grid_info));
5445 memset(&info->dvs_grid.dvs_stat_grid_info, 0,
5446 sizeof(info->dvs_grid.dvs_stat_grid_info));
5447 }
5448
5449 if (binary != NULL) {
5450
5451 info->isp_in_width = binary->internal_frame_info.res.width;
5452 info->isp_in_height = binary->internal_frame_info.res.height;
5453 }
5454
5455#if defined(HAS_VAMEM_VERSION_2)
5456 info->vamem_type = IA_CSS_VAMEM_TYPE_2;
5457#elif defined(HAS_VAMEM_VERSION_1)
5458 info->vamem_type = IA_CSS_VAMEM_TYPE_1;
5459#else
5460#error "Unknown VAMEM version"
5461#endif
5462
5463ERR:
5464 IA_CSS_LEAVE_ERR_PRIVATE(err);
5465 return err;
5466}
5467
5468#ifdef ISP2401
5469
5470
5471
5472
5473static enum ia_css_err
5474ia_css_pipe_check_format(struct ia_css_pipe *pipe, enum ia_css_frame_format format)
5475{
5476 const enum ia_css_frame_format *supported_formats;
5477 int number_of_formats;
5478 int found = 0;
5479 int i;
5480
5481 IA_CSS_ENTER_PRIVATE("");
5482
5483 if (NULL == pipe || NULL == pipe->pipe_settings.video.video_binary.info) {
5484 IA_CSS_ERROR("Pipe or binary info is not set");
5485 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
5486 return IA_CSS_ERR_INVALID_ARGUMENTS;
5487 }
5488
5489 supported_formats = pipe->pipe_settings.video.video_binary.info->output_formats;
5490 number_of_formats = sizeof(pipe->pipe_settings.video.video_binary.info->output_formats)/sizeof(enum ia_css_frame_format);
5491
5492 for (i = 0; i < number_of_formats && !found; i++) {
5493 if (supported_formats[i] == format) {
5494 found = 1;
5495 break;
5496 }
5497 }
5498 if (!found) {
5499 IA_CSS_ERROR("Requested format is not supported by binary");
5500 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
5501 return IA_CSS_ERR_INVALID_ARGUMENTS;
5502 } else {
5503 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
5504 return IA_CSS_SUCCESS;
5505 }
5506}
5507#endif
5508
5509static enum ia_css_err load_video_binaries(struct ia_css_pipe *pipe)
5510{
5511 struct ia_css_frame_info video_in_info, tnr_info,
5512 *video_vf_info, video_bds_out_info, *pipe_out_info, *pipe_vf_out_info;
5513 bool online;
5514 enum ia_css_err err = IA_CSS_SUCCESS;
5515 bool continuous = pipe->stream->config.continuous;
5516 unsigned int i;
5517 unsigned num_output_pins;
5518 struct ia_css_frame_info video_bin_out_info;
5519 bool need_scaler = false;
5520 bool vf_res_different_than_output = false;
5521 bool need_vf_pp = false;
5522 int vf_ds_log2;
5523 struct ia_css_video_settings *mycs = &pipe->pipe_settings.video;
5524
5525 IA_CSS_ENTER_PRIVATE("");
5526 assert(pipe != NULL);
5527 assert(pipe->mode == IA_CSS_PIPE_ID_VIDEO);
5528
5529
5530
5531
5532 if (mycs->video_binary.info)
5533 return IA_CSS_SUCCESS;
5534
5535 online = pipe->stream->config.online;
5536 pipe_out_info = &pipe->output_info[0];
5537 pipe_vf_out_info = &pipe->vf_output_info[0];
5538
5539 assert(pipe_out_info != NULL);
5540
5541
5542
5543
5544
5545
5546 err = ia_css_util_check_input(&pipe->stream->config, false, false);
5547 if (err != IA_CSS_SUCCESS)
5548 return err;
5549
5550 if (online && pipe->stream->config.mode == IA_CSS_INPUT_MODE_MEMORY)
5551 return IA_CSS_ERR_INVALID_ARGUMENTS;
5552 if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0]) {
5553 err = ia_css_util_check_vf_out_info(pipe_out_info,
5554 pipe_vf_out_info);
5555 if (err != IA_CSS_SUCCESS)
5556 return err;
5557 } else {
5558 err = ia_css_frame_check_info(pipe_out_info);
5559 if (err != IA_CSS_SUCCESS)
5560 return err;
5561 }
5562
5563 if (pipe->out_yuv_ds_input_info.res.width)
5564 video_bin_out_info = pipe->out_yuv_ds_input_info;
5565 else
5566 video_bin_out_info = *pipe_out_info;
5567
5568
5569 if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0]){
5570 video_vf_info = pipe_vf_out_info;
5571 vf_res_different_than_output = (video_vf_info->res.width != video_bin_out_info.res.width) ||
5572 (video_vf_info->res.height != video_bin_out_info.res.height);
5573 }
5574 else {
5575 video_vf_info = NULL;
5576 }
5577
5578 need_scaler = need_downscaling(video_bin_out_info.res, pipe_out_info->res);
5579
5580
5581
5582 if (need_scaler) {
5583 struct ia_css_cas_binary_descr cas_scaler_descr = { };
5584
5585
5586
5587 video_bin_out_info.format = IA_CSS_FRAME_FORMAT_NV12;
5588
5589 err = ia_css_pipe_create_cas_scaler_desc_single_output(
5590 &video_bin_out_info,
5591 pipe_out_info,
5592 NULL,
5593 &cas_scaler_descr);
5594 if (err != IA_CSS_SUCCESS)
5595 return err;
5596 mycs->num_yuv_scaler = cas_scaler_descr.num_stage;
5597 mycs->yuv_scaler_binary = kzalloc(cas_scaler_descr.num_stage *
5598 sizeof(struct ia_css_binary), GFP_KERNEL);
5599 if (!mycs->yuv_scaler_binary) {
5600 err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
5601 return err;
5602 }
5603 mycs->is_output_stage = kzalloc(cas_scaler_descr.num_stage
5604 * sizeof(bool), GFP_KERNEL);
5605 if (!mycs->is_output_stage) {
5606 err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
5607 return err;
5608 }
5609 for (i = 0; i < cas_scaler_descr.num_stage; i++) {
5610 struct ia_css_binary_descr yuv_scaler_descr;
5611 mycs->is_output_stage[i] = cas_scaler_descr.is_output_stage[i];
5612 ia_css_pipe_get_yuvscaler_binarydesc(pipe,
5613 &yuv_scaler_descr, &cas_scaler_descr.in_info[i],
5614 &cas_scaler_descr.out_info[i],
5615 &cas_scaler_descr.internal_out_info[i],
5616 &cas_scaler_descr.vf_info[i]);
5617 err = ia_css_binary_find(&yuv_scaler_descr,
5618 &mycs->yuv_scaler_binary[i]);
5619 if (err != IA_CSS_SUCCESS) {
5620 kfree(mycs->is_output_stage);
5621 mycs->is_output_stage = NULL;
5622 return err;
5623 }
5624 }
5625 ia_css_pipe_destroy_cas_scaler_desc(&cas_scaler_descr);
5626 }
5627
5628
5629 {
5630 struct ia_css_binary_descr video_descr;
5631 enum ia_css_frame_format vf_info_format;
5632
5633 err = ia_css_pipe_get_video_binarydesc(pipe,
5634 &video_descr, &video_in_info, &video_bds_out_info, &video_bin_out_info, video_vf_info,
5635 pipe->stream->config.left_padding);
5636 if (err != IA_CSS_SUCCESS)
5637 return err;
5638
5639
5640
5641
5642
5643
5644 err = ia_css_binary_find(&video_descr,
5645 &mycs->video_binary);
5646
5647 if (err != IA_CSS_SUCCESS) {
5648 if (video_vf_info) {
5649
5650 need_vf_pp = true;
5651 } else
5652 return err;
5653 } else if (video_vf_info) {
5654
5655
5656 num_output_pins = mycs->video_binary.info->num_output_pins;
5657 vf_ds_log2 = mycs->video_binary.vf_downscale_log2;
5658
5659
5660
5661 need_vf_pp |= ((num_output_pins == 2) && vf_res_different_than_output);
5662
5663
5664
5665 need_vf_pp |= ((num_output_pins == 1) &&
5666 ((video_vf_info->res.width << vf_ds_log2 != pipe_out_info->res.width) ||
5667 (video_vf_info->res.height << vf_ds_log2 != pipe_out_info->res.height)));
5668 }
5669
5670 if (need_vf_pp) {
5671
5672 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
5673 "load_video_binaries() need_vf_pp; find video binary with YUV_LINE again\n");
5674
5675 vf_info_format = video_vf_info->format;
5676
5677 if (!pipe->config.enable_vfpp_bci)
5678 ia_css_frame_info_set_format(video_vf_info,
5679 IA_CSS_FRAME_FORMAT_YUV_LINE);
5680
5681 ia_css_binary_destroy_isp_parameters(&mycs->video_binary);
5682
5683 err = ia_css_binary_find(&video_descr,
5684 &mycs->video_binary);
5685
5686
5687 ia_css_frame_info_set_format(video_vf_info,
5688 vf_info_format);
5689 if (err != IA_CSS_SUCCESS)
5690 return err;
5691 }
5692 }
5693
5694
5695
5696 if (!mycs->video_binary.info->sp.enable.ref_frame)
5697 pipe->dvs_frame_delay = 0;
5698
5699
5700
5701 pipe->num_invalid_frames = pipe->dvs_frame_delay;
5702 pipe->info.num_invalid_frames = pipe->num_invalid_frames;
5703
5704
5705
5706
5707 if (video_vf_info)
5708 pipe->num_invalid_frames *= 2;
5709
5710 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
5711 "load_video_binaries() num_invalid_frames=%d dvs_frame_delay=%d\n",
5712 pipe->num_invalid_frames, pipe->dvs_frame_delay);
5713
5714
5715#if !defined(USE_INPUT_SYSTEM_VERSION_2401)
5716
5717 if (!online && !continuous) {
5718
5719
5720
5721 err = load_copy_binary(pipe,
5722 &mycs->copy_binary,
5723 &mycs->video_binary);
5724 if (err != IA_CSS_SUCCESS)
5725 return err;
5726 }
5727#else
5728 (void)continuous;
5729#endif
5730
5731#if !defined(HAS_OUTPUT_SYSTEM)
5732 if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0] && need_vf_pp) {
5733 struct ia_css_binary_descr vf_pp_descr;
5734
5735 if (mycs->video_binary.vf_frame_info.format
5736 == IA_CSS_FRAME_FORMAT_YUV_LINE) {
5737 ia_css_pipe_get_vfpp_binarydesc(pipe, &vf_pp_descr,
5738 &mycs->video_binary.vf_frame_info,
5739 pipe_vf_out_info);
5740 } else {
5741
5742
5743 assert(pipe->config.enable_vfpp_bci == true);
5744 ia_css_pipe_get_yuvscaler_binarydesc(pipe, &vf_pp_descr,
5745 &mycs->video_binary.vf_frame_info,
5746 pipe_vf_out_info, NULL, NULL);
5747 }
5748
5749 err = ia_css_binary_find(&vf_pp_descr,
5750 &mycs->vf_pp_binary);
5751 if (err != IA_CSS_SUCCESS)
5752 return err;
5753 }
5754#endif
5755
5756 err = allocate_delay_frames(pipe);
5757
5758 if (err != IA_CSS_SUCCESS)
5759 return err;
5760
5761 if (mycs->video_binary.info->sp.enable.block_output) {
5762#ifdef ISP2401
5763 unsigned int tnr_width;
5764 unsigned int tnr_height;
5765#endif
5766 tnr_info = mycs->video_binary.out_frame_info[0];
5767#ifdef ISP2401
5768
5769
5770
5771
5772
5773 if (pipe->config.output_system_in_res.width && pipe->config.output_system_in_res.height) {
5774 tnr_width = pipe->config.output_system_in_res.width;
5775 tnr_height = pipe->config.output_system_in_res.height;
5776 } else {
5777 tnr_width = tnr_info.res.width;
5778 tnr_height = tnr_info.res.height;
5779 }
5780
5781
5782 tnr_info.res.width =
5783 CEIL_MUL(tnr_width,
5784 (mycs->video_binary.info->sp.block.block_width * ISP_NWAY));
5785 tnr_info.padded_width = tnr_info.res.width;
5786
5787#endif
5788
5789#ifndef ISP2401
5790 tnr_info.res.height =
5791 CEIL_MUL(tnr_info.res.height,
5792 mycs->video_binary.info->sp.block.output_block_height);
5793#else
5794 tnr_info.res.height =
5795 CEIL_MUL(tnr_height,
5796 mycs->video_binary.info->sp.block.output_block_height);
5797#endif
5798 } else {
5799 tnr_info = mycs->video_binary.internal_frame_info;
5800 }
5801 tnr_info.format = IA_CSS_FRAME_FORMAT_YUV_LINE;
5802 tnr_info.raw_bit_depth = SH_CSS_TNR_BIT_DEPTH;
5803
5804#ifndef ISP2401
5805 for (i = 0; i < NUM_VIDEO_TNR_FRAMES; i++) {
5806#else
5807 for (i = 0; i < NUM_TNR_FRAMES; i++) {
5808#endif
5809 if (mycs->tnr_frames[i]) {
5810 ia_css_frame_free(mycs->tnr_frames[i]);
5811 mycs->tnr_frames[i] = NULL;
5812 }
5813 err = ia_css_frame_allocate_from_info(
5814 &mycs->tnr_frames[i],
5815 &tnr_info);
5816 if (err != IA_CSS_SUCCESS)
5817 return err;
5818 }
5819 IA_CSS_LEAVE_PRIVATE("");
5820 return IA_CSS_SUCCESS;
5821}
5822
5823static enum ia_css_err
5824unload_video_binaries(struct ia_css_pipe *pipe)
5825{
5826 unsigned int i;
5827 IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
5828
5829 if ((pipe == NULL) || (pipe->mode != IA_CSS_PIPE_ID_VIDEO)) {
5830 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
5831 return IA_CSS_ERR_INVALID_ARGUMENTS;
5832 }
5833 ia_css_binary_unload(&pipe->pipe_settings.video.copy_binary);
5834 ia_css_binary_unload(&pipe->pipe_settings.video.video_binary);
5835 ia_css_binary_unload(&pipe->pipe_settings.video.vf_pp_binary);
5836#ifndef ISP2401
5837 ia_css_binary_unload(&pipe->pipe_settings.video.vf_pp_binary);
5838#endif
5839
5840 for (i = 0; i < pipe->pipe_settings.video.num_yuv_scaler; i++)
5841 ia_css_binary_unload(&pipe->pipe_settings.video.yuv_scaler_binary[i]);
5842
5843 kfree(pipe->pipe_settings.video.is_output_stage);
5844 pipe->pipe_settings.video.is_output_stage = NULL;
5845 kfree(pipe->pipe_settings.video.yuv_scaler_binary);
5846 pipe->pipe_settings.video.yuv_scaler_binary = NULL;
5847
5848 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
5849 return IA_CSS_SUCCESS;
5850}
5851
5852static enum ia_css_err video_start(struct ia_css_pipe *pipe)
5853{
5854 struct ia_css_binary *copy_binary;
5855 enum ia_css_err err = IA_CSS_SUCCESS;
5856 struct ia_css_pipe *copy_pipe, *capture_pipe;
5857 enum sh_css_pipe_config_override copy_ovrd;
5858 enum ia_css_input_mode video_pipe_input_mode;
5859
5860
5861 IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
5862 if ((pipe == NULL) || (pipe->mode != IA_CSS_PIPE_ID_VIDEO)) {
5863 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
5864 return IA_CSS_ERR_INVALID_ARGUMENTS;
5865 }
5866
5867 video_pipe_input_mode = pipe->stream->config.mode;
5868
5869 copy_pipe = pipe->pipe_settings.video.copy_pipe;
5870 capture_pipe = pipe->pipe_settings.video.capture_pipe;
5871
5872 copy_binary = &pipe->pipe_settings.video.copy_binary;
5873
5874 sh_css_metrics_start_frame();
5875
5876
5877
5878#if defined(USE_INPUT_SYSTEM_VERSION_2) || defined(USE_INPUT_SYSTEM_VERSION_2401)
5879 err = send_mipi_frames(pipe);
5880 if (err != IA_CSS_SUCCESS)
5881 return err;
5882#endif
5883
5884 send_raw_frames(pipe);
5885 {
5886 unsigned int thread_id;
5887
5888 ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
5889 copy_ovrd = 1 << thread_id;
5890
5891 if (pipe->stream->cont_capt) {
5892 ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(capture_pipe), &thread_id);
5893 copy_ovrd |= 1 << thread_id;
5894 }
5895 }
5896
5897
5898 if (pipe->stream->config.continuous) {
5899 sh_css_sp_init_pipeline(©_pipe->pipeline,
5900 IA_CSS_PIPE_ID_COPY,
5901 (uint8_t)ia_css_pipe_get_pipe_num(copy_pipe),
5902 false,
5903 pipe->stream->config.pixels_per_clock == 2, false,
5904 false, pipe->required_bds_factor,
5905 copy_ovrd,
5906 pipe->stream->config.mode,
5907 &pipe->stream->config.metadata_config,
5908#ifndef ISP2401
5909 &pipe->stream->info.metadata_info
5910#else
5911 &pipe->stream->info.metadata_info,
5912#endif
5913#if !defined(HAS_NO_INPUT_SYSTEM)
5914#ifndef ISP2401
5915 , pipe->stream->config.source.port.port
5916#else
5917 pipe->stream->config.source.port.port,
5918#endif
5919#endif
5920#ifndef ISP2401
5921 );
5922#else
5923 ©_pipe->config.internal_frame_origin_bqs_on_sctbl,
5924 copy_pipe->stream->isp_params_configs);
5925#endif
5926
5927
5928
5929 video_pipe_input_mode = IA_CSS_INPUT_MODE_MEMORY;
5930 }
5931
5932
5933 if (pipe->stream->cont_capt) {
5934 sh_css_sp_init_pipeline(&capture_pipe->pipeline,
5935 IA_CSS_PIPE_ID_CAPTURE,
5936 (uint8_t)ia_css_pipe_get_pipe_num(capture_pipe),
5937 capture_pipe->config.default_capture_config.enable_xnr != 0,
5938 capture_pipe->stream->config.pixels_per_clock == 2,
5939 true,
5940 false,
5941 capture_pipe->required_bds_factor,
5942 0,
5943 IA_CSS_INPUT_MODE_MEMORY,
5944 &pipe->stream->config.metadata_config,
5945#ifndef ISP2401
5946 &pipe->stream->info.metadata_info
5947#else
5948 &pipe->stream->info.metadata_info,
5949#endif
5950#if !defined(HAS_NO_INPUT_SYSTEM)
5951#ifndef ISP2401
5952 , (enum mipi_port_id)0
5953#else
5954 (enum mipi_port_id)0,
5955#endif
5956#endif
5957#ifndef ISP2401
5958 );
5959#else
5960 &capture_pipe->config.internal_frame_origin_bqs_on_sctbl,
5961 capture_pipe->stream->isp_params_configs);
5962#endif
5963 }
5964
5965 start_pipe(pipe, copy_ovrd, video_pipe_input_mode);
5966
5967 IA_CSS_LEAVE_ERR_PRIVATE(err);
5968 return err;
5969}
5970
5971static
5972enum ia_css_err sh_css_pipe_get_viewfinder_frame_info(
5973 struct ia_css_pipe *pipe,
5974 struct ia_css_frame_info *info,
5975 unsigned int idx)
5976{
5977 assert(pipe != NULL);
5978 assert(info != NULL);
5979
5980
5981 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "sh_css_pipe_get_viewfinder_frame_info() enter: void\n");
5982
5983 if ( pipe->mode == IA_CSS_PIPE_ID_CAPTURE &&
5984 (pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_RAW ||
5985 pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_BAYER))
5986 return IA_CSS_ERR_MODE_HAS_NO_VIEWFINDER;
5987
5988 *info = pipe->vf_output_info[idx];
5989
5990 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
5991 "sh_css_pipe_get_viewfinder_frame_info() leave: \
5992 info.res.width=%d, info.res.height=%d, \
5993 info.padded_width=%d, info.format=%d, \
5994 info.raw_bit_depth=%d, info.raw_bayer_order=%d\n",
5995 info->res.width,info->res.height,
5996 info->padded_width,info->format,
5997 info->raw_bit_depth,info->raw_bayer_order);
5998
5999 return IA_CSS_SUCCESS;
6000}
6001
6002static enum ia_css_err
6003sh_css_pipe_configure_viewfinder(struct ia_css_pipe *pipe, unsigned int width,
6004 unsigned int height, unsigned int min_width,
6005 enum ia_css_frame_format format,
6006 unsigned int idx)
6007{
6008 enum ia_css_err err = IA_CSS_SUCCESS;
6009
6010 IA_CSS_ENTER_PRIVATE("pipe = %p, width = %d, height = %d, min_width = %d, format = %d, idx = %d\n",
6011 pipe, width, height, min_width, format, idx);
6012
6013 if (pipe == NULL) {
6014 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
6015 return IA_CSS_ERR_INVALID_ARGUMENTS;
6016 }
6017
6018
6019 err = ia_css_util_check_res(width, height);
6020 if (err != IA_CSS_SUCCESS) {
6021 IA_CSS_LEAVE_ERR_PRIVATE(err);
6022 return err;
6023 }
6024 if (pipe->vf_output_info[idx].res.width != width ||
6025 pipe->vf_output_info[idx].res.height != height ||
6026 pipe->vf_output_info[idx].format != format) {
6027 ia_css_frame_info_init(&pipe->vf_output_info[idx], width, height,
6028 format, min_width);
6029 }
6030 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
6031 return IA_CSS_SUCCESS;
6032}
6033
6034static enum ia_css_err load_copy_binaries(struct ia_css_pipe *pipe)
6035{
6036 enum ia_css_err err = IA_CSS_SUCCESS;
6037
6038 assert(pipe != NULL);
6039 IA_CSS_ENTER_PRIVATE("");
6040
6041 assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE || pipe->mode == IA_CSS_PIPE_ID_COPY);
6042 if (pipe->pipe_settings.capture.copy_binary.info)
6043 return IA_CSS_SUCCESS;
6044
6045 err = ia_css_frame_check_info(&pipe->output_info[0]);
6046 if (err != IA_CSS_SUCCESS)
6047 goto ERR;
6048
6049 err = verify_copy_out_frame_format(pipe);
6050 if (err != IA_CSS_SUCCESS)
6051 goto ERR;
6052
6053 err = load_copy_binary(pipe,
6054 &pipe->pipe_settings.capture.copy_binary,
6055 NULL);
6056
6057ERR:
6058 IA_CSS_LEAVE_ERR_PRIVATE(err);
6059 return err;
6060}
6061
6062static bool need_capture_pp(
6063 const struct ia_css_pipe *pipe)
6064{
6065 const struct ia_css_frame_info *out_info = &pipe->output_info[0];
6066 IA_CSS_ENTER_LEAVE_PRIVATE("");
6067 assert(pipe != NULL);
6068 assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE);
6069#ifdef ISP2401
6070
6071
6072 if (need_capt_ldc(pipe) == true)
6073 return false;
6074#endif
6075
6076
6077
6078
6079
6080
6081 if (pipe->out_yuv_ds_input_info.res.width &&
6082 ((pipe->out_yuv_ds_input_info.res.width != out_info->res.width) ||
6083 (pipe->out_yuv_ds_input_info.res.height != out_info->res.height)))
6084 return true;
6085
6086 if (pipe->config.default_capture_config.enable_xnr != 0)
6087 return true;
6088
6089 if ((pipe->stream->isp_params_configs->dz_config.dx < HRT_GDC_N) ||
6090 (pipe->stream->isp_params_configs->dz_config.dy < HRT_GDC_N) ||
6091 pipe->config.enable_dz)
6092 return true;
6093
6094 return false;
6095}
6096
6097static bool need_capt_ldc(
6098 const struct ia_css_pipe *pipe)
6099{
6100 IA_CSS_ENTER_LEAVE_PRIVATE("");
6101 assert(pipe != NULL);
6102 assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE);
6103 return (pipe->extra_config.enable_dvs_6axis) ? true:false;
6104}
6105
6106static enum ia_css_err set_num_primary_stages(unsigned int *num, enum ia_css_pipe_version version)
6107{
6108 enum ia_css_err err = IA_CSS_SUCCESS;
6109
6110 if (num == NULL)
6111 return IA_CSS_ERR_INVALID_ARGUMENTS;
6112
6113 switch (version) {
6114 case IA_CSS_PIPE_VERSION_2_6_1:
6115 *num = NUM_PRIMARY_HQ_STAGES;
6116 break;
6117 case IA_CSS_PIPE_VERSION_2_2:
6118 case IA_CSS_PIPE_VERSION_1:
6119 *num = NUM_PRIMARY_STAGES;
6120 break;
6121 default:
6122 err = IA_CSS_ERR_INVALID_ARGUMENTS;
6123 break;
6124 }
6125
6126 return err;
6127}
6128
6129static enum ia_css_err load_primary_binaries(
6130 struct ia_css_pipe *pipe)
6131{
6132 bool online = false;
6133 bool memory = false;
6134 bool continuous = false;
6135 bool need_pp = false;
6136 bool need_isp_copy_binary = false;
6137 bool need_ldc = false;
6138#ifdef USE_INPUT_SYSTEM_VERSION_2401
6139 bool sensor = false;
6140#endif
6141 struct ia_css_frame_info prim_in_info,
6142 prim_out_info,
6143 capt_pp_out_info, vf_info,
6144 *vf_pp_in_info, *pipe_out_info,
6145#ifndef ISP2401
6146 *pipe_vf_out_info, *capt_pp_in_info,
6147 capt_ldc_out_info;
6148#else
6149 *pipe_vf_out_info;
6150#endif
6151 enum ia_css_err err = IA_CSS_SUCCESS;
6152 struct ia_css_capture_settings *mycs;
6153 unsigned int i;
6154 bool need_extra_yuv_scaler = false;
6155
6156 IA_CSS_ENTER_PRIVATE("");
6157 assert(pipe != NULL);
6158 assert(pipe->stream != NULL);
6159 assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE || pipe->mode == IA_CSS_PIPE_ID_COPY);
6160
6161 online = pipe->stream->config.online;
6162 memory = pipe->stream->config.mode == IA_CSS_INPUT_MODE_MEMORY;
6163 continuous = pipe->stream->config.continuous;
6164#ifdef USE_INPUT_SYSTEM_VERSION_2401
6165 sensor = (pipe->stream->config.mode == IA_CSS_INPUT_MODE_SENSOR);
6166#endif
6167
6168 mycs = &pipe->pipe_settings.capture;
6169 pipe_out_info = &pipe->output_info[0];
6170 pipe_vf_out_info = &pipe->vf_output_info[0];
6171
6172 if (mycs->primary_binary[0].info)
6173 return IA_CSS_SUCCESS;
6174
6175 err = set_num_primary_stages(&mycs->num_primary_stage, pipe->config.isp_pipe_version);
6176 if (err != IA_CSS_SUCCESS) {
6177 IA_CSS_LEAVE_ERR_PRIVATE(err);
6178 return err;
6179 }
6180
6181 if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0]) {
6182 err = ia_css_util_check_vf_out_info(pipe_out_info, pipe_vf_out_info);
6183 if (err != IA_CSS_SUCCESS) {
6184 IA_CSS_LEAVE_ERR_PRIVATE(err);
6185 return err;
6186 }
6187 }
6188 else{
6189 err = ia_css_frame_check_info(pipe_out_info);
6190 if (err != IA_CSS_SUCCESS) {
6191 IA_CSS_LEAVE_ERR_PRIVATE(err);
6192 return err;
6193 }
6194 }
6195 need_pp = need_capture_pp(pipe);
6196
6197
6198
6199
6200 vf_info = *pipe_vf_out_info;
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212 ia_css_frame_info_set_format(&vf_info, IA_CSS_FRAME_FORMAT_YUV_LINE);
6213
6214
6215
6216
6217
6218 capt_pp_out_info = pipe->out_yuv_ds_input_info;
6219 capt_pp_out_info.format = IA_CSS_FRAME_FORMAT_YUV420;
6220 capt_pp_out_info.res.width /= MAX_PREFERRED_YUV_DS_PER_STEP;
6221 capt_pp_out_info.res.height /= MAX_PREFERRED_YUV_DS_PER_STEP;
6222 ia_css_frame_info_set_width(&capt_pp_out_info, capt_pp_out_info.res.width, 0);
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234 need_extra_yuv_scaler = need_downscaling(capt_pp_out_info.res,
6235 pipe_out_info->res);
6236
6237 if (need_extra_yuv_scaler) {
6238 struct ia_css_cas_binary_descr cas_scaler_descr = { };
6239
6240 err = ia_css_pipe_create_cas_scaler_desc_single_output(
6241 &capt_pp_out_info,
6242 pipe_out_info,
6243 NULL,
6244 &cas_scaler_descr);
6245 if (err != IA_CSS_SUCCESS) {
6246 IA_CSS_LEAVE_ERR_PRIVATE(err);
6247 return err;
6248 }
6249 mycs->num_yuv_scaler = cas_scaler_descr.num_stage;
6250 mycs->yuv_scaler_binary = kzalloc(cas_scaler_descr.num_stage *
6251 sizeof(struct ia_css_binary), GFP_KERNEL);
6252 if (!mycs->yuv_scaler_binary) {
6253 err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
6254 IA_CSS_LEAVE_ERR_PRIVATE(err);
6255 return err;
6256 }
6257 mycs->is_output_stage = kzalloc(cas_scaler_descr.num_stage *
6258 sizeof(bool), GFP_KERNEL);
6259 if (!mycs->is_output_stage) {
6260 err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
6261 IA_CSS_LEAVE_ERR_PRIVATE(err);
6262 return err;
6263 }
6264 for (i = 0; i < cas_scaler_descr.num_stage; i++) {
6265 struct ia_css_binary_descr yuv_scaler_descr;
6266 mycs->is_output_stage[i] = cas_scaler_descr.is_output_stage[i];
6267 ia_css_pipe_get_yuvscaler_binarydesc(pipe,
6268 &yuv_scaler_descr, &cas_scaler_descr.in_info[i],
6269 &cas_scaler_descr.out_info[i],
6270 &cas_scaler_descr.internal_out_info[i],
6271 &cas_scaler_descr.vf_info[i]);
6272 err = ia_css_binary_find(&yuv_scaler_descr,
6273 &mycs->yuv_scaler_binary[i]);
6274 if (err != IA_CSS_SUCCESS) {
6275 IA_CSS_LEAVE_ERR_PRIVATE(err);
6276 return err;
6277 }
6278 }
6279 ia_css_pipe_destroy_cas_scaler_desc(&cas_scaler_descr);
6280
6281 } else {
6282 capt_pp_out_info = pipe->output_info[0];
6283 }
6284
6285
6286 need_ldc = need_capt_ldc(pipe);
6287#ifdef ISP2401
6288
6289 if (need_ldc) {
6290 struct ia_css_binary_descr capt_ldc_descr;
6291 ia_css_pipe_get_ldc_binarydesc(pipe,
6292 &capt_ldc_descr, &prim_out_info,
6293 &capt_pp_out_info);
6294#endif
6295
6296#ifdef ISP2401
6297 err = ia_css_binary_find(&capt_ldc_descr,
6298 &mycs->capture_ldc_binary);
6299 if (err != IA_CSS_SUCCESS) {
6300 IA_CSS_LEAVE_ERR_PRIVATE(err);
6301 return err;
6302 }
6303 } else if (need_pp) {
6304#endif
6305
6306
6307#ifndef ISP2401
6308 if (need_pp) {
6309#endif
6310 struct ia_css_binary_descr capture_pp_descr;
6311#ifndef ISP2401
6312 capt_pp_in_info = need_ldc ? &capt_ldc_out_info : &prim_out_info;
6313#endif
6314
6315 ia_css_pipe_get_capturepp_binarydesc(pipe,
6316#ifndef ISP2401
6317 &capture_pp_descr, capt_pp_in_info,
6318#else
6319 &capture_pp_descr, &prim_out_info,
6320#endif
6321 &capt_pp_out_info, &vf_info);
6322 err = ia_css_binary_find(&capture_pp_descr,
6323 &mycs->capture_pp_binary);
6324 if (err != IA_CSS_SUCCESS) {
6325 IA_CSS_LEAVE_ERR_PRIVATE(err);
6326 return err;
6327 }
6328#ifndef ISP2401
6329
6330 if(need_ldc) {
6331 struct ia_css_binary_descr capt_ldc_descr;
6332 ia_css_pipe_get_ldc_binarydesc(pipe,
6333 &capt_ldc_descr, &prim_out_info,
6334 &capt_ldc_out_info);
6335
6336 err = ia_css_binary_find(&capt_ldc_descr,
6337 &mycs->capture_ldc_binary);
6338 if (err != IA_CSS_SUCCESS) {
6339 IA_CSS_LEAVE_ERR_PRIVATE(err);
6340 return err;
6341 }
6342 }
6343#endif
6344 } else {
6345 prim_out_info = *pipe_out_info;
6346 }
6347
6348
6349 {
6350 struct ia_css_binary_descr prim_descr[MAX_NUM_PRIMARY_STAGES];
6351
6352 for (i = 0; i < mycs->num_primary_stage; i++) {
6353 struct ia_css_frame_info *local_vf_info = NULL;
6354 if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0] && (i == mycs->num_primary_stage - 1))
6355 local_vf_info = &vf_info;
6356 ia_css_pipe_get_primary_binarydesc(pipe, &prim_descr[i], &prim_in_info, &prim_out_info, local_vf_info, i);
6357 err = ia_css_binary_find(&prim_descr[i], &mycs->primary_binary[i]);
6358 if (err != IA_CSS_SUCCESS) {
6359 IA_CSS_LEAVE_ERR_PRIVATE(err);
6360 return err;
6361 }
6362 }
6363 }
6364
6365
6366 if (need_pp) {
6367 vf_pp_in_info =
6368 &mycs->capture_pp_binary.vf_frame_info;
6369 } else {
6370 vf_pp_in_info =
6371 &mycs->primary_binary[mycs->num_primary_stage - 1].vf_frame_info;
6372 }
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384 if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0])
6385 {
6386 struct ia_css_binary_descr vf_pp_descr;
6387
6388 ia_css_pipe_get_vfpp_binarydesc(pipe,
6389 &vf_pp_descr, vf_pp_in_info, pipe_vf_out_info);
6390 err = ia_css_binary_find(&vf_pp_descr, &mycs->vf_pp_binary);
6391 if (err != IA_CSS_SUCCESS) {
6392 IA_CSS_LEAVE_ERR_PRIVATE(err);
6393 return err;
6394 }
6395 }
6396 err = allocate_delay_frames(pipe);
6397
6398 if (err != IA_CSS_SUCCESS)
6399 return err;
6400
6401#ifdef USE_INPUT_SYSTEM_VERSION_2401
6402
6403
6404
6405 need_isp_copy_binary = !online && sensor;
6406#else
6407 need_isp_copy_binary = !online && !continuous && !memory;
6408#endif
6409
6410
6411 if (need_isp_copy_binary) {
6412 err = load_copy_binary(pipe,
6413 &mycs->copy_binary,
6414 &mycs->primary_binary[0]);
6415 if (err != IA_CSS_SUCCESS) {
6416 IA_CSS_LEAVE_ERR_PRIVATE(err);
6417 return err;
6418 }
6419 }
6420
6421 return IA_CSS_SUCCESS;
6422}
6423
6424static enum ia_css_err
6425allocate_delay_frames(struct ia_css_pipe *pipe)
6426{
6427 unsigned int num_delay_frames = 0, i = 0;
6428 unsigned int dvs_frame_delay = 0;
6429 struct ia_css_frame_info ref_info;
6430 enum ia_css_err err = IA_CSS_SUCCESS;
6431 enum ia_css_pipe_id mode = IA_CSS_PIPE_ID_VIDEO;
6432 struct ia_css_frame **delay_frames = NULL;
6433
6434 IA_CSS_ENTER_PRIVATE("");
6435
6436 if (pipe == NULL) {
6437 IA_CSS_ERROR("Invalid args - pipe %p", pipe);
6438 return IA_CSS_ERR_INVALID_ARGUMENTS;
6439 }
6440
6441 mode = pipe->mode;
6442 dvs_frame_delay = pipe->dvs_frame_delay;
6443
6444 if (dvs_frame_delay > 0)
6445 num_delay_frames = dvs_frame_delay + 1;
6446
6447 switch (mode) {
6448 case IA_CSS_PIPE_ID_CAPTURE:
6449 {
6450 struct ia_css_capture_settings *mycs_capture = &pipe->pipe_settings.capture;
6451 (void)mycs_capture;
6452 return err;
6453 }
6454 break;
6455 case IA_CSS_PIPE_ID_VIDEO:
6456 {
6457 struct ia_css_video_settings *mycs_video = &pipe->pipe_settings.video;
6458 ref_info = mycs_video->video_binary.internal_frame_info;
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470 ref_info.format = IA_CSS_FRAME_FORMAT_NV12;
6471 delay_frames = mycs_video->delay_frames;
6472 }
6473 break;
6474 case IA_CSS_PIPE_ID_PREVIEW:
6475 {
6476 struct ia_css_preview_settings *mycs_preview = &pipe->pipe_settings.preview;
6477 ref_info = mycs_preview->preview_binary.internal_frame_info;
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489 ref_info.format = IA_CSS_FRAME_FORMAT_NV12;
6490 delay_frames = mycs_preview->delay_frames;
6491 }
6492 break;
6493 default:
6494 return IA_CSS_ERR_INVALID_ARGUMENTS;
6495
6496 }
6497
6498 ref_info.raw_bit_depth = SH_CSS_REF_BIT_DEPTH;
6499
6500 assert(num_delay_frames <= MAX_NUM_VIDEO_DELAY_FRAMES);
6501 for (i = 0; i < num_delay_frames; i++) {
6502 err = ia_css_frame_allocate_from_info(&delay_frames[i], &ref_info);
6503 if (err != IA_CSS_SUCCESS)
6504 return err;
6505 }
6506 IA_CSS_LEAVE_PRIVATE("");
6507 return IA_CSS_SUCCESS;
6508}
6509
6510static enum ia_css_err load_advanced_binaries(
6511 struct ia_css_pipe *pipe)
6512{
6513 struct ia_css_frame_info pre_in_info, gdc_in_info,
6514 post_in_info, post_out_info,
6515 vf_info, *vf_pp_in_info, *pipe_out_info,
6516 *pipe_vf_out_info;
6517 bool need_pp;
6518 bool need_isp_copy = true;
6519 enum ia_css_err err = IA_CSS_SUCCESS;
6520
6521 IA_CSS_ENTER_PRIVATE("");
6522
6523 assert(pipe != NULL);
6524 assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE || pipe->mode == IA_CSS_PIPE_ID_COPY);
6525 if (pipe->pipe_settings.capture.pre_isp_binary.info)
6526 return IA_CSS_SUCCESS;
6527 pipe_out_info = &pipe->output_info[0];
6528 pipe_vf_out_info = &pipe->vf_output_info[0];
6529
6530 vf_info = *pipe_vf_out_info;
6531 err = ia_css_util_check_vf_out_info(pipe_out_info, &vf_info);
6532 if (err != IA_CSS_SUCCESS)
6533 return err;
6534 need_pp = need_capture_pp(pipe);
6535
6536 ia_css_frame_info_set_format(&vf_info,
6537 IA_CSS_FRAME_FORMAT_YUV_LINE);
6538
6539
6540
6541 if (need_pp) {
6542 struct ia_css_binary_descr capture_pp_descr;
6543
6544 ia_css_pipe_get_capturepp_binarydesc(pipe,
6545 &capture_pp_descr, &post_out_info, pipe_out_info, &vf_info);
6546 err = ia_css_binary_find(&capture_pp_descr,
6547 &pipe->pipe_settings.capture.capture_pp_binary);
6548 if (err != IA_CSS_SUCCESS)
6549 return err;
6550 } else {
6551 post_out_info = *pipe_out_info;
6552 }
6553
6554
6555 {
6556 struct ia_css_binary_descr post_gdc_descr;
6557
6558 ia_css_pipe_get_post_gdc_binarydesc(pipe,
6559 &post_gdc_descr, &post_in_info, &post_out_info, &vf_info);
6560 err = ia_css_binary_find(&post_gdc_descr,
6561 &pipe->pipe_settings.capture.post_isp_binary);
6562 if (err != IA_CSS_SUCCESS)
6563 return err;
6564 }
6565
6566
6567 {
6568 struct ia_css_binary_descr gdc_descr;
6569
6570 ia_css_pipe_get_gdc_binarydesc(pipe, &gdc_descr, &gdc_in_info,
6571 &pipe->pipe_settings.capture.post_isp_binary.in_frame_info);
6572 err = ia_css_binary_find(&gdc_descr,
6573 &pipe->pipe_settings.capture.anr_gdc_binary);
6574 if (err != IA_CSS_SUCCESS)
6575 return err;
6576 }
6577 pipe->pipe_settings.capture.anr_gdc_binary.left_padding =
6578 pipe->pipe_settings.capture.post_isp_binary.left_padding;
6579
6580
6581 {
6582 struct ia_css_binary_descr pre_gdc_descr;
6583
6584 ia_css_pipe_get_pre_gdc_binarydesc(pipe, &pre_gdc_descr, &pre_in_info,
6585 &pipe->pipe_settings.capture.anr_gdc_binary.in_frame_info);
6586 err = ia_css_binary_find(&pre_gdc_descr,
6587 &pipe->pipe_settings.capture.pre_isp_binary);
6588 if (err != IA_CSS_SUCCESS)
6589 return err;
6590 }
6591 pipe->pipe_settings.capture.pre_isp_binary.left_padding =
6592 pipe->pipe_settings.capture.anr_gdc_binary.left_padding;
6593
6594
6595 if (need_pp) {
6596 vf_pp_in_info =
6597 &pipe->pipe_settings.capture.capture_pp_binary.vf_frame_info;
6598 } else {
6599 vf_pp_in_info =
6600 &pipe->pipe_settings.capture.post_isp_binary.vf_frame_info;
6601 }
6602
6603 {
6604 struct ia_css_binary_descr vf_pp_descr;
6605
6606 ia_css_pipe_get_vfpp_binarydesc(pipe,
6607 &vf_pp_descr, vf_pp_in_info, pipe_vf_out_info);
6608 err = ia_css_binary_find(&vf_pp_descr,
6609 &pipe->pipe_settings.capture.vf_pp_binary);
6610 if (err != IA_CSS_SUCCESS)
6611 return err;
6612 }
6613
6614
6615#ifdef USE_INPUT_SYSTEM_VERSION_2401
6616
6617 need_isp_copy = pipe->stream->config.mode == IA_CSS_INPUT_MODE_SENSOR;
6618#endif
6619 if (need_isp_copy)
6620 load_copy_binary(pipe,
6621 &pipe->pipe_settings.capture.copy_binary,
6622 &pipe->pipe_settings.capture.pre_isp_binary);
6623
6624 return err;
6625}
6626
6627static enum ia_css_err load_bayer_isp_binaries(
6628 struct ia_css_pipe *pipe)
6629{
6630 struct ia_css_frame_info pre_isp_in_info, *pipe_out_info;
6631 enum ia_css_err err = IA_CSS_SUCCESS;
6632 struct ia_css_binary_descr pre_de_descr;
6633
6634 IA_CSS_ENTER_PRIVATE("");
6635 assert(pipe != NULL);
6636 assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE || pipe->mode == IA_CSS_PIPE_ID_COPY);
6637 pipe_out_info = &pipe->output_info[0];
6638
6639 if (pipe->pipe_settings.capture.pre_isp_binary.info)
6640 return IA_CSS_SUCCESS;
6641
6642 err = ia_css_frame_check_info(pipe_out_info);
6643 if (err != IA_CSS_SUCCESS)
6644 return err;
6645
6646 ia_css_pipe_get_pre_de_binarydesc(pipe, &pre_de_descr,
6647 &pre_isp_in_info,
6648 pipe_out_info);
6649
6650 err = ia_css_binary_find(&pre_de_descr,
6651 &pipe->pipe_settings.capture.pre_isp_binary);
6652
6653 return err;
6654}
6655
6656static enum ia_css_err load_low_light_binaries(
6657 struct ia_css_pipe *pipe)
6658{
6659 struct ia_css_frame_info pre_in_info, anr_in_info,
6660 post_in_info, post_out_info,
6661 vf_info, *pipe_vf_out_info, *pipe_out_info,
6662 *vf_pp_in_info;
6663 bool need_pp;
6664 bool need_isp_copy = true;
6665 enum ia_css_err err = IA_CSS_SUCCESS;
6666
6667 IA_CSS_ENTER_PRIVATE("");
6668 assert(pipe != NULL);
6669 assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE || pipe->mode == IA_CSS_PIPE_ID_COPY);
6670
6671 if (pipe->pipe_settings.capture.pre_isp_binary.info)
6672 return IA_CSS_SUCCESS;
6673 pipe_vf_out_info = &pipe->vf_output_info[0];
6674 pipe_out_info = &pipe->output_info[0];
6675
6676 vf_info = *pipe_vf_out_info;
6677 err = ia_css_util_check_vf_out_info(pipe_out_info,
6678 &vf_info);
6679 if (err != IA_CSS_SUCCESS)
6680 return err;
6681 need_pp = need_capture_pp(pipe);
6682
6683 ia_css_frame_info_set_format(&vf_info,
6684 IA_CSS_FRAME_FORMAT_YUV_LINE);
6685
6686
6687
6688 if (need_pp) {
6689 struct ia_css_binary_descr capture_pp_descr;
6690
6691 ia_css_pipe_get_capturepp_binarydesc(pipe,
6692 &capture_pp_descr, &post_out_info, pipe_out_info, &vf_info);
6693 err = ia_css_binary_find(&capture_pp_descr,
6694 &pipe->pipe_settings.capture.capture_pp_binary);
6695 if (err != IA_CSS_SUCCESS)
6696 return err;
6697 } else {
6698 post_out_info = *pipe_out_info;
6699 }
6700
6701
6702 {
6703 struct ia_css_binary_descr post_anr_descr;
6704
6705 ia_css_pipe_get_post_anr_binarydesc(pipe,
6706 &post_anr_descr, &post_in_info, &post_out_info, &vf_info);
6707 err = ia_css_binary_find(&post_anr_descr,
6708 &pipe->pipe_settings.capture.post_isp_binary);
6709 if (err != IA_CSS_SUCCESS)
6710 return err;
6711 }
6712
6713
6714 {
6715 struct ia_css_binary_descr anr_descr;
6716
6717 ia_css_pipe_get_anr_binarydesc(pipe, &anr_descr, &anr_in_info,
6718 &pipe->pipe_settings.capture.post_isp_binary.in_frame_info);
6719 err = ia_css_binary_find(&anr_descr,
6720 &pipe->pipe_settings.capture.anr_gdc_binary);
6721 if (err != IA_CSS_SUCCESS)
6722 return err;
6723 }
6724 pipe->pipe_settings.capture.anr_gdc_binary.left_padding =
6725 pipe->pipe_settings.capture.post_isp_binary.left_padding;
6726
6727
6728 {
6729 struct ia_css_binary_descr pre_anr_descr;
6730
6731 ia_css_pipe_get_pre_anr_binarydesc(pipe, &pre_anr_descr, &pre_in_info,
6732 &pipe->pipe_settings.capture.anr_gdc_binary.in_frame_info);
6733 err = ia_css_binary_find(&pre_anr_descr,
6734 &pipe->pipe_settings.capture.pre_isp_binary);
6735 if (err != IA_CSS_SUCCESS)
6736 return err;
6737 }
6738 pipe->pipe_settings.capture.pre_isp_binary.left_padding =
6739 pipe->pipe_settings.capture.anr_gdc_binary.left_padding;
6740
6741
6742 if (need_pp) {
6743 vf_pp_in_info =
6744 &pipe->pipe_settings.capture.capture_pp_binary.vf_frame_info;
6745 } else {
6746 vf_pp_in_info =
6747 &pipe->pipe_settings.capture.post_isp_binary.vf_frame_info;
6748 }
6749
6750 {
6751 struct ia_css_binary_descr vf_pp_descr;
6752
6753 ia_css_pipe_get_vfpp_binarydesc(pipe,
6754 &vf_pp_descr, vf_pp_in_info, pipe_vf_out_info);
6755 err = ia_css_binary_find(&vf_pp_descr,
6756 &pipe->pipe_settings.capture.vf_pp_binary);
6757 if (err != IA_CSS_SUCCESS)
6758 return err;
6759 }
6760
6761
6762#ifdef USE_INPUT_SYSTEM_VERSION_2401
6763
6764 need_isp_copy = pipe->stream->config.mode == IA_CSS_INPUT_MODE_SENSOR;
6765#endif
6766 if (need_isp_copy)
6767 err = load_copy_binary(pipe,
6768 &pipe->pipe_settings.capture.copy_binary,
6769 &pipe->pipe_settings.capture.pre_isp_binary);
6770
6771 return err;
6772}
6773
6774static bool copy_on_sp(struct ia_css_pipe *pipe)
6775{
6776 bool rval;
6777
6778 assert(pipe != NULL);
6779 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "copy_on_sp() enter:\n");
6780
6781 rval = true;
6782
6783 rval &= (pipe->mode == IA_CSS_PIPE_ID_CAPTURE);
6784
6785 rval &= (pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_RAW);
6786
6787 rval &= ((pipe->stream->config.input_config.format == ATOMISP_INPUT_FORMAT_BINARY_8) ||
6788 (pipe->config.mode == IA_CSS_PIPE_MODE_COPY));
6789
6790 return rval;
6791}
6792
6793static enum ia_css_err load_capture_binaries(
6794 struct ia_css_pipe *pipe)
6795{
6796 enum ia_css_err err = IA_CSS_SUCCESS;
6797 bool must_be_raw;
6798
6799 IA_CSS_ENTER_PRIVATE("");
6800 assert(pipe != NULL);
6801 assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE || pipe->mode == IA_CSS_PIPE_ID_COPY);
6802
6803 if (pipe->pipe_settings.capture.primary_binary[0].info) {
6804 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
6805 return IA_CSS_SUCCESS;
6806 }
6807
6808
6809
6810 must_be_raw =
6811 pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_ADVANCED ||
6812 pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_BAYER ||
6813 pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_LOW_LIGHT;
6814 err = ia_css_util_check_input(&pipe->stream->config, must_be_raw, false);
6815 if (err != IA_CSS_SUCCESS) {
6816 IA_CSS_LEAVE_ERR_PRIVATE(err);
6817 return err;
6818 }
6819 if (copy_on_sp(pipe) &&
6820 pipe->stream->config.input_config.format == ATOMISP_INPUT_FORMAT_BINARY_8) {
6821 ia_css_frame_info_init(
6822 &pipe->output_info[0],
6823 JPEG_BYTES,
6824 1,
6825 IA_CSS_FRAME_FORMAT_BINARY_8,
6826 0);
6827 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
6828 return IA_CSS_SUCCESS;
6829 }
6830
6831 switch (pipe->config.default_capture_config.mode) {
6832 case IA_CSS_CAPTURE_MODE_RAW:
6833 err = load_copy_binaries(pipe);
6834#if !defined(HAS_NO_INPUT_SYSTEM) && defined(USE_INPUT_SYSTEM_VERSION_2401)
6835 if (err == IA_CSS_SUCCESS)
6836 pipe->pipe_settings.capture.copy_binary.online = pipe->stream->config.online;
6837#endif
6838 break;
6839 case IA_CSS_CAPTURE_MODE_BAYER:
6840 err = load_bayer_isp_binaries(pipe);
6841 break;
6842 case IA_CSS_CAPTURE_MODE_PRIMARY:
6843 err = load_primary_binaries(pipe);
6844 break;
6845 case IA_CSS_CAPTURE_MODE_ADVANCED:
6846 err = load_advanced_binaries(pipe);
6847 break;
6848 case IA_CSS_CAPTURE_MODE_LOW_LIGHT:
6849 err = load_low_light_binaries(pipe);
6850 break;
6851 }
6852 if (err != IA_CSS_SUCCESS) {
6853 IA_CSS_LEAVE_ERR_PRIVATE(err);
6854 return err;
6855 }
6856
6857 IA_CSS_LEAVE_ERR_PRIVATE(err);
6858 return err;
6859}
6860
6861static enum ia_css_err
6862unload_capture_binaries(struct ia_css_pipe *pipe)
6863{
6864 unsigned int i;
6865 IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
6866
6867 if ((pipe == NULL) || ((pipe->mode != IA_CSS_PIPE_ID_CAPTURE) && (pipe->mode != IA_CSS_PIPE_ID_COPY))) {
6868 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
6869 return IA_CSS_ERR_INVALID_ARGUMENTS;
6870 }
6871 ia_css_binary_unload(&pipe->pipe_settings.capture.copy_binary);
6872 for (i = 0; i < MAX_NUM_PRIMARY_STAGES; i++)
6873 ia_css_binary_unload(&pipe->pipe_settings.capture.primary_binary[i]);
6874 ia_css_binary_unload(&pipe->pipe_settings.capture.pre_isp_binary);
6875 ia_css_binary_unload(&pipe->pipe_settings.capture.anr_gdc_binary);
6876 ia_css_binary_unload(&pipe->pipe_settings.capture.post_isp_binary);
6877 ia_css_binary_unload(&pipe->pipe_settings.capture.capture_pp_binary);
6878 ia_css_binary_unload(&pipe->pipe_settings.capture.capture_ldc_binary);
6879 ia_css_binary_unload(&pipe->pipe_settings.capture.vf_pp_binary);
6880
6881 for (i = 0; i < pipe->pipe_settings.capture.num_yuv_scaler; i++)
6882 ia_css_binary_unload(&pipe->pipe_settings.capture.yuv_scaler_binary[i]);
6883
6884 kfree(pipe->pipe_settings.capture.is_output_stage);
6885 pipe->pipe_settings.capture.is_output_stage = NULL;
6886 kfree(pipe->pipe_settings.capture.yuv_scaler_binary);
6887 pipe->pipe_settings.capture.yuv_scaler_binary = NULL;
6888
6889 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
6890 return IA_CSS_SUCCESS;
6891}
6892
6893static bool
6894need_downscaling(const struct ia_css_resolution in_res,
6895 const struct ia_css_resolution out_res)
6896{
6897
6898 if (in_res.width > out_res.width || in_res.height > out_res.height)
6899 return true;
6900
6901 return false;
6902}
6903
6904static bool
6905need_yuv_scaler_stage(const struct ia_css_pipe *pipe)
6906{
6907 unsigned int i;
6908 struct ia_css_resolution in_res, out_res;
6909
6910 bool need_format_conversion = false;
6911
6912 IA_CSS_ENTER_PRIVATE("");
6913 assert(pipe != NULL);
6914 assert(pipe->mode == IA_CSS_PIPE_ID_YUVPP);
6915
6916
6917 need_format_conversion =
6918 ((pipe->stream->config.input_config.format == ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY) &&
6919 (pipe->output_info[0].format != IA_CSS_FRAME_FORMAT_CSI_MIPI_LEGACY_YUV420_8));
6920
6921 in_res = pipe->config.input_effective_res;
6922
6923 if (pipe->config.enable_dz)
6924 return true;
6925
6926 if ((pipe->output_info[0].res.width != 0) && need_format_conversion)
6927 return true;
6928
6929 for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) {
6930 out_res = pipe->output_info[i].res;
6931
6932
6933 if ((out_res.width != 0) && need_downscaling(in_res, out_res))
6934 return true;
6935 }
6936
6937 return false;
6938}
6939
6940
6941
6942
6943static enum ia_css_err ia_css_pipe_create_cas_scaler_desc_single_output(
6944 struct ia_css_frame_info *cas_scaler_in_info,
6945 struct ia_css_frame_info *cas_scaler_out_info,
6946 struct ia_css_frame_info *cas_scaler_vf_info,
6947 struct ia_css_cas_binary_descr *descr)
6948{
6949 unsigned int i;
6950 unsigned int hor_ds_factor = 0, ver_ds_factor = 0;
6951 enum ia_css_err err = IA_CSS_SUCCESS;
6952 struct ia_css_frame_info tmp_in_info;
6953
6954 unsigned max_scale_factor_per_stage = MAX_PREFERRED_YUV_DS_PER_STEP;
6955
6956 assert(cas_scaler_in_info != NULL);
6957 assert(cas_scaler_out_info != NULL);
6958
6959 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_pipe_create_cas_scaler_desc() enter:\n");
6960
6961
6962 descr->num_output_stage = 1;
6963
6964 hor_ds_factor = CEIL_DIV(cas_scaler_in_info->res.width , cas_scaler_out_info->res.width);
6965 ver_ds_factor = CEIL_DIV(cas_scaler_in_info->res.height, cas_scaler_out_info->res.height);
6966
6967 assert(hor_ds_factor == ver_ds_factor);
6968
6969 i = 1;
6970 while (i < hor_ds_factor) {
6971 descr->num_stage++;
6972 i *= max_scale_factor_per_stage;
6973 }
6974
6975 descr->in_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info), GFP_KERNEL);
6976 if (!descr->in_info) {
6977 err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
6978 goto ERR;
6979 }
6980 descr->internal_out_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info), GFP_KERNEL);
6981 if (!descr->internal_out_info) {
6982 err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
6983 goto ERR;
6984 }
6985 descr->out_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info), GFP_KERNEL);
6986 if (!descr->out_info) {
6987 err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
6988 goto ERR;
6989 }
6990 descr->vf_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info), GFP_KERNEL);
6991 if (!descr->vf_info) {
6992 err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
6993 goto ERR;
6994 }
6995 descr->is_output_stage = kmalloc(descr->num_stage * sizeof(bool), GFP_KERNEL);
6996 if (!descr->is_output_stage) {
6997 err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
6998 goto ERR;
6999 }
7000
7001 tmp_in_info = *cas_scaler_in_info;
7002 for (i = 0; i < descr->num_stage; i++) {
7003
7004 descr->in_info[i] = tmp_in_info;
7005 if ((tmp_in_info.res.width / max_scale_factor_per_stage) <= cas_scaler_out_info->res.width) {
7006 descr->is_output_stage[i] = true;
7007 if ((descr->num_output_stage > 1) && (i != (descr->num_stage - 1))) {
7008 descr->internal_out_info[i].res.width = cas_scaler_out_info->res.width;
7009 descr->internal_out_info[i].res.height = cas_scaler_out_info->res.height;
7010 descr->internal_out_info[i].padded_width = cas_scaler_out_info->padded_width;
7011 descr->internal_out_info[i].format = IA_CSS_FRAME_FORMAT_YUV420;
7012 } else {
7013 assert(i == (descr->num_stage - 1));
7014 descr->internal_out_info[i].res.width = 0;
7015 descr->internal_out_info[i].res.height = 0;
7016 }
7017 descr->out_info[i].res.width = cas_scaler_out_info->res.width;
7018 descr->out_info[i].res.height = cas_scaler_out_info->res.height;
7019 descr->out_info[i].padded_width = cas_scaler_out_info->padded_width;
7020 descr->out_info[i].format = cas_scaler_out_info->format;
7021 if (cas_scaler_vf_info != NULL) {
7022 descr->vf_info[i].res.width = cas_scaler_vf_info->res.width;
7023 descr->vf_info[i].res.height = cas_scaler_vf_info->res.height;
7024 descr->vf_info[i].padded_width = cas_scaler_vf_info->padded_width;
7025 ia_css_frame_info_set_format(&descr->vf_info[i], IA_CSS_FRAME_FORMAT_YUV_LINE);
7026 } else {
7027 descr->vf_info[i].res.width = 0;
7028 descr->vf_info[i].res.height = 0;
7029 descr->vf_info[i].padded_width = 0;
7030 }
7031 } else {
7032 descr->is_output_stage[i] = false;
7033 descr->internal_out_info[i].res.width = tmp_in_info.res.width / max_scale_factor_per_stage;
7034 descr->internal_out_info[i].res.height = tmp_in_info.res.height / max_scale_factor_per_stage;
7035 descr->internal_out_info[i].format = IA_CSS_FRAME_FORMAT_YUV420;
7036 ia_css_frame_info_init(&descr->internal_out_info[i],
7037 tmp_in_info.res.width / max_scale_factor_per_stage,
7038 tmp_in_info.res.height / max_scale_factor_per_stage,
7039 IA_CSS_FRAME_FORMAT_YUV420, 0);
7040 descr->out_info[i].res.width = 0;
7041 descr->out_info[i].res.height = 0;
7042 descr->vf_info[i].res.width = 0;
7043 descr->vf_info[i].res.height = 0;
7044 }
7045 tmp_in_info = descr->internal_out_info[i];
7046 }
7047ERR:
7048 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_pipe_create_cas_scaler_desc() leave, err=%d\n",
7049 err);
7050 return err;
7051}
7052
7053
7054static enum ia_css_err ia_css_pipe_create_cas_scaler_desc(struct ia_css_pipe *pipe,
7055 struct ia_css_cas_binary_descr *descr)
7056{
7057 struct ia_css_frame_info in_info = IA_CSS_BINARY_DEFAULT_FRAME_INFO;
7058 struct ia_css_frame_info *out_info[IA_CSS_PIPE_MAX_OUTPUT_STAGE];
7059 struct ia_css_frame_info *vf_out_info[IA_CSS_PIPE_MAX_OUTPUT_STAGE];
7060 struct ia_css_frame_info tmp_in_info = IA_CSS_BINARY_DEFAULT_FRAME_INFO;
7061 unsigned int i, j;
7062 unsigned int hor_scale_factor[IA_CSS_PIPE_MAX_OUTPUT_STAGE],
7063 ver_scale_factor[IA_CSS_PIPE_MAX_OUTPUT_STAGE],
7064 scale_factor = 0;
7065 unsigned int num_stages = 0;
7066 enum ia_css_err err = IA_CSS_SUCCESS;
7067
7068 unsigned max_scale_factor_per_stage = MAX_PREFERRED_YUV_DS_PER_STEP;
7069
7070 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_pipe_create_cas_scaler_desc() enter:\n");
7071
7072 for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) {
7073 out_info[i] = NULL;
7074 vf_out_info[i] = NULL;
7075 hor_scale_factor[i] = 0;
7076 ver_scale_factor[i] = 0;
7077 }
7078
7079 in_info.res = pipe->config.input_effective_res;
7080 in_info.padded_width = in_info.res.width;
7081 descr->num_output_stage = 0;
7082
7083 for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) {
7084 if (pipe->output_info[i].res.width != 0) {
7085 out_info[i] = &pipe->output_info[i];
7086 if (pipe->vf_output_info[i].res.width != 0)
7087 vf_out_info[i] = &pipe->vf_output_info[i];
7088 descr->num_output_stage += 1;
7089 }
7090
7091 if (out_info[i] != NULL) {
7092 hor_scale_factor[i] = CEIL_DIV(in_info.res.width, out_info[i]->res.width);
7093 ver_scale_factor[i] = CEIL_DIV(in_info.res.height, out_info[i]->res.height);
7094
7095 assert(hor_scale_factor[i] == ver_scale_factor[i]);
7096 scale_factor = 1;
7097 do {
7098 num_stages++;
7099 scale_factor *= max_scale_factor_per_stage;
7100 } while (scale_factor < hor_scale_factor[i]);
7101
7102 in_info.res = out_info[i]->res;
7103 }
7104 }
7105
7106 if (need_yuv_scaler_stage(pipe) && (num_stages == 0))
7107 num_stages = 1;
7108
7109 descr->num_stage = num_stages;
7110
7111 descr->in_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info), GFP_KERNEL);
7112 if (!descr->in_info) {
7113 err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
7114 goto ERR;
7115 }
7116 descr->internal_out_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info), GFP_KERNEL);
7117 if (!descr->internal_out_info) {
7118 err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
7119 goto ERR;
7120 }
7121 descr->out_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info), GFP_KERNEL);
7122 if (!descr->out_info) {
7123 err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
7124 goto ERR;
7125 }
7126 descr->vf_info = kmalloc(descr->num_stage * sizeof(struct ia_css_frame_info), GFP_KERNEL);
7127 if (!descr->vf_info) {
7128 err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
7129 goto ERR;
7130 }
7131 descr->is_output_stage = kmalloc(descr->num_stage * sizeof(bool), GFP_KERNEL);
7132 if (descr->is_output_stage == NULL) {
7133 err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
7134 goto ERR;
7135 }
7136
7137 for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) {
7138 if (out_info[i]) {
7139 if (i > 0) {
7140 assert((out_info[i-1]->res.width >= out_info[i]->res.width) &&
7141 (out_info[i-1]->res.height >= out_info[i]->res.height));
7142 }
7143 }
7144 }
7145
7146 tmp_in_info.res = pipe->config.input_effective_res;
7147 tmp_in_info.format = IA_CSS_FRAME_FORMAT_YUV420;
7148 for (i = 0, j = 0; i < descr->num_stage; i++) {
7149 assert(j < 2);
7150 assert(out_info[j] != NULL);
7151
7152 descr->in_info[i] = tmp_in_info;
7153 if ((tmp_in_info.res.width / max_scale_factor_per_stage) <= out_info[j]->res.width) {
7154 descr->is_output_stage[i] = true;
7155 if ((descr->num_output_stage > 1) && (i != (descr->num_stage - 1))) {
7156 descr->internal_out_info[i].res.width = out_info[j]->res.width;
7157 descr->internal_out_info[i].res.height = out_info[j]->res.height;
7158 descr->internal_out_info[i].padded_width = out_info[j]->padded_width;
7159 descr->internal_out_info[i].format = IA_CSS_FRAME_FORMAT_YUV420;
7160 } else {
7161 assert(i == (descr->num_stage - 1));
7162 descr->internal_out_info[i].res.width = 0;
7163 descr->internal_out_info[i].res.height = 0;
7164 }
7165 descr->out_info[i].res.width = out_info[j]->res.width;
7166 descr->out_info[i].res.height = out_info[j]->res.height;
7167 descr->out_info[i].padded_width = out_info[j]->padded_width;
7168 descr->out_info[i].format = out_info[j]->format;
7169 if (vf_out_info[j] != NULL) {
7170 descr->vf_info[i].res.width = vf_out_info[j]->res.width;
7171 descr->vf_info[i].res.height = vf_out_info[j]->res.height;
7172 descr->vf_info[i].padded_width = vf_out_info[j]->padded_width;
7173 ia_css_frame_info_set_format(&descr->vf_info[i], IA_CSS_FRAME_FORMAT_YUV_LINE);
7174 } else {
7175 descr->vf_info[i].res.width = 0;
7176 descr->vf_info[i].res.height = 0;
7177 descr->vf_info[i].padded_width = 0;
7178 }
7179 j++;
7180 } else {
7181 descr->is_output_stage[i] = false;
7182 descr->internal_out_info[i].res.width = tmp_in_info.res.width / max_scale_factor_per_stage;
7183 descr->internal_out_info[i].res.height = tmp_in_info.res.height / max_scale_factor_per_stage;
7184 descr->internal_out_info[i].format = IA_CSS_FRAME_FORMAT_YUV420;
7185 ia_css_frame_info_init(&descr->internal_out_info[i],
7186 tmp_in_info.res.width / max_scale_factor_per_stage,
7187 tmp_in_info.res.height / max_scale_factor_per_stage,
7188 IA_CSS_FRAME_FORMAT_YUV420, 0);
7189 descr->out_info[i].res.width = 0;
7190 descr->out_info[i].res.height = 0;
7191 descr->vf_info[i].res.width = 0;
7192 descr->vf_info[i].res.height = 0;
7193 }
7194 tmp_in_info = descr->internal_out_info[i];
7195 }
7196ERR:
7197 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_pipe_create_cas_scaler_desc() leave, err=%d\n",
7198 err);
7199 return err;
7200}
7201
7202static void ia_css_pipe_destroy_cas_scaler_desc(struct ia_css_cas_binary_descr *descr)
7203{
7204 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_pipe_destroy_cas_scaler_desc() enter:\n");
7205 kfree(descr->in_info);
7206 descr->in_info = NULL;
7207 kfree(descr->internal_out_info);
7208 descr->internal_out_info = NULL;
7209 kfree(descr->out_info);
7210 descr->out_info = NULL;
7211 kfree(descr->vf_info);
7212 descr->vf_info = NULL;
7213 kfree(descr->is_output_stage);
7214 descr->is_output_stage = NULL;
7215 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "ia_css_pipe_destroy_cas_scaler_desc() leave\n");
7216}
7217
7218static enum ia_css_err
7219load_yuvpp_binaries(struct ia_css_pipe *pipe)
7220{
7221 enum ia_css_err err = IA_CSS_SUCCESS;
7222 bool need_scaler = false;
7223 struct ia_css_frame_info *vf_pp_in_info[IA_CSS_PIPE_MAX_OUTPUT_STAGE];
7224 struct ia_css_yuvpp_settings *mycs;
7225 struct ia_css_binary *next_binary;
7226 struct ia_css_cas_binary_descr cas_scaler_descr = { };
7227 unsigned int i, j;
7228 bool need_isp_copy_binary = false;
7229
7230 IA_CSS_ENTER_PRIVATE("");
7231 assert(pipe != NULL);
7232 assert(pipe->stream != NULL);
7233 assert(pipe->mode == IA_CSS_PIPE_ID_YUVPP);
7234
7235 if (pipe->pipe_settings.yuvpp.copy_binary.info)
7236 goto ERR;
7237
7238
7239 err = ia_css_util_check_input(&pipe->stream->config, false, false);
7240 if (err != IA_CSS_SUCCESS)
7241 goto ERR;
7242
7243 mycs = &pipe->pipe_settings.yuvpp;
7244
7245 for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) {
7246 if (pipe->vf_output_info[i].res.width != 0) {
7247 err = ia_css_util_check_vf_out_info(&pipe->output_info[i],
7248 &pipe->vf_output_info[i]);
7249 if (err != IA_CSS_SUCCESS)
7250 goto ERR;
7251 }
7252 vf_pp_in_info[i] = NULL;
7253 }
7254
7255 need_scaler = need_yuv_scaler_stage(pipe);
7256
7257
7258
7259 if (need_scaler) {
7260 struct ia_css_binary_descr yuv_scaler_descr;
7261
7262 err = ia_css_pipe_create_cas_scaler_desc(pipe,
7263 &cas_scaler_descr);
7264 if (err != IA_CSS_SUCCESS)
7265 goto ERR;
7266 mycs->num_output = cas_scaler_descr.num_output_stage;
7267 mycs->num_yuv_scaler = cas_scaler_descr.num_stage;
7268 mycs->yuv_scaler_binary = kzalloc(cas_scaler_descr.num_stage *
7269 sizeof(struct ia_css_binary), GFP_KERNEL);
7270 if (!mycs->yuv_scaler_binary) {
7271 err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
7272 goto ERR;
7273 }
7274 mycs->is_output_stage = kzalloc(cas_scaler_descr.num_stage *
7275 sizeof(bool), GFP_KERNEL);
7276 if (!mycs->is_output_stage) {
7277 err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
7278 goto ERR;
7279 }
7280 for (i = 0; i < cas_scaler_descr.num_stage; i++) {
7281 mycs->is_output_stage[i] = cas_scaler_descr.is_output_stage[i];
7282 ia_css_pipe_get_yuvscaler_binarydesc(pipe,
7283 &yuv_scaler_descr, &cas_scaler_descr.in_info[i],
7284 &cas_scaler_descr.out_info[i],
7285 &cas_scaler_descr.internal_out_info[i],
7286 &cas_scaler_descr.vf_info[i]);
7287 err = ia_css_binary_find(&yuv_scaler_descr,
7288 &mycs->yuv_scaler_binary[i]);
7289 if (err != IA_CSS_SUCCESS)
7290 goto ERR;
7291 }
7292 ia_css_pipe_destroy_cas_scaler_desc(&cas_scaler_descr);
7293 } else {
7294 mycs->num_output = 1;
7295 }
7296
7297 if (need_scaler) {
7298 next_binary = &mycs->yuv_scaler_binary[0];
7299 } else {
7300 next_binary = NULL;
7301 }
7302
7303#if defined(USE_INPUT_SYSTEM_VERSION_2401)
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321 need_isp_copy_binary =
7322 (pipe->stream->config.input_config.format == ATOMISP_INPUT_FORMAT_YUV422_8);
7323#else
7324 need_isp_copy_binary = true;
7325#endif
7326
7327 if (need_isp_copy_binary) {
7328 err = load_copy_binary(pipe,
7329 &mycs->copy_binary,
7330 next_binary);
7331
7332 if (err != IA_CSS_SUCCESS)
7333 goto ERR;
7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353 pipe->pipe_settings.capture.copy_binary.online = pipe->stream->config.online;
7354 }
7355
7356
7357 if (need_scaler) {
7358 for (i = 0, j = 0; i < mycs->num_yuv_scaler; i++) {
7359 if (mycs->is_output_stage[i]) {
7360 assert(j < 2);
7361 vf_pp_in_info[j] =
7362 &mycs->yuv_scaler_binary[i].vf_frame_info;
7363 j++;
7364 }
7365 }
7366 mycs->num_vf_pp = j;
7367 } else {
7368 vf_pp_in_info[0] =
7369 &mycs->copy_binary.vf_frame_info;
7370 for (i = 1; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) {
7371 vf_pp_in_info[i] = NULL;
7372 }
7373 mycs->num_vf_pp = 1;
7374 }
7375 mycs->vf_pp_binary = kzalloc(mycs->num_vf_pp * sizeof(struct ia_css_binary),
7376 GFP_KERNEL);
7377 if (!mycs->vf_pp_binary) {
7378 err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
7379 goto ERR;
7380 }
7381
7382 {
7383 struct ia_css_binary_descr vf_pp_descr;
7384
7385 for (i = 0; i < mycs->num_vf_pp; i++) {
7386 if (pipe->vf_output_info[i].res.width != 0) {
7387 ia_css_pipe_get_vfpp_binarydesc(pipe,
7388 &vf_pp_descr, vf_pp_in_info[i], &pipe->vf_output_info[i]);
7389 err = ia_css_binary_find(&vf_pp_descr, &mycs->vf_pp_binary[i]);
7390 if (err != IA_CSS_SUCCESS)
7391 goto ERR;
7392 }
7393 }
7394 }
7395
7396 if (err != IA_CSS_SUCCESS)
7397 goto ERR;
7398
7399ERR:
7400 if (need_scaler) {
7401 ia_css_pipe_destroy_cas_scaler_desc(&cas_scaler_descr);
7402 }
7403 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "load_yuvpp_binaries() leave, err=%d\n",
7404 err);
7405 return err;
7406}
7407
7408static enum ia_css_err
7409unload_yuvpp_binaries(struct ia_css_pipe *pipe)
7410{
7411 unsigned int i;
7412 IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
7413
7414 if ((pipe == NULL) || (pipe->mode != IA_CSS_PIPE_ID_YUVPP)) {
7415 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
7416 return IA_CSS_ERR_INVALID_ARGUMENTS;
7417 }
7418 ia_css_binary_unload(&pipe->pipe_settings.yuvpp.copy_binary);
7419 for (i = 0; i < pipe->pipe_settings.yuvpp.num_yuv_scaler; i++) {
7420 ia_css_binary_unload(&pipe->pipe_settings.yuvpp.yuv_scaler_binary[i]);
7421 }
7422 for (i = 0; i < pipe->pipe_settings.yuvpp.num_vf_pp; i++) {
7423 ia_css_binary_unload(&pipe->pipe_settings.yuvpp.vf_pp_binary[i]);
7424 }
7425 kfree(pipe->pipe_settings.yuvpp.is_output_stage);
7426 pipe->pipe_settings.yuvpp.is_output_stage = NULL;
7427 kfree(pipe->pipe_settings.yuvpp.yuv_scaler_binary);
7428 pipe->pipe_settings.yuvpp.yuv_scaler_binary = NULL;
7429 kfree(pipe->pipe_settings.yuvpp.vf_pp_binary);
7430 pipe->pipe_settings.yuvpp.vf_pp_binary = NULL;
7431
7432 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
7433 return IA_CSS_SUCCESS;
7434}
7435
7436static enum ia_css_err yuvpp_start(struct ia_css_pipe *pipe)
7437{
7438 struct ia_css_binary *copy_binary;
7439 enum ia_css_err err = IA_CSS_SUCCESS;
7440 enum sh_css_pipe_config_override copy_ovrd;
7441 enum ia_css_input_mode yuvpp_pipe_input_mode;
7442
7443 IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
7444 if ((pipe == NULL) || (pipe->mode != IA_CSS_PIPE_ID_YUVPP)) {
7445 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
7446 return IA_CSS_ERR_INVALID_ARGUMENTS;
7447 }
7448
7449 yuvpp_pipe_input_mode = pipe->stream->config.mode;
7450
7451 copy_binary = &pipe->pipe_settings.yuvpp.copy_binary;
7452
7453 sh_css_metrics_start_frame();
7454
7455
7456
7457#if !defined(HAS_NO_INPUT_SYSTEM) && ( defined(USE_INPUT_SYSTEM_VERSION_2) || defined(USE_INPUT_SYSTEM_VERSION_2401) )
7458 err = send_mipi_frames(pipe);
7459 if (err != IA_CSS_SUCCESS) {
7460 IA_CSS_LEAVE_ERR_PRIVATE(err);
7461 return err;
7462 }
7463#endif
7464
7465 {
7466 unsigned int thread_id;
7467
7468 ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
7469 copy_ovrd = 1 << thread_id;
7470 }
7471
7472 start_pipe(pipe, copy_ovrd, yuvpp_pipe_input_mode);
7473
7474 IA_CSS_LEAVE_ERR_PRIVATE(err);
7475 return err;
7476}
7477
7478static enum ia_css_err
7479sh_css_pipe_unload_binaries(struct ia_css_pipe *pipe)
7480{
7481 enum ia_css_err err = IA_CSS_SUCCESS;
7482 IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
7483
7484 if (pipe == NULL) {
7485 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
7486 return IA_CSS_ERR_INVALID_ARGUMENTS;
7487 }
7488
7489 if (pipe->config.mode == IA_CSS_PIPE_MODE_COPY) {
7490 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
7491 return IA_CSS_SUCCESS;
7492 }
7493
7494 switch (pipe->mode) {
7495 case IA_CSS_PIPE_ID_PREVIEW:
7496 err = unload_preview_binaries(pipe);
7497 break;
7498 case IA_CSS_PIPE_ID_VIDEO:
7499 err = unload_video_binaries(pipe);
7500 break;
7501 case IA_CSS_PIPE_ID_CAPTURE:
7502 err = unload_capture_binaries(pipe);
7503 break;
7504 case IA_CSS_PIPE_ID_YUVPP:
7505 err = unload_yuvpp_binaries(pipe);
7506 break;
7507 default:
7508 break;
7509 }
7510 IA_CSS_LEAVE_ERR_PRIVATE(err);
7511 return err;
7512}
7513
7514static enum ia_css_err
7515sh_css_pipe_load_binaries(struct ia_css_pipe *pipe)
7516{
7517 enum ia_css_err err = IA_CSS_SUCCESS;
7518
7519 assert(pipe != NULL);
7520 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "sh_css_pipe_load_binaries() enter:\n");
7521
7522
7523 if (pipe->config.mode == IA_CSS_PIPE_MODE_COPY)
7524 return err;
7525
7526 switch (pipe->mode) {
7527 case IA_CSS_PIPE_ID_PREVIEW:
7528 err = load_preview_binaries(pipe);
7529 break;
7530 case IA_CSS_PIPE_ID_VIDEO:
7531 err = load_video_binaries(pipe);
7532 break;
7533 case IA_CSS_PIPE_ID_CAPTURE:
7534 err = load_capture_binaries(pipe);
7535 break;
7536 case IA_CSS_PIPE_ID_YUVPP:
7537 err = load_yuvpp_binaries(pipe);
7538 break;
7539 case IA_CSS_PIPE_ID_ACC:
7540 break;
7541 default:
7542 err = IA_CSS_ERR_INTERNAL_ERROR;
7543 break;
7544 }
7545 if (err != IA_CSS_SUCCESS) {
7546 if (sh_css_pipe_unload_binaries(pipe) != IA_CSS_SUCCESS) {
7547
7548
7549 err = IA_CSS_ERR_INTERNAL_ERROR;
7550 }
7551 }
7552 return err;
7553}
7554
7555static enum ia_css_err
7556create_host_yuvpp_pipeline(struct ia_css_pipe *pipe)
7557{
7558 struct ia_css_pipeline *me;
7559 enum ia_css_err err = IA_CSS_SUCCESS;
7560 struct ia_css_pipeline_stage *vf_pp_stage = NULL,
7561 *copy_stage = NULL,
7562 *yuv_scaler_stage = NULL;
7563 struct ia_css_binary *copy_binary,
7564 *vf_pp_binary,
7565 *yuv_scaler_binary;
7566 bool need_scaler = false;
7567 unsigned int num_stage, num_vf_pp_stage, num_output_stage;
7568 unsigned int i, j;
7569
7570 struct ia_css_frame *in_frame = NULL;
7571 struct ia_css_frame *out_frame[IA_CSS_PIPE_MAX_OUTPUT_STAGE];
7572 struct ia_css_frame *bin_out_frame[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
7573 struct ia_css_frame *vf_frame[IA_CSS_PIPE_MAX_OUTPUT_STAGE];
7574 struct ia_css_pipeline_stage_desc stage_desc;
7575 bool need_in_frameinfo_memory = false;
7576#ifdef USE_INPUT_SYSTEM_VERSION_2401
7577 bool sensor = false;
7578 bool buffered_sensor = false;
7579 bool online = false;
7580 bool continuous = false;
7581#endif
7582
7583 IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
7584 if ((pipe == NULL) || (pipe->stream == NULL) || (pipe->mode != IA_CSS_PIPE_ID_YUVPP)) {
7585 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
7586 return IA_CSS_ERR_INVALID_ARGUMENTS;
7587 }
7588 me = &pipe->pipeline;
7589 ia_css_pipeline_clean(me);
7590 for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) {
7591 out_frame[i] = NULL;
7592 vf_frame[i] = NULL;
7593 }
7594 ia_css_pipe_util_create_output_frames(bin_out_frame);
7595 num_stage = pipe->pipe_settings.yuvpp.num_yuv_scaler;
7596 num_vf_pp_stage = pipe->pipe_settings.yuvpp.num_vf_pp;
7597 num_output_stage = pipe->pipe_settings.yuvpp.num_output;
7598
7599#ifdef USE_INPUT_SYSTEM_VERSION_2401
7600
7601
7602
7603
7604
7605
7606 sensor = pipe->stream->config.mode == IA_CSS_INPUT_MODE_SENSOR;
7607 buffered_sensor = pipe->stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR;
7608 online = pipe->stream->config.online;
7609 continuous = pipe->stream->config.continuous;
7610 need_in_frameinfo_memory =
7611 !((sensor && (online || continuous)) || (buffered_sensor && continuous));
7612#else
7613
7614 need_in_frameinfo_memory = pipe->stream->config.mode == IA_CSS_INPUT_MODE_MEMORY;
7615#endif
7616
7617
7618
7619 if (need_in_frameinfo_memory) {
7620
7621
7622
7623
7624
7625
7626
7627
7628
7629 int in_frame_format;
7630 if (pipe->stream->config.input_config.format == ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY) {
7631 in_frame_format = IA_CSS_FRAME_FORMAT_CSI_MIPI_LEGACY_YUV420_8;
7632 } else if (pipe->stream->config.input_config.format == ATOMISP_INPUT_FORMAT_YUV422_8) {
7633
7634
7635
7636
7637
7638
7639
7640
7641
7642
7643
7644
7645
7646
7647
7648
7649
7650 in_frame_format = IA_CSS_FRAME_FORMAT_RAW;
7651 } else {
7652 in_frame_format = IA_CSS_FRAME_FORMAT_NV12;
7653 }
7654
7655 err = init_in_frameinfo_memory_defaults(pipe,
7656 &me->in_frame,
7657 in_frame_format);
7658
7659 if (err != IA_CSS_SUCCESS) {
7660 IA_CSS_LEAVE_ERR_PRIVATE(err);
7661 return err;
7662 }
7663
7664 in_frame = &me->in_frame;
7665 } else {
7666 in_frame = NULL;
7667 }
7668
7669 for (i = 0; i < num_output_stage; i++) {
7670 assert(i < IA_CSS_PIPE_MAX_OUTPUT_STAGE);
7671 if (pipe->output_info[i].res.width != 0) {
7672 err = init_out_frameinfo_defaults(pipe, &me->out_frame[i], i);
7673 if (err != IA_CSS_SUCCESS) {
7674 IA_CSS_LEAVE_ERR_PRIVATE(err);
7675 return err;
7676 }
7677 out_frame[i] = &me->out_frame[i];
7678 }
7679
7680
7681 if (pipe->vf_output_info[i].res.width != 0) {
7682 err = init_vf_frameinfo_defaults(pipe, &me->vf_frame[i], i);
7683 if (err != IA_CSS_SUCCESS) {
7684 IA_CSS_LEAVE_ERR_PRIVATE(err);
7685 return err;
7686 }
7687 vf_frame[i] = &me->vf_frame[i];
7688 }
7689 }
7690
7691 copy_binary = &pipe->pipe_settings.yuvpp.copy_binary;
7692 vf_pp_binary = pipe->pipe_settings.yuvpp.vf_pp_binary;
7693 yuv_scaler_binary = pipe->pipe_settings.yuvpp.yuv_scaler_binary;
7694 need_scaler = need_yuv_scaler_stage(pipe);
7695
7696 if (pipe->pipe_settings.yuvpp.copy_binary.info) {
7697
7698 struct ia_css_frame *in_frame_local = NULL;
7699
7700#ifdef USE_INPUT_SYSTEM_VERSION_2401
7701
7702 if (!online)
7703 in_frame_local = in_frame;
7704#endif
7705
7706 if (need_scaler) {
7707 ia_css_pipe_util_set_output_frames(bin_out_frame, 0, NULL);
7708 ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary,
7709 bin_out_frame, in_frame_local, NULL);
7710 } else {
7711 ia_css_pipe_util_set_output_frames(bin_out_frame, 0, out_frame[0]);
7712 ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary,
7713 bin_out_frame, in_frame_local, NULL);
7714 }
7715
7716 err = ia_css_pipeline_create_and_add_stage(me,
7717 &stage_desc,
7718 ©_stage);
7719
7720 if (err != IA_CSS_SUCCESS) {
7721 IA_CSS_LEAVE_ERR_PRIVATE(err);
7722 return err;
7723 }
7724
7725 if (copy_stage) {
7726
7727 copy_stage->args.copy_vf = !need_scaler;
7728
7729 copy_stage->args.copy_output = true;
7730
7731 in_frame = copy_stage->args.out_frame[0];
7732 }
7733 }
7734
7735 if (need_scaler) {
7736 struct ia_css_frame *tmp_out_frame = NULL;
7737 struct ia_css_frame *tmp_vf_frame = NULL;
7738 struct ia_css_frame *tmp_in_frame = in_frame;
7739
7740 for (i = 0, j = 0; i < num_stage; i++) {
7741 assert(j < num_output_stage);
7742 if (pipe->pipe_settings.yuvpp.is_output_stage[i]) {
7743 tmp_out_frame = out_frame[j];
7744 tmp_vf_frame = vf_frame[j];
7745 } else {
7746 tmp_out_frame = NULL;
7747 tmp_vf_frame = NULL;
7748 }
7749
7750 err = add_yuv_scaler_stage(pipe, me, tmp_in_frame, tmp_out_frame,
7751 NULL,
7752 &yuv_scaler_binary[i],
7753 &yuv_scaler_stage);
7754
7755 if (err != IA_CSS_SUCCESS) {
7756 IA_CSS_LEAVE_ERR_PRIVATE(err);
7757 return err;
7758 }
7759
7760 tmp_in_frame = yuv_scaler_stage->args.out_frame[1];
7761 if (pipe->pipe_settings.yuvpp.is_output_stage[i]) {
7762 if (tmp_vf_frame && (tmp_vf_frame->info.res.width != 0)) {
7763 in_frame = yuv_scaler_stage->args.out_vf_frame;
7764 err = add_vf_pp_stage(pipe, in_frame, tmp_vf_frame, &vf_pp_binary[j],
7765 &vf_pp_stage);
7766
7767 if (err != IA_CSS_SUCCESS) {
7768 IA_CSS_LEAVE_ERR_PRIVATE(err);
7769 return err;
7770 }
7771 }
7772 j++;
7773 }
7774 }
7775 } else if (copy_stage != NULL) {
7776 if (vf_frame[0] != NULL && vf_frame[0]->info.res.width != 0) {
7777 in_frame = copy_stage->args.out_vf_frame;
7778 err = add_vf_pp_stage(pipe, in_frame, vf_frame[0], &vf_pp_binary[0],
7779 &vf_pp_stage);
7780 }
7781 if (err != IA_CSS_SUCCESS) {
7782 IA_CSS_LEAVE_ERR_PRIVATE(err);
7783 return err;
7784 }
7785 }
7786
7787 ia_css_pipeline_finalize_stages(&pipe->pipeline, pipe->stream->config.continuous);
7788
7789 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
7790
7791 return IA_CSS_SUCCESS;
7792}
7793
7794static enum ia_css_err
7795create_host_copy_pipeline(struct ia_css_pipe *pipe,
7796 unsigned max_input_width,
7797 struct ia_css_frame *out_frame)
7798{
7799 struct ia_css_pipeline *me;
7800 enum ia_css_err err = IA_CSS_SUCCESS;
7801 struct ia_css_pipeline_stage_desc stage_desc;
7802
7803 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
7804 "create_host_copy_pipeline() enter:\n");
7805
7806
7807 me = &pipe->pipeline;
7808 ia_css_pipeline_clean(me);
7809
7810
7811 out_frame->contiguous = false;
7812 out_frame->flash_state = IA_CSS_FRAME_FLASH_STATE_NONE;
7813
7814 if (copy_on_sp(pipe) &&
7815 pipe->stream->config.input_config.format == ATOMISP_INPUT_FORMAT_BINARY_8) {
7816 ia_css_frame_info_init(
7817 &out_frame->info,
7818 JPEG_BYTES,
7819 1,
7820 IA_CSS_FRAME_FORMAT_BINARY_8,
7821 0);
7822 } else if (out_frame->info.format == IA_CSS_FRAME_FORMAT_RAW) {
7823 out_frame->info.raw_bit_depth =
7824 ia_css_pipe_util_pipe_input_format_bpp(pipe);
7825 }
7826
7827 me->num_stages = 1;
7828 me->pipe_id = IA_CSS_PIPE_ID_COPY;
7829 pipe->mode = IA_CSS_PIPE_ID_COPY;
7830
7831 ia_css_pipe_get_sp_func_stage_desc(&stage_desc, out_frame,
7832 IA_CSS_PIPELINE_RAW_COPY, max_input_width);
7833 err = ia_css_pipeline_create_and_add_stage(me,
7834 &stage_desc,
7835 NULL);
7836
7837 ia_css_pipeline_finalize_stages(&pipe->pipeline, pipe->stream->config.continuous);
7838
7839 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
7840 "create_host_copy_pipeline() leave:\n");
7841
7842 return err;
7843}
7844
7845static enum ia_css_err
7846create_host_isyscopy_capture_pipeline(struct ia_css_pipe *pipe)
7847{
7848 struct ia_css_pipeline *me = &pipe->pipeline;
7849 enum ia_css_err err = IA_CSS_SUCCESS;
7850 struct ia_css_pipeline_stage_desc stage_desc;
7851 struct ia_css_frame *out_frame = &me->out_frame[0];
7852 struct ia_css_pipeline_stage *out_stage = NULL;
7853 unsigned int thread_id;
7854 enum sh_css_queue_id queue_id;
7855 unsigned int max_input_width = MAX_VECTORS_PER_INPUT_LINE_CONT * ISP_VEC_NELEMS;
7856
7857 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
7858 "create_host_isyscopy_capture_pipeline() enter:\n");
7859 ia_css_pipeline_clean(me);
7860
7861
7862 err = sh_css_pipe_get_output_frame_info(pipe, &out_frame->info, 0);
7863 if (err != IA_CSS_SUCCESS)
7864 return err;
7865 out_frame->contiguous = false;
7866 out_frame->flash_state = IA_CSS_FRAME_FLASH_STATE_NONE;
7867 ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
7868 ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_OUTPUT_FRAME, thread_id, &queue_id);
7869 out_frame->dynamic_queue_id = queue_id;
7870 out_frame->buf_type = IA_CSS_BUFFER_TYPE_OUTPUT_FRAME;
7871
7872 me->num_stages = 1;
7873 me->pipe_id = IA_CSS_PIPE_ID_CAPTURE;
7874 pipe->mode = IA_CSS_PIPE_ID_CAPTURE;
7875 ia_css_pipe_get_sp_func_stage_desc(&stage_desc, out_frame,
7876 IA_CSS_PIPELINE_ISYS_COPY, max_input_width);
7877 err = ia_css_pipeline_create_and_add_stage(me,
7878 &stage_desc, &out_stage);
7879 if(err != IA_CSS_SUCCESS)
7880 return err;
7881
7882 ia_css_pipeline_finalize_stages(me, pipe->stream->config.continuous);
7883
7884 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
7885 "create_host_isyscopy_capture_pipeline() leave:\n");
7886
7887 return err;
7888}
7889
7890static enum ia_css_err
7891create_host_regular_capture_pipeline(struct ia_css_pipe *pipe)
7892{
7893 struct ia_css_pipeline *me;
7894 enum ia_css_err err = IA_CSS_SUCCESS;
7895 enum ia_css_capture_mode mode;
7896 struct ia_css_pipeline_stage *current_stage = NULL;
7897 struct ia_css_pipeline_stage *yuv_scaler_stage = NULL;
7898 struct ia_css_binary *copy_binary,
7899 *primary_binary[MAX_NUM_PRIMARY_STAGES],
7900 *vf_pp_binary,
7901 *pre_isp_binary,
7902 *anr_gdc_binary,
7903 *post_isp_binary,
7904 *yuv_scaler_binary,
7905 *capture_pp_binary,
7906 *capture_ldc_binary;
7907 bool need_pp = false;
7908 bool raw;
7909
7910 struct ia_css_frame *in_frame;
7911 struct ia_css_frame *out_frame;
7912 struct ia_css_frame *out_frames[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
7913 struct ia_css_frame *vf_frame;
7914 struct ia_css_pipeline_stage_desc stage_desc;
7915 bool need_in_frameinfo_memory = false;
7916#ifdef USE_INPUT_SYSTEM_VERSION_2401
7917 bool sensor = false;
7918 bool buffered_sensor = false;
7919 bool online = false;
7920 bool continuous = false;
7921#endif
7922 unsigned int i, num_yuv_scaler, num_primary_stage;
7923 bool need_yuv_pp = false;
7924 bool *is_output_stage = NULL;
7925 bool need_ldc = false;
7926
7927 IA_CSS_ENTER_PRIVATE("");
7928 assert(pipe != NULL);
7929 assert(pipe->stream != NULL);
7930 assert(pipe->mode == IA_CSS_PIPE_ID_CAPTURE || pipe->mode == IA_CSS_PIPE_ID_COPY);
7931
7932 me = &pipe->pipeline;
7933 mode = pipe->config.default_capture_config.mode;
7934 raw = (mode == IA_CSS_CAPTURE_MODE_RAW);
7935 ia_css_pipeline_clean(me);
7936 ia_css_pipe_util_create_output_frames(out_frames);
7937
7938#ifdef USE_INPUT_SYSTEM_VERSION_2401
7939
7940
7941
7942
7943
7944
7945
7946 sensor = (pipe->stream->config.mode == IA_CSS_INPUT_MODE_SENSOR);
7947 buffered_sensor = (pipe->stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR);
7948 online = pipe->stream->config.online;
7949 continuous = pipe->stream->config.continuous;
7950 need_in_frameinfo_memory =
7951 !((sensor && (online || continuous)) || (buffered_sensor && (online || continuous)));
7952#else
7953
7954 need_in_frameinfo_memory = pipe->stream->config.mode == IA_CSS_INPUT_MODE_MEMORY;
7955#endif
7956 if (need_in_frameinfo_memory) {
7957 err = init_in_frameinfo_memory_defaults(pipe, &me->in_frame, IA_CSS_FRAME_FORMAT_RAW);
7958 if (err != IA_CSS_SUCCESS) {
7959 IA_CSS_LEAVE_ERR_PRIVATE(err);
7960 return err;
7961 }
7962
7963 in_frame = &me->in_frame;
7964 } else {
7965 in_frame = NULL;
7966 }
7967
7968 err = init_out_frameinfo_defaults(pipe, &me->out_frame[0], 0);
7969 if (err != IA_CSS_SUCCESS) {
7970 IA_CSS_LEAVE_ERR_PRIVATE(err);
7971 return err;
7972 }
7973 out_frame = &me->out_frame[0];
7974
7975
7976 if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0]) {
7977 if (mode == IA_CSS_CAPTURE_MODE_RAW || mode == IA_CSS_CAPTURE_MODE_BAYER) {
7978
7979 vf_frame = NULL;
7980 } else {
7981 init_vf_frameinfo_defaults(pipe, &me->vf_frame[0], 0);
7982 vf_frame = &me->vf_frame[0];
7983 }
7984 } else {
7985 vf_frame = NULL;
7986 }
7987
7988 copy_binary = &pipe->pipe_settings.capture.copy_binary;
7989 num_primary_stage = pipe->pipe_settings.capture.num_primary_stage;
7990 if ((num_primary_stage == 0) && (mode == IA_CSS_CAPTURE_MODE_PRIMARY)) {
7991 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INTERNAL_ERROR);
7992 return IA_CSS_ERR_INTERNAL_ERROR;
7993 }
7994 for (i = 0; i < num_primary_stage; i++) {
7995 primary_binary[i] = &pipe->pipe_settings.capture.primary_binary[i];
7996 }
7997 vf_pp_binary = &pipe->pipe_settings.capture.vf_pp_binary;
7998 pre_isp_binary = &pipe->pipe_settings.capture.pre_isp_binary;
7999 anr_gdc_binary = &pipe->pipe_settings.capture.anr_gdc_binary;
8000 post_isp_binary = &pipe->pipe_settings.capture.post_isp_binary;
8001 capture_pp_binary = &pipe->pipe_settings.capture.capture_pp_binary;
8002 yuv_scaler_binary = pipe->pipe_settings.capture.yuv_scaler_binary;
8003 num_yuv_scaler = pipe->pipe_settings.capture.num_yuv_scaler;
8004 is_output_stage = pipe->pipe_settings.capture.is_output_stage;
8005 capture_ldc_binary = &pipe->pipe_settings.capture.capture_ldc_binary;
8006
8007 need_pp = (need_capture_pp(pipe) || pipe->output_stage) &&
8008 mode != IA_CSS_CAPTURE_MODE_RAW &&
8009 mode != IA_CSS_CAPTURE_MODE_BAYER;
8010 need_yuv_pp = (yuv_scaler_binary != NULL && yuv_scaler_binary->info != NULL);
8011 need_ldc = (capture_ldc_binary != NULL && capture_ldc_binary->info != NULL);
8012
8013 if (pipe->pipe_settings.capture.copy_binary.info) {
8014 if (raw) {
8015 ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
8016#if !defined(HAS_NO_INPUT_SYSTEM) && defined(USE_INPUT_SYSTEM_VERSION_2401)
8017 if (!continuous) {
8018 ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary,
8019 out_frames, in_frame, NULL);
8020 } else {
8021 in_frame = pipe->stream->last_pipe->continuous_frames[0];
8022 ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary,
8023 out_frames, in_frame, NULL);
8024 }
8025#else
8026 ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary,
8027 out_frames, NULL, NULL);
8028#endif
8029 } else {
8030 ia_css_pipe_util_set_output_frames(out_frames, 0, in_frame);
8031 ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary,
8032 out_frames, NULL, NULL);
8033 }
8034
8035 err = ia_css_pipeline_create_and_add_stage(me,
8036 &stage_desc,
8037 ¤t_stage);
8038 if (err != IA_CSS_SUCCESS) {
8039 IA_CSS_LEAVE_ERR_PRIVATE(err);
8040 return err;
8041 }
8042 } else if (pipe->stream->config.continuous) {
8043 in_frame = pipe->stream->last_pipe->continuous_frames[0];
8044 }
8045
8046 if (mode == IA_CSS_CAPTURE_MODE_PRIMARY) {
8047 struct ia_css_frame *local_in_frame = NULL;
8048 struct ia_css_frame *local_out_frame = NULL;
8049
8050 for (i = 0; i < num_primary_stage; i++) {
8051 if (i == 0)
8052 local_in_frame = in_frame;
8053 else
8054 local_in_frame = NULL;
8055#ifndef ISP2401
8056 if (!need_pp && (i == num_primary_stage - 1))
8057#else
8058 if (!need_pp && (i == num_primary_stage - 1) && !need_ldc)
8059#endif
8060 local_out_frame = out_frame;
8061 else
8062 local_out_frame = NULL;
8063 ia_css_pipe_util_set_output_frames(out_frames, 0, local_out_frame);
8064
8065
8066
8067
8068
8069
8070
8071
8072
8073
8074 ia_css_pipe_get_generic_stage_desc(&stage_desc, primary_binary[i],
8075 out_frames, local_in_frame, NULL);
8076 err = ia_css_pipeline_create_and_add_stage(me,
8077 &stage_desc,
8078 ¤t_stage);
8079 if (err != IA_CSS_SUCCESS) {
8080 IA_CSS_LEAVE_ERR_PRIVATE(err);
8081 return err;
8082 }
8083 }
8084
8085
8086 current_stage->args.copy_vf =
8087 primary_binary[0]->info->sp.pipeline.mode ==
8088 IA_CSS_BINARY_MODE_COPY;
8089 current_stage->args.copy_output = current_stage->args.copy_vf;
8090 } else if (mode == IA_CSS_CAPTURE_MODE_ADVANCED ||
8091 mode == IA_CSS_CAPTURE_MODE_LOW_LIGHT) {
8092 ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
8093 ia_css_pipe_get_generic_stage_desc(&stage_desc, pre_isp_binary,
8094 out_frames, in_frame, NULL);
8095 err = ia_css_pipeline_create_and_add_stage(me,
8096 &stage_desc, NULL);
8097 if (err != IA_CSS_SUCCESS) {
8098 IA_CSS_LEAVE_ERR_PRIVATE(err);
8099 return err;
8100 }
8101 ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
8102 ia_css_pipe_get_generic_stage_desc(&stage_desc, anr_gdc_binary,
8103 out_frames, NULL, NULL);
8104 err = ia_css_pipeline_create_and_add_stage(me,
8105 &stage_desc, NULL);
8106 if (err != IA_CSS_SUCCESS) {
8107 IA_CSS_LEAVE_ERR_PRIVATE(err);
8108 return err;
8109 }
8110
8111 if(need_pp) {
8112 ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
8113 ia_css_pipe_get_generic_stage_desc(&stage_desc, post_isp_binary,
8114 out_frames, NULL, NULL);
8115 } else {
8116 ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
8117 ia_css_pipe_get_generic_stage_desc(&stage_desc, post_isp_binary,
8118 out_frames, NULL, NULL);
8119 }
8120
8121 err = ia_css_pipeline_create_and_add_stage(me,
8122 &stage_desc, ¤t_stage);
8123 if (err != IA_CSS_SUCCESS) {
8124 IA_CSS_LEAVE_ERR_PRIVATE(err);
8125 return err;
8126 }
8127 } else if (mode == IA_CSS_CAPTURE_MODE_BAYER) {
8128 ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
8129 ia_css_pipe_get_generic_stage_desc(&stage_desc, pre_isp_binary,
8130 out_frames, in_frame, NULL);
8131 err = ia_css_pipeline_create_and_add_stage(me,
8132 &stage_desc,
8133 NULL);
8134 if (err != IA_CSS_SUCCESS) {
8135 IA_CSS_LEAVE_ERR_PRIVATE(err);
8136 return err;
8137 }
8138 }
8139
8140#ifndef ISP2401
8141 if (need_pp && current_stage) {
8142 struct ia_css_frame *local_in_frame = NULL;
8143 local_in_frame = current_stage->args.out_frame[0];
8144
8145 if(need_ldc) {
8146 ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
8147 ia_css_pipe_get_generic_stage_desc(&stage_desc, capture_ldc_binary,
8148 out_frames, local_in_frame, NULL);
8149 err = ia_css_pipeline_create_and_add_stage(me,
8150 &stage_desc,
8151 ¤t_stage);
8152 local_in_frame = current_stage->args.out_frame[0];
8153 }
8154 err = add_capture_pp_stage(pipe, me, local_in_frame, need_yuv_pp ? NULL : out_frame,
8155#else
8156
8157 if (need_ldc && current_stage) {
8158 in_frame = current_stage->args.out_frame[0];
8159 ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
8160 ia_css_pipe_get_generic_stage_desc(&stage_desc, capture_ldc_binary,
8161 out_frames, in_frame, NULL);
8162 err = ia_css_pipeline_create_and_add_stage(me,
8163 &stage_desc,
8164 NULL);
8165 } else if (need_pp && current_stage) {
8166 in_frame = current_stage->args.out_frame[0];
8167 err = add_capture_pp_stage(pipe, me, in_frame, need_yuv_pp ? NULL : out_frame,
8168#endif
8169 capture_pp_binary,
8170 ¤t_stage);
8171 if (err != IA_CSS_SUCCESS) {
8172 IA_CSS_LEAVE_ERR_PRIVATE(err);
8173 return err;
8174 }
8175 }
8176
8177 if (need_yuv_pp && current_stage) {
8178 struct ia_css_frame *tmp_in_frame = current_stage->args.out_frame[0];
8179 struct ia_css_frame *tmp_out_frame = NULL;
8180
8181 for (i = 0; i < num_yuv_scaler; i++) {
8182 if (is_output_stage[i] == true)
8183 tmp_out_frame = out_frame;
8184 else
8185 tmp_out_frame = NULL;
8186
8187 err = add_yuv_scaler_stage(pipe, me, tmp_in_frame, tmp_out_frame,
8188 NULL,
8189 &yuv_scaler_binary[i],
8190 &yuv_scaler_stage);
8191 if (err != IA_CSS_SUCCESS) {
8192 IA_CSS_LEAVE_ERR_PRIVATE(err);
8193 return err;
8194 }
8195
8196 tmp_in_frame = yuv_scaler_stage->args.out_frame[1];
8197 }
8198 }
8199
8200
8201
8202
8203
8204
8205
8206
8207
8208
8209 if (mode != IA_CSS_CAPTURE_MODE_RAW && mode != IA_CSS_CAPTURE_MODE_BAYER && current_stage && vf_frame) {
8210 in_frame = current_stage->args.out_vf_frame;
8211 err = add_vf_pp_stage(pipe, in_frame, vf_frame, vf_pp_binary,
8212 ¤t_stage);
8213 if (err != IA_CSS_SUCCESS) {
8214 IA_CSS_LEAVE_ERR_PRIVATE(err);
8215 return err;
8216 }
8217 }
8218 ia_css_pipeline_finalize_stages(&pipe->pipeline, pipe->stream->config.continuous);
8219
8220 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
8221 "create_host_regular_capture_pipeline() leave:\n");
8222
8223 return IA_CSS_SUCCESS;
8224}
8225
8226static enum ia_css_err
8227create_host_capture_pipeline(struct ia_css_pipe *pipe)
8228{
8229 enum ia_css_err err = IA_CSS_SUCCESS;
8230
8231 IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
8232
8233 if (pipe->config.mode == IA_CSS_PIPE_MODE_COPY)
8234 err = create_host_isyscopy_capture_pipeline(pipe);
8235 else
8236 err = create_host_regular_capture_pipeline(pipe);
8237 if (err != IA_CSS_SUCCESS) {
8238 IA_CSS_LEAVE_ERR_PRIVATE(err);
8239 return err;
8240 }
8241
8242 IA_CSS_LEAVE_ERR_PRIVATE(err);
8243
8244 return err;
8245}
8246
8247static enum ia_css_err capture_start(
8248 struct ia_css_pipe *pipe)
8249{
8250 struct ia_css_pipeline *me;
8251
8252 enum ia_css_err err = IA_CSS_SUCCESS;
8253 enum sh_css_pipe_config_override copy_ovrd;
8254
8255 IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
8256 if (pipe == NULL) {
8257 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
8258 return IA_CSS_ERR_INVALID_ARGUMENTS;
8259 }
8260
8261 me = &pipe->pipeline;
8262
8263 if ((pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_RAW ||
8264 pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_BAYER ) &&
8265 (pipe->config.mode != IA_CSS_PIPE_MODE_COPY)) {
8266 if (copy_on_sp(pipe)) {
8267 err = start_copy_on_sp(pipe, &me->out_frame[0]);
8268 IA_CSS_LEAVE_ERR_PRIVATE(err);
8269 return err;
8270 }
8271 }
8272
8273#if defined(USE_INPUT_SYSTEM_VERSION_2)
8274
8275 err = send_mipi_frames(pipe);
8276 if (err != IA_CSS_SUCCESS) {
8277 IA_CSS_LEAVE_ERR_PRIVATE(err);
8278 return err;
8279 }
8280#elif defined(USE_INPUT_SYSTEM_VERSION_2401)
8281 if (pipe->config.mode != IA_CSS_PIPE_MODE_COPY) {
8282 err = send_mipi_frames(pipe);
8283 if (err != IA_CSS_SUCCESS) {
8284 IA_CSS_LEAVE_ERR_PRIVATE(err);
8285 return err;
8286 }
8287 }
8288
8289#endif
8290
8291 {
8292 unsigned int thread_id;
8293
8294 ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
8295 copy_ovrd = 1 << thread_id;
8296
8297 }
8298 start_pipe(pipe, copy_ovrd, pipe->stream->config.mode);
8299
8300#if !defined(HAS_NO_INPUT_SYSTEM) && !defined(USE_INPUT_SYSTEM_VERSION_2401)
8301
8302
8303
8304
8305
8306 if (pipe->config.mode == IA_CSS_PIPE_MODE_COPY && pipe->stream->reconfigure_css_rx) {
8307 ia_css_isys_rx_configure(&pipe->stream->csi_rx_config, pipe->stream->config.mode);
8308 pipe->stream->reconfigure_css_rx = false;
8309 }
8310#endif
8311
8312 IA_CSS_LEAVE_ERR_PRIVATE(err);
8313 return err;
8314
8315}
8316
8317static enum ia_css_err
8318sh_css_pipe_get_output_frame_info(struct ia_css_pipe *pipe,
8319 struct ia_css_frame_info *info,
8320 unsigned int idx)
8321{
8322 assert(pipe != NULL);
8323 assert(info != NULL);
8324
8325 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
8326 "sh_css_pipe_get_output_frame_info() enter:\n");
8327
8328 *info = pipe->output_info[idx];
8329 if (copy_on_sp(pipe) &&
8330 pipe->stream->config.input_config.format == ATOMISP_INPUT_FORMAT_BINARY_8) {
8331 ia_css_frame_info_init(
8332 info,
8333 JPEG_BYTES,
8334 1,
8335 IA_CSS_FRAME_FORMAT_BINARY_8,
8336 0);
8337 } else if (info->format == IA_CSS_FRAME_FORMAT_RAW ||
8338 info->format == IA_CSS_FRAME_FORMAT_RAW_PACKED) {
8339 info->raw_bit_depth =
8340 ia_css_pipe_util_pipe_input_format_bpp(pipe);
8341
8342 }
8343
8344 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
8345 "sh_css_pipe_get_output_frame_info() leave:\n");
8346 return IA_CSS_SUCCESS;
8347}
8348
8349#if !defined(HAS_NO_INPUT_SYSTEM)
8350void
8351ia_css_stream_send_input_frame(const struct ia_css_stream *stream,
8352 const unsigned short *data,
8353 unsigned int width,
8354 unsigned int height)
8355{
8356 assert(stream != NULL);
8357
8358 ia_css_inputfifo_send_input_frame(
8359 data, width, height,
8360 stream->config.channel_id,
8361 stream->config.input_config.format,
8362 stream->config.pixels_per_clock == 2);
8363}
8364
8365void
8366ia_css_stream_start_input_frame(const struct ia_css_stream *stream)
8367{
8368 assert(stream != NULL);
8369
8370 ia_css_inputfifo_start_frame(
8371 stream->config.channel_id,
8372 stream->config.input_config.format,
8373 stream->config.pixels_per_clock == 2);
8374}
8375
8376void
8377ia_css_stream_send_input_line(const struct ia_css_stream *stream,
8378 const unsigned short *data,
8379 unsigned int width,
8380 const unsigned short *data2,
8381 unsigned int width2)
8382{
8383 assert(stream != NULL);
8384
8385 ia_css_inputfifo_send_line(stream->config.channel_id,
8386 data, width, data2, width2);
8387}
8388
8389void
8390ia_css_stream_send_input_embedded_line(const struct ia_css_stream *stream,
8391 enum atomisp_input_format format,
8392 const unsigned short *data,
8393 unsigned int width)
8394{
8395 assert(stream != NULL);
8396 if (data == NULL || width == 0)
8397 return;
8398 ia_css_inputfifo_send_embedded_line(stream->config.channel_id,
8399 format, data, width);
8400}
8401
8402void
8403ia_css_stream_end_input_frame(const struct ia_css_stream *stream)
8404{
8405 assert(stream != NULL);
8406
8407 ia_css_inputfifo_end_frame(stream->config.channel_id);
8408}
8409#endif
8410
8411static void
8412append_firmware(struct ia_css_fw_info **l, struct ia_css_fw_info *firmware)
8413{
8414 IA_CSS_ENTER_PRIVATE("l = %p, firmware = %p", l , firmware);
8415 if (l == NULL) {
8416 IA_CSS_ERROR("NULL fw_info");
8417 IA_CSS_LEAVE_PRIVATE("");
8418 return;
8419 }
8420 while (*l)
8421 l = &(*l)->next;
8422 *l = firmware;
8423
8424 IA_CSS_LEAVE_PRIVATE("");
8425}
8426
8427static void
8428remove_firmware(struct ia_css_fw_info **l, struct ia_css_fw_info *firmware)
8429{
8430 assert(*l);
8431 assert(firmware);
8432 (void)l;
8433 (void)firmware;
8434 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "remove_firmware() enter:\n");
8435
8436 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, "remove_firmware() leave:\n");
8437 return;
8438}
8439
8440static enum ia_css_err upload_isp_code(struct ia_css_fw_info *firmware)
8441{
8442 hrt_vaddress binary;
8443
8444 if (firmware == NULL) {
8445 IA_CSS_ERROR("NULL input parameter");
8446 return IA_CSS_ERR_INVALID_ARGUMENTS;
8447 }
8448 binary = firmware->info.isp.xmem_addr;
8449
8450 if (!binary) {
8451 unsigned size = firmware->blob.size;
8452 const unsigned char *blob;
8453 const unsigned char *binary_name;
8454 binary_name =
8455 (const unsigned char *)(IA_CSS_EXT_ISP_PROG_NAME(
8456 firmware));
8457 blob = binary_name +
8458 strlen((const char *)binary_name) +
8459 1;
8460 binary = sh_css_load_blob(blob, size);
8461 firmware->info.isp.xmem_addr = binary;
8462 }
8463
8464 if (!binary)
8465 return IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
8466 return IA_CSS_SUCCESS;
8467}
8468
8469static enum ia_css_err
8470acc_load_extension(struct ia_css_fw_info *firmware)
8471{
8472 enum ia_css_err err;
8473 struct ia_css_fw_info *hd = firmware;
8474 while (hd){
8475 err = upload_isp_code(hd);
8476 if (err != IA_CSS_SUCCESS)
8477 return err;
8478 hd = hd->next;
8479 }
8480
8481 if (firmware == NULL)
8482 return IA_CSS_ERR_INVALID_ARGUMENTS;
8483 firmware->loaded = true;
8484 return IA_CSS_SUCCESS;
8485}
8486
8487static void
8488acc_unload_extension(struct ia_css_fw_info *firmware)
8489{
8490 struct ia_css_fw_info *hd = firmware;
8491 struct ia_css_fw_info *hdn = NULL;
8492
8493 if (firmware == NULL)
8494 return;
8495
8496 while (hd){
8497 hdn = (hd->next) ? &(*hd->next) : NULL;
8498 if (hd->info.isp.xmem_addr) {
8499 hmm_free(hd->info.isp.xmem_addr);
8500 hd->info.isp.xmem_addr = mmgr_NULL;
8501 }
8502 hd->isp_code = NULL;
8503 hd->next = NULL;
8504 hd = hdn;
8505 }
8506
8507 firmware->loaded = false;
8508}
8509
8510static enum ia_css_err
8511ia_css_pipe_load_extension(struct ia_css_pipe *pipe,
8512 struct ia_css_fw_info *firmware)
8513{
8514 enum ia_css_err err = IA_CSS_SUCCESS;
8515
8516 IA_CSS_ENTER_PRIVATE("fw = %p pipe = %p", firmware, pipe);
8517
8518 if ((firmware == NULL) || (pipe == NULL)) {
8519 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
8520 return IA_CSS_ERR_INVALID_ARGUMENTS;
8521 }
8522
8523 if (firmware->info.isp.type == IA_CSS_ACC_OUTPUT) {
8524 if (&pipe->output_stage != NULL)
8525 append_firmware(&pipe->output_stage, firmware);
8526 else {
8527 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INTERNAL_ERROR);
8528 return IA_CSS_ERR_INTERNAL_ERROR;
8529 }
8530 }
8531 else if (firmware->info.isp.type == IA_CSS_ACC_VIEWFINDER) {
8532 if (&pipe->vf_stage != NULL)
8533 append_firmware(&pipe->vf_stage, firmware);
8534 else {
8535 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INTERNAL_ERROR);
8536 return IA_CSS_ERR_INTERNAL_ERROR;
8537 }
8538 }
8539 err = acc_load_extension(firmware);
8540
8541 IA_CSS_LEAVE_ERR_PRIVATE(err);
8542 return err;
8543}
8544
8545
8546static void
8547ia_css_pipe_unload_extension(struct ia_css_pipe *pipe,
8548 struct ia_css_fw_info *firmware)
8549{
8550 IA_CSS_ENTER_PRIVATE("fw = %p pipe = %p", firmware, pipe);
8551
8552 if ((firmware == NULL) || (pipe == NULL)) {
8553 IA_CSS_ERROR("NULL input parameters");
8554 IA_CSS_LEAVE_PRIVATE("");
8555 return;
8556 }
8557
8558 if (firmware->info.isp.type == IA_CSS_ACC_OUTPUT)
8559 remove_firmware(&pipe->output_stage, firmware);
8560 else if (firmware->info.isp.type == IA_CSS_ACC_VIEWFINDER)
8561 remove_firmware(&pipe->vf_stage, firmware);
8562 acc_unload_extension(firmware);
8563
8564 IA_CSS_LEAVE_PRIVATE("");
8565}
8566
8567bool
8568ia_css_pipeline_uses_params(struct ia_css_pipeline *me)
8569{
8570 struct ia_css_pipeline_stage *stage;
8571
8572 assert(me != NULL);
8573
8574 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
8575 "ia_css_pipeline_uses_params() enter: me=%p\n", me);
8576
8577 for (stage = me->stages; stage; stage = stage->next)
8578 if (stage->binary_info && stage->binary_info->enable.params) {
8579 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
8580 "ia_css_pipeline_uses_params() leave: "
8581 "return_bool=true\n");
8582 return true;
8583 }
8584 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
8585 "ia_css_pipeline_uses_params() leave: return_bool=false\n");
8586 return false;
8587}
8588
8589static enum ia_css_err
8590sh_css_pipeline_add_acc_stage(struct ia_css_pipeline *pipeline,
8591 const void *acc_fw)
8592{
8593 struct ia_css_fw_info *fw = (struct ia_css_fw_info *)acc_fw;
8594
8595 enum ia_css_err err = IA_CSS_SUCCESS;
8596 if (fw->loaded == false)
8597 err = acc_load_extension(fw);
8598
8599 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
8600 "sh_css_pipeline_add_acc_stage() enter: pipeline=%p,"
8601 " acc_fw=%p\n", pipeline, acc_fw);
8602
8603 if (err == IA_CSS_SUCCESS) {
8604 struct ia_css_pipeline_stage_desc stage_desc;
8605 ia_css_pipe_get_acc_stage_desc(&stage_desc, NULL, fw);
8606 err = ia_css_pipeline_create_and_add_stage(pipeline,
8607 &stage_desc,
8608 NULL);
8609 }
8610
8611 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
8612 "sh_css_pipeline_add_acc_stage() leave: return_err=%d\n",err);
8613 return err;
8614}
8615
8616
8617
8618
8619
8620enum ia_css_err ia_css_stream_capture_frame(struct ia_css_stream *stream,
8621 unsigned int exp_id)
8622{
8623 struct sh_css_tag_descr tag_descr;
8624 uint32_t encoded_tag_descr;
8625 enum ia_css_err err;
8626
8627 assert(stream != NULL);
8628 IA_CSS_ENTER("exp_id=%d", exp_id);
8629
8630
8631 if (exp_id == 0 || !stream->config.continuous) {
8632 IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
8633 return IA_CSS_ERR_INVALID_ARGUMENTS;
8634 }
8635
8636 if (!sh_css_sp_is_running()) {
8637
8638 IA_CSS_LEAVE_ERR(IA_CSS_ERR_RESOURCE_NOT_AVAILABLE);
8639 return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
8640 }
8641
8642
8643 sh_css_create_tag_descr(0, 0, 0, exp_id, &tag_descr);
8644
8645 encoded_tag_descr = sh_css_encode_tag_descr(&tag_descr);
8646
8647
8648
8649
8650 err= ia_css_bufq_enqueue_tag_cmd(encoded_tag_descr);
8651
8652 IA_CSS_LEAVE_ERR(err);
8653 return err;
8654}
8655
8656
8657
8658
8659
8660enum ia_css_err ia_css_stream_capture(
8661 struct ia_css_stream *stream,
8662 int num_captures,
8663 unsigned int skip,
8664 int offset)
8665{
8666 struct sh_css_tag_descr tag_descr;
8667 unsigned int encoded_tag_descr;
8668 enum ia_css_err return_err;
8669
8670 if (stream == NULL)
8671 return IA_CSS_ERR_INVALID_ARGUMENTS;
8672
8673 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
8674 "ia_css_stream_capture() enter: num_captures=%d,"
8675 " skip=%d, offset=%d\n", num_captures, skip,offset);
8676
8677
8678 if (num_captures < SH_CSS_MINIMUM_TAG_ID) {
8679 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
8680 "ia_css_stream_capture() leave: return_err=%d\n",
8681 IA_CSS_ERR_INVALID_ARGUMENTS);
8682 return IA_CSS_ERR_INVALID_ARGUMENTS;
8683 }
8684
8685
8686 sh_css_create_tag_descr(num_captures, skip, offset, 0, &tag_descr);
8687
8688
8689
8690 encoded_tag_descr = sh_css_encode_tag_descr(&tag_descr);
8691
8692 if (!sh_css_sp_is_running()) {
8693
8694 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
8695 "ia_css_stream_capture() leaving:"
8696 "queues unavailable\n");
8697 return IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
8698 }
8699
8700
8701
8702
8703
8704 return_err = ia_css_bufq_enqueue_tag_cmd((uint32_t)encoded_tag_descr);
8705
8706 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
8707 "ia_css_stream_capture() leave: return_err=%d\n",
8708 return_err);
8709
8710 return return_err;
8711}
8712
8713void ia_css_stream_request_flash(struct ia_css_stream *stream)
8714{
8715 (void)stream;
8716
8717 assert(stream != NULL);
8718 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_request_flash() enter: void\n");
8719
8720#ifndef ISP2401
8721 sh_css_write_host2sp_command(host2sp_cmd_start_flash);
8722#else
8723 if (sh_css_sp_is_running()) {
8724 if (!sh_css_write_host2sp_command(host2sp_cmd_start_flash)) {
8725 IA_CSS_ERROR("Call to 'sh-css_write_host2sp_command()' failed");
8726 ia_css_debug_dump_sp_sw_debug_info();
8727 ia_css_debug_dump_debug_info(NULL);
8728 }
8729 } else
8730 IA_CSS_LOG("SP is not running!");
8731
8732#endif
8733 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
8734 "ia_css_stream_request_flash() leave: return_void\n");
8735}
8736
8737static void
8738sh_css_init_host_sp_control_vars(void)
8739{
8740 const struct ia_css_fw_info *fw;
8741 unsigned int HIVE_ADDR_ia_css_ispctrl_sp_isp_started;
8742
8743 unsigned int HIVE_ADDR_host_sp_queues_initialized;
8744 unsigned int HIVE_ADDR_sp_sleep_mode;
8745 unsigned int HIVE_ADDR_ia_css_dmaproxy_sp_invalidate_tlb;
8746#ifndef ISP2401
8747 unsigned int HIVE_ADDR_sp_stop_copy_preview;
8748#endif
8749 unsigned int HIVE_ADDR_host_sp_com;
8750 unsigned int o = offsetof(struct host_sp_communication, host2sp_command)
8751 / sizeof(int);
8752
8753#if defined(USE_INPUT_SYSTEM_VERSION_2) || defined(USE_INPUT_SYSTEM_VERSION_2401)
8754 unsigned int i;
8755#endif
8756
8757 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
8758 "sh_css_init_host_sp_control_vars() enter: void\n");
8759
8760 fw = &sh_css_sp_fw;
8761 HIVE_ADDR_ia_css_ispctrl_sp_isp_started = fw->info.sp.isp_started;
8762
8763 HIVE_ADDR_host_sp_queues_initialized =
8764 fw->info.sp.host_sp_queues_initialized;
8765 HIVE_ADDR_sp_sleep_mode = fw->info.sp.sleep_mode;
8766 HIVE_ADDR_ia_css_dmaproxy_sp_invalidate_tlb = fw->info.sp.invalidate_tlb;
8767#ifndef ISP2401
8768 HIVE_ADDR_sp_stop_copy_preview = fw->info.sp.stop_copy_preview;
8769#endif
8770 HIVE_ADDR_host_sp_com = fw->info.sp.host_sp_com;
8771
8772 (void)HIVE_ADDR_ia_css_ispctrl_sp_isp_started;
8773
8774 (void)HIVE_ADDR_sp_sleep_mode;
8775 (void)HIVE_ADDR_ia_css_dmaproxy_sp_invalidate_tlb;
8776#ifndef ISP2401
8777 (void)HIVE_ADDR_sp_stop_copy_preview;
8778#endif
8779 (void)HIVE_ADDR_host_sp_com;
8780
8781 sp_dmem_store_uint32(SP0_ID,
8782 (unsigned int)sp_address_of(ia_css_ispctrl_sp_isp_started),
8783 (uint32_t)(0));
8784
8785 sp_dmem_store_uint32(SP0_ID,
8786 (unsigned int)sp_address_of(host_sp_queues_initialized),
8787 (uint32_t)(0));
8788 sp_dmem_store_uint32(SP0_ID,
8789 (unsigned int)sp_address_of(sp_sleep_mode),
8790 (uint32_t)(0));
8791 sp_dmem_store_uint32(SP0_ID,
8792 (unsigned int)sp_address_of(ia_css_dmaproxy_sp_invalidate_tlb),
8793 (uint32_t)(false));
8794#ifndef ISP2401
8795 sp_dmem_store_uint32(SP0_ID,
8796 (unsigned int)sp_address_of(sp_stop_copy_preview),
8797 my_css.stop_copy_preview?(uint32_t)(1):(uint32_t)(0));
8798#endif
8799 store_sp_array_uint(host_sp_com, o, host2sp_cmd_ready);
8800
8801#if !defined(HAS_NO_INPUT_SYSTEM)
8802 for (i = 0; i < N_CSI_PORTS; i++) {
8803 sh_css_update_host2sp_num_mipi_frames
8804 (my_css.num_mipi_frames[i]);
8805 }
8806#endif
8807
8808 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
8809 "sh_css_init_host_sp_control_vars() leave: return_void\n");
8810}
8811
8812
8813
8814
8815void ia_css_pipe_config_defaults(struct ia_css_pipe_config *pipe_config)
8816{
8817 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_pipe_config_defaults()\n");
8818 *pipe_config = DEFAULT_PIPE_CONFIG;
8819}
8820
8821void
8822ia_css_pipe_extra_config_defaults(struct ia_css_pipe_extra_config *extra_config)
8823{
8824 if (extra_config == NULL) {
8825 IA_CSS_ERROR("NULL input parameter");
8826 return;
8827 }
8828
8829 extra_config->enable_raw_binning = false;
8830 extra_config->enable_yuv_ds = false;
8831 extra_config->enable_high_speed = false;
8832 extra_config->enable_dvs_6axis = false;
8833 extra_config->enable_reduced_pipe = false;
8834 extra_config->disable_vf_pp = false;
8835 extra_config->enable_fractional_ds = false;
8836}
8837
8838void ia_css_stream_config_defaults(struct ia_css_stream_config *stream_config)
8839{
8840 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_config_defaults()\n");
8841 assert(stream_config != NULL);
8842 memset(stream_config, 0, sizeof(*stream_config));
8843 stream_config->online = true;
8844 stream_config->left_padding = -1;
8845 stream_config->pixels_per_clock = 1;
8846
8847
8848
8849 stream_config->source.port.rxcount = 0x04040404;
8850}
8851
8852static enum ia_css_err
8853ia_css_acc_pipe_create(struct ia_css_pipe *pipe)
8854{
8855 enum ia_css_err err = IA_CSS_SUCCESS;
8856
8857 if (pipe == NULL) {
8858 IA_CSS_ERROR("NULL input parameter");
8859 return IA_CSS_ERR_INVALID_ARGUMENTS;
8860 }
8861
8862
8863 if (pipe->config.acc_num_execs == 0)
8864 pipe->config.acc_num_execs = 1;
8865
8866 if (pipe->config.acc_extension) {
8867 err = ia_css_pipe_load_extension(pipe, pipe->config.acc_extension);
8868 }
8869
8870 return err;
8871}
8872
8873enum ia_css_err
8874ia_css_pipe_create(const struct ia_css_pipe_config *config,
8875 struct ia_css_pipe **pipe)
8876{
8877#ifndef ISP2401
8878 if (config == NULL)
8879#else
8880 enum ia_css_err err = IA_CSS_SUCCESS;
8881 IA_CSS_ENTER_PRIVATE("config = %p, pipe = %p", config, pipe);
8882
8883 if (config == NULL) {
8884 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
8885#endif
8886 return IA_CSS_ERR_INVALID_ARGUMENTS;
8887#ifndef ISP2401
8888 if (pipe == NULL)
8889#else
8890 }
8891 if (pipe == NULL) {
8892 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
8893#endif
8894 return IA_CSS_ERR_INVALID_ARGUMENTS;
8895#ifndef ISP2401
8896 return ia_css_pipe_create_extra(config, NULL, pipe);
8897#else
8898 }
8899
8900 err = ia_css_pipe_create_extra(config, NULL, pipe);
8901
8902 if(err == IA_CSS_SUCCESS) {
8903 IA_CSS_LOG("pipe created successfully = %p", *pipe);
8904 }
8905
8906 IA_CSS_LEAVE_ERR_PRIVATE(err);
8907
8908 return err;
8909#endif
8910}
8911
8912enum ia_css_err
8913ia_css_pipe_create_extra(const struct ia_css_pipe_config *config,
8914 const struct ia_css_pipe_extra_config *extra_config,
8915 struct ia_css_pipe **pipe)
8916{
8917 enum ia_css_err err = IA_CSS_ERR_INTERNAL_ERROR;
8918 struct ia_css_pipe *internal_pipe = NULL;
8919 unsigned int i;
8920
8921 IA_CSS_ENTER_PRIVATE("config = %p, extra_config = %p and pipe = %p", config, extra_config, pipe);
8922
8923
8924 if (my_css.pipe_counter >= IA_CSS_PIPELINE_NUM_MAX) {
8925 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_RESOURCE_EXHAUSTED);
8926 return IA_CSS_ERR_INVALID_ARGUMENTS;
8927 }
8928
8929 if ((pipe == NULL) || (config == NULL)) {
8930 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
8931 return IA_CSS_ERR_INVALID_ARGUMENTS;
8932 }
8933
8934 ia_css_debug_dump_pipe_config(config);
8935 ia_css_debug_dump_pipe_extra_config(extra_config);
8936
8937 err = create_pipe(config->mode, &internal_pipe, false);
8938 if (err != IA_CSS_SUCCESS) {
8939 IA_CSS_LEAVE_ERR_PRIVATE(err);
8940 return err;
8941 }
8942
8943
8944 internal_pipe->config = *config;
8945 if (extra_config)
8946 internal_pipe->extra_config = *extra_config;
8947 else
8948 ia_css_pipe_extra_config_defaults(&internal_pipe->extra_config);
8949
8950 if (config->mode == IA_CSS_PIPE_MODE_ACC) {
8951
8952
8953
8954 *pipe = internal_pipe;
8955 if (!internal_pipe->config.acc_extension &&
8956 internal_pipe->config.num_acc_stages == 0){
8957 *pipe = NULL;
8958 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
8959 return IA_CSS_SUCCESS;
8960 }
8961 return ia_css_acc_pipe_create(internal_pipe);
8962 }
8963
8964
8965 if (internal_pipe->config.dvs_frame_delay == IA_CSS_FRAME_DELAY_2)
8966 internal_pipe->dvs_frame_delay = 2;
8967 else
8968 internal_pipe->dvs_frame_delay = 1;
8969
8970
8971
8972
8973
8974
8975
8976 if (internal_pipe->extra_config.enable_raw_binning &&
8977 internal_pipe->config.bayer_ds_out_res.width) {
8978
8979 }
8980
8981
8982 if ((internal_pipe->config.vf_pp_in_res.width ||
8983 internal_pipe->config.capt_pp_in_res.width)) {
8984 enum ia_css_frame_format format;
8985 if (internal_pipe->config.vf_pp_in_res.width) {
8986 format = IA_CSS_FRAME_FORMAT_YUV_LINE;
8987 ia_css_frame_info_init(
8988 &internal_pipe->vf_yuv_ds_input_info,
8989 internal_pipe->config.vf_pp_in_res.width,
8990 internal_pipe->config.vf_pp_in_res.height,
8991 format, 0);
8992 }
8993 if (internal_pipe->config.capt_pp_in_res.width) {
8994 format = IA_CSS_FRAME_FORMAT_YUV420;
8995 ia_css_frame_info_init(
8996 &internal_pipe->out_yuv_ds_input_info,
8997 internal_pipe->config.capt_pp_in_res.width,
8998 internal_pipe->config.capt_pp_in_res.height,
8999 format, 0);
9000 }
9001 }
9002 if (internal_pipe->config.vf_pp_in_res.width &&
9003 internal_pipe->config.mode == IA_CSS_PIPE_MODE_PREVIEW) {
9004 ia_css_frame_info_init(
9005 &internal_pipe->vf_yuv_ds_input_info,
9006 internal_pipe->config.vf_pp_in_res.width,
9007 internal_pipe->config.vf_pp_in_res.height,
9008 IA_CSS_FRAME_FORMAT_YUV_LINE, 0);
9009 }
9010
9011 if (internal_pipe->config.bayer_ds_out_res.width) {
9012 ia_css_frame_info_init(
9013 &internal_pipe->bds_output_info,
9014 internal_pipe->config.bayer_ds_out_res.width,
9015 internal_pipe->config.bayer_ds_out_res.height,
9016 IA_CSS_FRAME_FORMAT_RAW, 0);
9017 }
9018
9019
9020 for (i = 0; i < IA_CSS_PIPE_MAX_OUTPUT_STAGE; i++) {
9021 if (internal_pipe->config.output_info[i].res.width) {
9022 err = sh_css_pipe_configure_output(
9023 internal_pipe,
9024 internal_pipe->config.output_info[i].res.width,
9025 internal_pipe->config.output_info[i].res.height,
9026 internal_pipe->config.output_info[i].padded_width,
9027 internal_pipe->config.output_info[i].format,
9028 i);
9029 if (err != IA_CSS_SUCCESS) {
9030 IA_CSS_LEAVE_ERR_PRIVATE(err);
9031 sh_css_free(internal_pipe);
9032 internal_pipe = NULL;
9033 return err;
9034 }
9035 }
9036
9037
9038 internal_pipe->enable_viewfinder[i] = (internal_pipe->config.vf_output_info[i].res.width != 0);
9039 if (internal_pipe->config.vf_output_info[i].res.width) {
9040 err = sh_css_pipe_configure_viewfinder(
9041 internal_pipe,
9042 internal_pipe->config.vf_output_info[i].res.width,
9043 internal_pipe->config.vf_output_info[i].res.height,
9044 internal_pipe->config.vf_output_info[i].padded_width,
9045 internal_pipe->config.vf_output_info[i].format,
9046 i);
9047 if (err != IA_CSS_SUCCESS) {
9048 IA_CSS_LEAVE_ERR_PRIVATE(err);
9049 sh_css_free(internal_pipe);
9050 internal_pipe = NULL;
9051 return err;
9052 }
9053 }
9054 }
9055 if (internal_pipe->config.acc_extension) {
9056 err = ia_css_pipe_load_extension(internal_pipe,
9057 internal_pipe->config.acc_extension);
9058 if (err != IA_CSS_SUCCESS) {
9059 IA_CSS_LEAVE_ERR_PRIVATE(err);
9060 sh_css_free(internal_pipe);
9061 return err;
9062 }
9063 }
9064
9065 memset(&internal_pipe->info, 0, sizeof(internal_pipe->info));
9066
9067
9068 *pipe = internal_pipe;
9069 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
9070 return IA_CSS_SUCCESS;
9071}
9072
9073
9074enum ia_css_err
9075ia_css_pipe_get_info(const struct ia_css_pipe *pipe,
9076 struct ia_css_pipe_info *pipe_info)
9077{
9078 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
9079 "ia_css_pipe_get_info()\n");
9080 assert(pipe_info != NULL);
9081 if (pipe_info == NULL) {
9082 ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
9083 "ia_css_pipe_get_info: pipe_info cannot be NULL\n");
9084 return IA_CSS_ERR_INVALID_ARGUMENTS;
9085 }
9086 if (pipe == NULL || pipe->stream == NULL) {
9087 ia_css_debug_dtrace(IA_CSS_DEBUG_ERROR,
9088 "ia_css_pipe_get_info: ia_css_stream_create needs to"
9089 " be called before ia_css_[stream/pipe]_get_info\n");
9090 return IA_CSS_ERR_INVALID_ARGUMENTS;
9091 }
9092
9093 *pipe_info = pipe->info;
9094 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_pipe_get_info() leave\n");
9095 return IA_CSS_SUCCESS;
9096}
9097
9098bool ia_css_pipe_has_dvs_stats(struct ia_css_pipe_info *pipe_info)
9099{
9100 unsigned int i;
9101
9102 if (pipe_info != NULL) {
9103 for (i = 0; i < IA_CSS_DVS_STAT_NUM_OF_LEVELS; i++) {
9104 if (pipe_info->grid_info.dvs_grid.dvs_stat_grid_info.grd_cfg[i].grd_start.enable)
9105 return true;
9106 }
9107 }
9108
9109 return false;
9110}
9111
9112#ifdef ISP2401
9113enum ia_css_err
9114ia_css_pipe_override_frame_format(struct ia_css_pipe *pipe,
9115 int pin_index,
9116 enum ia_css_frame_format new_format)
9117{
9118 enum ia_css_err err = IA_CSS_SUCCESS;
9119
9120 IA_CSS_ENTER_PRIVATE("pipe = %p, pin_index = %d, new_formats = %d", pipe, pin_index, new_format);
9121
9122 if (NULL == pipe) {
9123 IA_CSS_ERROR("pipe is not set");
9124 err = IA_CSS_ERR_INVALID_ARGUMENTS;
9125 IA_CSS_LEAVE_ERR_PRIVATE(err);
9126 return err;
9127 }
9128 if (0 != pin_index && 1 != pin_index) {
9129 IA_CSS_ERROR("pin index is not valid");
9130 err = IA_CSS_ERR_INVALID_ARGUMENTS;
9131 IA_CSS_LEAVE_ERR_PRIVATE(err);
9132 return err;
9133 }
9134 if (IA_CSS_FRAME_FORMAT_NV12_TILEY != new_format) {
9135 IA_CSS_ERROR("new format is not valid");
9136 err = IA_CSS_ERR_INVALID_ARGUMENTS;
9137 IA_CSS_LEAVE_ERR_PRIVATE(err);
9138 return err;
9139 } else {
9140 err = ia_css_pipe_check_format(pipe, new_format);
9141 if (IA_CSS_SUCCESS == err) {
9142 if (pin_index == 0) {
9143 pipe->output_info[0].format = new_format;
9144 } else {
9145 pipe->vf_output_info[0].format = new_format;
9146 }
9147 }
9148 }
9149 IA_CSS_LEAVE_ERR_PRIVATE(err);
9150 return err;
9151}
9152
9153#endif
9154#if defined(USE_INPUT_SYSTEM_VERSION_2)
9155
9156static enum ia_css_err
9157ia_css_stream_configure_rx(struct ia_css_stream *stream)
9158{
9159 struct ia_css_input_port *config;
9160 assert(stream != NULL);
9161
9162 config = &stream->config.source.port;
9163
9164 if (config->num_lanes == 1)
9165 stream->csi_rx_config.mode = MONO_1L_1L_0L;
9166 else if (config->num_lanes == 2)
9167 stream->csi_rx_config.mode = MONO_2L_1L_0L;
9168 else if (config->num_lanes == 3)
9169 stream->csi_rx_config.mode = MONO_3L_1L_0L;
9170 else if (config->num_lanes == 4)
9171 stream->csi_rx_config.mode = MONO_4L_1L_0L;
9172 else if (config->num_lanes != 0)
9173 return IA_CSS_ERR_INVALID_ARGUMENTS;
9174
9175 if (config->port > MIPI_PORT2_ID)
9176 return IA_CSS_ERR_INVALID_ARGUMENTS;
9177 stream->csi_rx_config.port =
9178 ia_css_isys_port_to_mipi_port(config->port);
9179 stream->csi_rx_config.timeout = config->timeout;
9180 stream->csi_rx_config.initcount = 0;
9181 stream->csi_rx_config.synccount = 0x28282828;
9182 stream->csi_rx_config.rxcount = config->rxcount;
9183 if (config->compression.type == IA_CSS_CSI2_COMPRESSION_TYPE_NONE)
9184 stream->csi_rx_config.comp = MIPI_PREDICTOR_NONE;
9185 else {
9186
9187
9188 return IA_CSS_ERR_INVALID_ARGUMENTS;
9189 }
9190 stream->csi_rx_config.is_two_ppc = (stream->config.pixels_per_clock == 2);
9191 stream->reconfigure_css_rx = true;
9192 return IA_CSS_SUCCESS;
9193}
9194#endif
9195
9196static struct ia_css_pipe *
9197find_pipe(struct ia_css_pipe *pipes[],
9198 unsigned int num_pipes,
9199 enum ia_css_pipe_mode mode,
9200 bool copy_pipe)
9201{
9202 unsigned i;
9203 assert(pipes != NULL);
9204 for (i = 0; i < num_pipes; i++) {
9205 assert(pipes[i] != NULL);
9206 if (pipes[i]->config.mode != mode)
9207 continue;
9208 if (copy_pipe && pipes[i]->mode != IA_CSS_PIPE_ID_COPY)
9209 continue;
9210 return pipes[i];
9211 }
9212 return NULL;
9213}
9214
9215static enum ia_css_err
9216ia_css_acc_stream_create(struct ia_css_stream *stream)
9217{
9218 int i;
9219 enum ia_css_err err = IA_CSS_SUCCESS;
9220
9221 assert(stream != NULL);
9222 IA_CSS_ENTER_PRIVATE("stream = %p", stream);
9223
9224 if (stream == NULL) {
9225 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
9226 return IA_CSS_ERR_INVALID_ARGUMENTS;
9227 }
9228
9229 for (i = 0; i < stream->num_pipes; i++) {
9230 struct ia_css_pipe *pipe = stream->pipes[i];
9231 assert(pipe != NULL);
9232 if (pipe == NULL) {
9233 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_ERR_INVALID_ARGUMENTS);
9234 return IA_CSS_ERR_INVALID_ARGUMENTS;
9235 }
9236
9237 pipe->stream = stream;
9238 }
9239
9240
9241 err = map_sp_threads(stream, true);
9242 if (err != IA_CSS_SUCCESS) {
9243 IA_CSS_LEAVE_ERR_PRIVATE(err);
9244 return err;
9245 }
9246
9247 for (i = 0; i < stream->num_pipes; i++) {
9248 struct ia_css_pipe *pipe = stream->pipes[i];
9249 assert(pipe != NULL);
9250 ia_css_pipe_map_queue(pipe, true);
9251 }
9252
9253 err = create_host_pipeline_structure(stream);
9254 if (err != IA_CSS_SUCCESS) {
9255 IA_CSS_LEAVE_ERR_PRIVATE(err);
9256 return err;
9257 }
9258
9259 stream->started = false;
9260
9261
9262 IA_CSS_LEAVE_ERR_PRIVATE(IA_CSS_SUCCESS);
9263
9264 return IA_CSS_SUCCESS;
9265}
9266
9267static enum ia_css_err
9268metadata_info_init(const struct ia_css_metadata_config *mdc,
9269 struct ia_css_metadata_info *md)
9270{
9271
9272 if ((mdc->resolution.height > 0) ^ (mdc->resolution.width > 0))
9273 return IA_CSS_ERR_INVALID_ARGUMENTS;
9274
9275 md->resolution = mdc->resolution;
9276
9277
9278 md->stride = CEIL_MUL(mdc->resolution.width, HIVE_ISP_DDR_WORD_BYTES);
9279 md->size = mdc->resolution.height * md->stride;
9280 return IA_CSS_SUCCESS;
9281}
9282
9283#ifdef ISP2401
9284static enum ia_css_err check_pipe_resolutions(const struct ia_css_pipe *pipe)
9285{
9286 enum ia_css_err err = IA_CSS_SUCCESS;
9287
9288 IA_CSS_ENTER_PRIVATE("");
9289
9290 if (!pipe || !pipe->stream) {
9291 IA_CSS_ERROR("null arguments");
9292 err = IA_CSS_ERR_INTERNAL_ERROR;
9293 goto EXIT;
9294 }
9295
9296 if (ia_css_util_check_res(pipe->config.input_effective_res.width,
9297 pipe->config.input_effective_res.height) != IA_CSS_SUCCESS) {
9298 IA_CSS_ERROR("effective resolution not supported");
9299 err = IA_CSS_ERR_INVALID_ARGUMENTS;
9300 goto EXIT;
9301 }
9302 if (!ia_css_util_resolution_is_zero(pipe->stream->config.input_config.input_res)) {
9303 if (!ia_css_util_res_leq(pipe->config.input_effective_res,
9304 pipe->stream->config.input_config.input_res)) {
9305 IA_CSS_ERROR("effective resolution is larger than input resolution");
9306 err = IA_CSS_ERR_INVALID_ARGUMENTS;
9307 goto EXIT;
9308 }
9309 }
9310 if (!ia_css_util_resolution_is_even(pipe->config.output_info[0].res)) {
9311 IA_CSS_ERROR("output resolution must be even");
9312 err = IA_CSS_ERR_INVALID_ARGUMENTS;
9313 goto EXIT;
9314 }
9315 if (!ia_css_util_resolution_is_even(pipe->config.vf_output_info[0].res)) {
9316 IA_CSS_ERROR("VF resolution must be even");
9317 err = IA_CSS_ERR_INVALID_ARGUMENTS;
9318 goto EXIT;
9319 }
9320EXIT:
9321 IA_CSS_LEAVE_ERR_PRIVATE(err);
9322 return err;
9323}
9324
9325#endif
9326
9327enum ia_css_err
9328ia_css_stream_create(const struct ia_css_stream_config *stream_config,
9329 int num_pipes,
9330 struct ia_css_pipe *pipes[],
9331 struct ia_css_stream **stream)
9332{
9333 struct ia_css_pipe *curr_pipe;
9334 struct ia_css_stream *curr_stream = NULL;
9335 bool spcopyonly;
9336 bool sensor_binning_changed;
9337 int i, j;
9338 enum ia_css_err err = IA_CSS_ERR_INTERNAL_ERROR;
9339 struct ia_css_metadata_info md_info;
9340#ifndef ISP2401
9341 struct ia_css_resolution effective_res;
9342#else
9343#ifdef USE_INPUT_SYSTEM_VERSION_2401
9344 bool aspect_ratio_crop_enabled = false;
9345#endif
9346#endif
9347
9348 IA_CSS_ENTER("num_pipes=%d", num_pipes);
9349 ia_css_debug_dump_stream_config(stream_config, num_pipes);
9350
9351
9352 if (num_pipes == 0 ||
9353 stream == NULL ||
9354 pipes == NULL) {
9355 err = IA_CSS_ERR_INVALID_ARGUMENTS;
9356 IA_CSS_LEAVE_ERR(err);
9357 return err;
9358 }
9359
9360#if defined(USE_INPUT_SYSTEM_VERSION_2)
9361
9362 if (stream_config->input_config.format == ATOMISP_INPUT_FORMAT_BINARY_8 &&
9363 stream_config->metadata_config.resolution.height > 0) {
9364 err = IA_CSS_ERR_INVALID_ARGUMENTS;
9365 IA_CSS_LEAVE_ERR(err);
9366 return err;
9367 }
9368#endif
9369
9370#ifdef USE_INPUT_SYSTEM_VERSION_2401
9371 if (stream_config->online && stream_config->pack_raw_pixels) {
9372 IA_CSS_LOG("online and pack raw is invalid on input system 2401");
9373 err = IA_CSS_ERR_INVALID_ARGUMENTS;
9374 IA_CSS_LEAVE_ERR(err);
9375 return err;
9376 }
9377#endif
9378
9379#if !defined(HAS_NO_INPUT_SYSTEM)
9380 ia_css_debug_pipe_graph_dump_stream_config(stream_config);
9381
9382
9383 if (stream_config->mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR)
9384#ifdef USE_INPUT_SYSTEM_VERSION_2401
9385 if (!stream_config->online)
9386#endif
9387 {
9388 unsigned int port = (unsigned int) stream_config->source.port.port;
9389 if (port >= N_MIPI_PORT_ID) {
9390 err = IA_CSS_ERR_INVALID_ARGUMENTS;
9391 IA_CSS_LEAVE_ERR(err);
9392 return err;
9393 }
9394
9395 if (my_css.size_mem_words != 0){
9396 my_css.mipi_frame_size[port] = my_css.size_mem_words;
9397 } else if (stream_config->mipi_buffer_config.size_mem_words != 0) {
9398 my_css.mipi_frame_size[port] = stream_config->mipi_buffer_config.size_mem_words;
9399 } else {
9400 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
9401 "ia_css_stream_create() exit: error, need to set mipi frame size.\n");
9402 assert(stream_config->mipi_buffer_config.size_mem_words != 0);
9403 err = IA_CSS_ERR_INTERNAL_ERROR;
9404 IA_CSS_LEAVE_ERR(err);
9405 return err;
9406 }
9407
9408 if (my_css.size_mem_words != 0) {
9409 my_css.num_mipi_frames[port] = 2;
9410 } else if (stream_config->mipi_buffer_config.nof_mipi_buffers != 0) {
9411 my_css.num_mipi_frames[port] = stream_config->mipi_buffer_config.nof_mipi_buffers;
9412 } else {
9413 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
9414 "ia_css_stream_create() exit: error, need to set number of mipi frames.\n");
9415 assert(stream_config->mipi_buffer_config.nof_mipi_buffers != 0);
9416 err = IA_CSS_ERR_INTERNAL_ERROR;
9417 IA_CSS_LEAVE_ERR(err);
9418 return err;
9419 }
9420
9421 }
9422#endif
9423
9424
9425 err = metadata_info_init(&stream_config->metadata_config, &md_info);
9426 if (err != IA_CSS_SUCCESS) {
9427 IA_CSS_LEAVE_ERR(err);
9428 return err;
9429 }
9430
9431
9432 curr_stream = kmalloc(sizeof(struct ia_css_stream), GFP_KERNEL);
9433 if (!curr_stream) {
9434 err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
9435 IA_CSS_LEAVE_ERR(err);
9436 return err;
9437 }
9438
9439 memset(curr_stream, 0, sizeof(struct ia_css_stream));
9440 curr_stream->info.metadata_info = md_info;
9441
9442
9443 curr_stream->num_pipes = num_pipes;
9444 curr_stream->pipes = kzalloc(num_pipes * sizeof(struct ia_css_pipe *), GFP_KERNEL);
9445 if (!curr_stream->pipes) {
9446 curr_stream->num_pipes = 0;
9447 kfree(curr_stream);
9448 curr_stream = NULL;
9449 err = IA_CSS_ERR_CANNOT_ALLOCATE_MEMORY;
9450 IA_CSS_LEAVE_ERR(err);
9451 return err;
9452 }
9453
9454 spcopyonly = (num_pipes == 1) && (pipes[0]->config.mode == IA_CSS_PIPE_MODE_COPY);
9455 for (i = 0; i < num_pipes; i++)
9456 curr_stream->pipes [i] = pipes[i];
9457 curr_stream->last_pipe = curr_stream->pipes[0];
9458
9459 curr_stream->config = *stream_config;
9460
9461#if defined(USE_INPUT_SYSTEM_VERSION_2401) && defined(CSI2P_DISABLE_ISYS2401_ONLINE_MODE)
9462 if (stream_config->mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR &&
9463 stream_config->online)
9464 curr_stream->config.online = false;
9465#endif
9466
9467#ifdef USE_INPUT_SYSTEM_VERSION_2401
9468 if (curr_stream->config.online) {
9469 curr_stream->config.source.port.num_lanes = stream_config->source.port.num_lanes;
9470 curr_stream->config.mode = IA_CSS_INPUT_MODE_BUFFERED_SENSOR;
9471 }
9472#endif
9473
9474 if (curr_stream->config.target_num_cont_raw_buf == 0)
9475 curr_stream->config.target_num_cont_raw_buf = NUM_CONTINUOUS_FRAMES;
9476 if (curr_stream->config.init_num_cont_raw_buf == 0)
9477 curr_stream->config.init_num_cont_raw_buf = curr_stream->config.target_num_cont_raw_buf;
9478
9479
9480 if (curr_stream->config.ia_css_enable_raw_buffer_locking)
9481 sh_css_sp_configure_enable_raw_pool_locking(
9482 curr_stream->config.lock_all);
9483
9484
9485 switch (curr_stream->config.mode) {
9486 case IA_CSS_INPUT_MODE_SENSOR:
9487 case IA_CSS_INPUT_MODE_BUFFERED_SENSOR:
9488#if defined(USE_INPUT_SYSTEM_VERSION_2)
9489 ia_css_stream_configure_rx(curr_stream);
9490#endif
9491 break;
9492 case IA_CSS_INPUT_MODE_TPG:
9493#if !defined(HAS_NO_INPUT_SYSTEM) && defined(USE_INPUT_SYSTEM_VERSION_2)
9494 IA_CSS_LOG("tpg_configuration: x_mask=%d, y_mask=%d, x_delta=%d, y_delta=%d, xy_mask=%d",
9495 curr_stream->config.source.tpg.x_mask,
9496 curr_stream->config.source.tpg.y_mask,
9497 curr_stream->config.source.tpg.x_delta,
9498 curr_stream->config.source.tpg.y_delta,
9499 curr_stream->config.source.tpg.xy_mask);
9500
9501 sh_css_sp_configure_tpg(
9502 curr_stream->config.source.tpg.x_mask,
9503 curr_stream->config.source.tpg.y_mask,
9504 curr_stream->config.source.tpg.x_delta,
9505 curr_stream->config.source.tpg.y_delta,
9506 curr_stream->config.source.tpg.xy_mask);
9507#endif
9508 break;
9509 case IA_CSS_INPUT_MODE_PRBS:
9510#if !defined(HAS_NO_INPUT_SYSTEM) && defined(USE_INPUT_SYSTEM_VERSION_2)
9511 IA_CSS_LOG("mode prbs");
9512 sh_css_sp_configure_prbs(curr_stream->config.source.prbs.seed);
9513#endif
9514 break;
9515 case IA_CSS_INPUT_MODE_MEMORY:
9516 IA_CSS_LOG("mode memory");
9517 curr_stream->reconfigure_css_rx = false;
9518 break;
9519 default:
9520 IA_CSS_LOG("mode sensor/default");
9521 }
9522
9523#ifdef ISP2401
9524#ifdef USE_INPUT_SYSTEM_VERSION_2401
9525 err = aspect_ratio_crop_init(curr_stream,
9526 pipes,
9527 &aspect_ratio_crop_enabled);
9528 if (err != IA_CSS_SUCCESS) {
9529 IA_CSS_LEAVE_ERR(err);
9530 return err;
9531 }
9532#endif
9533
9534#endif
9535 for (i = 0; i < num_pipes; i++) {
9536#ifdef ISP2401
9537 struct ia_css_resolution effective_res;
9538#endif
9539 curr_pipe = pipes[i];
9540
9541 curr_pipe->stream = curr_stream;
9542
9543
9544 effective_res = curr_pipe->config.input_effective_res;
9545 if (effective_res.height == 0 || effective_res.width == 0) {
9546 effective_res = curr_pipe->stream->config.input_config.effective_res;
9547#ifdef ISP2401
9548
9549#if defined(USE_INPUT_SYSTEM_VERSION_2401)
9550
9551
9552 if (aspect_ratio_crop_check(aspect_ratio_crop_enabled, curr_pipe)) {
9553
9554 struct ia_css_resolution crop_res;
9555
9556 err = aspect_ratio_crop(curr_pipe, &crop_res);
9557 if (err == IA_CSS_SUCCESS) {
9558 effective_res = crop_res;
9559 } else {
9560
9561
9562 IA_CSS_LOG("aspect_ratio_crop() failed with err(%d)", err);
9563 }
9564 }
9565#endif
9566#endif
9567 curr_pipe->config.input_effective_res = effective_res;
9568 }
9569 IA_CSS_LOG("effective_res=%dx%d",
9570 effective_res.width,
9571 effective_res.height);
9572 }
9573
9574#ifdef ISP2401
9575 for (i = 0; i < num_pipes; i++) {
9576 if (pipes[i]->config.mode != IA_CSS_PIPE_MODE_ACC &&
9577 pipes[i]->config.mode != IA_CSS_PIPE_MODE_COPY) {
9578 err = check_pipe_resolutions(pipes[i]);
9579 if (err != IA_CSS_SUCCESS) {
9580 goto ERR;
9581 }
9582 }
9583 }
9584
9585#endif
9586 err = ia_css_stream_isp_parameters_init(curr_stream);
9587 if (err != IA_CSS_SUCCESS)
9588 goto ERR;
9589 IA_CSS_LOG("isp_params_configs: %p", curr_stream->isp_params_configs);
9590
9591 if (num_pipes == 1 && pipes[0]->config.mode == IA_CSS_PIPE_MODE_ACC) {
9592 *stream = curr_stream;
9593 err = ia_css_acc_stream_create(curr_stream);
9594 goto ERR;
9595 }
9596
9597 if (!spcopyonly){
9598 sensor_binning_changed =
9599 sh_css_params_set_binning_factor(curr_stream, curr_stream->config.sensor_binning_factor);
9600 } else {
9601 sensor_binning_changed = false;
9602 }
9603
9604 IA_CSS_LOG("sensor_binning=%d, changed=%d",
9605 curr_stream->config.sensor_binning_factor, sensor_binning_changed);
9606
9607 IA_CSS_LOG("num_pipes=%d", num_pipes);
9608 curr_stream->cont_capt = false;
9609
9610
9611 if (curr_stream->config.continuous) {
9612
9613 struct ia_css_pipe *preview_pipe;
9614 struct ia_css_pipe *video_pipe;
9615 struct ia_css_pipe *acc_pipe;
9616 struct ia_css_pipe *capture_pipe = NULL;
9617 struct ia_css_pipe *copy_pipe = NULL;
9618
9619 if (num_pipes >= 2) {
9620 curr_stream->cont_capt = true;
9621 curr_stream->disable_cont_vf = curr_stream->config.disable_cont_viewfinder;
9622#ifndef ISP2401
9623 curr_stream->stop_copy_preview = my_css.stop_copy_preview;
9624#endif
9625 }
9626
9627
9628 preview_pipe = find_pipe(pipes, num_pipes,
9629 IA_CSS_PIPE_MODE_PREVIEW, false);
9630 video_pipe = find_pipe(pipes, num_pipes,
9631 IA_CSS_PIPE_MODE_VIDEO, false);
9632 acc_pipe = find_pipe(pipes, num_pipes,
9633 IA_CSS_PIPE_MODE_ACC, false);
9634 if (acc_pipe && num_pipes == 2 && curr_stream->cont_capt == true)
9635 curr_stream->cont_capt = false;
9636 if (curr_stream->cont_capt == true) {
9637 capture_pipe = find_pipe(pipes, num_pipes,
9638 IA_CSS_PIPE_MODE_CAPTURE, false);
9639 if (capture_pipe == NULL) {
9640 err = IA_CSS_ERR_INTERNAL_ERROR;
9641 goto ERR;
9642 }
9643 }
9644
9645 if (preview_pipe && video_pipe) {
9646 err = IA_CSS_ERR_INVALID_ARGUMENTS;
9647 goto ERR;
9648 }
9649
9650 if (preview_pipe && !preview_pipe->pipe_settings.preview.copy_pipe) {
9651 err = create_pipe(IA_CSS_PIPE_MODE_CAPTURE, ©_pipe, true);
9652 if (err != IA_CSS_SUCCESS)
9653 goto ERR;
9654 ia_css_pipe_config_defaults(©_pipe->config);
9655 preview_pipe->pipe_settings.preview.copy_pipe = copy_pipe;
9656 copy_pipe->stream = curr_stream;
9657 }
9658 if (preview_pipe && (curr_stream->cont_capt == true)) {
9659 preview_pipe->pipe_settings.preview.capture_pipe = capture_pipe;
9660 }
9661 if (video_pipe && !video_pipe->pipe_settings.video.copy_pipe) {
9662 err = create_pipe(IA_CSS_PIPE_MODE_CAPTURE, ©_pipe, true);
9663 if (err != IA_CSS_SUCCESS)
9664 goto ERR;
9665 ia_css_pipe_config_defaults(©_pipe->config);
9666 video_pipe->pipe_settings.video.copy_pipe = copy_pipe;
9667 copy_pipe->stream = curr_stream;
9668 }
9669 if (video_pipe && (curr_stream->cont_capt == true)) {
9670 video_pipe->pipe_settings.video.capture_pipe = capture_pipe;
9671 }
9672 if (preview_pipe && acc_pipe) {
9673 preview_pipe->pipe_settings.preview.acc_pipe = acc_pipe;
9674 }
9675 }
9676 for (i = 0; i < num_pipes; i++) {
9677 curr_pipe = pipes[i];
9678
9679 curr_pipe->stream = curr_stream;
9680#ifndef ISP2401
9681
9682
9683 effective_res = curr_pipe->config.input_effective_res;
9684 err = ia_css_util_check_res(
9685 effective_res.width,
9686 effective_res.height);
9687 if (err != IA_CSS_SUCCESS)
9688 goto ERR;
9689#endif
9690
9691 if (sensor_binning_changed)
9692 sh_css_pipe_free_shading_table(curr_pipe);
9693 }
9694
9695
9696 for (i = 0; i < num_pipes; i++) {
9697 struct ia_css_pipe_info *pipe_info = NULL;
9698 curr_pipe = pipes[i];
9699
9700 err = sh_css_pipe_load_binaries(curr_pipe);
9701 if (err != IA_CSS_SUCCESS)
9702 goto ERR;
9703
9704
9705 pipe_info = &curr_pipe->info;
9706 for (j = 0; j < IA_CSS_PIPE_MAX_OUTPUT_STAGE; j++) {
9707 err = sh_css_pipe_get_output_frame_info(curr_pipe,
9708 &pipe_info->output_info[j], j);
9709 if (err != IA_CSS_SUCCESS)
9710 goto ERR;
9711 }
9712#ifdef ISP2401
9713 pipe_info->output_system_in_res_info = curr_pipe->config.output_system_in_res;
9714#endif
9715 if (!spcopyonly){
9716 err = sh_css_pipe_get_shading_info(curr_pipe,
9717#ifndef ISP2401
9718 &pipe_info->shading_info);
9719#else
9720 &pipe_info->shading_info, &curr_pipe->config);
9721#endif
9722 if (err != IA_CSS_SUCCESS)
9723 goto ERR;
9724 err = sh_css_pipe_get_grid_info(curr_pipe,
9725 &pipe_info->grid_info);
9726 if (err != IA_CSS_SUCCESS)
9727 goto ERR;
9728 for (j = 0; j < IA_CSS_PIPE_MAX_OUTPUT_STAGE; j++) {
9729 sh_css_pipe_get_viewfinder_frame_info(curr_pipe,
9730 &pipe_info->vf_output_info[j], j);
9731 if (err != IA_CSS_SUCCESS)
9732 goto ERR;
9733 }
9734 }
9735
9736 my_css.active_pipes[ia_css_pipe_get_pipe_num(curr_pipe)] = curr_pipe;
9737 }
9738
9739 curr_stream->started = false;
9740
9741
9742 err = map_sp_threads(curr_stream, true);
9743 if (err != IA_CSS_SUCCESS) {
9744 IA_CSS_LOG("map_sp_threads: return_err=%d", err);
9745 goto ERR;
9746 }
9747
9748 for (i = 0; i < num_pipes; i++) {
9749 curr_pipe = pipes[i];
9750 ia_css_pipe_map_queue(curr_pipe, true);
9751 }
9752
9753
9754 err = create_host_pipeline_structure(curr_stream);
9755 if (err != IA_CSS_SUCCESS) {
9756 IA_CSS_LOG("create_host_pipeline_structure: return_err=%d", err);
9757 goto ERR;
9758 }
9759
9760
9761 *stream = curr_stream;
9762
9763ERR:
9764#ifndef ISP2401
9765 if (err == IA_CSS_SUCCESS)
9766 {
9767
9768 if (my_css_save.mode == sh_css_mode_working) {
9769 for (i = 0; i < MAX_ACTIVE_STREAMS; i++)
9770 if (!my_css_save.stream_seeds[i].stream) {
9771 IA_CSS_LOG("entered stream into loc=%d", i);
9772 my_css_save.stream_seeds[i].orig_stream = stream;
9773 my_css_save.stream_seeds[i].stream = curr_stream;
9774 my_css_save.stream_seeds[i].num_pipes = num_pipes;
9775 my_css_save.stream_seeds[i].stream_config = *stream_config;
9776 for (j = 0; j < num_pipes; j++) {
9777 my_css_save.stream_seeds[i].pipe_config[j] = pipes[j]->config;
9778 my_css_save.stream_seeds[i].pipes[j] = pipes[j];
9779 my_css_save.stream_seeds[i].orig_pipes[j] = &pipes[j];
9780 }
9781 break;
9782 }
9783 }
9784#else
9785 if (err == IA_CSS_SUCCESS) {
9786 err = ia_css_save_stream(curr_stream);
9787#endif
9788 } else {
9789 ia_css_stream_destroy(curr_stream);
9790 }
9791#ifndef ISP2401
9792 IA_CSS_LEAVE("return_err=%d mode=%d", err, my_css_save.mode);
9793#else
9794 IA_CSS_LEAVE("return_err=%d", err);
9795#endif
9796 return err;
9797}
9798
9799enum ia_css_err
9800ia_css_stream_destroy(struct ia_css_stream *stream)
9801{
9802 int i;
9803 enum ia_css_err err = IA_CSS_SUCCESS;
9804#ifdef ISP2401
9805 enum ia_css_err err1 = IA_CSS_SUCCESS;
9806 enum ia_css_err err2 = IA_CSS_SUCCESS;
9807#endif
9808
9809 IA_CSS_ENTER_PRIVATE("stream = %p", stream);
9810 if (stream == NULL) {
9811 err = IA_CSS_ERR_INVALID_ARGUMENTS;
9812 IA_CSS_LEAVE_ERR_PRIVATE(err);
9813 return err;
9814 }
9815
9816 ia_css_stream_isp_parameters_uninit(stream);
9817
9818 if ((stream->last_pipe != NULL) &&
9819 ia_css_pipeline_is_mapped(stream->last_pipe->pipe_num)) {
9820#if defined(USE_INPUT_SYSTEM_VERSION_2401)
9821 for (i = 0; i < stream->num_pipes; i++) {
9822 struct ia_css_pipe *entry = stream->pipes[i];
9823 unsigned int sp_thread_id;
9824 struct sh_css_sp_pipeline_terminal *sp_pipeline_input_terminal;
9825
9826 assert(entry != NULL);
9827 if (entry != NULL) {
9828
9829 if (ia_css_pipeline_get_sp_thread_id(
9830 ia_css_pipe_get_pipe_num(entry), &sp_thread_id) != true)
9831 return IA_CSS_ERR_INTERNAL_ERROR;
9832
9833 sp_pipeline_input_terminal =
9834 &(sh_css_sp_group.pipe_io[sp_thread_id].input);
9835
9836 for (i = 0; i < IA_CSS_STREAM_MAX_ISYS_STREAM_PER_CH; i++) {
9837 ia_css_isys_stream_h isys_stream =
9838 &(sp_pipeline_input_terminal->context.virtual_input_system_stream[i]);
9839 if (stream->config.isys_config[i].valid && isys_stream->valid)
9840 ia_css_isys_stream_destroy(isys_stream);
9841 }
9842 }
9843 }
9844#ifndef ISP2401
9845 if (stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR) {
9846#else
9847 if (stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR ||
9848 stream->config.mode == IA_CSS_INPUT_MODE_TPG ||
9849 stream->config.mode == IA_CSS_INPUT_MODE_PRBS) {
9850#endif
9851 for (i = 0; i < stream->num_pipes; i++) {
9852 struct ia_css_pipe *entry = stream->pipes[i];
9853
9854
9855
9856
9857 if (entry != NULL)
9858 free_mipi_frames(entry);
9859 }
9860 }
9861 stream_unregister_with_csi_rx(stream);
9862#endif
9863
9864 for (i = 0; i < stream->num_pipes; i++) {
9865 struct ia_css_pipe *curr_pipe = stream->pipes[i];
9866 assert(curr_pipe != NULL);
9867 ia_css_pipe_map_queue(curr_pipe, false);
9868 }
9869
9870 err = map_sp_threads(stream, false);
9871 if (err != IA_CSS_SUCCESS) {
9872 IA_CSS_LEAVE_ERR_PRIVATE(err);
9873 return err;
9874 }
9875 }
9876
9877
9878 for (i = 0; i < stream->num_pipes; i++) {
9879 struct ia_css_pipe *entry = stream->pipes[i];
9880 assert(entry != NULL);
9881 if (entry != NULL) {
9882
9883 entry->stream = NULL;
9884
9885 if (entry->mode == IA_CSS_PIPE_ID_PREVIEW &&
9886 entry->pipe_settings.preview.copy_pipe) {
9887 IA_CSS_LOG("clearing stream on internal preview copy pipe");
9888 entry->pipe_settings.preview.copy_pipe->stream = NULL;
9889 }
9890 if (entry->mode == IA_CSS_PIPE_ID_VIDEO &&
9891 entry->pipe_settings.video.copy_pipe) {
9892 IA_CSS_LOG("clearing stream on internal video copy pipe");
9893 entry->pipe_settings.video.copy_pipe->stream = NULL;
9894 }
9895 err = sh_css_pipe_unload_binaries(entry);
9896 }
9897 }
9898
9899 kfree(stream->pipes);
9900 stream->pipes = NULL;
9901 stream->num_pipes = 0;
9902#ifndef ISP2401
9903
9904 if (my_css_save.mode == sh_css_mode_working)
9905 for(i=0;i<MAX_ACTIVE_STREAMS;i++)
9906 if (my_css_save.stream_seeds[i].stream == stream)
9907 {
9908 IA_CSS_LOG("took out stream %d", i);
9909 my_css_save.stream_seeds[i].stream = NULL;
9910 break;
9911 }
9912#else
9913 err2 = ia_css_save_restore_remove_stream(stream);
9914
9915 err1 = (err != IA_CSS_SUCCESS) ? err : err2;
9916#endif
9917 kfree(stream);
9918#ifndef ISP2401
9919 IA_CSS_LEAVE_ERR(err);
9920#else
9921 IA_CSS_LEAVE_ERR(err1);
9922#endif
9923
9924#ifndef ISP2401
9925 return err;
9926#else
9927 return err1;
9928#endif
9929}
9930
9931enum ia_css_err
9932ia_css_stream_get_info(const struct ia_css_stream *stream,
9933 struct ia_css_stream_info *stream_info)
9934{
9935 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_get_info: enter/exit\n");
9936 assert(stream != NULL);
9937 assert(stream_info != NULL);
9938
9939 *stream_info = stream->info;
9940 return IA_CSS_SUCCESS;
9941}
9942
9943
9944
9945
9946
9947
9948
9949enum ia_css_err
9950ia_css_stream_load(struct ia_css_stream *stream)
9951{
9952#ifndef ISP2401
9953 int i;
9954 enum ia_css_err err;
9955 assert(stream != NULL);
9956 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_load() enter, \n");
9957 for (i = 0; i < MAX_ACTIVE_STREAMS; i++) {
9958 if (my_css_save.stream_seeds[i].stream == stream) {
9959 int j;
9960 for ( j = 0; j < my_css_save.stream_seeds[i].num_pipes; j++) {
9961 if ((err = ia_css_pipe_create(&(my_css_save.stream_seeds[i].pipe_config[j]), &my_css_save.stream_seeds[i].pipes[j])) != IA_CSS_SUCCESS) {
9962 if (j) {
9963 int k;
9964 for(k=0;k<j;k++)
9965 ia_css_pipe_destroy(my_css_save.stream_seeds[i].pipes[k]);
9966 }
9967 return err;
9968 }
9969 }
9970 err = ia_css_stream_create(&(my_css_save.stream_seeds[i].stream_config),
9971 my_css_save.stream_seeds[i].num_pipes,
9972 my_css_save.stream_seeds[i].pipes,
9973 &(my_css_save.stream_seeds[i].stream));
9974 if (err != IA_CSS_SUCCESS) {
9975 ia_css_stream_destroy(stream);
9976 for (j = 0; j < my_css_save.stream_seeds[i].num_pipes; j++)
9977 ia_css_pipe_destroy(my_css_save.stream_seeds[i].pipes[j]);
9978 return err;
9979 }
9980 break;
9981 }
9982 }
9983 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_load() exit, \n");
9984 return IA_CSS_SUCCESS;
9985#else
9986
9987 (void)stream;
9988 return IA_CSS_ERR_NOT_SUPPORTED;
9989#endif
9990}
9991
9992enum ia_css_err
9993ia_css_stream_start(struct ia_css_stream *stream)
9994{
9995 enum ia_css_err err = IA_CSS_SUCCESS;
9996 IA_CSS_ENTER("stream = %p", stream);
9997 if ((stream == NULL) || (stream->last_pipe == NULL)) {
9998 IA_CSS_LEAVE_ERR(IA_CSS_ERR_INVALID_ARGUMENTS);
9999 return IA_CSS_ERR_INVALID_ARGUMENTS;
10000 }
10001 IA_CSS_LOG("starting %d", stream->last_pipe->mode);
10002
10003 sh_css_sp_set_disable_continuous_viewfinder(stream->disable_cont_vf);
10004
10005
10006 err = create_host_pipeline(stream);
10007 if (err != IA_CSS_SUCCESS) {
10008 IA_CSS_LEAVE_ERR(err);
10009 return err;
10010 }
10011
10012#if !defined(HAS_NO_INPUT_SYSTEM)
10013#if defined(USE_INPUT_SYSTEM_VERSION_2401)
10014 if((stream->config.mode == IA_CSS_INPUT_MODE_SENSOR) ||
10015 (stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR))
10016 stream_register_with_csi_rx(stream);
10017#endif
10018#endif
10019
10020#if !defined(HAS_NO_INPUT_SYSTEM) && defined(USE_INPUT_SYSTEM_VERSION_2)
10021
10022 if (stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR)
10023 {
10024 unsigned int idx;
10025 unsigned int port = (unsigned int) (stream->config.source.port.port) ;
10026
10027 for (idx = 0; idx < IA_CSS_MIPI_SIZE_CHECK_MAX_NOF_ENTRIES_PER_PORT; idx++) {
10028 sh_css_sp_group.config.mipi_sizes_for_check[port][idx] = sh_css_get_mipi_sizes_for_check(port, idx);
10029 }
10030 }
10031#endif
10032
10033#if !defined(HAS_NO_INPUT_SYSTEM)
10034 if (stream->config.mode != IA_CSS_INPUT_MODE_MEMORY) {
10035 err = sh_css_config_input_network(stream);
10036 if (err != IA_CSS_SUCCESS)
10037 return err;
10038 }
10039#endif
10040
10041 err = sh_css_pipe_start(stream);
10042 IA_CSS_LEAVE_ERR(err);
10043 return err;
10044}
10045
10046enum ia_css_err
10047ia_css_stream_stop(struct ia_css_stream *stream)
10048{
10049 enum ia_css_err err = IA_CSS_SUCCESS;
10050
10051 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_stop() enter/exit\n");
10052 assert(stream != NULL);
10053 assert(stream->last_pipe != NULL);
10054 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_stop: stopping %d\n",
10055 stream->last_pipe->mode);
10056
10057#if !defined(HAS_NO_INPUT_SYSTEM) && defined(USE_INPUT_SYSTEM_VERSION_2)
10058
10059 if (stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR)
10060 {
10061 unsigned int idx;
10062 unsigned int port = (unsigned int) (stream->config.source.port.port) ;
10063
10064 for (idx = 0; idx < IA_CSS_MIPI_SIZE_CHECK_MAX_NOF_ENTRIES_PER_PORT; idx++) {
10065 sh_css_sp_group.config.mipi_sizes_for_check[port][idx] = 0;
10066 }
10067 }
10068#endif
10069#ifndef ISP2401
10070 err = ia_css_pipeline_request_stop(&stream->last_pipe->pipeline);
10071#else
10072
10073 err = sh_css_pipes_stop(stream);
10074#endif
10075 if (err != IA_CSS_SUCCESS)
10076 return err;
10077
10078
10079
10080
10081
10082 return err;
10083}
10084
10085bool
10086ia_css_stream_has_stopped(struct ia_css_stream *stream)
10087{
10088 bool stopped;
10089 assert(stream != NULL);
10090
10091#ifndef ISP2401
10092 stopped = ia_css_pipeline_has_stopped(&stream->last_pipe->pipeline);
10093#else
10094 stopped = sh_css_pipes_have_stopped(stream);
10095#endif
10096
10097 return stopped;
10098}
10099
10100#ifndef ISP2401
10101
10102
10103
10104
10105enum ia_css_err
10106ia_css_stream_unload(struct ia_css_stream *stream)
10107{
10108 int i;
10109 assert(stream != NULL);
10110 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_unload() enter, \n");
10111
10112 assert (stream != NULL);
10113 for(i=0;i<MAX_ACTIVE_STREAMS;i++)
10114 if (my_css_save.stream_seeds[i].stream == stream)
10115 {
10116 int j;
10117 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_unload(): unloading %d (%p)\n", i, my_css_save.stream_seeds[i].stream);
10118 ia_css_stream_destroy(stream);
10119 for(j=0;j<my_css_save.stream_seeds[i].num_pipes;j++)
10120 ia_css_pipe_destroy(my_css_save.stream_seeds[i].pipes[j]);
10121 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_unload(): after unloading %d (%p)\n", i, my_css_save.stream_seeds[i].stream);
10122 break;
10123 }
10124 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_stream_unload() exit, \n");
10125 return IA_CSS_SUCCESS;
10126}
10127
10128#endif
10129enum ia_css_err
10130ia_css_temp_pipe_to_pipe_id(const struct ia_css_pipe *pipe, enum ia_css_pipe_id *pipe_id)
10131{
10132 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_temp_pipe_to_pipe_id() enter/exit\n");
10133 if (pipe != NULL)
10134 *pipe_id = pipe->mode;
10135 else
10136 *pipe_id = IA_CSS_PIPE_ID_COPY;
10137
10138 return IA_CSS_SUCCESS;
10139}
10140
10141enum atomisp_input_format
10142ia_css_stream_get_format(const struct ia_css_stream *stream)
10143{
10144 return stream->config.input_config.format;
10145}
10146
10147bool
10148ia_css_stream_get_two_pixels_per_clock(const struct ia_css_stream *stream)
10149{
10150 return (stream->config.pixels_per_clock == 2);
10151}
10152
10153struct ia_css_binary *
10154ia_css_stream_get_shading_correction_binary(const struct ia_css_stream *stream)
10155{
10156 struct ia_css_pipe *pipe;
10157
10158 assert(stream != NULL);
10159
10160 pipe = stream->pipes[0];
10161
10162 if (stream->num_pipes == 2) {
10163 assert(stream->pipes[1] != NULL);
10164 if (stream->pipes[1]->config.mode == IA_CSS_PIPE_MODE_VIDEO ||
10165 stream->pipes[1]->config.mode == IA_CSS_PIPE_MODE_PREVIEW)
10166 pipe = stream->pipes[1];
10167 }
10168
10169 return ia_css_pipe_get_shading_correction_binary(pipe);
10170}
10171
10172struct ia_css_binary *
10173ia_css_stream_get_dvs_binary(const struct ia_css_stream *stream)
10174{
10175 int i;
10176 struct ia_css_pipe *video_pipe = NULL;
10177
10178
10179 for (i=0; i<stream->num_pipes; i++) {
10180 struct ia_css_pipe *pipe = stream->pipes[i];
10181 if (pipe->config.mode == IA_CSS_PIPE_MODE_VIDEO) {
10182 video_pipe = pipe;
10183 break;
10184 }
10185 }
10186 if (video_pipe)
10187 return &video_pipe->pipe_settings.video.video_binary;
10188 return NULL;
10189}
10190
10191struct ia_css_binary *
10192ia_css_stream_get_3a_binary(const struct ia_css_stream *stream)
10193{
10194 struct ia_css_pipe *pipe;
10195 struct ia_css_binary *s3a_binary = NULL;
10196
10197 assert(stream != NULL);
10198
10199 pipe = stream->pipes[0];
10200
10201 if (stream->num_pipes == 2) {
10202 assert(stream->pipes[1] != NULL);
10203 if (stream->pipes[1]->config.mode == IA_CSS_PIPE_MODE_VIDEO ||
10204 stream->pipes[1]->config.mode == IA_CSS_PIPE_MODE_PREVIEW)
10205 pipe = stream->pipes[1];
10206 }
10207
10208 s3a_binary = ia_css_pipe_get_s3a_binary(pipe);
10209
10210 return s3a_binary;
10211}
10212
10213
10214enum ia_css_err
10215ia_css_stream_set_output_padded_width(struct ia_css_stream *stream, unsigned int output_padded_width)
10216{
10217 struct ia_css_pipe *pipe;
10218
10219 assert(stream != NULL);
10220
10221 pipe = stream->last_pipe;
10222
10223 assert(pipe != NULL);
10224
10225
10226 pipe->config.output_info[IA_CSS_PIPE_OUTPUT_STAGE_0].padded_width = output_padded_width;
10227 pipe->output_info[IA_CSS_PIPE_OUTPUT_STAGE_0].padded_width = output_padded_width;
10228
10229 return IA_CSS_SUCCESS;
10230}
10231
10232static struct ia_css_binary *
10233ia_css_pipe_get_shading_correction_binary(const struct ia_css_pipe *pipe)
10234{
10235 struct ia_css_binary *binary = NULL;
10236
10237 assert(pipe != NULL);
10238
10239 switch (pipe->config.mode) {
10240 case IA_CSS_PIPE_MODE_PREVIEW:
10241 binary = (struct ia_css_binary *)&pipe->pipe_settings.preview.preview_binary;
10242 break;
10243 case IA_CSS_PIPE_MODE_VIDEO:
10244 binary = (struct ia_css_binary *)&pipe->pipe_settings.video.video_binary;
10245 break;
10246 case IA_CSS_PIPE_MODE_CAPTURE:
10247 if (pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_PRIMARY) {
10248 unsigned int i;
10249
10250 for (i = 0; i < pipe->pipe_settings.capture.num_primary_stage; i++) {
10251 if (pipe->pipe_settings.capture.primary_binary[i].info->sp.enable.sc) {
10252 binary = (struct ia_css_binary *)&pipe->pipe_settings.capture.primary_binary[i];
10253 break;
10254 }
10255 }
10256 }
10257 else if (pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_BAYER)
10258 binary = (struct ia_css_binary *)&pipe->pipe_settings.capture.pre_isp_binary;
10259 else if (pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_ADVANCED ||
10260 pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_LOW_LIGHT) {
10261 if (pipe->config.isp_pipe_version == IA_CSS_PIPE_VERSION_1)
10262 binary = (struct ia_css_binary *)&pipe->pipe_settings.capture.pre_isp_binary;
10263 else if (pipe->config.isp_pipe_version == IA_CSS_PIPE_VERSION_2_2)
10264 binary = (struct ia_css_binary *)&pipe->pipe_settings.capture.post_isp_binary;
10265 }
10266 break;
10267 default:
10268 break;
10269 }
10270
10271 if (binary && binary->info->sp.enable.sc)
10272 return binary;
10273
10274 return NULL;
10275}
10276
10277static struct ia_css_binary *
10278ia_css_pipe_get_s3a_binary(const struct ia_css_pipe *pipe)
10279{
10280 struct ia_css_binary *binary = NULL;
10281
10282 assert(pipe != NULL);
10283
10284 switch (pipe->config.mode) {
10285 case IA_CSS_PIPE_MODE_PREVIEW:
10286 binary = (struct ia_css_binary*)&pipe->pipe_settings.preview.preview_binary;
10287 break;
10288 case IA_CSS_PIPE_MODE_VIDEO:
10289 binary = (struct ia_css_binary*)&pipe->pipe_settings.video.video_binary;
10290 break;
10291 case IA_CSS_PIPE_MODE_CAPTURE:
10292 if (pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_PRIMARY) {
10293 unsigned int i;
10294 for (i = 0; i < pipe->pipe_settings.capture.num_primary_stage; i++) {
10295 if (pipe->pipe_settings.capture.primary_binary[i].info->sp.enable.s3a) {
10296 binary = (struct ia_css_binary *)&pipe->pipe_settings.capture.primary_binary[i];
10297 break;
10298 }
10299 }
10300 }
10301 else if (pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_BAYER)
10302 binary = (struct ia_css_binary *)&pipe->pipe_settings.capture.pre_isp_binary;
10303 else if (pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_ADVANCED ||
10304 pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_LOW_LIGHT) {
10305 if (pipe->config.isp_pipe_version == IA_CSS_PIPE_VERSION_1)
10306 binary = (struct ia_css_binary *)&pipe->pipe_settings.capture.pre_isp_binary;
10307 else if (pipe->config.isp_pipe_version == IA_CSS_PIPE_VERSION_2_2)
10308 binary = (struct ia_css_binary *)&pipe->pipe_settings.capture.post_isp_binary;
10309 else
10310 assert(0);
10311 }
10312 break;
10313 default:
10314 break;
10315 }
10316
10317 if (binary && !binary->info->sp.enable.s3a)
10318 binary = NULL;
10319
10320 return binary;
10321}
10322
10323static struct ia_css_binary *
10324ia_css_pipe_get_sdis_binary(const struct ia_css_pipe *pipe)
10325{
10326 struct ia_css_binary *binary = NULL;
10327
10328 assert(pipe != NULL);
10329
10330 switch (pipe->config.mode) {
10331 case IA_CSS_PIPE_MODE_VIDEO:
10332 binary = (struct ia_css_binary*)&pipe->pipe_settings.video.video_binary;
10333 break;
10334 default:
10335 break;
10336 }
10337
10338 if (binary && !binary->info->sp.enable.dis)
10339 binary = NULL;
10340
10341 return binary;
10342}
10343
10344struct ia_css_pipeline *
10345ia_css_pipe_get_pipeline(const struct ia_css_pipe *pipe)
10346{
10347 assert(pipe != NULL);
10348
10349 return (struct ia_css_pipeline*)&pipe->pipeline;
10350}
10351
10352unsigned int
10353ia_css_pipe_get_pipe_num(const struct ia_css_pipe *pipe)
10354{
10355 assert(pipe != NULL);
10356
10357
10358
10359
10360
10361
10362 assert(pipe->pipe_num < IA_CSS_PIPELINE_NUM_MAX);
10363
10364 if (pipe->pipe_num >= IA_CSS_PIPELINE_NUM_MAX)
10365 return (IA_CSS_PIPELINE_NUM_MAX - 1);
10366
10367 return pipe->pipe_num;
10368}
10369
10370
10371unsigned int
10372ia_css_pipe_get_isp_pipe_version(const struct ia_css_pipe *pipe)
10373{
10374 assert(pipe != NULL);
10375
10376 return (unsigned int)pipe->config.isp_pipe_version;
10377}
10378
10379#define SP_START_TIMEOUT_US 30000000
10380
10381enum ia_css_err
10382ia_css_start_sp(void)
10383{
10384 unsigned long timeout;
10385 enum ia_css_err err = IA_CSS_SUCCESS;
10386
10387 IA_CSS_ENTER("");
10388 sh_css_sp_start_isp();
10389
10390
10391 timeout = SP_START_TIMEOUT_US;
10392 while((ia_css_spctrl_get_state(SP0_ID) != IA_CSS_SP_SW_INITIALIZED) && timeout) {
10393 timeout--;
10394 hrt_sleep();
10395 }
10396 if (timeout == 0) {
10397 IA_CSS_ERROR("timeout during SP initialization");
10398 return IA_CSS_ERR_INTERNAL_ERROR;
10399 }
10400
10401
10402
10403
10404 sh_css_init_host_sp_control_vars();
10405
10406
10407
10408
10409 sh_css_setup_queues();
10410 ia_css_bufq_dump_queue_info();
10411
10412#ifdef ISP2401
10413 if (ia_css_is_system_mode_suspend_or_resume() == false) {
10414 ia_css_set_system_mode(IA_CSS_SYS_MODE_WORKING);
10415 }
10416#endif
10417 IA_CSS_LEAVE_ERR(err);
10418 return err;
10419}
10420
10421
10422
10423
10424
10425
10426#define SP_SHUTDOWN_TIMEOUT_US 200000
10427
10428enum ia_css_err
10429ia_css_stop_sp(void)
10430{
10431 unsigned long timeout;
10432 enum ia_css_err err = IA_CSS_SUCCESS;
10433
10434 IA_CSS_ENTER("void");
10435
10436 if (!sh_css_sp_is_running()) {
10437 err = IA_CSS_ERR_INVALID_ARGUMENTS;
10438 IA_CSS_LEAVE("SP already stopped : return_err=%d", err);
10439
10440
10441 return err;
10442 }
10443
10444
10445#ifndef ISP2401
10446 sh_css_write_host2sp_command(host2sp_cmd_terminate);
10447#else
10448 if (!sh_css_write_host2sp_command(host2sp_cmd_terminate)) {
10449 IA_CSS_ERROR("Call to 'sh-css_write_host2sp_command()' failed");
10450 ia_css_debug_dump_sp_sw_debug_info();
10451 ia_css_debug_dump_debug_info(NULL);
10452 }
10453#endif
10454 sh_css_sp_set_sp_running(false);
10455
10456 timeout = SP_SHUTDOWN_TIMEOUT_US;
10457 while (!ia_css_spctrl_is_idle(SP0_ID) && timeout) {
10458 timeout--;
10459 hrt_sleep();
10460 }
10461 if ((ia_css_spctrl_get_state(SP0_ID) != IA_CSS_SP_SW_TERMINATED))
10462 IA_CSS_WARNING("SP has not terminated (SW)");
10463
10464 if (timeout == 0) {
10465 IA_CSS_WARNING("SP is not idle");
10466 ia_css_debug_dump_sp_sw_debug_info();
10467 }
10468 timeout = SP_SHUTDOWN_TIMEOUT_US;
10469 while (!isp_ctrl_getbit(ISP0_ID, ISP_SC_REG, ISP_IDLE_BIT) && timeout) {
10470 timeout--;
10471 hrt_sleep();
10472 }
10473 if (timeout == 0) {
10474 IA_CSS_WARNING("ISP is not idle");
10475 ia_css_debug_dump_sp_sw_debug_info();
10476 }
10477
10478 sh_css_hmm_buffer_record_uninit();
10479
10480#ifndef ISP2401
10481
10482 sh_css_param_clear_param_sets();
10483#else
10484 if (ia_css_is_system_mode_suspend_or_resume() == false) {
10485
10486 sh_css_param_clear_param_sets();
10487 ia_css_set_system_mode(IA_CSS_SYS_MODE_INIT);
10488 }
10489#endif
10490
10491 IA_CSS_LEAVE_ERR(err);
10492 return err;
10493}
10494
10495enum ia_css_err
10496ia_css_update_continuous_frames(struct ia_css_stream *stream)
10497{
10498 struct ia_css_pipe *pipe;
10499 unsigned int i;
10500
10501 ia_css_debug_dtrace(
10502 IA_CSS_DEBUG_TRACE,
10503 "sh_css_update_continuous_frames() enter:\n");
10504
10505 if (stream == NULL) {
10506 ia_css_debug_dtrace(
10507 IA_CSS_DEBUG_TRACE,
10508 "sh_css_update_continuous_frames() leave: invalid stream, return_void\n");
10509 return IA_CSS_ERR_INVALID_ARGUMENTS;
10510 }
10511
10512 pipe = stream->continuous_pipe;
10513
10514 for (i = stream->config.init_num_cont_raw_buf;
10515 i < stream->config.target_num_cont_raw_buf; i++) {
10516 sh_css_update_host2sp_offline_frame(i,
10517 pipe->continuous_frames[i], pipe->cont_md_buffers[i]);
10518 }
10519 sh_css_update_host2sp_cont_num_raw_frames
10520 (stream->config.target_num_cont_raw_buf, true);
10521 ia_css_debug_dtrace(
10522 IA_CSS_DEBUG_TRACE,
10523 "sh_css_update_continuous_frames() leave: return_void\n");
10524
10525 return IA_CSS_SUCCESS;
10526}
10527
10528void ia_css_pipe_map_queue(struct ia_css_pipe *pipe, bool map)
10529{
10530 unsigned int thread_id;
10531 enum ia_css_pipe_id pipe_id;
10532 unsigned int pipe_num;
10533 bool need_input_queue;
10534
10535 IA_CSS_ENTER("");
10536 assert(pipe != NULL);
10537
10538 pipe_id = pipe->mode;
10539 pipe_num = pipe->pipe_num;
10540
10541 ia_css_pipeline_get_sp_thread_id(pipe_num, &thread_id);
10542
10543#if defined(HAS_NO_INPUT_SYSTEM) || defined(USE_INPUT_SYSTEM_VERSION_2401)
10544 need_input_queue = true;
10545#else
10546 need_input_queue = pipe->stream->config.mode == IA_CSS_INPUT_MODE_MEMORY;
10547#endif
10548
10549
10550
10551 if (pipe->mode == IA_CSS_PIPE_ID_PREVIEW) {
10552 if (need_input_queue)
10553 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_INPUT_FRAME, map);
10554 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_OUTPUT_FRAME, map);
10555 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_PARAMETER_SET, map);
10556 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_PER_FRAME_PARAMETER_SET, map);
10557#if defined SH_CSS_ENABLE_METADATA
10558 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_METADATA, map);
10559#endif
10560 if (pipe->pipe_settings.preview.preview_binary.info &&
10561 pipe->pipe_settings.preview.preview_binary.info->sp.enable.s3a)
10562 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_3A_STATISTICS, map);
10563 } else if (pipe->mode == IA_CSS_PIPE_ID_CAPTURE) {
10564 unsigned int i;
10565
10566 if (need_input_queue)
10567 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_INPUT_FRAME, map);
10568 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_OUTPUT_FRAME, map);
10569 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME, map);
10570 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_PARAMETER_SET, map);
10571 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_PER_FRAME_PARAMETER_SET, map);
10572#if defined SH_CSS_ENABLE_METADATA
10573 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_METADATA, map);
10574#endif
10575 if (pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_PRIMARY) {
10576 for (i = 0; i < pipe->pipe_settings.capture.num_primary_stage; i++) {
10577 if (pipe->pipe_settings.capture.primary_binary[i].info &&
10578 pipe->pipe_settings.capture.primary_binary[i].info->sp.enable.s3a) {
10579 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_3A_STATISTICS, map);
10580 break;
10581 }
10582 }
10583 } else if (pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_ADVANCED ||
10584 pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_LOW_LIGHT ||
10585 pipe->config.default_capture_config.mode == IA_CSS_CAPTURE_MODE_BAYER) {
10586 if (pipe->pipe_settings.capture.pre_isp_binary.info &&
10587 pipe->pipe_settings.capture.pre_isp_binary.info->sp.enable.s3a)
10588 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_3A_STATISTICS, map);
10589 }
10590 } else if (pipe->mode == IA_CSS_PIPE_ID_VIDEO) {
10591 if (need_input_queue)
10592 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_INPUT_FRAME, map);
10593 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_OUTPUT_FRAME, map);
10594 if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0])
10595 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME, map);
10596 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_PARAMETER_SET, map);
10597 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_PER_FRAME_PARAMETER_SET, map);
10598#if defined SH_CSS_ENABLE_METADATA
10599 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_METADATA, map);
10600#endif
10601 if (pipe->pipe_settings.video.video_binary.info &&
10602 pipe->pipe_settings.video.video_binary.info->sp.enable.s3a)
10603 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_3A_STATISTICS, map);
10604 if (pipe->pipe_settings.video.video_binary.info &&
10605 (pipe->pipe_settings.video.video_binary.info->sp.enable.dis
10606 ))
10607 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_DIS_STATISTICS, map);
10608 } else if (pipe->mode == IA_CSS_PIPE_ID_COPY) {
10609 if (need_input_queue)
10610 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_INPUT_FRAME, map);
10611 if (!pipe->stream->config.continuous)
10612 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_OUTPUT_FRAME, map);
10613#if defined SH_CSS_ENABLE_METADATA
10614 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_METADATA, map);
10615#endif
10616 } else if (pipe->mode == IA_CSS_PIPE_ID_ACC) {
10617 if (need_input_queue)
10618 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_INPUT_FRAME, map);
10619 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_OUTPUT_FRAME, map);
10620 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_PARAMETER_SET, map);
10621 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_PER_FRAME_PARAMETER_SET, map);
10622#if defined SH_CSS_ENABLE_METADATA
10623 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_METADATA, map);
10624#endif
10625 } else if (pipe->mode == IA_CSS_PIPE_ID_YUVPP) {
10626 unsigned int idx;
10627 for (idx = 0; idx < IA_CSS_PIPE_MAX_OUTPUT_STAGE; idx++) {
10628 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_OUTPUT_FRAME + idx, map);
10629 if (pipe->enable_viewfinder[idx])
10630 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME + idx, map);
10631 }
10632 if (need_input_queue)
10633 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_INPUT_FRAME, map);
10634 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_PARAMETER_SET, map);
10635#if defined SH_CSS_ENABLE_METADATA
10636 ia_css_queue_map(thread_id, IA_CSS_BUFFER_TYPE_METADATA, map);
10637#endif
10638 }
10639 IA_CSS_LEAVE("");
10640}
10641
10642#if CONFIG_ON_FRAME_ENQUEUE()
10643static enum ia_css_err set_config_on_frame_enqueue(struct ia_css_frame_info *info, struct frame_data_wrapper *frame)
10644{
10645 frame->config_on_frame_enqueue.padded_width = 0;
10646
10647
10648
10649 switch (info->format) {
10650 case IA_CSS_FRAME_FORMAT_YUV420:
10651 case IA_CSS_FRAME_FORMAT_NV12:
10652 if (info->padded_width > info->res.width)
10653 {
10654 frame->config_on_frame_enqueue.padded_width = info->padded_width;
10655 }
10656 else if ((info->padded_width < info->res.width) && (info->padded_width > 0))
10657 {
10658 return IA_CSS_ERR_INVALID_ARGUMENTS;
10659 }
10660
10661 break;
10662 default:
10663 break;
10664 }
10665
10666 return IA_CSS_SUCCESS;
10667}
10668#endif
10669
10670enum ia_css_err
10671ia_css_unlock_raw_frame(struct ia_css_stream *stream, uint32_t exp_id)
10672{
10673 enum ia_css_err ret;
10674
10675 IA_CSS_ENTER("");
10676
10677
10678
10679 if (stream == NULL || !stream->config.continuous) {
10680 IA_CSS_ERROR("invalid stream pointer");
10681 return IA_CSS_ERR_INVALID_ARGUMENTS;
10682 }
10683
10684 if (exp_id > IA_CSS_ISYS_MAX_EXPOSURE_ID ||
10685 exp_id < IA_CSS_ISYS_MIN_EXPOSURE_ID) {
10686 IA_CSS_ERROR("invalid expsure ID: %d\n", exp_id);
10687 return IA_CSS_ERR_INVALID_ARGUMENTS;
10688 }
10689
10690
10691
10692 ret = ia_css_bufq_enqueue_psys_event(
10693 IA_CSS_PSYS_SW_EVENT_UNLOCK_RAW_BUFFER, exp_id, 0, 0);
10694
10695 IA_CSS_LEAVE_ERR(ret);
10696 return ret;
10697}
10698
10699
10700
10701
10702enum ia_css_err
10703ia_css_pipe_set_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle, bool enable)
10704{
10705 unsigned int thread_id;
10706 struct ia_css_pipeline_stage *stage;
10707 enum ia_css_err err = IA_CSS_SUCCESS;
10708
10709 IA_CSS_ENTER("");
10710
10711
10712 if (pipe == NULL || pipe->stream == NULL) {
10713 IA_CSS_ERROR("Invalid Pipe.");
10714 err = IA_CSS_ERR_INVALID_ARGUMENTS;
10715 } else if (!(pipe->config.acc_extension)) {
10716 IA_CSS_ERROR("Invalid Pipe(No Extension Firmware)");
10717 err = IA_CSS_ERR_INVALID_ARGUMENTS;
10718 } else if (!sh_css_sp_is_running()) {
10719 IA_CSS_ERROR("Leaving: queue unavailable.");
10720 err = IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
10721 } else {
10722
10723 ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
10724 err = ia_css_pipeline_get_stage_from_fw(&(pipe->pipeline), fw_handle, &stage);
10725 if (err == IA_CSS_SUCCESS) {
10726
10727 err = ia_css_bufq_enqueue_psys_event(
10728 (uint8_t) IA_CSS_PSYS_SW_EVENT_STAGE_ENABLE_DISABLE,
10729 (uint8_t) thread_id,
10730 (uint8_t) stage->stage_num,
10731 enable ? 1 : 0);
10732 if (err == IA_CSS_SUCCESS) {
10733 if(enable)
10734 SH_CSS_QOS_STAGE_ENABLE(&(sh_css_sp_group.pipe[thread_id]),stage->stage_num);
10735 else
10736 SH_CSS_QOS_STAGE_DISABLE(&(sh_css_sp_group.pipe[thread_id]),stage->stage_num);
10737 }
10738 }
10739 }
10740 IA_CSS_LEAVE("err:%d handle:%u enable:%d", err, fw_handle, enable);
10741 return err;
10742}
10743
10744
10745
10746
10747enum ia_css_err
10748ia_css_pipe_get_qos_ext_state(struct ia_css_pipe *pipe, uint32_t fw_handle, bool *enable)
10749{
10750 struct ia_css_pipeline_stage *stage;
10751 unsigned int thread_id;
10752 enum ia_css_err err = IA_CSS_SUCCESS;
10753
10754 IA_CSS_ENTER("");
10755
10756
10757 if (pipe == NULL || pipe->stream == NULL) {
10758 IA_CSS_ERROR("Invalid Pipe.");
10759 err = IA_CSS_ERR_INVALID_ARGUMENTS;
10760 } else if (!(pipe->config.acc_extension)) {
10761 IA_CSS_ERROR("Invalid Pipe (No Extension Firmware).");
10762 err = IA_CSS_ERR_INVALID_ARGUMENTS;
10763 } else if (!sh_css_sp_is_running()) {
10764 IA_CSS_ERROR("Leaving: queue unavailable.");
10765 err = IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
10766 } else {
10767
10768 ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
10769 err = ia_css_pipeline_get_stage_from_fw(&pipe->pipeline, fw_handle, &stage);
10770
10771 if (err == IA_CSS_SUCCESS) {
10772
10773 *enable = (SH_CSS_QOS_STAGE_IS_ENABLED(&(sh_css_sp_group.pipe[thread_id]),stage->stage_num)) ? true : false;
10774 }
10775 }
10776 IA_CSS_LEAVE("err:%d handle:%u enable:%d", err, fw_handle, *enable);
10777 return err;
10778}
10779
10780#ifdef ISP2401
10781enum ia_css_err
10782ia_css_pipe_update_qos_ext_mapped_arg(struct ia_css_pipe *pipe, uint32_t fw_handle,
10783 struct ia_css_isp_param_css_segments *css_seg, struct ia_css_isp_param_isp_segments *isp_seg)
10784{
10785 unsigned int HIVE_ADDR_sp_group;
10786 static struct sh_css_sp_group sp_group;
10787 static struct sh_css_sp_stage sp_stage;
10788 static struct sh_css_isp_stage isp_stage;
10789 const struct ia_css_fw_info *fw;
10790 unsigned int thread_id;
10791 struct ia_css_pipeline_stage *stage;
10792 enum ia_css_err err = IA_CSS_SUCCESS;
10793 int stage_num = 0;
10794 enum ia_css_isp_memories mem;
10795 bool enabled;
10796
10797 IA_CSS_ENTER("");
10798
10799 fw = &sh_css_sp_fw;
10800
10801
10802 if (pipe == NULL || pipe->stream == NULL) {
10803 IA_CSS_ERROR("Invalid Pipe.");
10804 err = IA_CSS_ERR_INVALID_ARGUMENTS;
10805 } else if (!(pipe->config.acc_extension)) {
10806 IA_CSS_ERROR("Invalid Pipe (No Extension Firmware).");
10807 err = IA_CSS_ERR_INVALID_ARGUMENTS;
10808 } else if (!sh_css_sp_is_running()) {
10809 IA_CSS_ERROR("Leaving: queue unavailable.");
10810 err = IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
10811 } else {
10812
10813 ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
10814 err = ia_css_pipeline_get_stage_from_fw(&(pipe->pipeline), fw_handle, &stage);
10815 if (err == IA_CSS_SUCCESS) {
10816
10817 enabled = (SH_CSS_QOS_STAGE_IS_ENABLED(&(sh_css_sp_group.pipe[thread_id]), stage->stage_num)) ? true : false;
10818
10819 if (enabled) {
10820 IA_CSS_ERROR("Leaving: cannot update when stage is enabled.");
10821 err = IA_CSS_ERR_RESOURCE_NOT_AVAILABLE;
10822 } else {
10823 stage_num = stage->stage_num;
10824
10825 HIVE_ADDR_sp_group = fw->info.sp.group;
10826 sp_dmem_load(SP0_ID,
10827 (unsigned int)sp_address_of(sp_group),
10828 &sp_group, sizeof(struct sh_css_sp_group));
10829 mmgr_load(sp_group.pipe[thread_id].sp_stage_addr[stage_num],
10830 &sp_stage, sizeof(struct sh_css_sp_stage));
10831
10832 mmgr_load(sp_stage.isp_stage_addr,
10833 &isp_stage, sizeof(struct sh_css_isp_stage));
10834
10835 for (mem = 0; mem < N_IA_CSS_ISP_MEMORIES; mem++) {
10836 isp_stage.mem_initializers.params[IA_CSS_PARAM_CLASS_PARAM][mem].address =
10837 css_seg->params[IA_CSS_PARAM_CLASS_PARAM][mem].address;
10838 isp_stage.mem_initializers.params[IA_CSS_PARAM_CLASS_PARAM][mem].size =
10839 css_seg->params[IA_CSS_PARAM_CLASS_PARAM][mem].size;
10840 isp_stage.binary_info.mem_initializers.params[IA_CSS_PARAM_CLASS_PARAM][mem].address =
10841 isp_seg->params[IA_CSS_PARAM_CLASS_PARAM][mem].address;
10842 isp_stage.binary_info.mem_initializers.params[IA_CSS_PARAM_CLASS_PARAM][mem].size =
10843 isp_seg->params[IA_CSS_PARAM_CLASS_PARAM][mem].size;
10844 }
10845
10846 mmgr_store(sp_stage.isp_stage_addr,
10847 &isp_stage, sizeof(struct sh_css_isp_stage));
10848 }
10849 }
10850 }
10851 IA_CSS_LEAVE("err:%d handle:%u", err, fw_handle);
10852 return err;
10853}
10854
10855#ifdef USE_INPUT_SYSTEM_VERSION_2401
10856static enum ia_css_err
10857aspect_ratio_crop_init(struct ia_css_stream *curr_stream,
10858 struct ia_css_pipe *pipes[],
10859 bool *do_crop_status)
10860{
10861 enum ia_css_err err = IA_CSS_SUCCESS;
10862 int i;
10863 struct ia_css_pipe *curr_pipe;
10864 uint32_t pipe_mask = 0;
10865
10866 if ((curr_stream == NULL) ||
10867 (curr_stream->num_pipes == 0) ||
10868 (pipes == NULL) ||
10869 (do_crop_status == NULL)) {
10870 err = IA_CSS_ERR_INVALID_ARGUMENTS;
10871 IA_CSS_LEAVE_ERR(err);
10872 return err;
10873 }
10874
10875 for (i = 0; i < curr_stream->num_pipes; i++) {
10876 curr_pipe = pipes[i];
10877 pipe_mask |= (1 << curr_pipe->config.mode);
10878 }
10879
10880 *do_crop_status =
10881 (((pipe_mask & (1 << IA_CSS_PIPE_MODE_PREVIEW)) ||
10882 (pipe_mask & (1 << IA_CSS_PIPE_MODE_VIDEO))) &&
10883 (pipe_mask & (1 << IA_CSS_PIPE_MODE_CAPTURE)) &&
10884 curr_stream->config.continuous);
10885 return IA_CSS_SUCCESS;
10886}
10887
10888static bool
10889aspect_ratio_crop_check(bool enabled, struct ia_css_pipe *curr_pipe)
10890{
10891 bool status = false;
10892
10893 if ((curr_pipe != NULL) && enabled) {
10894 if ((curr_pipe->config.mode == IA_CSS_PIPE_MODE_PREVIEW) ||
10895 (curr_pipe->config.mode == IA_CSS_PIPE_MODE_VIDEO) ||
10896 (curr_pipe->config.mode == IA_CSS_PIPE_MODE_CAPTURE))
10897 status = true;
10898 }
10899
10900 return status;
10901}
10902
10903static enum ia_css_err
10904aspect_ratio_crop(struct ia_css_pipe *curr_pipe,
10905 struct ia_css_resolution *effective_res)
10906{
10907 enum ia_css_err err = IA_CSS_SUCCESS;
10908 struct ia_css_resolution crop_res;
10909 struct ia_css_resolution *in_res = NULL;
10910 struct ia_css_resolution *out_res = NULL;
10911 bool use_bds_output_info = false;
10912 bool use_vf_pp_in_res = false;
10913 bool use_capt_pp_in_res = false;
10914
10915 if ((curr_pipe == NULL) ||
10916 (effective_res == NULL)) {
10917 err = IA_CSS_ERR_INVALID_ARGUMENTS;
10918 IA_CSS_LEAVE_ERR(err);
10919 return err;
10920 }
10921
10922 if ((curr_pipe->config.mode != IA_CSS_PIPE_MODE_PREVIEW) &&
10923 (curr_pipe->config.mode != IA_CSS_PIPE_MODE_VIDEO) &&
10924 (curr_pipe->config.mode != IA_CSS_PIPE_MODE_CAPTURE)) {
10925 err = IA_CSS_ERR_INVALID_ARGUMENTS;
10926 IA_CSS_LEAVE_ERR(err);
10927 return err;
10928 }
10929
10930 use_bds_output_info =
10931 ((curr_pipe->bds_output_info.res.width != 0) &&
10932 (curr_pipe->bds_output_info.res.height != 0));
10933
10934 use_vf_pp_in_res =
10935 ((curr_pipe->config.vf_pp_in_res.width != 0) &&
10936 (curr_pipe->config.vf_pp_in_res.height != 0));
10937
10938 use_capt_pp_in_res =
10939 ((curr_pipe->config.capt_pp_in_res.width != 0) &&
10940 (curr_pipe->config.capt_pp_in_res.height != 0));
10941
10942 in_res = &curr_pipe->stream->config.input_config.effective_res;
10943 out_res = &curr_pipe->output_info[0].res;
10944
10945 switch (curr_pipe->config.mode) {
10946 case IA_CSS_PIPE_MODE_PREVIEW:
10947 if (use_bds_output_info)
10948 out_res = &curr_pipe->bds_output_info.res;
10949 else if (use_vf_pp_in_res)
10950 out_res = &curr_pipe->config.vf_pp_in_res;
10951 break;
10952 case IA_CSS_PIPE_MODE_VIDEO:
10953 if (use_bds_output_info)
10954 out_res = &curr_pipe->bds_output_info.res;
10955 break;
10956 case IA_CSS_PIPE_MODE_CAPTURE:
10957 if (use_capt_pp_in_res)
10958 out_res = &curr_pipe->config.capt_pp_in_res;
10959 break;
10960 case IA_CSS_PIPE_MODE_ACC:
10961 case IA_CSS_PIPE_MODE_COPY:
10962 case IA_CSS_PIPE_MODE_YUVPP:
10963 default:
10964 IA_CSS_ERROR("aspect ratio cropping invalid args: mode[%d]\n",
10965 curr_pipe->config.mode);
10966 assert(0);
10967 break;
10968 }
10969
10970 err = ia_css_frame_find_crop_resolution(in_res, out_res, &crop_res);
10971 if (err == IA_CSS_SUCCESS) {
10972 *effective_res = crop_res;
10973 } else {
10974
10975
10976 IA_CSS_LOG("ia_css_frame_find_crop_resolution() failed with err(%d)", err);
10977 }
10978 return err;
10979}
10980#endif
10981
10982#endif
10983static void
10984sh_css_hmm_buffer_record_init(void)
10985{
10986 int i;
10987
10988#ifndef ISP2401
10989 for (i = 0; i < MAX_HMM_BUFFER_NUM; i++) {
10990 sh_css_hmm_buffer_record_reset(&hmm_buffer_record[i]);
10991#else
10992 if (ia_css_is_system_mode_suspend_or_resume() == false) {
10993 for (i = 0; i < MAX_HMM_BUFFER_NUM; i++) {
10994 sh_css_hmm_buffer_record_reset(&hmm_buffer_record[i]);
10995 }
10996#endif
10997 }
10998}
10999
11000static void
11001sh_css_hmm_buffer_record_uninit(void)
11002{
11003 int i;
11004 struct sh_css_hmm_buffer_record *buffer_record = NULL;
11005
11006#ifndef ISP2401
11007 buffer_record = &hmm_buffer_record[0];
11008 for (i = 0; i < MAX_HMM_BUFFER_NUM; i++) {
11009 if (buffer_record->in_use) {
11010 if (buffer_record->h_vbuf != NULL)
11011 ia_css_rmgr_rel_vbuf(hmm_buffer_pool, &buffer_record->h_vbuf);
11012 sh_css_hmm_buffer_record_reset(buffer_record);
11013#else
11014 if (ia_css_is_system_mode_suspend_or_resume() == false) {
11015 buffer_record = &hmm_buffer_record[0];
11016 for (i = 0; i < MAX_HMM_BUFFER_NUM; i++) {
11017 if (buffer_record->in_use) {
11018 if (buffer_record->h_vbuf != NULL)
11019 ia_css_rmgr_rel_vbuf(hmm_buffer_pool, &buffer_record->h_vbuf);
11020 sh_css_hmm_buffer_record_reset(buffer_record);
11021 }
11022 buffer_record++;
11023#endif
11024 }
11025#ifndef ISP2401
11026 buffer_record++;
11027#endif
11028 }
11029}
11030
11031static void
11032sh_css_hmm_buffer_record_reset(struct sh_css_hmm_buffer_record *buffer_record)
11033{
11034 assert(buffer_record != NULL);
11035 buffer_record->in_use = false;
11036 buffer_record->type = IA_CSS_BUFFER_TYPE_INVALID;
11037 buffer_record->h_vbuf = NULL;
11038 buffer_record->kernel_ptr = 0;
11039}
11040
11041static struct sh_css_hmm_buffer_record
11042*sh_css_hmm_buffer_record_acquire(struct ia_css_rmgr_vbuf_handle *h_vbuf,
11043 enum ia_css_buffer_type type,
11044 hrt_address kernel_ptr)
11045{
11046 int i;
11047 struct sh_css_hmm_buffer_record *buffer_record = NULL;
11048 struct sh_css_hmm_buffer_record *out_buffer_record = NULL;
11049
11050 assert(h_vbuf != NULL);
11051 assert((type > IA_CSS_BUFFER_TYPE_INVALID) && (type < IA_CSS_NUM_DYNAMIC_BUFFER_TYPE));
11052 assert(kernel_ptr != 0);
11053
11054 buffer_record = &hmm_buffer_record[0];
11055 for (i = 0; i < MAX_HMM_BUFFER_NUM; i++) {
11056 if (!buffer_record->in_use) {
11057 buffer_record->in_use = true;
11058 buffer_record->type = type;
11059 buffer_record->h_vbuf = h_vbuf;
11060 buffer_record->kernel_ptr = kernel_ptr;
11061 out_buffer_record = buffer_record;
11062 break;
11063 }
11064 buffer_record++;
11065 }
11066
11067 return out_buffer_record;
11068}
11069
11070static struct sh_css_hmm_buffer_record
11071*sh_css_hmm_buffer_record_validate(hrt_vaddress ddr_buffer_addr,
11072 enum ia_css_buffer_type type)
11073{
11074 int i;
11075 struct sh_css_hmm_buffer_record *buffer_record = NULL;
11076 bool found_record = false;
11077
11078 buffer_record = &hmm_buffer_record[0];
11079 for (i = 0; i < MAX_HMM_BUFFER_NUM; i++) {
11080 if ((buffer_record->in_use) &&
11081 (buffer_record->type == type) &&
11082 (buffer_record->h_vbuf != NULL) &&
11083 (buffer_record->h_vbuf->vptr == ddr_buffer_addr)) {
11084 found_record = true;
11085 break;
11086 }
11087 buffer_record++;
11088 }
11089
11090 if (found_record)
11091 return buffer_record;
11092 else
11093 return NULL;
11094}
11095