1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include <linux/mm.h>
18#include <linux/slab.h>
19#include <linux/vmalloc.h>
20
21#include "hmm.h"
22
23#include "ia_css.h"
24#include "sh_css_hrt.h"
25#include "ia_css_buffer.h"
26#include "ia_css_binary.h"
27#include "sh_css_internal.h"
28#include "sh_css_mipi.h"
29#include "sh_css_sp.h"
30#include "ia_css_isys.h"
31#include "ia_css_frame.h"
32#include "sh_css_defs.h"
33#include "sh_css_firmware.h"
34#include "sh_css_params.h"
35#include "sh_css_params_internal.h"
36#include "sh_css_param_shading.h"
37#include "ia_css_refcount.h"
38#include "ia_css_rmgr.h"
39#include "ia_css_debug.h"
40#include "ia_css_debug_pipe.h"
41#include "ia_css_device_access.h"
42#include "device_access.h"
43#include "sh_css_legacy.h"
44#include "ia_css_pipeline.h"
45#include "ia_css_stream.h"
46#include "sh_css_stream_format.h"
47#include "ia_css_pipe.h"
48#include "ia_css_util.h"
49#include "ia_css_pipe_util.h"
50#include "ia_css_pipe_binarydesc.h"
51#include "ia_css_pipe_stagedesc.h"
52
53#include "tag.h"
54#include "assert_support.h"
55#include "math_support.h"
56#include "sw_event_global.h"
57#if !defined(ISP2401)
58#include "ia_css_ifmtr.h"
59#endif
60#include "input_system.h"
61#include "mmu_device.h"
62#include "ia_css_mmu_private.h"
63#include "gdc_device.h"
64#include "dma.h"
65#include "irq.h"
66#include "sp.h"
67#include "isp.h"
68#include "gp_device.h"
69#define __INLINE_GPIO__
70#include "gpio.h"
71#include "timed_ctrl.h"
72#include "ia_css_inputfifo.h"
73#define WITH_PC_MONITORING 0
74
75#define SH_CSS_VIDEO_BUFFER_ALIGNMENT 0
76
77#if WITH_PC_MONITORING
78#define MULTIPLE_SAMPLES 1
79#define NOF_SAMPLES 60
80#include "linux/kthread.h"
81#include "linux/sched.h"
82#include "linux/delay.h"
83#include "sh_css_metrics.h"
84static int thread_alive;
85#endif
86
87#include "ia_css_spctrl.h"
88#include "ia_css_version_data.h"
89#include "sh_css_struct.h"
90#include "ia_css_bufq.h"
91#include "ia_css_timer.h"
92
93#include "isp/modes/interface/input_buf.isp.h"
94
95
96#define SP_PROG_NAME "sp"
97
98#define REFCOUNT_SIZE 1000
99
100
101
102
103
104#define JPEG_BYTES (16 * 1024 * 1024)
105
106#define STATS_ENABLED(stage) (stage && stage->binary && stage->binary->info && \
107 (stage->binary->info->sp.enable.s3a || stage->binary->info->sp.enable.dis))
108
109struct sh_css my_css;
110
111int __printf(1, 0) (*sh_css_printf)(const char *fmt, va_list args) = NULL;
112
113
114
115
116enum ia_sh_css_modes {
117 sh_css_mode_none = 0,
118 sh_css_mode_working,
119 sh_css_mode_suspend,
120 sh_css_mode_resume
121};
122
123
124
125
126struct sh_css_stream_seed {
127 struct ia_css_stream
128 **orig_stream;
129 struct ia_css_stream *stream;
130 struct ia_css_stream_config stream_config;
131 int num_pipes;
132 struct ia_css_pipe *pipes[IA_CSS_PIPE_ID_NUM];
133 struct ia_css_pipe
134 **orig_pipes[IA_CSS_PIPE_ID_NUM];
135 struct ia_css_pipe_config
136 pipe_config[IA_CSS_PIPE_ID_NUM];
137};
138
139#define MAX_ACTIVE_STREAMS 5
140
141
142
143struct sh_css_save {
144 enum ia_sh_css_modes mode;
145 u32 mmu_base;
146 enum ia_css_irq_type irq_type;
147 struct sh_css_stream_seed stream_seeds[MAX_ACTIVE_STREAMS];
148 struct ia_css_fw *loaded_fw;
149 struct ia_css_env driver_env;
150};
151
152static bool my_css_save_initialized;
153static struct sh_css_save my_css_save;
154
155
156
157
158#define MAX_HMM_BUFFER_NUM \
159 (SH_CSS_MAX_NUM_QUEUES * (IA_CSS_NUM_ELEMS_SP2HOST_BUFFER_QUEUE + 2))
160
161struct sh_css_hmm_buffer_record {
162 bool in_use;
163 enum ia_css_buffer_type type;
164 struct ia_css_rmgr_vbuf_handle *h_vbuf;
165 hrt_address kernel_ptr;
166};
167
168static struct sh_css_hmm_buffer_record hmm_buffer_record[MAX_HMM_BUFFER_NUM];
169
170#define GPIO_FLASH_PIN_MASK BIT(HIVE_GPIO_STROBE_TRIGGER_PIN)
171
172static bool fw_explicitly_loaded;
173
174
175
176
177
178static int
179allocate_delay_frames(struct ia_css_pipe *pipe);
180
181static int
182sh_css_pipe_start(struct ia_css_stream *stream);
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202static int
203sh_css_pipes_stop(struct ia_css_stream *stream);
204
205
206
207
208
209
210
211
212
213
214
215
216
217static bool
218sh_css_pipes_have_stopped(struct ia_css_stream *stream);
219
220
221static int
222ia_css_pipe_check_format(struct ia_css_pipe *pipe,
223 enum ia_css_frame_format format);
224
225
226static int
227check_pipe_resolutions(const struct ia_css_pipe *pipe);
228
229static int
230ia_css_pipe_load_extension(struct ia_css_pipe *pipe,
231 struct ia_css_fw_info *firmware);
232
233static void
234ia_css_pipe_unload_extension(struct ia_css_pipe *pipe,
235 struct ia_css_fw_info *firmware);
236static void
237ia_css_reset_defaults(struct sh_css *css);
238
239static void
240sh_css_init_host_sp_control_vars(void);
241
242static int
243set_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 int 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
258 *descr);
259
260static bool
261need_downscaling(const struct ia_css_resolution in_res,
262 const struct ia_css_resolution out_res);
263
264static bool need_capt_ldc(const struct ia_css_pipe *pipe);
265
266static int
267sh_css_pipe_load_binaries(struct ia_css_pipe *pipe);
268
269static
270int sh_css_pipe_get_viewfinder_frame_info(
271 struct ia_css_pipe *pipe,
272 struct ia_css_frame_info *info,
273 unsigned int idx);
274
275static int
276sh_css_pipe_get_output_frame_info(struct ia_css_pipe *pipe,
277 struct ia_css_frame_info *info,
278 unsigned int idx);
279
280static int
281capture_start(struct ia_css_pipe *pipe);
282
283static int
284video_start(struct ia_css_pipe *pipe);
285
286static int
287preview_start(struct ia_css_pipe *pipe);
288
289static int
290yuvpp_start(struct ia_css_pipe *pipe);
291
292static bool copy_on_sp(struct ia_css_pipe *pipe);
293
294static int
295init_vf_frameinfo_defaults(struct ia_css_pipe *pipe,
296 struct ia_css_frame *vf_frame, unsigned int idx);
297
298static int
299init_in_frameinfo_memory_defaults(struct ia_css_pipe *pipe,
300 struct ia_css_frame *frame, enum ia_css_frame_format format);
301
302static int
303init_out_frameinfo_defaults(struct ia_css_pipe *pipe,
304 struct ia_css_frame *out_frame, unsigned int idx);
305
306static int
307sh_css_pipeline_add_acc_stage(struct ia_css_pipeline *pipeline,
308 const void *acc_fw);
309
310static int
311alloc_continuous_frames(struct ia_css_pipe *pipe, bool init_time);
312
313static void
314pipe_global_init(void);
315
316static int
317pipe_generate_pipe_num(const struct ia_css_pipe *pipe,
318 unsigned int *pipe_number);
319
320static void
321pipe_release_pipe_num(unsigned int pipe_num);
322
323static int
324create_host_pipeline_structure(struct ia_css_stream *stream);
325
326static int
327create_host_pipeline(struct ia_css_stream *stream);
328
329static int
330create_host_preview_pipeline(struct ia_css_pipe *pipe);
331
332static int
333create_host_video_pipeline(struct ia_css_pipe *pipe);
334
335static int
336create_host_copy_pipeline(struct ia_css_pipe *pipe,
337 unsigned int max_input_width,
338 struct ia_css_frame *out_frame);
339
340static int
341create_host_isyscopy_capture_pipeline(struct ia_css_pipe *pipe);
342
343static int
344create_host_capture_pipeline(struct ia_css_pipe *pipe);
345
346static int
347create_host_yuvpp_pipeline(struct ia_css_pipe *pipe);
348
349static int
350create_host_acc_pipeline(struct ia_css_pipe *pipe);
351
352static unsigned int
353sh_css_get_sw_interrupt_value(unsigned int irq);
354
355static struct ia_css_binary *ia_css_pipe_get_shading_correction_binary(
356 const struct ia_css_pipe *pipe);
357
358static struct ia_css_binary *
359ia_css_pipe_get_s3a_binary(const struct ia_css_pipe *pipe);
360
361static struct ia_css_binary *
362ia_css_pipe_get_sdis_binary(const struct ia_css_pipe *pipe);
363
364static void
365sh_css_hmm_buffer_record_init(void);
366
367static void
368sh_css_hmm_buffer_record_uninit(void);
369
370static void
371sh_css_hmm_buffer_record_reset(struct sh_css_hmm_buffer_record *buffer_record);
372
373static struct sh_css_hmm_buffer_record
374*sh_css_hmm_buffer_record_acquire(struct ia_css_rmgr_vbuf_handle *h_vbuf,
375 enum ia_css_buffer_type type,
376 hrt_address kernel_ptr);
377
378static struct sh_css_hmm_buffer_record
379*sh_css_hmm_buffer_record_validate(ia_css_ptr ddr_buffer_addr,
380 enum ia_css_buffer_type type);
381
382void
383ia_css_get_acc_configs(
384 struct ia_css_pipe *pipe,
385 struct ia_css_isp_config *config);
386
387#if CONFIG_ON_FRAME_ENQUEUE()
388static int set_config_on_frame_enqueue(struct ia_css_frame_info
389 *info, struct frame_data_wrapper *frame);
390#endif
391
392#ifdef ISP2401
393static unsigned int get_crop_lines_for_bayer_order(const struct
394 ia_css_stream_config *config);
395static unsigned int get_crop_columns_for_bayer_order(const struct
396 ia_css_stream_config *config);
397static void get_pipe_extra_pixel(struct ia_css_pipe *pipe,
398 unsigned int *extra_row, unsigned int *extra_column);
399static int
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 int
408aspect_ratio_crop(struct ia_css_pipe *curr_pipe,
409 struct ia_css_resolution *effective_res);
410#endif
411
412static void
413sh_css_pipe_free_shading_table(struct ia_css_pipe *pipe)
414{
415 if (!pipe) {
416 IA_CSS_ERROR("NULL input parameter");
417 return;
418 }
419
420 if (pipe->shading_table)
421 ia_css_shading_table_free(pipe->shading_table);
422 pipe->shading_table = NULL;
423}
424
425static enum ia_css_frame_format yuv420_copy_formats[] = {
426 IA_CSS_FRAME_FORMAT_NV12,
427 IA_CSS_FRAME_FORMAT_NV21,
428 IA_CSS_FRAME_FORMAT_YV12,
429 IA_CSS_FRAME_FORMAT_YUV420,
430 IA_CSS_FRAME_FORMAT_YUV420_16,
431 IA_CSS_FRAME_FORMAT_CSI_MIPI_YUV420_8,
432 IA_CSS_FRAME_FORMAT_CSI_MIPI_LEGACY_YUV420_8
433};
434
435static enum ia_css_frame_format yuv422_copy_formats[] = {
436 IA_CSS_FRAME_FORMAT_NV12,
437 IA_CSS_FRAME_FORMAT_NV16,
438 IA_CSS_FRAME_FORMAT_NV21,
439 IA_CSS_FRAME_FORMAT_NV61,
440 IA_CSS_FRAME_FORMAT_YV12,
441 IA_CSS_FRAME_FORMAT_YV16,
442 IA_CSS_FRAME_FORMAT_YUV420,
443 IA_CSS_FRAME_FORMAT_YUV420_16,
444 IA_CSS_FRAME_FORMAT_YUV422,
445 IA_CSS_FRAME_FORMAT_YUV422_16,
446 IA_CSS_FRAME_FORMAT_UYVY,
447 IA_CSS_FRAME_FORMAT_YUYV
448};
449
450
451
452
453static int
454verify_copy_out_frame_format(struct ia_css_pipe *pipe)
455{
456 enum ia_css_frame_format out_fmt = pipe->output_info[0].format;
457 unsigned int i, found = 0;
458
459 assert(pipe);
460 assert(pipe->stream);
461
462 switch (pipe->stream->config.input_config.format) {
463 case ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY:
464 case ATOMISP_INPUT_FORMAT_YUV420_8:
465 for (i = 0; i < ARRAY_SIZE(yuv420_copy_formats) && !found; i++)
466 found = (out_fmt == yuv420_copy_formats[i]);
467 break;
468 case ATOMISP_INPUT_FORMAT_YUV420_10:
469 case ATOMISP_INPUT_FORMAT_YUV420_16:
470 found = (out_fmt == IA_CSS_FRAME_FORMAT_YUV420_16);
471 break;
472 case ATOMISP_INPUT_FORMAT_YUV422_8:
473 for (i = 0; i < ARRAY_SIZE(yuv422_copy_formats) && !found; i++)
474 found = (out_fmt == yuv422_copy_formats[i]);
475 break;
476 case ATOMISP_INPUT_FORMAT_YUV422_10:
477 case ATOMISP_INPUT_FORMAT_YUV422_16:
478 found = (out_fmt == IA_CSS_FRAME_FORMAT_YUV422_16 ||
479 out_fmt == IA_CSS_FRAME_FORMAT_YUV420_16);
480 break;
481 case ATOMISP_INPUT_FORMAT_RGB_444:
482 case ATOMISP_INPUT_FORMAT_RGB_555:
483 case ATOMISP_INPUT_FORMAT_RGB_565:
484 found = (out_fmt == IA_CSS_FRAME_FORMAT_RGBA888 ||
485 out_fmt == IA_CSS_FRAME_FORMAT_RGB565);
486 break;
487 case ATOMISP_INPUT_FORMAT_RGB_666:
488 case ATOMISP_INPUT_FORMAT_RGB_888:
489 found = (out_fmt == IA_CSS_FRAME_FORMAT_RGBA888 ||
490 out_fmt == IA_CSS_FRAME_FORMAT_YUV420);
491 break;
492 case ATOMISP_INPUT_FORMAT_RAW_6:
493 case ATOMISP_INPUT_FORMAT_RAW_7:
494 case ATOMISP_INPUT_FORMAT_RAW_8:
495 case ATOMISP_INPUT_FORMAT_RAW_10:
496 case ATOMISP_INPUT_FORMAT_RAW_12:
497 case ATOMISP_INPUT_FORMAT_RAW_14:
498 case ATOMISP_INPUT_FORMAT_RAW_16:
499 found = (out_fmt == IA_CSS_FRAME_FORMAT_RAW) ||
500 (out_fmt == IA_CSS_FRAME_FORMAT_RAW_PACKED);
501 break;
502 case ATOMISP_INPUT_FORMAT_BINARY_8:
503 found = (out_fmt == IA_CSS_FRAME_FORMAT_BINARY_8);
504 break;
505 default:
506 break;
507 }
508 if (!found)
509 return -EINVAL;
510 return 0;
511}
512
513unsigned int
514ia_css_stream_input_format_bits_per_pixel(struct ia_css_stream *stream)
515{
516 int bpp = 0;
517
518 if (stream)
519 bpp = ia_css_util_input_format_bpp(stream->config.input_config.format,
520 stream->config.pixels_per_clock == 2);
521
522 return bpp;
523}
524
525#define GP_ISEL_TPG_MODE 0x90058
526
527#if !defined(ISP2401)
528static int
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 int err = 0;
535
536 assert(stream);
537 assert(pipe);
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)
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)
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 +
571 (stream->config.pixels_per_clock == 2));
572 height = stream->config.input_config.input_res.height;
573 vblank_cycles = vblank_lines * (width + hblank_cycles);
574 sh_css_sp_configure_sync_gen(width, height, hblank_cycles,
575 vblank_cycles);
576 if (!IS_ISP2401) {
577 if (pipe->stream->config.mode == IA_CSS_INPUT_MODE_TPG) {
578
579 ia_css_device_store_uint32(GP_ISEL_TPG_MODE, 0);
580 }
581 }
582 }
583 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
584 "sh_css_config_input_network() leave:\n");
585 return 0;
586}
587#elif defined(ISP2401)
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 break;
731 case IA_CSS_INPUT_MODE_PRBS:
732
733 if (stream_cfg->source.prbs.id == IA_CSS_PRBS_ID0)
734 isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT0_ID;
735 else if (stream_cfg->source.prbs.id == IA_CSS_PRBS_ID1)
736 isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT1_ID;
737 else if (stream_cfg->source.prbs.id == IA_CSS_PRBS_ID2)
738 isys_stream_descr->input_port_id = INPUT_SYSTEM_PIXELGEN_PORT2_ID;
739
740 break;
741 case IA_CSS_INPUT_MODE_BUFFERED_SENSOR:
742
743 if (stream_cfg->source.port.port == MIPI_PORT0_ID)
744 isys_stream_descr->input_port_id = INPUT_SYSTEM_CSI_PORT0_ID;
745 else if (stream_cfg->source.port.port == MIPI_PORT1_ID)
746 isys_stream_descr->input_port_id = INPUT_SYSTEM_CSI_PORT1_ID;
747 else if (stream_cfg->source.port.port == MIPI_PORT2_ID)
748 isys_stream_descr->input_port_id = INPUT_SYSTEM_CSI_PORT2_ID;
749
750 break;
751 default:
752 rc = false;
753 break;
754 }
755
756 return rc;
757}
758
759static bool sh_css_translate_stream_cfg_to_input_system_input_port_type(
760 struct ia_css_stream_config *stream_cfg,
761 ia_css_isys_descr_t *isys_stream_descr)
762{
763 bool rc;
764
765 rc = true;
766 switch (stream_cfg->mode) {
767 case IA_CSS_INPUT_MODE_TPG:
768
769 isys_stream_descr->mode = INPUT_SYSTEM_SOURCE_TYPE_TPG;
770
771 break;
772 case IA_CSS_INPUT_MODE_PRBS:
773
774 isys_stream_descr->mode = INPUT_SYSTEM_SOURCE_TYPE_PRBS;
775
776 break;
777 case IA_CSS_INPUT_MODE_SENSOR:
778 case IA_CSS_INPUT_MODE_BUFFERED_SENSOR:
779
780 isys_stream_descr->mode = INPUT_SYSTEM_SOURCE_TYPE_SENSOR;
781 break;
782
783 default:
784 rc = false;
785 break;
786 }
787
788 return rc;
789}
790
791static bool sh_css_translate_stream_cfg_to_input_system_input_port_attr(
792 struct ia_css_stream_config *stream_cfg,
793 ia_css_isys_descr_t *isys_stream_descr,
794 int isys_stream_idx)
795{
796 bool rc;
797
798 rc = true;
799 switch (stream_cfg->mode) {
800 case IA_CSS_INPUT_MODE_TPG:
801 if (stream_cfg->source.tpg.mode == IA_CSS_TPG_MODE_RAMP)
802 isys_stream_descr->tpg_port_attr.mode = PIXELGEN_TPG_MODE_RAMP;
803 else if (stream_cfg->source.tpg.mode == IA_CSS_TPG_MODE_CHECKERBOARD)
804 isys_stream_descr->tpg_port_attr.mode = PIXELGEN_TPG_MODE_CHBO;
805 else if (stream_cfg->source.tpg.mode == IA_CSS_TPG_MODE_MONO)
806 isys_stream_descr->tpg_port_attr.mode = PIXELGEN_TPG_MODE_MONO;
807 else
808 rc = false;
809
810
811
812
813
814 isys_stream_descr->tpg_port_attr.color_cfg.R1 = 51;
815 isys_stream_descr->tpg_port_attr.color_cfg.G1 = 102;
816 isys_stream_descr->tpg_port_attr.color_cfg.B1 = 255;
817 isys_stream_descr->tpg_port_attr.color_cfg.R2 = 0;
818 isys_stream_descr->tpg_port_attr.color_cfg.G2 = 100;
819 isys_stream_descr->tpg_port_attr.color_cfg.B2 = 160;
820
821 isys_stream_descr->tpg_port_attr.mask_cfg.h_mask =
822 stream_cfg->source.tpg.x_mask;
823 isys_stream_descr->tpg_port_attr.mask_cfg.v_mask =
824 stream_cfg->source.tpg.y_mask;
825 isys_stream_descr->tpg_port_attr.mask_cfg.hv_mask =
826 stream_cfg->source.tpg.xy_mask;
827
828 isys_stream_descr->tpg_port_attr.delta_cfg.h_delta =
829 stream_cfg->source.tpg.x_delta;
830 isys_stream_descr->tpg_port_attr.delta_cfg.v_delta =
831 stream_cfg->source.tpg.y_delta;
832
833
834
835
836
837 isys_stream_descr->tpg_port_attr.sync_gen_cfg.hblank_cycles = 100;
838 isys_stream_descr->tpg_port_attr.sync_gen_cfg.vblank_cycles = 100;
839 isys_stream_descr->tpg_port_attr.sync_gen_cfg.pixels_per_clock =
840 stream_cfg->pixels_per_clock;
841 isys_stream_descr->tpg_port_attr.sync_gen_cfg.nr_of_frames = (uint32_t)~(0x0);
842 isys_stream_descr->tpg_port_attr.sync_gen_cfg.pixels_per_line =
843 stream_cfg->isys_config[IA_CSS_STREAM_DEFAULT_ISYS_STREAM_IDX].input_res.width;
844 isys_stream_descr->tpg_port_attr.sync_gen_cfg.lines_per_frame =
845 stream_cfg->isys_config[IA_CSS_STREAM_DEFAULT_ISYS_STREAM_IDX].input_res.height;
846
847 break;
848 case IA_CSS_INPUT_MODE_PRBS:
849
850 isys_stream_descr->prbs_port_attr.seed0 = stream_cfg->source.prbs.seed;
851 isys_stream_descr->prbs_port_attr.seed1 = stream_cfg->source.prbs.seed1;
852
853
854
855
856
857 isys_stream_descr->prbs_port_attr.sync_gen_cfg.hblank_cycles = 100;
858 isys_stream_descr->prbs_port_attr.sync_gen_cfg.vblank_cycles = 100;
859 isys_stream_descr->prbs_port_attr.sync_gen_cfg.pixels_per_clock =
860 stream_cfg->pixels_per_clock;
861 isys_stream_descr->prbs_port_attr.sync_gen_cfg.nr_of_frames = (uint32_t)~(0x0);
862 isys_stream_descr->prbs_port_attr.sync_gen_cfg.pixels_per_line =
863 stream_cfg->isys_config[IA_CSS_STREAM_DEFAULT_ISYS_STREAM_IDX].input_res.width;
864 isys_stream_descr->prbs_port_attr.sync_gen_cfg.lines_per_frame =
865 stream_cfg->isys_config[IA_CSS_STREAM_DEFAULT_ISYS_STREAM_IDX].input_res.height;
866
867 break;
868 case IA_CSS_INPUT_MODE_BUFFERED_SENSOR: {
869 int err;
870 unsigned int fmt_type;
871
872 err = ia_css_isys_convert_stream_format_to_mipi_format(
873 stream_cfg->isys_config[isys_stream_idx].format,
874 MIPI_PREDICTOR_NONE,
875 &fmt_type);
876 if (err)
877 rc = false;
878
879 isys_stream_descr->csi_port_attr.active_lanes =
880 stream_cfg->source.port.num_lanes;
881 isys_stream_descr->csi_port_attr.fmt_type = fmt_type;
882 isys_stream_descr->csi_port_attr.ch_id = stream_cfg->channel_id;
883#ifdef ISP2401
884 isys_stream_descr->online = stream_cfg->online;
885#endif
886 err |= ia_css_isys_convert_compressed_format(
887 &stream_cfg->source.port.compression,
888 isys_stream_descr);
889 if (err)
890 rc = false;
891
892
893 isys_stream_descr->metadata.enable = false;
894 if (stream_cfg->metadata_config.resolution.height > 0) {
895 err = ia_css_isys_convert_stream_format_to_mipi_format(
896 stream_cfg->metadata_config.data_type,
897 MIPI_PREDICTOR_NONE,
898 &fmt_type);
899 if (err)
900 rc = false;
901 isys_stream_descr->metadata.fmt_type = fmt_type;
902 isys_stream_descr->metadata.bits_per_pixel =
903 ia_css_util_input_format_bpp(stream_cfg->metadata_config.data_type, true);
904 isys_stream_descr->metadata.pixels_per_line =
905 stream_cfg->metadata_config.resolution.width;
906 isys_stream_descr->metadata.lines_per_frame =
907 stream_cfg->metadata_config.resolution.height;
908#ifdef ISP2401
909
910
911 if (isys_stream_descr->metadata.lines_per_frame > 0)
912 isys_stream_descr->metadata.lines_per_frame +=
913 (isys_stream_descr->metadata.lines_per_frame & 1);
914#endif
915 isys_stream_descr->metadata.align_req_in_bytes =
916 ia_css_csi2_calculate_input_system_alignment(
917 stream_cfg->metadata_config.data_type);
918 isys_stream_descr->metadata.enable = true;
919 }
920
921 break;
922 }
923 default:
924 rc = false;
925 break;
926 }
927
928 return rc;
929}
930
931static bool sh_css_translate_stream_cfg_to_input_system_input_port_resolution(
932 struct ia_css_stream_config *stream_cfg,
933 ia_css_isys_descr_t *isys_stream_descr,
934 int isys_stream_idx)
935{
936 unsigned int bits_per_subpixel;
937 unsigned int max_subpixels_per_line;
938 unsigned int lines_per_frame;
939 unsigned int align_req_in_bytes;
940 enum atomisp_input_format fmt_type;
941
942 fmt_type = stream_cfg->isys_config[isys_stream_idx].format;
943 if ((stream_cfg->mode == IA_CSS_INPUT_MODE_SENSOR ||
944 stream_cfg->mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR) &&
945 stream_cfg->source.port.compression.type != IA_CSS_CSI2_COMPRESSION_TYPE_NONE) {
946 if (stream_cfg->source.port.compression.uncompressed_bits_per_pixel ==
947 UNCOMPRESSED_BITS_PER_PIXEL_10)
948 fmt_type = ATOMISP_INPUT_FORMAT_RAW_10;
949 else if (stream_cfg->source.port.compression.uncompressed_bits_per_pixel ==
950 UNCOMPRESSED_BITS_PER_PIXEL_12)
951 fmt_type = ATOMISP_INPUT_FORMAT_RAW_12;
952 else
953 return false;
954 }
955
956 bits_per_subpixel =
957 sh_css_stream_format_2_bits_per_subpixel(fmt_type);
958 if (bits_per_subpixel == 0)
959 return false;
960
961 max_subpixels_per_line =
962 csi2_protocol_calculate_max_subpixels_per_line(fmt_type,
963 stream_cfg->isys_config[isys_stream_idx].input_res.width);
964 if (max_subpixels_per_line == 0)
965 return false;
966
967 lines_per_frame = stream_cfg->isys_config[isys_stream_idx].input_res.height;
968 if (lines_per_frame == 0)
969 return false;
970
971 align_req_in_bytes = ia_css_csi2_calculate_input_system_alignment(fmt_type);
972
973
974 isys_stream_descr->input_port_resolution.bits_per_pixel = bits_per_subpixel;
975 isys_stream_descr->input_port_resolution.pixels_per_line =
976 max_subpixels_per_line;
977 isys_stream_descr->input_port_resolution.lines_per_frame = lines_per_frame;
978 isys_stream_descr->input_port_resolution.align_req_in_bytes =
979 align_req_in_bytes;
980
981 return true;
982}
983
984static bool sh_css_translate_stream_cfg_to_isys_stream_descr(
985 struct ia_css_stream_config *stream_cfg,
986 bool early_polling,
987 ia_css_isys_descr_t *isys_stream_descr,
988 int isys_stream_idx)
989{
990 bool rc;
991
992 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
993 "sh_css_translate_stream_cfg_to_isys_stream_descr() enter:\n");
994 rc = sh_css_translate_stream_cfg_to_input_system_input_port_id(stream_cfg,
995 isys_stream_descr);
996 rc &= sh_css_translate_stream_cfg_to_input_system_input_port_type(stream_cfg,
997 isys_stream_descr);
998 rc &= sh_css_translate_stream_cfg_to_input_system_input_port_attr(stream_cfg,
999 isys_stream_descr, isys_stream_idx);
1000 rc &= sh_css_translate_stream_cfg_to_input_system_input_port_resolution(
1001 stream_cfg, isys_stream_descr, isys_stream_idx);
1002
1003 isys_stream_descr->raw_packed = stream_cfg->pack_raw_pixels;
1004 isys_stream_descr->linked_isys_stream_id = (int8_t)
1005 stream_cfg->isys_config[isys_stream_idx].linked_isys_stream_id;
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015#if 0
1016 isys_stream_descr->polling_mode
1017 = early_polling ? INPUT_SYSTEM_POLL_ON_CAPTURE_REQUEST
1018 : INPUT_SYSTEM_POLL_ON_WAIT_FOR_FRAME;
1019 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
1020 "sh_css_translate_stream_cfg_to_isys_stream_descr() leave:\n");
1021#endif
1022
1023 return rc;
1024}
1025
1026static bool sh_css_translate_binary_info_to_input_system_output_port_attr(
1027 struct ia_css_binary *binary,
1028 ia_css_isys_descr_t *isys_stream_descr)
1029{
1030 if (!binary)
1031 return false;
1032
1033 isys_stream_descr->output_port_attr.left_padding = binary->left_padding;
1034 isys_stream_descr->output_port_attr.max_isp_input_width =
1035 binary->info->sp.input.max_width;
1036
1037 return true;
1038}
1039
1040static int
1041sh_css_config_input_network(struct ia_css_stream *stream)
1042{
1043 bool rc;
1044 ia_css_isys_descr_t isys_stream_descr;
1045 unsigned int sp_thread_id;
1046 struct sh_css_sp_pipeline_terminal *sp_pipeline_input_terminal;
1047 struct ia_css_pipe *pipe = NULL;
1048 struct ia_css_binary *binary = NULL;
1049 int i;
1050 u32 isys_stream_id;
1051 bool early_polling = false;
1052
1053 assert(stream);
1054 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
1055 "sh_css_config_input_network() enter 0x%p:\n", stream);
1056
1057 if (stream->config.continuous) {
1058 if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_CAPTURE)
1059 pipe = stream->last_pipe;
1060 else if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_YUVPP)
1061 pipe = stream->last_pipe;
1062 else if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_PREVIEW)
1063 pipe = stream->last_pipe->pipe_settings.preview.copy_pipe;
1064 else if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_VIDEO)
1065 pipe = stream->last_pipe->pipe_settings.video.copy_pipe;
1066 } else {
1067 pipe = stream->last_pipe;
1068 if (stream->last_pipe->config.mode == IA_CSS_PIPE_MODE_CAPTURE) {
1069
1070
1071
1072
1073
1074
1075
1076
1077 early_polling = true;
1078 }
1079 }
1080
1081 if (!pipe)
1082 return -EINVAL;
1083
1084 if (pipe->pipeline.stages)
1085 if (pipe->pipeline.stages->binary)
1086 binary = pipe->pipeline.stages->binary;
1087
1088 if (binary) {
1089
1090
1091
1092
1093 ia_css_get_crop_offsets(pipe, &binary->in_frame_info);
1094 }
1095
1096
1097 rc = ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &sp_thread_id);
1098 if (!rc)
1099 return -EINVAL;
1100
1101 sp_pipeline_input_terminal = &sh_css_sp_group.pipe_io[sp_thread_id].input;
1102
1103 for (i = 0; i < IA_CSS_STREAM_MAX_ISYS_STREAM_PER_CH; i++) {
1104
1105 memset((void *)(&isys_stream_descr), 0, sizeof(ia_css_isys_descr_t));
1106 sp_pipeline_input_terminal->context.virtual_input_system_stream[i].valid = 0;
1107 sp_pipeline_input_terminal->ctrl.virtual_input_system_stream_cfg[i].valid = 0;
1108
1109 if (!stream->config.isys_config[i].valid)
1110 continue;
1111
1112
1113 rc = sh_css_translate_stream_cfg_to_isys_stream_descr(
1114 &stream->config,
1115 early_polling,
1116 &(isys_stream_descr), i);
1117
1118 if (stream->config.online) {
1119 rc &= sh_css_translate_binary_info_to_input_system_output_port_attr(
1120 binary,
1121 &(isys_stream_descr));
1122 }
1123
1124 if (!rc)
1125 return -EINVAL;
1126
1127 isys_stream_id = ia_css_isys_generate_stream_id(sp_thread_id, i);
1128
1129
1130 rc = ia_css_isys_stream_create(
1131 &(isys_stream_descr),
1132 &sp_pipeline_input_terminal->context.virtual_input_system_stream[i],
1133 isys_stream_id);
1134 if (!rc)
1135 return -EINVAL;
1136
1137
1138 rc = ia_css_isys_stream_calculate_cfg(
1139 &sp_pipeline_input_terminal->context.virtual_input_system_stream[i],
1140 &(isys_stream_descr),
1141 &sp_pipeline_input_terminal->ctrl.virtual_input_system_stream_cfg[i]);
1142 if (!rc) {
1143 ia_css_isys_stream_destroy(
1144 &sp_pipeline_input_terminal->context.virtual_input_system_stream[i]);
1145 return -EINVAL;
1146 }
1147 }
1148
1149 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
1150 "sh_css_config_input_network() leave:\n");
1151
1152 return 0;
1153}
1154
1155static inline struct ia_css_pipe *stream_get_last_pipe(
1156 struct ia_css_stream *stream)
1157{
1158 struct ia_css_pipe *last_pipe = NULL;
1159
1160 if (stream)
1161 last_pipe = stream->last_pipe;
1162
1163 return last_pipe;
1164}
1165
1166static inline struct ia_css_pipe *stream_get_copy_pipe(
1167 struct ia_css_stream *stream)
1168{
1169 struct ia_css_pipe *copy_pipe = NULL;
1170 struct ia_css_pipe *last_pipe = NULL;
1171 enum ia_css_pipe_id pipe_id;
1172
1173 last_pipe = stream_get_last_pipe(stream);
1174
1175 if ((stream) &&
1176 (last_pipe) &&
1177 (stream->config.continuous)) {
1178 pipe_id = last_pipe->mode;
1179 switch (pipe_id) {
1180 case IA_CSS_PIPE_ID_PREVIEW:
1181 copy_pipe = last_pipe->pipe_settings.preview.copy_pipe;
1182 break;
1183 case IA_CSS_PIPE_ID_VIDEO:
1184 copy_pipe = last_pipe->pipe_settings.video.copy_pipe;
1185 break;
1186 default:
1187 copy_pipe = NULL;
1188 break;
1189 }
1190 }
1191
1192 return copy_pipe;
1193}
1194
1195static inline struct ia_css_pipe *stream_get_target_pipe(
1196 struct ia_css_stream *stream)
1197{
1198 struct ia_css_pipe *target_pipe;
1199
1200
1201 if (stream->config.continuous)
1202 target_pipe = stream_get_copy_pipe(stream);
1203 else
1204 target_pipe = stream_get_last_pipe(stream);
1205
1206 return target_pipe;
1207}
1208
1209static int stream_csi_rx_helper(
1210 struct ia_css_stream *stream,
1211 int (*func)(enum mipi_port_id, uint32_t))
1212{
1213 int retval = -EINVAL;
1214 u32 sp_thread_id, stream_id;
1215 bool rc;
1216 struct ia_css_pipe *target_pipe = NULL;
1217
1218 if ((!stream) || (stream->config.mode != IA_CSS_INPUT_MODE_BUFFERED_SENSOR))
1219 goto exit;
1220
1221 target_pipe = stream_get_target_pipe(stream);
1222
1223 if (!target_pipe)
1224 goto exit;
1225
1226 rc = ia_css_pipeline_get_sp_thread_id(
1227 ia_css_pipe_get_pipe_num(target_pipe),
1228 &sp_thread_id);
1229
1230 if (!rc)
1231 goto exit;
1232
1233
1234 stream_id = 0;
1235 do {
1236 if (stream->config.isys_config[stream_id].valid) {
1237 u32 isys_stream_id = ia_css_isys_generate_stream_id(sp_thread_id, stream_id);
1238
1239 retval = func(stream->config.source.port.port, isys_stream_id);
1240 }
1241 stream_id++;
1242 } while ((retval == 0) &&
1243 (stream_id < IA_CSS_STREAM_MAX_ISYS_STREAM_PER_CH));
1244
1245exit:
1246 return retval;
1247}
1248
1249static inline int stream_register_with_csi_rx(
1250 struct ia_css_stream *stream)
1251{
1252 return stream_csi_rx_helper(stream, ia_css_isys_csi_rx_register_stream);
1253}
1254
1255static inline int stream_unregister_with_csi_rx(
1256 struct ia_css_stream *stream)
1257{
1258 return stream_csi_rx_helper(stream, ia_css_isys_csi_rx_unregister_stream);
1259}
1260#endif
1261
1262#if WITH_PC_MONITORING
1263static struct task_struct *my_kthread;
1264static int sh_binary_running;
1265
1266static void print_pc_histo(char *core_name, struct sh_css_pc_histogram *hist)
1267{
1268 unsigned int i;
1269 unsigned int cnt_run = 0;
1270 unsigned int cnt_stall = 0;
1271
1272 if (!hist)
1273 return;
1274
1275 sh_css_print("%s histogram length = %d\n", core_name, hist->length);
1276 sh_css_print("%s PC\turn\tstall\n", core_name);
1277
1278 for (i = 0; i < hist->length; i++) {
1279 if ((hist->run[i] == 0) && (hist->run[i] == hist->stall[i]))
1280 continue;
1281 sh_css_print("%s %d\t%d\t%d\n",
1282 core_name, i, hist->run[i], hist->stall[i]);
1283 cnt_run += hist->run[i];
1284 cnt_stall += hist->stall[i];
1285 }
1286
1287 sh_css_print(" Statistics for %s, cnt_run = %d, cnt_stall = %d, hist->length = %d\n",
1288 core_name, cnt_run, cnt_stall, hist->length);
1289}
1290
1291static void print_pc_histogram(void)
1292{
1293 struct ia_css_binary_metrics *metrics;
1294
1295 for (metrics = sh_css_metrics.binary_metrics;
1296 metrics;
1297 metrics = metrics->next) {
1298 if (metrics->mode == IA_CSS_BINARY_MODE_PREVIEW ||
1299 metrics->mode == IA_CSS_BINARY_MODE_VF_PP) {
1300 sh_css_print("pc_histogram for binary %d is SKIPPED\n",
1301 metrics->id);
1302 continue;
1303 }
1304
1305 sh_css_print(" pc_histogram for binary %d\n", metrics->id);
1306 print_pc_histo(" ISP", &metrics->isp_histogram);
1307 print_pc_histo(" SP", &metrics->sp_histogram);
1308 sh_css_print("print_pc_histogram() done for binary->id = %d, done.\n",
1309 metrics->id);
1310 }
1311
1312 sh_css_print("PC_MONITORING:print_pc_histogram() -- DONE\n");
1313}
1314
1315static int pc_monitoring(void *data)
1316{
1317 int i = 0;
1318
1319 (void)data;
1320 while (true) {
1321 if (sh_binary_running) {
1322 sh_css_metrics_sample_pcs();
1323#if MULTIPLE_SAMPLES
1324 for (i = 0; i < NOF_SAMPLES; i++)
1325 sh_css_metrics_sample_pcs();
1326#endif
1327 }
1328 usleep_range(10, 50);
1329 }
1330 return 0;
1331}
1332
1333static void spying_thread_create(void)
1334{
1335 my_kthread = kthread_run(pc_monitoring, NULL, "sh_pc_monitor");
1336 sh_css_metrics_enable_pc_histogram(1);
1337}
1338
1339static void input_frame_info(struct ia_css_frame_info frame_info)
1340{
1341 sh_css_print("SH_CSS:input_frame_info() -- frame->info.res.width = %d, frame->info.res.height = %d, format = %d\n",
1342 frame_info.res.width, frame_info.res.height, frame_info.format);
1343}
1344#endif
1345
1346static void
1347start_binary(struct ia_css_pipe *pipe,
1348 struct ia_css_binary *binary)
1349{
1350 assert(pipe);
1351
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 , enable_dvs_envelope = %d\n",
1358 __func__, binary->info->sp.id,
1359 binary->info->sp.enable.dvs_envelope);
1360 input_frame_info(binary->in_frame_info);
1361
1362 if (binary && binary->info->sp.pipeline.mode == IA_CSS_BINARY_MODE_VIDEO)
1363 sh_binary_running = true;
1364#endif
1365
1366#if !defined(ISP2401)
1367 if (pipe->stream->reconfigure_css_rx) {
1368 ia_css_isys_rx_configure(&pipe->stream->csi_rx_config,
1369 pipe->stream->config.mode);
1370 pipe->stream->reconfigure_css_rx = false;
1371 }
1372#endif
1373}
1374
1375
1376static int
1377start_copy_on_sp(struct ia_css_pipe *pipe,
1378 struct ia_css_frame *out_frame)
1379{
1380 (void)out_frame;
1381
1382 if ((!pipe) || (!pipe->stream))
1383 return -EINVAL;
1384
1385#if !defined(ISP2401)
1386 if (pipe->stream->reconfigure_css_rx)
1387 ia_css_isys_rx_disable();
1388#endif
1389
1390 if (pipe->stream->config.input_config.format != ATOMISP_INPUT_FORMAT_BINARY_8)
1391 return -EINVAL;
1392 sh_css_sp_start_binary_copy(ia_css_pipe_get_pipe_num(pipe), out_frame, pipe->stream->config.pixels_per_clock == 2);
1393
1394#if !defined(ISP2401)
1395 if (pipe->stream->reconfigure_css_rx) {
1396 ia_css_isys_rx_configure(&pipe->stream->csi_rx_config,
1397 pipe->stream->config.mode);
1398 pipe->stream->reconfigure_css_rx = false;
1399 }
1400#endif
1401
1402 return 0;
1403}
1404
1405void sh_css_binary_args_reset(struct sh_css_binary_args *args)
1406{
1407 unsigned int i;
1408
1409 for (i = 0; i < NUM_TNR_FRAMES; i++)
1410 args->tnr_frames[i] = NULL;
1411 for (i = 0; i < MAX_NUM_VIDEO_DELAY_FRAMES; i++)
1412 args->delay_frames[i] = NULL;
1413 args->in_frame = NULL;
1414 for (i = 0; i < IA_CSS_BINARY_MAX_OUTPUT_PORTS; i++)
1415 args->out_frame[i] = NULL;
1416 args->out_vf_frame = NULL;
1417 args->copy_vf = false;
1418 args->copy_output = true;
1419 args->vf_downscale_log2 = 0;
1420}
1421
1422static void start_pipe(
1423 struct ia_css_pipe *me,
1424 enum sh_css_pipe_config_override copy_ovrd,
1425 enum ia_css_input_mode input_mode)
1426{
1427 const struct ia_css_coordinate *coord = NULL;
1428 const struct ia_css_isp_parameters *params = NULL;
1429
1430
1431 IA_CSS_ENTER_PRIVATE("me = %p, copy_ovrd = %d, input_mode = %d",
1432 me, copy_ovrd, input_mode);
1433
1434 assert(me);
1435
1436 if (!IS_ISP2401) {
1437 coord = &me->config.internal_frame_origin_bqs_on_sctbl;
1438 params = me->stream->isp_params_configs;
1439 }
1440
1441 sh_css_sp_init_pipeline(&me->pipeline,
1442 me->mode,
1443 (uint8_t)ia_css_pipe_get_pipe_num(me),
1444 me->config.default_capture_config.enable_xnr != 0,
1445 me->stream->config.pixels_per_clock == 2,
1446 me->stream->config.continuous,
1447 false,
1448 me->required_bds_factor,
1449 copy_ovrd,
1450 input_mode,
1451 &me->stream->config.metadata_config,
1452 &me->stream->info.metadata_info
1453 , (input_mode == IA_CSS_INPUT_MODE_MEMORY) ?
1454 (enum mipi_port_id)0 :
1455 me->stream->config.source.port.port,
1456 coord,
1457 params);
1458
1459 if (me->config.mode != IA_CSS_PIPE_MODE_COPY) {
1460 struct ia_css_pipeline_stage *stage;
1461
1462 stage = me->pipeline.stages;
1463 if (stage) {
1464 me->pipeline.current_stage = stage;
1465 start_binary(me, stage->binary);
1466 }
1467 }
1468 IA_CSS_LEAVE_PRIVATE("void");
1469}
1470
1471void
1472sh_css_invalidate_shading_tables(struct ia_css_stream *stream)
1473{
1474 int i;
1475
1476 assert(stream);
1477
1478 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1479 "sh_css_invalidate_shading_tables() enter:\n");
1480
1481 for (i = 0; i < stream->num_pipes; i++) {
1482 assert(stream->pipes[i]);
1483 sh_css_pipe_free_shading_table(stream->pipes[i]);
1484 }
1485
1486 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
1487 "sh_css_invalidate_shading_tables() leave: return_void\n");
1488}
1489
1490static void
1491enable_interrupts(enum ia_css_irq_type irq_type)
1492{
1493#ifndef ISP2401
1494 enum mipi_port_id port;
1495#endif
1496 bool enable_pulse = irq_type != IA_CSS_IRQ_TYPE_EDGE;
1497
1498 IA_CSS_ENTER_PRIVATE("");
1499
1500
1501 cnd_sp_irq_enable(SP0_ID, true);
1502
1503 irq_enable_pulse(IRQ0_ID, enable_pulse);
1504
1505 cnd_virq_enable_channel(virq_sp, true);
1506
1507
1508 cnd_virq_enable_channel(
1509 (enum virq_id)(IRQ_SW_CHANNEL0_ID + IRQ_SW_CHANNEL_OFFSET),
1510 true);
1511
1512 cnd_virq_enable_channel(
1513 (enum virq_id)(IRQ_SW_CHANNEL1_ID + IRQ_SW_CHANNEL_OFFSET),
1514 true);
1515
1516#ifndef ISP2401
1517 for (port = 0; port < N_MIPI_PORT_ID; port++)
1518 ia_css_isys_rx_enable_all_interrupts(port);
1519#endif
1520
1521 IA_CSS_LEAVE_PRIVATE("");
1522}
1523
1524static bool sh_css_setup_spctrl_config(const struct ia_css_fw_info *fw,
1525 const char *program,
1526 ia_css_spctrl_cfg *spctrl_cfg)
1527{
1528 if ((!fw) || (!spctrl_cfg))
1529 return false;
1530 spctrl_cfg->sp_entry = 0;
1531 spctrl_cfg->program_name = (char *)(program);
1532
1533 spctrl_cfg->ddr_data_offset = fw->blob.data_source;
1534 spctrl_cfg->dmem_data_addr = fw->blob.data_target;
1535 spctrl_cfg->dmem_bss_addr = fw->blob.bss_target;
1536 spctrl_cfg->data_size = fw->blob.data_size;
1537 spctrl_cfg->bss_size = fw->blob.bss_size;
1538
1539 spctrl_cfg->spctrl_config_dmem_addr = fw->info.sp.init_dmem_data;
1540 spctrl_cfg->spctrl_state_dmem_addr = fw->info.sp.sw_state;
1541
1542 spctrl_cfg->code_size = fw->blob.size;
1543 spctrl_cfg->code = fw->blob.code;
1544 spctrl_cfg->sp_entry = fw->info.sp.sp_entry;
1545
1546 return true;
1547}
1548
1549void
1550ia_css_unload_firmware(void)
1551{
1552 if (sh_css_num_binaries) {
1553
1554 ia_css_binary_uninit();
1555 sh_css_unload_firmware();
1556 }
1557 fw_explicitly_loaded = false;
1558}
1559
1560static void
1561ia_css_reset_defaults(struct sh_css *css)
1562{
1563 struct sh_css default_css;
1564
1565
1566 memset(&default_css, 0, sizeof(default_css));
1567
1568
1569 default_css.check_system_idle = true;
1570 default_css.num_cont_raw_frames = NUM_CONTINUOUS_FRAMES;
1571
1572
1573
1574
1575
1576 default_css.irq_type = IA_CSS_IRQ_TYPE_EDGE;
1577
1578
1579 *css = default_css;
1580}
1581
1582int
1583ia_css_load_firmware(struct device *dev, const struct ia_css_env *env,
1584 const struct ia_css_fw *fw)
1585{
1586 int err;
1587
1588 if (!env)
1589 return -EINVAL;
1590 if (!fw)
1591 return -EINVAL;
1592
1593 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_load_firmware() enter\n");
1594
1595
1596 if (my_css.flush != env->cpu_mem_env.flush) {
1597 ia_css_reset_defaults(&my_css);
1598 my_css.flush = env->cpu_mem_env.flush;
1599 }
1600
1601 ia_css_unload_firmware();
1602 err = sh_css_load_firmware(dev, fw->data, fw->bytes);
1603 if (!err) {
1604 err = ia_css_binary_init_infos();
1605 if (!err)
1606 fw_explicitly_loaded = true;
1607 }
1608
1609 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_load_firmware() leave\n");
1610 return err;
1611}
1612
1613int
1614ia_css_init(struct device *dev, const struct ia_css_env *env,
1615 const struct ia_css_fw *fw,
1616 u32 mmu_l1_base,
1617 enum ia_css_irq_type irq_type)
1618{
1619 int err;
1620 ia_css_spctrl_cfg spctrl_cfg;
1621
1622 void (*flush_func)(struct ia_css_acc_fw *fw);
1623 hrt_data select, enable;
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642 COMPILATION_ERROR_IF(sizeof(struct sh_css_ddr_address_map) != SIZE_OF_SH_CSS_DDR_ADDRESS_MAP_STRUCT);
1643
1644 COMPILATION_ERROR_IF(sizeof(struct host_sp_queues) != SIZE_OF_HOST_SP_QUEUES_STRUCT);
1645 COMPILATION_ERROR_IF(sizeof(struct ia_css_circbuf_desc_s) != SIZE_OF_IA_CSS_CIRCBUF_DESC_S_STRUCT);
1646 COMPILATION_ERROR_IF(sizeof(struct ia_css_circbuf_elem_s) != SIZE_OF_IA_CSS_CIRCBUF_ELEM_S_STRUCT);
1647
1648
1649 COMPILATION_ERROR_IF(sizeof(struct host_sp_communication) != SIZE_OF_HOST_SP_COMMUNICATION_STRUCT);
1650 COMPILATION_ERROR_IF(sizeof(struct sh_css_event_irq_mask) != SIZE_OF_SH_CSS_EVENT_IRQ_MASK_STRUCT);
1651
1652
1653 COMPILATION_ERROR_IF(sizeof(struct sh_css_hmm_buffer) != SIZE_OF_SH_CSS_HMM_BUFFER_STRUCT);
1654 COMPILATION_ERROR_IF(sizeof(struct ia_css_isp_3a_statistics) != SIZE_OF_IA_CSS_ISP_3A_STATISTICS_STRUCT);
1655 COMPILATION_ERROR_IF(sizeof(struct ia_css_isp_dvs_statistics) != SIZE_OF_IA_CSS_ISP_DVS_STATISTICS_STRUCT);
1656 COMPILATION_ERROR_IF(sizeof(struct ia_css_metadata) != SIZE_OF_IA_CSS_METADATA_STRUCT);
1657
1658
1659 COMPILATION_ERROR_IF(sizeof(struct ia_css_sp_init_dmem_cfg) != SIZE_OF_IA_CSS_SP_INIT_DMEM_CFG_STRUCT);
1660
1661 if (!fw && !fw_explicitly_loaded)
1662 return -EINVAL;
1663 if (!env)
1664 return -EINVAL;
1665
1666 sh_css_printf = env->print_env.debug_print;
1667
1668 IA_CSS_ENTER("void");
1669
1670 flush_func = env->cpu_mem_env.flush;
1671
1672 pipe_global_init();
1673 ia_css_pipeline_init();
1674 ia_css_queue_map_init();
1675
1676 ia_css_device_access_init(&env->hw_access_env);
1677
1678 select = gpio_reg_load(GPIO0_ID, _gpio_block_reg_do_select)
1679 & (~GPIO_FLASH_PIN_MASK);
1680 enable = gpio_reg_load(GPIO0_ID, _gpio_block_reg_do_e)
1681 | GPIO_FLASH_PIN_MASK;
1682 sh_css_mmu_set_page_table_base_index(mmu_l1_base);
1683
1684 my_css_save.mmu_base = mmu_l1_base;
1685
1686 ia_css_reset_defaults(&my_css);
1687
1688 my_css_save.driver_env = *env;
1689 my_css.flush = flush_func;
1690
1691 err = ia_css_rmgr_init();
1692 if (err) {
1693 IA_CSS_LEAVE_ERR(err);
1694 return err;
1695 }
1696
1697 IA_CSS_LOG("init: %d", my_css_save_initialized);
1698
1699 if (!my_css_save_initialized) {
1700 my_css_save_initialized = true;
1701 my_css_save.mode = sh_css_mode_working;
1702 memset(my_css_save.stream_seeds, 0,
1703 sizeof(struct sh_css_stream_seed) * MAX_ACTIVE_STREAMS);
1704 IA_CSS_LOG("init: %d mode=%d", my_css_save_initialized, my_css_save.mode);
1705 }
1706
1707 mipi_init();
1708
1709#ifndef ISP2401
1710
1711
1712 my_css.page_table_base_index = mmu_get_page_table_base_index(MMU0_ID);
1713
1714#endif
1715 my_css.irq_type = irq_type;
1716
1717 my_css_save.irq_type = irq_type;
1718
1719 enable_interrupts(my_css.irq_type);
1720
1721
1722 gpio_reg_store(GPIO0_ID, _gpio_block_reg_do_select, select);
1723 gpio_reg_store(GPIO0_ID, _gpio_block_reg_do_e, enable);
1724 gpio_reg_store(GPIO0_ID, _gpio_block_reg_do_0, 0);
1725
1726 err = ia_css_refcount_init(REFCOUNT_SIZE);
1727 if (err) {
1728 IA_CSS_LEAVE_ERR(err);
1729 return err;
1730 }
1731 err = sh_css_params_init();
1732 if (err) {
1733 IA_CSS_LEAVE_ERR(err);
1734 return err;
1735 }
1736 if (fw) {
1737 ia_css_unload_firmware();
1738 err = sh_css_load_firmware(dev, fw->data, fw->bytes);
1739 if (err) {
1740 IA_CSS_LEAVE_ERR(err);
1741 return err;
1742 }
1743 err = ia_css_binary_init_infos();
1744 if (err) {
1745 IA_CSS_LEAVE_ERR(err);
1746 return err;
1747 }
1748 fw_explicitly_loaded = false;
1749#ifndef ISP2401
1750 my_css_save.loaded_fw = (struct ia_css_fw *)fw;
1751#endif
1752 }
1753 if (!sh_css_setup_spctrl_config(&sh_css_sp_fw, SP_PROG_NAME, &spctrl_cfg))
1754 return -EINVAL;
1755
1756 err = ia_css_spctrl_load_fw(SP0_ID, &spctrl_cfg);
1757 if (err) {
1758 IA_CSS_LEAVE_ERR(err);
1759 return err;
1760 }
1761
1762#if WITH_PC_MONITORING
1763 if (!thread_alive) {
1764 thread_alive++;
1765 sh_css_print("PC_MONITORING: %s() -- create thread DISABLED\n",
1766 __func__);
1767 spying_thread_create();
1768 }
1769#endif
1770 if (!sh_css_hrt_system_is_idle()) {
1771 IA_CSS_LEAVE_ERR(-EBUSY);
1772 return -EBUSY;
1773 }
1774
1775
1776
1777
1778
1779
1780
1781#if defined(ISP2401)
1782 gp_device_reg_store(GP_DEVICE0_ID, _REG_GP_SWITCH_ISYS2401_ADDR, 1);
1783#endif
1784
1785
1786 if (!IS_ISP2401)
1787 dma_set_max_burst_size(DMA0_ID, HIVE_DMA_BUS_DDR_CONN,
1788 ISP2400_DMA_MAX_BURST_LENGTH);
1789 else
1790 dma_set_max_burst_size(DMA0_ID, HIVE_DMA_BUS_DDR_CONN,
1791 ISP2401_DMA_MAX_BURST_LENGTH);
1792
1793 if (ia_css_isys_init() != INPUT_SYSTEM_ERR_NO_ERROR)
1794 err = -EINVAL;
1795
1796 sh_css_params_map_and_store_default_gdc_lut();
1797
1798 IA_CSS_LEAVE_ERR(err);
1799 return err;
1800}
1801
1802int
1803ia_css_enable_isys_event_queue(bool enable)
1804{
1805 if (sh_css_sp_is_running())
1806 return -EBUSY;
1807 sh_css_sp_enable_isys_event_queue(enable);
1808 return 0;
1809}
1810
1811
1812void
1813sh_css_flush(struct ia_css_acc_fw *fw)
1814{
1815 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "sh_css_flush() enter:\n");
1816 if ((fw) && (my_css.flush))
1817 my_css.flush(fw);
1818}
1819
1820
1821
1822
1823
1824static int
1825map_sp_threads(struct ia_css_stream *stream, bool map)
1826{
1827 struct ia_css_pipe *main_pipe = NULL;
1828 struct ia_css_pipe *copy_pipe = NULL;
1829 struct ia_css_pipe *capture_pipe = NULL;
1830 struct ia_css_pipe *acc_pipe = NULL;
1831 int err = 0;
1832 enum ia_css_pipe_id pipe_id;
1833
1834 IA_CSS_ENTER_PRIVATE("stream = %p, map = %s",
1835 stream, map ? "true" : "false");
1836
1837 if (!stream) {
1838 IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
1839 return -EINVAL;
1840 }
1841
1842 main_pipe = stream->last_pipe;
1843 pipe_id = main_pipe->mode;
1844
1845 ia_css_pipeline_map(main_pipe->pipe_num, map);
1846
1847 switch (pipe_id) {
1848 case IA_CSS_PIPE_ID_PREVIEW:
1849 copy_pipe = main_pipe->pipe_settings.preview.copy_pipe;
1850 capture_pipe = main_pipe->pipe_settings.preview.capture_pipe;
1851 acc_pipe = main_pipe->pipe_settings.preview.acc_pipe;
1852 break;
1853
1854 case IA_CSS_PIPE_ID_VIDEO:
1855 copy_pipe = main_pipe->pipe_settings.video.copy_pipe;
1856 capture_pipe = main_pipe->pipe_settings.video.capture_pipe;
1857 break;
1858
1859 case IA_CSS_PIPE_ID_CAPTURE:
1860 case IA_CSS_PIPE_ID_ACC:
1861 default:
1862 break;
1863 }
1864
1865 if (acc_pipe)
1866 ia_css_pipeline_map(acc_pipe->pipe_num, map);
1867
1868 if (capture_pipe)
1869 ia_css_pipeline_map(capture_pipe->pipe_num, map);
1870
1871
1872 if (copy_pipe)
1873 ia_css_pipeline_map(copy_pipe->pipe_num, map);
1874
1875
1876 if (!stream->config.continuous) {
1877 int i;
1878
1879 for (i = 1; i < stream->num_pipes; i++)
1880 ia_css_pipeline_map(stream->pipes[i]->pipe_num, map);
1881 }
1882
1883 IA_CSS_LEAVE_ERR_PRIVATE(err);
1884 return err;
1885}
1886
1887
1888
1889static int
1890create_host_pipeline_structure(struct ia_css_stream *stream)
1891{
1892 struct ia_css_pipe *copy_pipe = NULL, *capture_pipe = NULL;
1893 struct ia_css_pipe *acc_pipe = NULL;
1894 enum ia_css_pipe_id pipe_id;
1895 struct ia_css_pipe *main_pipe = NULL;
1896 int err = 0;
1897 unsigned int copy_pipe_delay = 0,
1898 capture_pipe_delay = 0;
1899
1900 IA_CSS_ENTER_PRIVATE("stream = %p", stream);
1901
1902 if (!stream) {
1903 IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
1904 return -EINVAL;
1905 }
1906
1907 main_pipe = stream->last_pipe;
1908 if (!main_pipe) {
1909 IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
1910 return -EINVAL;
1911 }
1912
1913 pipe_id = main_pipe->mode;
1914
1915 switch (pipe_id) {
1916 case IA_CSS_PIPE_ID_PREVIEW:
1917 copy_pipe = main_pipe->pipe_settings.preview.copy_pipe;
1918 copy_pipe_delay = main_pipe->dvs_frame_delay;
1919 capture_pipe = main_pipe->pipe_settings.preview.capture_pipe;
1920 capture_pipe_delay = IA_CSS_FRAME_DELAY_0;
1921 acc_pipe = main_pipe->pipe_settings.preview.acc_pipe;
1922 err = ia_css_pipeline_create(&main_pipe->pipeline, main_pipe->mode,
1923 main_pipe->pipe_num, main_pipe->dvs_frame_delay);
1924 break;
1925
1926 case IA_CSS_PIPE_ID_VIDEO:
1927 copy_pipe = main_pipe->pipe_settings.video.copy_pipe;
1928 copy_pipe_delay = main_pipe->dvs_frame_delay;
1929 capture_pipe = main_pipe->pipe_settings.video.capture_pipe;
1930 capture_pipe_delay = IA_CSS_FRAME_DELAY_0;
1931 err = ia_css_pipeline_create(&main_pipe->pipeline, main_pipe->mode,
1932 main_pipe->pipe_num, main_pipe->dvs_frame_delay);
1933 break;
1934
1935 case IA_CSS_PIPE_ID_CAPTURE:
1936 capture_pipe = main_pipe;
1937 capture_pipe_delay = main_pipe->dvs_frame_delay;
1938 break;
1939
1940 case IA_CSS_PIPE_ID_YUVPP:
1941 err = ia_css_pipeline_create(&main_pipe->pipeline, main_pipe->mode,
1942 main_pipe->pipe_num, main_pipe->dvs_frame_delay);
1943 break;
1944
1945 case IA_CSS_PIPE_ID_ACC:
1946 err = ia_css_pipeline_create(&main_pipe->pipeline, main_pipe->mode,
1947 main_pipe->pipe_num, main_pipe->dvs_frame_delay);
1948 break;
1949
1950 default:
1951 err = -EINVAL;
1952 }
1953
1954 if (!(err) && copy_pipe)
1955 err = ia_css_pipeline_create(©_pipe->pipeline,
1956 copy_pipe->mode,
1957 copy_pipe->pipe_num,
1958 copy_pipe_delay);
1959
1960 if (!(err) && capture_pipe)
1961 err = ia_css_pipeline_create(&capture_pipe->pipeline,
1962 capture_pipe->mode,
1963 capture_pipe->pipe_num,
1964 capture_pipe_delay);
1965
1966 if (!(err) && acc_pipe)
1967 err = ia_css_pipeline_create(&acc_pipe->pipeline, acc_pipe->mode,
1968 acc_pipe->pipe_num, main_pipe->dvs_frame_delay);
1969
1970
1971 if (!stream->config.continuous) {
1972 int i;
1973
1974 for (i = 1; i < stream->num_pipes && 0 == err; i++) {
1975 main_pipe = stream->pipes[i];
1976 err = ia_css_pipeline_create(&main_pipe->pipeline,
1977 main_pipe->mode,
1978 main_pipe->pipe_num,
1979 main_pipe->dvs_frame_delay);
1980 }
1981 }
1982
1983 IA_CSS_LEAVE_ERR_PRIVATE(err);
1984 return err;
1985}
1986
1987
1988
1989static int
1990create_host_pipeline(struct ia_css_stream *stream)
1991{
1992 struct ia_css_pipe *copy_pipe = NULL, *capture_pipe = NULL;
1993 struct ia_css_pipe *acc_pipe = NULL;
1994 enum ia_css_pipe_id pipe_id;
1995 struct ia_css_pipe *main_pipe = NULL;
1996 int err = 0;
1997 unsigned int max_input_width = 0;
1998
1999 IA_CSS_ENTER_PRIVATE("stream = %p", stream);
2000 if (!stream) {
2001 IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
2002 return -EINVAL;
2003 }
2004
2005 main_pipe = stream->last_pipe;
2006 pipe_id = main_pipe->mode;
2007
2008
2009
2010 if ((pipe_id == IA_CSS_PIPE_ID_PREVIEW) ||
2011 (pipe_id == IA_CSS_PIPE_ID_VIDEO)) {
2012
2013
2014
2015
2016
2017
2018 if (stream->config.continuous ||
2019 (pipe_id == IA_CSS_PIPE_ID_PREVIEW &&
2020 stream->config.mode != IA_CSS_INPUT_MODE_MEMORY)) {
2021 err = alloc_continuous_frames(main_pipe, true);
2022 if (err)
2023 goto ERR;
2024 }
2025 }
2026
2027#if !defined(ISP2401)
2028
2029 if (pipe_id != IA_CSS_PIPE_ID_ACC) {
2030 err = allocate_mipi_frames(main_pipe, &stream->info);
2031 if (err)
2032 goto ERR;
2033 }
2034#elif defined(ISP2401)
2035 if ((pipe_id != IA_CSS_PIPE_ID_ACC) &&
2036 (main_pipe->config.mode != IA_CSS_PIPE_MODE_COPY)) {
2037 err = allocate_mipi_frames(main_pipe, &stream->info);
2038 if (err)
2039 goto ERR;
2040 }
2041#endif
2042
2043 switch (pipe_id) {
2044 case IA_CSS_PIPE_ID_PREVIEW:
2045 copy_pipe = main_pipe->pipe_settings.preview.copy_pipe;
2046 capture_pipe = main_pipe->pipe_settings.preview.capture_pipe;
2047 acc_pipe = main_pipe->pipe_settings.preview.acc_pipe;
2048 max_input_width =
2049 main_pipe->pipe_settings.preview.preview_binary.info->sp.input.max_width;
2050
2051 err = create_host_preview_pipeline(main_pipe);
2052 if (err)
2053 goto ERR;
2054
2055 break;
2056
2057 case IA_CSS_PIPE_ID_VIDEO:
2058 copy_pipe = main_pipe->pipe_settings.video.copy_pipe;
2059 capture_pipe = main_pipe->pipe_settings.video.capture_pipe;
2060 max_input_width =
2061 main_pipe->pipe_settings.video.video_binary.info->sp.input.max_width;
2062
2063 err = create_host_video_pipeline(main_pipe);
2064 if (err)
2065 goto ERR;
2066
2067 break;
2068
2069 case IA_CSS_PIPE_ID_CAPTURE:
2070 capture_pipe = main_pipe;
2071
2072 break;
2073
2074 case IA_CSS_PIPE_ID_YUVPP:
2075 err = create_host_yuvpp_pipeline(main_pipe);
2076 if (err)
2077 goto ERR;
2078
2079 break;
2080
2081 case IA_CSS_PIPE_ID_ACC:
2082 err = create_host_acc_pipeline(main_pipe);
2083 if (err)
2084 goto ERR;
2085
2086 break;
2087 default:
2088 err = -EINVAL;
2089 }
2090 if (err)
2091 goto ERR;
2092
2093 if (copy_pipe) {
2094 err = create_host_copy_pipeline(copy_pipe, max_input_width,
2095 main_pipe->continuous_frames[0]);
2096 if (err)
2097 goto ERR;
2098 }
2099
2100 if (capture_pipe) {
2101 err = create_host_capture_pipeline(capture_pipe);
2102 if (err)
2103 goto ERR;
2104 }
2105
2106 if (acc_pipe) {
2107 err = create_host_acc_pipeline(acc_pipe);
2108 if (err)
2109 goto ERR;
2110 }
2111
2112
2113 if (!stream->config.continuous) {
2114 int i;
2115
2116 for (i = 1; i < stream->num_pipes && 0 == err; i++) {
2117 switch (stream->pipes[i]->mode) {
2118 case IA_CSS_PIPE_ID_PREVIEW:
2119 err = create_host_preview_pipeline(stream->pipes[i]);
2120 break;
2121 case IA_CSS_PIPE_ID_VIDEO:
2122 err = create_host_video_pipeline(stream->pipes[i]);
2123 break;
2124 case IA_CSS_PIPE_ID_CAPTURE:
2125 err = create_host_capture_pipeline(stream->pipes[i]);
2126 break;
2127 case IA_CSS_PIPE_ID_YUVPP:
2128 err = create_host_yuvpp_pipeline(stream->pipes[i]);
2129 break;
2130 case IA_CSS_PIPE_ID_ACC:
2131 err = create_host_acc_pipeline(stream->pipes[i]);
2132 break;
2133 default:
2134 err = -EINVAL;
2135 }
2136 if (err)
2137 goto ERR;
2138 }
2139 }
2140
2141ERR:
2142 IA_CSS_LEAVE_ERR_PRIVATE(err);
2143 return err;
2144}
2145
2146static const struct ia_css_pipe default_pipe = IA_CSS_DEFAULT_PIPE;
2147static const struct ia_css_preview_settings preview = IA_CSS_DEFAULT_PREVIEW_SETTINGS;
2148static const struct ia_css_capture_settings capture = IA_CSS_DEFAULT_CAPTURE_SETTINGS;
2149static const struct ia_css_video_settings video = IA_CSS_DEFAULT_VIDEO_SETTINGS;
2150static const struct ia_css_yuvpp_settings yuvpp = IA_CSS_DEFAULT_YUVPP_SETTINGS;
2151
2152static int
2153init_pipe_defaults(enum ia_css_pipe_mode mode,
2154 struct ia_css_pipe *pipe,
2155 bool copy_pipe)
2156{
2157 if (!pipe) {
2158 IA_CSS_ERROR("NULL pipe parameter");
2159 return -EINVAL;
2160 }
2161
2162
2163 memcpy(pipe, &default_pipe, sizeof(default_pipe));
2164
2165
2166 switch (mode) {
2167 case IA_CSS_PIPE_MODE_PREVIEW:
2168 pipe->mode = IA_CSS_PIPE_ID_PREVIEW;
2169 memcpy(&pipe->pipe_settings.preview, &preview, sizeof(preview));
2170 break;
2171 case IA_CSS_PIPE_MODE_CAPTURE:
2172 if (copy_pipe)
2173 pipe->mode = IA_CSS_PIPE_ID_COPY;
2174 else
2175 pipe->mode = IA_CSS_PIPE_ID_CAPTURE;
2176
2177 memcpy(&pipe->pipe_settings.capture, &capture, sizeof(capture));
2178 break;
2179 case IA_CSS_PIPE_MODE_VIDEO:
2180 pipe->mode = IA_CSS_PIPE_ID_VIDEO;
2181 memcpy(&pipe->pipe_settings.video, &video, sizeof(video));
2182 break;
2183 case IA_CSS_PIPE_MODE_ACC:
2184 pipe->mode = IA_CSS_PIPE_ID_ACC;
2185 break;
2186 case IA_CSS_PIPE_MODE_COPY:
2187 pipe->mode = IA_CSS_PIPE_ID_CAPTURE;
2188 break;
2189 case IA_CSS_PIPE_MODE_YUVPP:
2190 pipe->mode = IA_CSS_PIPE_ID_YUVPP;
2191 memcpy(&pipe->pipe_settings.yuvpp, &yuvpp, sizeof(yuvpp));
2192 break;
2193 default:
2194 return -EINVAL;
2195 }
2196
2197 return 0;
2198}
2199
2200static void
2201pipe_global_init(void)
2202{
2203 u8 i;
2204
2205 my_css.pipe_counter = 0;
2206 for (i = 0; i < IA_CSS_PIPELINE_NUM_MAX; i++)
2207 my_css.all_pipes[i] = NULL;
2208}
2209
2210static int
2211pipe_generate_pipe_num(const struct ia_css_pipe *pipe,
2212 unsigned int *pipe_number)
2213{
2214 const u8 INVALID_PIPE_NUM = (uint8_t)~(0);
2215 u8 pipe_num = INVALID_PIPE_NUM;
2216 u8 i;
2217
2218 if (!pipe) {
2219 IA_CSS_ERROR("NULL pipe parameter");
2220 return -EINVAL;
2221 }
2222
2223
2224 for (i = 0; i < IA_CSS_PIPELINE_NUM_MAX; i++) {
2225 if (!my_css.all_pipes[i]) {
2226
2227 my_css.all_pipes[i] = (struct ia_css_pipe *)pipe;
2228 pipe_num = i;
2229 break;
2230 }
2231 }
2232 if (pipe_num == INVALID_PIPE_NUM) {
2233
2234 IA_CSS_ERROR("Max number of pipes already created");
2235 return -ENOSPC;
2236 }
2237
2238 my_css.pipe_counter++;
2239
2240 IA_CSS_LOG("pipe_num (%d)", pipe_num);
2241
2242 *pipe_number = pipe_num;
2243 return 0;
2244}
2245
2246static void
2247pipe_release_pipe_num(unsigned int pipe_num)
2248{
2249 my_css.all_pipes[pipe_num] = NULL;
2250 my_css.pipe_counter--;
2251 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
2252 "pipe_release_pipe_num (%d)\n", pipe_num);
2253}
2254
2255static int
2256create_pipe(enum ia_css_pipe_mode mode,
2257 struct ia_css_pipe **pipe,
2258 bool copy_pipe)
2259{
2260 int err = 0;
2261 struct ia_css_pipe *me;
2262
2263 if (!pipe) {
2264 IA_CSS_ERROR("NULL pipe parameter");
2265 return -EINVAL;
2266 }
2267
2268 me = kmalloc(sizeof(*me), GFP_KERNEL);
2269 if (!me)
2270 return -ENOMEM;
2271
2272 err = init_pipe_defaults(mode, me, copy_pipe);
2273 if (err) {
2274 kfree(me);
2275 return err;
2276 }
2277
2278 err = pipe_generate_pipe_num(me, &me->pipe_num);
2279 if (err) {
2280 kfree(me);
2281 return err;
2282 }
2283
2284 *pipe = me;
2285 return 0;
2286}
2287
2288struct ia_css_pipe *
2289find_pipe_by_num(uint32_t pipe_num)
2290{
2291 unsigned int i;
2292
2293 for (i = 0; i < IA_CSS_PIPELINE_NUM_MAX; i++) {
2294 if (my_css.all_pipes[i] &&
2295 ia_css_pipe_get_pipe_num(my_css.all_pipes[i]) == pipe_num) {
2296 return my_css.all_pipes[i];
2297 }
2298 }
2299 return NULL;
2300}
2301
2302static void sh_css_pipe_free_acc_binaries(
2303 struct ia_css_pipe *pipe)
2304{
2305 struct ia_css_pipeline *pipeline;
2306 struct ia_css_pipeline_stage *stage;
2307
2308 if (!pipe) {
2309 IA_CSS_ERROR("NULL input pointer");
2310 return;
2311 }
2312 pipeline = &pipe->pipeline;
2313
2314
2315 for (stage = pipeline->stages; stage; stage = stage->next) {
2316 struct ia_css_fw_info *firmware = (struct ia_css_fw_info *)
2317 stage->firmware;
2318 if (firmware)
2319 ia_css_pipe_unload_extension(pipe, firmware);
2320 }
2321}
2322
2323int
2324ia_css_pipe_destroy(struct ia_css_pipe *pipe)
2325{
2326 int err = 0;
2327
2328 IA_CSS_ENTER("pipe = %p", pipe);
2329
2330 if (!pipe) {
2331 IA_CSS_LEAVE_ERR(-EINVAL);
2332 return -EINVAL;
2333 }
2334
2335 if (pipe->stream) {
2336 IA_CSS_LOG("ia_css_stream_destroy not called!");
2337 IA_CSS_LEAVE_ERR(-EINVAL);
2338 return -EINVAL;
2339 }
2340
2341 switch (pipe->config.mode) {
2342 case IA_CSS_PIPE_MODE_PREVIEW:
2343
2344
2345 if (pipe->mode == IA_CSS_PIPE_ID_PREVIEW) {
2346 ia_css_frame_free_multiple(NUM_CONTINUOUS_FRAMES,
2347 pipe->continuous_frames);
2348 ia_css_metadata_free_multiple(NUM_CONTINUOUS_FRAMES,
2349 pipe->cont_md_buffers);
2350 if (pipe->pipe_settings.preview.copy_pipe) {
2351 err = ia_css_pipe_destroy(pipe->pipe_settings.preview.copy_pipe);
2352 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
2353 "ia_css_pipe_destroy(): destroyed internal copy pipe err=%d\n",
2354 err);
2355 }
2356 }
2357 break;
2358 case IA_CSS_PIPE_MODE_VIDEO:
2359 if (pipe->mode == IA_CSS_PIPE_ID_VIDEO) {
2360 ia_css_frame_free_multiple(NUM_CONTINUOUS_FRAMES,
2361 pipe->continuous_frames);
2362 ia_css_metadata_free_multiple(NUM_CONTINUOUS_FRAMES,
2363 pipe->cont_md_buffers);
2364 if (pipe->pipe_settings.video.copy_pipe) {
2365 err = ia_css_pipe_destroy(pipe->pipe_settings.video.copy_pipe);
2366 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
2367 "ia_css_pipe_destroy(): destroyed internal copy pipe err=%d\n",
2368 err);
2369 }
2370 }
2371#ifndef ISP2401
2372 ia_css_frame_free_multiple(NUM_TNR_FRAMES,
2373 pipe->pipe_settings.video.tnr_frames);
2374#else
2375 ia_css_frame_free_multiple(NUM_TNR_FRAMES,
2376 pipe->pipe_settings.video.tnr_frames);
2377#endif
2378 ia_css_frame_free_multiple(MAX_NUM_VIDEO_DELAY_FRAMES,
2379 pipe->pipe_settings.video.delay_frames);
2380 break;
2381 case IA_CSS_PIPE_MODE_CAPTURE:
2382 ia_css_frame_free_multiple(MAX_NUM_VIDEO_DELAY_FRAMES,
2383 pipe->pipe_settings.capture.delay_frames);
2384 break;
2385 case IA_CSS_PIPE_MODE_ACC:
2386 sh_css_pipe_free_acc_binaries(pipe);
2387 break;
2388 case IA_CSS_PIPE_MODE_COPY:
2389 break;
2390 case IA_CSS_PIPE_MODE_YUVPP:
2391 break;
2392 }
2393
2394 sh_css_params_free_gdc_lut(pipe->scaler_pp_lut);
2395 pipe->scaler_pp_lut = mmgr_NULL;
2396
2397 my_css.active_pipes[ia_css_pipe_get_pipe_num(pipe)] = NULL;
2398 sh_css_pipe_free_shading_table(pipe);
2399
2400 ia_css_pipeline_destroy(&pipe->pipeline);
2401 pipe_release_pipe_num(ia_css_pipe_get_pipe_num(pipe));
2402
2403
2404 if (pipe->config.acc_extension)
2405 ia_css_pipe_unload_extension(pipe, pipe->config.acc_extension);
2406
2407 kfree(pipe);
2408 IA_CSS_LEAVE("err = %d", err);
2409 return err;
2410}
2411
2412void
2413ia_css_uninit(void)
2414{
2415 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_uninit() enter: void\n");
2416#if WITH_PC_MONITORING
2417 sh_css_print("PC_MONITORING: %s() -- started\n", __func__);
2418 print_pc_histogram();
2419#endif
2420
2421 sh_css_params_free_default_gdc_lut();
2422
2423
2424
2425
2426 sh_css_params_uninit();
2427 ia_css_refcount_uninit();
2428
2429 ia_css_rmgr_uninit();
2430
2431#if !defined(ISP2401)
2432
2433 ifmtr_set_if_blocking_mode_reset = true;
2434#endif
2435
2436 if (!fw_explicitly_loaded)
2437 ia_css_unload_firmware();
2438
2439 ia_css_spctrl_unload_fw(SP0_ID);
2440 sh_css_sp_set_sp_running(false);
2441
2442 free_mipi_frames(NULL);
2443
2444 sh_css_sp_reset_global_vars();
2445
2446 ia_css_isys_uninit();
2447
2448 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "ia_css_uninit() leave: return_void\n");
2449}
2450
2451int ia_css_irq_translate(
2452 unsigned int *irq_infos)
2453{
2454 enum virq_id irq;
2455 enum hrt_isp_css_irq_status status = hrt_isp_css_irq_status_more_irqs;
2456 unsigned int infos = 0;
2457
2458
2459
2460 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
2461 "ia_css_irq_translate() enter: irq_infos=%p\n", irq_infos);
2462
2463 while (status == hrt_isp_css_irq_status_more_irqs) {
2464 status = virq_get_channel_id(&irq);
2465 if (status == hrt_isp_css_irq_status_error)
2466 return -EINVAL;
2467
2468#if WITH_PC_MONITORING
2469 sh_css_print("PC_MONITORING: %s() irq = %d, sh_binary_running set to 0\n",
2470 __func__, irq);
2471 sh_binary_running = 0;
2472#endif
2473
2474 switch (irq) {
2475 case virq_sp:
2476
2477
2478 infos |= IA_CSS_IRQ_INFO_EVENTS_READY;
2479 break;
2480 case virq_isp:
2481 break;
2482 case virq_isys_sof:
2483 infos |= IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF;
2484 break;
2485 case virq_isys_eof:
2486 infos |= IA_CSS_IRQ_INFO_CSS_RECEIVER_EOF;
2487 break;
2488 case virq_isys_csi:
2489 infos |= IA_CSS_IRQ_INFO_INPUT_SYSTEM_ERROR;
2490 break;
2491#if !defined(ISP2401)
2492 case virq_ifmt0_id:
2493 infos |= IA_CSS_IRQ_INFO_IF_ERROR;
2494 break;
2495#endif
2496 case virq_dma:
2497 infos |= IA_CSS_IRQ_INFO_DMA_ERROR;
2498 break;
2499 case virq_sw_pin_0:
2500 infos |= sh_css_get_sw_interrupt_value(0);
2501 break;
2502 case virq_sw_pin_1:
2503 infos |= sh_css_get_sw_interrupt_value(1);
2504
2505 break;
2506 default:
2507 break;
2508 }
2509 }
2510
2511 if (irq_infos)
2512 *irq_infos = infos;
2513
2514 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
2515 "ia_css_irq_translate() leave: irq_infos=%u\n",
2516 infos);
2517
2518 return 0;
2519}
2520
2521int ia_css_irq_enable(
2522 enum ia_css_irq_info info,
2523 bool enable)
2524{
2525 enum virq_id irq = N_virq_id;
2526
2527 IA_CSS_ENTER("info=%d, enable=%d", info, enable);
2528
2529 switch (info) {
2530#if !defined(ISP2401)
2531 case IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF:
2532 irq = virq_isys_sof;
2533 break;
2534 case IA_CSS_IRQ_INFO_CSS_RECEIVER_EOF:
2535 irq = virq_isys_eof;
2536 break;
2537 case IA_CSS_IRQ_INFO_INPUT_SYSTEM_ERROR:
2538 irq = virq_isys_csi;
2539 break;
2540 case IA_CSS_IRQ_INFO_IF_ERROR:
2541 irq = virq_ifmt0_id;
2542 break;
2543#else
2544 case IA_CSS_IRQ_INFO_CSS_RECEIVER_SOF:
2545 case IA_CSS_IRQ_INFO_CSS_RECEIVER_EOF:
2546 case IA_CSS_IRQ_INFO_INPUT_SYSTEM_ERROR:
2547 case IA_CSS_IRQ_INFO_IF_ERROR:
2548
2549 return 0;
2550#endif
2551 case IA_CSS_IRQ_INFO_DMA_ERROR:
2552 irq = virq_dma;
2553 break;
2554 case IA_CSS_IRQ_INFO_SW_0:
2555 irq = virq_sw_pin_0;
2556 break;
2557 case IA_CSS_IRQ_INFO_SW_1:
2558 irq = virq_sw_pin_1;
2559 break;
2560 default:
2561 IA_CSS_LEAVE_ERR(-EINVAL);
2562 return -EINVAL;
2563 }
2564
2565 cnd_virq_enable_channel(irq, enable);
2566
2567 IA_CSS_LEAVE_ERR(0);
2568 return 0;
2569}
2570
2571
2572static unsigned int
2573sh_css_get_sw_interrupt_value(unsigned int irq)
2574{
2575 unsigned int irq_value;
2576
2577 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
2578 "sh_css_get_sw_interrupt_value() enter: irq=%d\n", irq);
2579 irq_value = sh_css_sp_get_sw_interrupt_value(irq);
2580 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
2581 "sh_css_get_sw_interrupt_value() leave: irq_value=%d\n", irq_value);
2582 return irq_value;
2583}
2584
2585
2586
2587static int load_copy_binary(
2588 struct ia_css_pipe *pipe,
2589 struct ia_css_binary *copy_binary,
2590 struct ia_css_binary *next_binary)
2591{
2592 struct ia_css_frame_info copy_out_info, copy_in_info, copy_vf_info;
2593 unsigned int left_padding;
2594 int err;
2595 struct ia_css_binary_descr copy_descr;
2596
2597
2598 assert(pipe);
2599 assert(copy_binary);
2600 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
2601 "load_copy_binary() enter:\n");
2602
2603 if (next_binary) {
2604 copy_out_info = next_binary->in_frame_info;
2605 left_padding = next_binary->left_padding;
2606 } else {
2607 copy_out_info = pipe->output_info[0];
2608 copy_vf_info = pipe->vf_output_info[0];
2609 ia_css_frame_info_set_format(©_vf_info, IA_CSS_FRAME_FORMAT_YUV_LINE);
2610 left_padding = 0;
2611 }
2612
2613 ia_css_pipe_get_copy_binarydesc(pipe, ©_descr,
2614 ©_in_info, ©_out_info,
2615 (next_binary) ? NULL : NULL);
2616 err = ia_css_binary_find(©_descr, copy_binary);
2617 if (err)
2618 return err;
2619 copy_binary->left_padding = left_padding;
2620 return 0;
2621}
2622
2623static int
2624alloc_continuous_frames(struct ia_css_pipe *pipe, bool init_time)
2625{
2626 int err = 0;
2627 struct ia_css_frame_info ref_info;
2628 enum ia_css_pipe_id pipe_id;
2629 bool continuous;
2630 unsigned int i, idx;
2631 unsigned int num_frames;
2632
2633 IA_CSS_ENTER_PRIVATE("pipe = %p, init_time = %d", pipe, init_time);
2634
2635 if ((!pipe) || (!pipe->stream)) {
2636 IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
2637 return -EINVAL;
2638 }
2639
2640 pipe_id = pipe->mode;
2641 continuous = pipe->stream->config.continuous;
2642
2643 if (continuous) {
2644 if (init_time) {
2645 num_frames = pipe->stream->config.init_num_cont_raw_buf;
2646 pipe->stream->continuous_pipe = pipe;
2647 } else {
2648 num_frames = pipe->stream->config.target_num_cont_raw_buf;
2649 }
2650 } else {
2651 num_frames = NUM_ONLINE_INIT_CONTINUOUS_FRAMES;
2652 }
2653
2654 if (pipe_id == IA_CSS_PIPE_ID_PREVIEW) {
2655 ref_info = pipe->pipe_settings.preview.preview_binary.in_frame_info;
2656 } else if (pipe_id == IA_CSS_PIPE_ID_VIDEO) {
2657 ref_info = pipe->pipe_settings.video.video_binary.in_frame_info;
2658 } else {
2659
2660 IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
2661 return -EINVAL;
2662 }
2663
2664#if defined(ISP2401)
2665
2666 ref_info.res.width = pipe->stream->config.input_config.input_res.width;
2667 ref_info.res.height = pipe->stream->config.input_config.input_res.height;
2668
2669
2670 ref_info.padded_width = CEIL_MUL(ref_info.res.width, 2 * ISP_VEC_NELEMS);
2671#endif
2672
2673#if !defined(HAS_NO_PACKED_RAW_PIXELS)
2674 if (pipe->stream->config.pack_raw_pixels) {
2675 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
2676 "alloc_continuous_frames() IA_CSS_FRAME_FORMAT_RAW_PACKED\n");
2677 ref_info.format = IA_CSS_FRAME_FORMAT_RAW_PACKED;
2678 } else
2679#endif
2680 {
2681 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
2682 "alloc_continuous_frames() IA_CSS_FRAME_FORMAT_RAW\n");
2683 ref_info.format = IA_CSS_FRAME_FORMAT_RAW;
2684 }
2685
2686
2687 if (pipe_id == IA_CSS_PIPE_ID_PREVIEW) {
2688 pipe->pipe_settings.preview.preview_binary.in_frame_info.format =
2689 ref_info.format;
2690 } else if (pipe_id == IA_CSS_PIPE_ID_VIDEO) {
2691 pipe->pipe_settings.video.video_binary.in_frame_info.format = ref_info.format;
2692 } else {
2693
2694 IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
2695 return -EINVAL;
2696 }
2697
2698 if (init_time)
2699 idx = 0;
2700 else
2701 idx = pipe->stream->config.init_num_cont_raw_buf;
2702
2703 for (i = idx; i < NUM_CONTINUOUS_FRAMES; i++) {
2704
2705 if (pipe->continuous_frames[i]) {
2706 ia_css_frame_free(pipe->continuous_frames[i]);
2707 pipe->continuous_frames[i] = NULL;
2708 }
2709
2710 ia_css_metadata_free(pipe->cont_md_buffers[i]);
2711 pipe->cont_md_buffers[i] = NULL;
2712
2713
2714 if (i < num_frames) {
2715
2716 err = ia_css_frame_allocate_from_info(
2717 &pipe->continuous_frames[i],
2718 &ref_info);
2719 if (err) {
2720 IA_CSS_LEAVE_ERR_PRIVATE(err);
2721 return err;
2722 }
2723
2724 pipe->cont_md_buffers[i] = ia_css_metadata_allocate(
2725 &pipe->stream->info.metadata_info);
2726 }
2727 }
2728 IA_CSS_LEAVE_ERR_PRIVATE(0);
2729 return 0;
2730}
2731
2732int
2733ia_css_alloc_continuous_frame_remain(struct ia_css_stream *stream)
2734{
2735 if (!stream)
2736 return -EINVAL;
2737 return alloc_continuous_frames(stream->continuous_pipe, false);
2738}
2739
2740static int
2741load_preview_binaries(struct ia_css_pipe *pipe)
2742{
2743 struct ia_css_frame_info prev_in_info,
2744 prev_bds_out_info,
2745 prev_out_info,
2746 prev_vf_info;
2747 struct ia_css_binary_descr preview_descr;
2748 bool online;
2749 int err = 0;
2750 bool need_vf_pp = false;
2751 bool need_isp_copy_binary = false;
2752#ifdef ISP2401
2753 bool sensor = false;
2754#else
2755 bool continuous;
2756#endif
2757
2758 struct ia_css_frame_info *pipe_out_info = &pipe->output_info[0];
2759 struct ia_css_preview_settings *mycs = &pipe->pipe_settings.preview;
2760
2761 IA_CSS_ENTER_PRIVATE("");
2762 assert(pipe);
2763 assert(pipe->stream);
2764 assert(pipe->mode == IA_CSS_PIPE_ID_PREVIEW);
2765
2766 online = pipe->stream->config.online;
2767#ifdef ISP2401
2768 sensor = pipe->stream->config.mode == IA_CSS_INPUT_MODE_SENSOR;
2769#else
2770 continuous = pipe->stream->config.continuous;
2771#endif
2772
2773 if (mycs->preview_binary.info)
2774 return 0;
2775
2776 err = ia_css_util_check_input(&pipe->stream->config, false, false);
2777 if (err)
2778 return err;
2779 err = ia_css_frame_check_info(pipe_out_info);
2780 if (err)
2781 return err;
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797 need_vf_pp = pipe->config.enable_dz;
2798 need_vf_pp |= pipe_out_info->format != IA_CSS_FRAME_FORMAT_YUV_LINE &&
2799 !(pipe_out_info->format == IA_CSS_FRAME_FORMAT_NV12 ||
2800 pipe_out_info->format == IA_CSS_FRAME_FORMAT_NV12_16 ||
2801 pipe_out_info->format == IA_CSS_FRAME_FORMAT_NV12_TILEY);
2802
2803
2804 if (pipe->vf_yuv_ds_input_info.res.width)
2805 prev_vf_info = pipe->vf_yuv_ds_input_info;
2806 else
2807 prev_vf_info = *pipe_out_info;
2808
2809
2810
2811
2812
2813 if (need_vf_pp)
2814 ia_css_frame_info_set_format(&prev_vf_info,
2815 IA_CSS_FRAME_FORMAT_YUV_LINE);
2816
2817 err = ia_css_pipe_get_preview_binarydesc(
2818 pipe,
2819 &preview_descr,
2820 &prev_in_info,
2821 &prev_bds_out_info,
2822 &prev_out_info,
2823 &prev_vf_info);
2824 if (err)
2825 return err;
2826 err = ia_css_binary_find(&preview_descr, &mycs->preview_binary);
2827 if (err)
2828 return err;
2829
2830 if (IS_ISP2401) {
2831
2832
2833 pipe->num_invalid_frames = pipe->dvs_frame_delay;
2834 pipe->info.num_invalid_frames = pipe->num_invalid_frames;
2835
2836 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE,
2837 "load_preview_binaries() num_invalid_frames=%d dvs_frame_delay=%d\n",
2838 pipe->num_invalid_frames, pipe->dvs_frame_delay);
2839 }
2840
2841
2842 need_vf_pp |= mycs->preview_binary.out_frame_info[0].res.width != pipe_out_info->res.width;
2843 need_vf_pp |= mycs->preview_binary.out_frame_info[0].res.height != pipe_out_info->res.height;
2844
2845
2846
2847
2848
2849 if (need_vf_pp &&
2850 (mycs->preview_binary.out_frame_info[0].format != IA_CSS_FRAME_FORMAT_YUV_LINE)) {
2851
2852 if (pipe->vf_yuv_ds_input_info.res.width)
2853 prev_vf_info = pipe->vf_yuv_ds_input_info;
2854 else
2855 prev_vf_info = *pipe_out_info;
2856
2857 ia_css_frame_info_set_format(&prev_vf_info,
2858 IA_CSS_FRAME_FORMAT_YUV_LINE);
2859
2860 err = ia_css_pipe_get_preview_binarydesc(
2861 pipe,
2862 &preview_descr,
2863 &prev_in_info,
2864 &prev_bds_out_info,
2865 &prev_out_info,
2866 &prev_vf_info);
2867 if (err)
2868 return err;
2869 err = ia_css_binary_find(&preview_descr,
2870 &mycs->preview_binary);
2871 if (err)
2872 return err;
2873 }
2874
2875 if (need_vf_pp) {
2876 struct ia_css_binary_descr vf_pp_descr;
2877
2878
2879 ia_css_pipe_get_vfpp_binarydesc(pipe, &vf_pp_descr,
2880 &mycs->preview_binary.out_frame_info[0],
2881 pipe_out_info);
2882 err = ia_css_binary_find(&vf_pp_descr,
2883 &mycs->vf_pp_binary);
2884 if (err)
2885 return err;
2886 }
2887
2888#ifdef ISP2401
2889
2890
2891
2892 need_isp_copy_binary = !online && sensor;
2893#else
2894
2895
2896
2897
2898
2899 if (!IS_ISP2401)
2900 need_isp_copy_binary = !online && !continuous;
2901 else
2902 need_isp_copy_binary = !online && !continuous && !(pipe->stream->config.mode == IA_CSS_INPUT_MODE_MEMORY);
2903#endif
2904
2905
2906 if (need_isp_copy_binary) {
2907 err = load_copy_binary(pipe,
2908 &mycs->copy_binary,
2909 &mycs->preview_binary);
2910 if (err)
2911 return err;
2912 }
2913
2914 if (pipe->shading_table) {
2915 ia_css_shading_table_free(pipe->shading_table);
2916 pipe->shading_table = NULL;
2917 }
2918
2919 return 0;
2920}
2921
2922static void
2923ia_css_binary_unload(struct ia_css_binary *binary)
2924{
2925 ia_css_binary_destroy_isp_parameters(binary);
2926}
2927
2928static int
2929unload_preview_binaries(struct ia_css_pipe *pipe)
2930{
2931 IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
2932
2933 if ((!pipe) || (pipe->mode != IA_CSS_PIPE_ID_PREVIEW)) {
2934 IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
2935 return -EINVAL;
2936 }
2937 ia_css_binary_unload(&pipe->pipe_settings.preview.copy_binary);
2938 ia_css_binary_unload(&pipe->pipe_settings.preview.preview_binary);
2939 ia_css_binary_unload(&pipe->pipe_settings.preview.vf_pp_binary);
2940
2941 IA_CSS_LEAVE_ERR_PRIVATE(0);
2942 return 0;
2943}
2944
2945static const struct ia_css_fw_info *last_output_firmware(
2946 const struct ia_css_fw_info *fw)
2947{
2948 const struct ia_css_fw_info *last_fw = NULL;
2949
2950 IA_CSS_ENTER_LEAVE_PRIVATE("");
2951
2952 for (; fw; fw = fw->next) {
2953 const struct ia_css_fw_info *info = fw;
2954
2955 if (info->info.isp.sp.enable.output)
2956 last_fw = fw;
2957 }
2958 return last_fw;
2959}
2960
2961static int add_firmwares(
2962 struct ia_css_pipeline *me,
2963 struct ia_css_binary *binary,
2964 const struct ia_css_fw_info *fw,
2965 const struct ia_css_fw_info *last_fw,
2966 unsigned int binary_mode,
2967 struct ia_css_frame *in_frame,
2968 struct ia_css_frame *out_frame,
2969 struct ia_css_frame *vf_frame,
2970 struct ia_css_pipeline_stage **my_stage,
2971 struct ia_css_pipeline_stage **vf_stage)
2972{
2973 int err = 0;
2974 struct ia_css_pipeline_stage *extra_stage = NULL;
2975 struct ia_css_pipeline_stage_desc stage_desc;
2976
2977
2978 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
2979 "add_firmwares() enter:\n");
2980
2981 for (; fw; fw = fw->next) {
2982 struct ia_css_frame *out[IA_CSS_BINARY_MAX_OUTPUT_PORTS] = {NULL};
2983 struct ia_css_frame *in = NULL;
2984 struct ia_css_frame *vf = NULL;
2985
2986 if ((fw == last_fw) && (fw->info.isp.sp.enable.out_frame != 0))
2987 out[0] = out_frame;
2988
2989 if (fw->info.isp.sp.enable.in_frame != 0)
2990 in = in_frame;
2991
2992 if (fw->info.isp.sp.enable.out_frame != 0)
2993 vf = vf_frame;
2994
2995 ia_css_pipe_get_firmwares_stage_desc(&stage_desc, binary,
2996 out, in, vf, fw, binary_mode);
2997 err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
2998 &extra_stage);
2999 if (err)
3000 return err;
3001 if (fw->info.isp.sp.enable.output != 0)
3002 in_frame = extra_stage->args.out_frame[0];
3003 if (my_stage && !*my_stage && extra_stage)
3004 *my_stage = extra_stage;
3005 if (vf_stage && !*vf_stage && extra_stage &&
3006 fw->info.isp.sp.enable.vf_veceven)
3007 *vf_stage = extra_stage;
3008 }
3009 return err;
3010}
3011
3012static int add_vf_pp_stage(
3013 struct ia_css_pipe *pipe,
3014 struct ia_css_frame *in_frame,
3015 struct ia_css_frame *out_frame,
3016 struct ia_css_binary *vf_pp_binary,
3017 struct ia_css_pipeline_stage **vf_pp_stage)
3018{
3019 struct ia_css_pipeline *me = NULL;
3020 const struct ia_css_fw_info *last_fw = NULL;
3021 int err = 0;
3022 struct ia_css_frame *out_frames[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
3023 struct ia_css_pipeline_stage_desc stage_desc;
3024
3025
3026
3027 if (!pipe)
3028 return -EINVAL;
3029 if (!in_frame)
3030 return -EINVAL;
3031 if (!vf_pp_binary)
3032 return -EINVAL;
3033 if (!vf_pp_stage)
3034 return -EINVAL;
3035
3036 ia_css_pipe_util_create_output_frames(out_frames);
3037 me = &pipe->pipeline;
3038
3039 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
3040 "add_vf_pp_stage() enter:\n");
3041
3042 *vf_pp_stage = NULL;
3043
3044 last_fw = last_output_firmware(pipe->vf_stage);
3045 if (!pipe->extra_config.disable_vf_pp) {
3046 if (last_fw) {
3047 ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
3048 ia_css_pipe_get_generic_stage_desc(&stage_desc, vf_pp_binary,
3049 out_frames, in_frame, NULL);
3050 } else {
3051 ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
3052 ia_css_pipe_get_generic_stage_desc(&stage_desc, vf_pp_binary,
3053 out_frames, in_frame, NULL);
3054 }
3055 err = ia_css_pipeline_create_and_add_stage(me, &stage_desc, vf_pp_stage);
3056 if (err)
3057 return err;
3058 in_frame = (*vf_pp_stage)->args.out_frame[0];
3059 }
3060 err = add_firmwares(me, vf_pp_binary, pipe->vf_stage, last_fw,
3061 IA_CSS_BINARY_MODE_VF_PP,
3062 in_frame, out_frame, NULL,
3063 vf_pp_stage, NULL);
3064 return err;
3065}
3066
3067static int add_yuv_scaler_stage(
3068 struct ia_css_pipe *pipe,
3069 struct ia_css_pipeline *me,
3070 struct ia_css_frame *in_frame,
3071 struct ia_css_frame *out_frame,
3072 struct ia_css_frame *internal_out_frame,
3073 struct ia_css_binary *yuv_scaler_binary,
3074 struct ia_css_pipeline_stage **pre_vf_pp_stage)
3075{
3076 const struct ia_css_fw_info *last_fw;
3077 int err = 0;
3078 struct ia_css_frame *vf_frame = NULL;
3079 struct ia_css_frame *out_frames[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
3080 struct ia_css_pipeline_stage_desc stage_desc;
3081
3082
3083 assert(in_frame);
3084 assert(pipe);
3085 assert(me);
3086 assert(yuv_scaler_binary);
3087 assert(pre_vf_pp_stage);
3088 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
3089 "add_yuv_scaler_stage() enter:\n");
3090
3091 *pre_vf_pp_stage = NULL;
3092 ia_css_pipe_util_create_output_frames(out_frames);
3093
3094 last_fw = last_output_firmware(pipe->output_stage);
3095
3096 if (last_fw) {
3097 ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
3098 ia_css_pipe_get_generic_stage_desc(&stage_desc,
3099 yuv_scaler_binary, out_frames, in_frame, vf_frame);
3100 } else {
3101 ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
3102 ia_css_pipe_util_set_output_frames(out_frames, 1, internal_out_frame);
3103 ia_css_pipe_get_generic_stage_desc(&stage_desc,
3104 yuv_scaler_binary, out_frames, in_frame, vf_frame);
3105 }
3106 err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
3107 pre_vf_pp_stage);
3108 if (err)
3109 return err;
3110 in_frame = (*pre_vf_pp_stage)->args.out_frame[0];
3111
3112 err = add_firmwares(me, yuv_scaler_binary, pipe->output_stage, last_fw,
3113 IA_CSS_BINARY_MODE_CAPTURE_PP,
3114 in_frame, out_frame, vf_frame,
3115 NULL, pre_vf_pp_stage);
3116
3117 (*pre_vf_pp_stage)->args.vf_downscale_log2 =
3118 yuv_scaler_binary->vf_downscale_log2;
3119
3120 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
3121 "add_yuv_scaler_stage() leave:\n");
3122 return err;
3123}
3124
3125static int add_capture_pp_stage(
3126 struct ia_css_pipe *pipe,
3127 struct ia_css_pipeline *me,
3128 struct ia_css_frame *in_frame,
3129 struct ia_css_frame *out_frame,
3130 struct ia_css_binary *capture_pp_binary,
3131 struct ia_css_pipeline_stage **capture_pp_stage)
3132{
3133 const struct ia_css_fw_info *last_fw = NULL;
3134 int err = 0;
3135 struct ia_css_frame *vf_frame = NULL;
3136 struct ia_css_frame *out_frames[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
3137 struct ia_css_pipeline_stage_desc stage_desc;
3138
3139
3140 assert(in_frame);
3141 assert(pipe);
3142 assert(me);
3143 assert(capture_pp_binary);
3144 assert(capture_pp_stage);
3145 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
3146 "add_capture_pp_stage() enter:\n");
3147
3148 *capture_pp_stage = NULL;
3149 ia_css_pipe_util_create_output_frames(out_frames);
3150
3151 last_fw = last_output_firmware(pipe->output_stage);
3152 err = ia_css_frame_allocate_from_info(&vf_frame,
3153 &capture_pp_binary->vf_frame_info);
3154 if (err)
3155 return err;
3156 if (last_fw) {
3157 ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
3158 ia_css_pipe_get_generic_stage_desc(&stage_desc,
3159 capture_pp_binary, out_frames, NULL, vf_frame);
3160 } else {
3161 ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
3162 ia_css_pipe_get_generic_stage_desc(&stage_desc,
3163 capture_pp_binary, out_frames, NULL, vf_frame);
3164 }
3165 err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
3166 capture_pp_stage);
3167 if (err)
3168 return err;
3169 err = add_firmwares(me, capture_pp_binary, pipe->output_stage, last_fw,
3170 IA_CSS_BINARY_MODE_CAPTURE_PP,
3171 in_frame, out_frame, vf_frame,
3172 NULL, capture_pp_stage);
3173
3174 if (*capture_pp_stage) {
3175 (*capture_pp_stage)->args.vf_downscale_log2 =
3176 capture_pp_binary->vf_downscale_log2;
3177 }
3178 return err;
3179}
3180
3181static void sh_css_setup_queues(void)
3182{
3183 const struct ia_css_fw_info *fw;
3184 unsigned int HIVE_ADDR_host_sp_queues_initialized;
3185
3186 sh_css_hmm_buffer_record_init();
3187
3188 sh_css_event_init_irq_mask();
3189
3190 fw = &sh_css_sp_fw;
3191 HIVE_ADDR_host_sp_queues_initialized =
3192 fw->info.sp.host_sp_queues_initialized;
3193
3194 ia_css_bufq_init();
3195
3196
3197 sp_dmem_store_uint32(SP0_ID,
3198 (unsigned int)sp_address_of(host_sp_queues_initialized),
3199 (uint32_t)(1));
3200 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE, "sh_css_setup_queues() leave:\n");
3201}
3202
3203static int
3204init_vf_frameinfo_defaults(struct ia_css_pipe *pipe,
3205 struct ia_css_frame *vf_frame, unsigned int idx)
3206{
3207 int err = 0;
3208 unsigned int thread_id;
3209 enum sh_css_queue_id queue_id;
3210
3211 assert(vf_frame);
3212
3213 sh_css_pipe_get_viewfinder_frame_info(pipe, &vf_frame->info, idx);
3214 vf_frame->contiguous = false;
3215 vf_frame->flash_state = IA_CSS_FRAME_FLASH_STATE_NONE;
3216 ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
3217 ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME + idx, thread_id, &queue_id);
3218 vf_frame->dynamic_queue_id = queue_id;
3219 vf_frame->buf_type = IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME + idx;
3220
3221 err = ia_css_frame_init_planes(vf_frame);
3222 return err;
3223}
3224
3225#ifdef ISP2401
3226static unsigned int
3227get_crop_lines_for_bayer_order(
3228 const struct ia_css_stream_config *config)
3229{
3230 assert(config);
3231 if ((config->input_config.bayer_order == IA_CSS_BAYER_ORDER_BGGR)
3232 || (config->input_config.bayer_order == IA_CSS_BAYER_ORDER_GBRG))
3233 return 1;
3234
3235 return 0;
3236}
3237
3238static unsigned int
3239get_crop_columns_for_bayer_order(
3240 const struct ia_css_stream_config *config)
3241{
3242 assert(config);
3243 if ((config->input_config.bayer_order == IA_CSS_BAYER_ORDER_RGGB)
3244 || (config->input_config.bayer_order == IA_CSS_BAYER_ORDER_GBRG))
3245 return 1;
3246
3247 return 0;
3248}
3249
3250
3251
3252static void get_pipe_extra_pixel(struct ia_css_pipe *pipe,
3253 unsigned int *extra_row, unsigned int *extra_column)
3254{
3255 enum ia_css_pipe_id pipe_id = pipe->mode;
3256 unsigned int left_cropping = 0, top_cropping = 0;
3257 unsigned int i;
3258 struct ia_css_resolution dvs_env = pipe->config.dvs_envelope;
3259
3260
3261
3262
3263
3264 switch (pipe_id) {
3265 case IA_CSS_PIPE_ID_PREVIEW:
3266 if (pipe->pipe_settings.preview.preview_binary.info) {
3267 left_cropping =
3268 pipe->pipe_settings.preview.preview_binary.info->sp.pipeline.left_cropping;
3269 top_cropping =
3270 pipe->pipe_settings.preview.preview_binary.info->sp.pipeline.top_cropping;
3271 }
3272 dvs_env = pipe->pipe_settings.preview.preview_binary.dvs_envelope;
3273 break;
3274 case IA_CSS_PIPE_ID_VIDEO:
3275 if (pipe->pipe_settings.video.video_binary.info) {
3276 left_cropping =
3277 pipe->pipe_settings.video.video_binary.info->sp.pipeline.left_cropping;
3278 top_cropping =
3279 pipe->pipe_settings.video.video_binary.info->sp.pipeline.top_cropping;
3280 }
3281 dvs_env = pipe->pipe_settings.video.video_binary.dvs_envelope;
3282 break;
3283 case IA_CSS_PIPE_ID_CAPTURE:
3284 for (i = 0; i < pipe->pipe_settings.capture.num_primary_stage; i++) {
3285 if (pipe->pipe_settings.capture.primary_binary[i].info) {
3286 left_cropping +=
3287 pipe->pipe_settings.capture.primary_binary[i].info->sp.pipeline.left_cropping;
3288 top_cropping +=
3289 pipe->pipe_settings.capture.primary_binary[i].info->sp.pipeline.top_cropping;
3290 }
3291 dvs_env.width +=
3292 pipe->pipe_settings.capture.primary_binary[i].dvs_envelope.width;
3293 dvs_env.height +=
3294 pipe->pipe_settings.capture.primary_binary[i].dvs_envelope.height;
3295 }
3296 break;
3297 default:
3298 break;
3299 }
3300
3301 *extra_row = top_cropping + dvs_env.height;
3302 *extra_column = left_cropping + dvs_env.width;
3303}
3304
3305void
3306ia_css_get_crop_offsets(
3307 struct ia_css_pipe *pipe,
3308 struct ia_css_frame_info *in_frame)
3309{
3310 unsigned int row = 0;
3311 unsigned int column = 0;
3312 struct ia_css_resolution *input_res;
3313 struct ia_css_resolution *effective_res;
3314 unsigned int extra_row = 0, extra_col = 0;
3315 unsigned int min_reqd_height, min_reqd_width;
3316
3317 assert(pipe);
3318 assert(pipe->stream);
3319 assert(in_frame);
3320
3321 IA_CSS_ENTER_PRIVATE("pipe = %p effective_wd = %u effective_ht = %u",
3322 pipe, pipe->config.input_effective_res.width,
3323 pipe->config.input_effective_res.height);
3324
3325 input_res = &pipe->stream->config.input_config.input_res;
3326#ifndef ISP2401
3327 effective_res = &pipe->stream->config.input_config.effective_res;
3328#else
3329 effective_res = &pipe->config.input_effective_res;
3330#endif
3331
3332 get_pipe_extra_pixel(pipe, &extra_row, &extra_col);
3333
3334 in_frame->raw_bayer_order = pipe->stream->config.input_config.bayer_order;
3335
3336 min_reqd_height = effective_res->height + extra_row;
3337 min_reqd_width = effective_res->width + extra_col;
3338
3339 if (input_res->height > min_reqd_height) {
3340 row = (input_res->height - min_reqd_height) / 2;
3341 row &= ~0x1;
3342 }
3343 if (input_res->width > min_reqd_width) {
3344 column = (input_res->width - min_reqd_width) / 2;
3345 column &= ~0x1;
3346 }
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357 column += get_crop_columns_for_bayer_order(&pipe->stream->config);
3358 row += get_crop_lines_for_bayer_order(&pipe->stream->config);
3359
3360 in_frame->crop_info.start_column = column;
3361 in_frame->crop_info.start_line = row;
3362
3363 IA_CSS_LEAVE_PRIVATE("void start_col: %u start_row: %u", column, row);
3364
3365 return;
3366}
3367#endif
3368
3369static int
3370init_in_frameinfo_memory_defaults(struct ia_css_pipe *pipe,
3371 struct ia_css_frame *frame, enum ia_css_frame_format format)
3372{
3373 struct ia_css_frame *in_frame;
3374 int err = 0;
3375 unsigned int thread_id;
3376 enum sh_css_queue_id queue_id;
3377
3378 assert(frame);
3379 in_frame = frame;
3380
3381 in_frame->info.format = format;
3382
3383#ifdef ISP2401
3384 if (format == IA_CSS_FRAME_FORMAT_RAW)
3385 in_frame->info.format = (pipe->stream->config.pack_raw_pixels) ?
3386 IA_CSS_FRAME_FORMAT_RAW_PACKED : IA_CSS_FRAME_FORMAT_RAW;
3387#endif
3388
3389 in_frame->info.res.width = pipe->stream->config.input_config.input_res.width;
3390 in_frame->info.res.height = pipe->stream->config.input_config.input_res.height;
3391 in_frame->info.raw_bit_depth =
3392 ia_css_pipe_util_pipe_input_format_bpp(pipe);
3393 ia_css_frame_info_set_width(&in_frame->info, pipe->stream->config.input_config.input_res.width, 0);
3394 in_frame->contiguous = false;
3395 in_frame->flash_state = IA_CSS_FRAME_FLASH_STATE_NONE;
3396 ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
3397 ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_INPUT_FRAME, thread_id, &queue_id);
3398 in_frame->dynamic_queue_id = queue_id;
3399 in_frame->buf_type = IA_CSS_BUFFER_TYPE_INPUT_FRAME;
3400#ifdef ISP2401
3401 ia_css_get_crop_offsets(pipe, &in_frame->info);
3402#endif
3403 err = ia_css_frame_init_planes(in_frame);
3404
3405 ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE,
3406 "init_in_frameinfo_memory_defaults() bayer_order = %d:\n", in_frame->info.raw_bayer_order);
3407
3408 return err;
3409}
3410
3411static int
3412init_out_frameinfo_defaults(struct ia_css_pipe *pipe,
3413 struct ia_css_frame *out_frame, unsigned int idx)
3414{
3415 int err = 0;
3416 unsigned int thread_id;
3417 enum sh_css_queue_id queue_id;
3418
3419 assert(out_frame);
3420
3421 sh_css_pipe_get_output_frame_info(pipe, &out_frame->info, idx);
3422 out_frame->contiguous = false;
3423 out_frame->flash_state = IA_CSS_FRAME_FLASH_STATE_NONE;
3424 ia_css_pipeline_get_sp_thread_id(ia_css_pipe_get_pipe_num(pipe), &thread_id);
3425 ia_css_query_internal_queue_id(IA_CSS_BUFFER_TYPE_OUTPUT_FRAME + idx, thread_id, &queue_id);
3426 out_frame->dynamic_queue_id = queue_id;
3427 out_frame->buf_type = IA_CSS_BUFFER_TYPE_OUTPUT_FRAME + idx;
3428 err = ia_css_frame_init_planes(out_frame);
3429
3430 return err;
3431}
3432
3433
3434static int create_host_video_pipeline(struct ia_css_pipe *pipe)
3435{
3436 struct ia_css_pipeline_stage_desc stage_desc;
3437 struct ia_css_binary *copy_binary, *video_binary,
3438 *yuv_scaler_binary, *vf_pp_binary;
3439 struct ia_css_pipeline_stage *copy_stage = NULL;
3440 struct ia_css_pipeline_stage *video_stage = NULL;
3441 struct ia_css_pipeline_stage *yuv_scaler_stage = NULL;
3442 struct ia_css_pipeline_stage *vf_pp_stage = NULL;
3443 struct ia_css_pipeline *me;
3444 struct ia_css_frame *in_frame = NULL;
3445 struct ia_css_frame *out_frame;
3446 struct ia_css_frame *out_frames[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
3447 struct ia_css_frame *vf_frame = NULL;
3448 int err = 0;
3449 bool need_copy = false;
3450 bool need_vf_pp = false;
3451 bool need_yuv_pp = false;
3452 bool need_in_frameinfo_memory = false;
3453
3454 unsigned int i, num_yuv_scaler;
3455 bool *is_output_stage = NULL;
3456
3457 IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
3458 if ((!pipe) || (!pipe->stream) || (pipe->mode != IA_CSS_PIPE_ID_VIDEO)) {
3459 IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
3460 return -EINVAL;
3461 }
3462 ia_css_pipe_util_create_output_frames(out_frames);
3463 out_frame = &pipe->out_frame_struct;
3464
3465
3466 me = &pipe->pipeline;
3467 ia_css_pipeline_clean(me);
3468
3469 me->dvs_frame_delay = pipe->dvs_frame_delay;
3470
3471#ifdef ISP2401
3472
3473
3474
3475 need_in_frameinfo_memory = !(pipe->stream->config.online ||
3476 pipe->stream->config.continuous);
3477#else
3478
3479 need_in_frameinfo_memory = pipe->stream->config.mode ==
3480 IA_CSS_INPUT_MODE_MEMORY;
3481#endif
3482
3483
3484 if (need_in_frameinfo_memory) {
3485 in_frame = &pipe->in_frame_struct;
3486 err = init_in_frameinfo_memory_defaults(pipe, in_frame,
3487 IA_CSS_FRAME_FORMAT_RAW);
3488 if (err)
3489 goto ERR;
3490 }
3491
3492 out_frame->data = 0;
3493 err = init_out_frameinfo_defaults(pipe, out_frame, 0);
3494 if (err)
3495 goto ERR;
3496
3497 if (pipe->enable_viewfinder[IA_CSS_PIPE_OUTPUT_STAGE_0]) {
3498 vf_frame = &pipe->vf_frame_struct;
3499 vf_frame->data = 0;
3500 err = init_vf_frameinfo_defaults(pipe, vf_frame, 0);
3501 if (err)
3502 goto ERR;
3503 }
3504
3505 copy_binary = &pipe->pipe_settings.video.copy_binary;
3506 video_binary = &pipe->pipe_settings.video.video_binary;
3507 vf_pp_binary = &pipe->pipe_settings.video.vf_pp_binary;
3508
3509 yuv_scaler_binary = pipe->pipe_settings.video.yuv_scaler_binary;
3510 num_yuv_scaler = pipe->pipe_settings.video.num_yuv_scaler;
3511 is_output_stage = pipe->pipe_settings.video.is_output_stage;
3512
3513 need_copy = (copy_binary && copy_binary->info);
3514 need_vf_pp = (vf_pp_binary && vf_pp_binary->info);
3515 need_yuv_pp = (yuv_scaler_binary && yuv_scaler_binary->info);
3516
3517 if (need_copy) {
3518 ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
3519 ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary,
3520 out_frames, NULL, NULL);
3521 err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
3522 ©_stage);
3523 if (err)
3524 goto ERR;
3525 in_frame = me->stages->args.out_frame[0];
3526 } else if (pipe->stream->config.continuous) {
3527#ifdef ISP2401
3528
3529
3530
3531 in_frame = pipe->stream->last_pipe->continuous_frames[0];
3532#else
3533 in_frame = pipe->continuous_frames[0];
3534#endif
3535 }
3536
3537 ia_css_pipe_util_set_output_frames(out_frames, 0,
3538 need_yuv_pp ? NULL : out_frame);
3539
3540
3541
3542 if (need_vf_pp) {
3543 ia_css_pipe_get_generic_stage_desc(&stage_desc, video_binary,
3544 out_frames, in_frame, NULL);
3545 } else {
3546 ia_css_pipe_get_generic_stage_desc(&stage_desc, video_binary,
3547 out_frames, in_frame, vf_frame);
3548 }
3549 err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
3550 &video_stage);
3551 if (err)
3552 goto ERR;
3553
3554
3555 if (video_stage) {
3556 video_stage->args.copy_vf =
3557 video_binary->info->sp.pipeline.mode == IA_CSS_BINARY_MODE_COPY;
3558 video_stage->args.copy_output = video_stage->args.copy_vf;
3559 }
3560
3561
3562
3563 if (need_vf_pp && video_stage) {
3564 in_frame = video_stage->args.out_vf_frame;
3565 err = add_vf_pp_stage(pipe, in_frame, vf_frame, vf_pp_binary,
3566 &vf_pp_stage);
3567 if (err)
3568 goto ERR;
3569 }
3570 if (video_stage) {
3571 int frm;
3572
3573 for (frm = 0; frm < NUM_TNR_FRAMES; frm++) {
3574 video_stage->args.tnr_frames[frm] =
3575 pipe->pipe_settings.video.tnr_frames[frm];
3576 }
3577 for (frm = 0; frm < MAX_NUM_VIDEO_DELAY_FRAMES; frm++) {
3578 video_stage->args.delay_frames[frm] =
3579 pipe->pipe_settings.video.delay_frames[frm];
3580 }
3581 }
3582
3583
3584 if (!need_vf_pp && video_stage && pipe->config.acc_extension &&
3585 (pipe->config.acc_extension->info.isp.type == IA_CSS_ACC_OUTPUT)) {
3586 struct ia_css_frame *out = NULL;
3587 struct ia_css_frame *in = NULL;
3588
3589 if ((pipe->config.acc_extension->info.isp.sp.enable.output) &&
3590 (pipe->config.acc_extension->info.isp.sp.enable.in_frame) &&
3591 (pipe->config.acc_extension->info.isp.sp.enable.out_frame)) {
3592
3593 out = video_stage->args.out_frame[0];
3594 err = ia_css_frame_allocate_from_info(&in, &pipe->output_info[0]);
3595 if (err)
3596 goto ERR;
3597 video_stage->args.out_frame[0] = in;
3598 }
3599
3600 err = add_firmwares(me, video_binary, pipe->output_stage,
3601 last_output_firmware(pipe->output_stage),
3602 IA_CSS_BINARY_MODE_VIDEO,
3603 in, out, NULL, &video_stage, NULL);
3604 if (err)
3605 goto ERR;
3606 }
3607
3608 if (need_yuv_pp && video_stage) {
3609 struct ia_css_frame *tmp_in_frame = video_stage->args.out_frame[0];
3610 struct ia_css_frame *tmp_out_frame = NULL;
3611
3612 for (i = 0; i < num_yuv_scaler; i++) {
3613 tmp_out_frame = is_output_stage[i] ? out_frame : NULL;
3614
3615 err = add_yuv_scaler_stage(pipe, me, tmp_in_frame,
3616 tmp_out_frame, NULL,
3617 &yuv_scaler_binary[i],
3618 &yuv_scaler_stage);
3619
3620 if (err) {
3621 IA_CSS_LEAVE_ERR_PRIVATE(err);
3622 return err;
3623 }
3624
3625 if (yuv_scaler_stage)
3626 tmp_in_frame = yuv_scaler_stage->args.out_frame[1];
3627 }
3628 }
3629
3630 pipe->pipeline.acquire_isp_each_stage = false;
3631 ia_css_pipeline_finalize_stages(&pipe->pipeline,
3632 pipe->stream->config.continuous);
3633
3634ERR:
3635 IA_CSS_LEAVE_ERR_PRIVATE(err);
3636 return err;
3637}
3638
3639static int
3640create_host_acc_pipeline(struct ia_css_pipe *pipe)
3641{
3642 int err = 0;
3643 const struct ia_css_fw_info *fw;
3644 unsigned int i;
3645
3646 IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
3647 if ((!pipe) || (!pipe->stream)) {
3648 IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
3649 return -EINVAL;
3650 }
3651
3652 pipe->pipeline.num_execs = pipe->config.acc_num_execs;
3653
3654 if (pipe->config.acc_extension)
3655 pipe->pipeline.pipe_qos_config = 0;
3656
3657 fw = pipe->vf_stage;
3658 for (i = 0; fw; fw = fw->next) {
3659 err = sh_css_pipeline_add_acc_stage(&pipe->pipeline, fw);
3660 if (err)
3661 goto ERR;
3662 }
3663
3664 for (i = 0; i < pipe->config.num_acc_stages; i++) {
3665 struct ia_css_fw_info *fw = pipe->config.acc_stages[i];
3666
3667 err = sh_css_pipeline_add_acc_stage(&pipe->pipeline, fw);
3668 if (err)
3669 goto ERR;
3670 }
3671
3672 ia_css_pipeline_finalize_stages(&pipe->pipeline, pipe->stream->config.continuous);
3673
3674ERR:
3675 IA_CSS_LEAVE_ERR_PRIVATE(err);
3676 return err;
3677}
3678
3679
3680static int
3681create_host_preview_pipeline(struct ia_css_pipe *pipe)
3682{
3683 struct ia_css_pipeline_stage *copy_stage = NULL;
3684 struct ia_css_pipeline_stage *preview_stage = NULL;
3685 struct ia_css_pipeline_stage *vf_pp_stage = NULL;
3686 struct ia_css_pipeline_stage_desc stage_desc;
3687 struct ia_css_pipeline *me = NULL;
3688 struct ia_css_binary *copy_binary, *preview_binary, *vf_pp_binary = NULL;
3689 struct ia_css_frame *in_frame = NULL;
3690 int err = 0;
3691 struct ia_css_frame *out_frame;
3692 struct ia_css_frame *out_frames[IA_CSS_BINARY_MAX_OUTPUT_PORTS];
3693 bool need_in_frameinfo_memory = false;
3694#ifdef ISP2401
3695 bool sensor = false;
3696 bool buffered_sensor = false;
3697 bool online = false;
3698 bool continuous = false;
3699#endif
3700
3701 IA_CSS_ENTER_PRIVATE("pipe = %p", pipe);
3702 if ((!pipe) || (!pipe->stream) || (pipe->mode != IA_CSS_PIPE_ID_PREVIEW)) {
3703 IA_CSS_LEAVE_ERR_PRIVATE(-EINVAL);
3704 return -EINVAL;
3705 }
3706
3707 ia_css_pipe_util_create_output_frames(out_frames);
3708
3709 me = &pipe->pipeline;
3710 ia_css_pipeline_clean(me);
3711
3712#ifdef ISP2401
3713
3714
3715
3716
3717
3718
3719
3720 sensor = (pipe->stream->config.mode == IA_CSS_INPUT_MODE_SENSOR);
3721 buffered_sensor = (pipe->stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR);
3722 online = pipe->stream->config.online;
3723 continuous = pipe->stream->config.continuous;
3724 need_in_frameinfo_memory =
3725 !((sensor && (online || continuous)) || (buffered_sensor && (online || continuous)));
3726#else
3727
3728 need_in_frameinfo_memory = pipe->stream->config.mode == IA_CSS_INPUT_MODE_MEMORY;
3729#endif
3730 if (need_in_frameinfo_memory) {
3731 err = init_in_frameinfo_memory_defaults(pipe, &me->in_frame,
3732 IA_CSS_FRAME_FORMAT_RAW);
3733 if (err)
3734 goto ERR;
3735
3736 in_frame = &me->in_frame;
3737 } else {
3738 in_frame = NULL;
3739 }
3740
3741 err = init_out_frameinfo_defaults(pipe, &me->out_frame[0], 0);
3742 if (err)
3743 goto ERR;
3744 out_frame = &me->out_frame[0];
3745
3746 copy_binary = &pipe->pipe_settings.preview.copy_binary;
3747 preview_binary = &pipe->pipe_settings.preview.preview_binary;
3748 if (pipe->pipe_settings.preview.vf_pp_binary.info)
3749 vf_pp_binary = &pipe->pipe_settings.preview.vf_pp_binary;
3750
3751 if (pipe->pipe_settings.preview.copy_binary.info) {
3752 ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
3753 ia_css_pipe_get_generic_stage_desc(&stage_desc, copy_binary,
3754 out_frames, NULL, NULL);
3755 err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
3756 ©_stage);
3757 if (err)
3758 goto ERR;
3759 in_frame = me->stages->args.out_frame[0];
3760 } else if (pipe->stream->config.continuous) {
3761#ifdef ISP2401
3762
3763
3764
3765 if (continuous || !online)
3766 in_frame = pipe->stream->last_pipe->continuous_frames[0];
3767
3768#else
3769 in_frame = pipe->continuous_frames[0];
3770#endif
3771 }
3772
3773 if (vf_pp_binary) {
3774 ia_css_pipe_util_set_output_frames(out_frames, 0, NULL);
3775 ia_css_pipe_get_generic_stage_desc(&stage_desc, preview_binary,
3776 out_frames, in_frame, NULL);
3777 } else {
3778 ia_css_pipe_util_set_output_frames(out_frames, 0, out_frame);
3779 ia_css_pipe_get_generic_stage_desc(&stage_desc, preview_binary,
3780 out_frames, in_frame, NULL);
3781 }
3782 err = ia_css_pipeline_create_and_add_stage(me, &stage_desc,
3783 &preview_stage);
3784 if (err)
3785 goto ERR;
3786
3787 preview_stage->args.copy_vf =
3788 preview_binary->info->sp.pipeline.mode == IA_CSS_BINARY_MODE_COPY;
3789 preview_stage->args.copy_output = !preview_stage->args.copy_vf;
3790 if (preview_stage->args.copy_vf && !preview_stage->args.out_vf_frame) {
3791
3792 preview_stage->args.out_vf_frame =
3793 preview_stage->args.out_frame[0];
3794 }
3795 if (vf_pp_binary) {
3796 if (preview_binary->info->sp.pipeline.mode == IA_CSS_BINARY_MODE_COPY)
3797 in_frame = preview_stage->args.out_vf_frame;
3798 else
3799 in_frame = preview_stage->args.out_frame[0];
3800 err = add_vf_pp_stage(pipe, in_frame, out_frame, vf_pp_binary,
3801 &vf_pp_stage);
3802 if (err)
3803 goto ERR;
3804 }
3805
3806 pipe->pipeline.acquire_isp_each_stage = false;
3807 ia_css_pipeline_finalize_stages(&pipe->pipeline, pipe->stream->config.continuous);
3808
3809ERR:
3810 IA_CSS_LEAVE_ERR_PRIVATE(err);
3811 return err;
3812}
3813
3814static void send_raw_frames(struct ia_css_pipe *pipe)
3815{
3816 if (pipe->stream->config.continuous) {
3817 unsigned int i;
3818
3819 sh_css_update_host2sp_cont_num_raw_frames
3820 (pipe->stream->config.init_num_cont_raw_buf, true);
3821 sh_css_update_host2sp_cont_num_raw_frames
3822 (pipe->stream->config.target_num_cont_raw_buf, false);
3823
3824
3825 for (i = 0; i < pipe->stream->config.init_num_cont_raw_buf; i++) {
3826 sh_css_update_host2sp_offline_frame(i,
3827 pipe->continuous_frames[i], pipe->cont_md_buffers[i]);
3828 }
3829 }
3830
3831 return;
3832}
3833
3834static int
3835preview_start(struct ia_css_pipe *pipe)
3836{
3837 int err = 0;
3838 struct ia_css_pipe *copy_pipe, *capture_pipe;
3839 struct ia_css_pipe *acc_pipe;
3840 enum