2 * Support for Clovertrail PNW Camera Imaging ISP subsystem.
4 * Copyright (c) 2013 Intel Corporation. All Rights Reserved.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License version
8 * 2 as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 #include <media/videobuf-vmalloc.h>
23 #include <media/v4l2-dev.h>
24 #include <media/v4l2-event.h>
26 #include "mmu/isp_mmu.h"
27 #include "mmu/sh_mmu_mrfld.h"
28 #include "hmm/hmm_bo.h"
31 #include "atomisp_compat.h"
32 #include "atomisp_internal.h"
33 #include "atomisp_cmd.h"
34 #include "atomisp-regs.h"
35 #include "atomisp_fops.h"
36 #include "atomisp_ioctl.h"
37 #include "atomisp_acc.h"
39 #include "hrt/hive_isp_css_mm_hrt.h"
41 #include <asm/intel-mid.h>
43 #include "ia_css_debug.h"
44 #include "ia_css_isp_param.h"
45 #include "sh_css_hrt.h"
46 #include "ia_css_isys.h"
48 #include <linux/pm_runtime.h>
50 /* Assume max number of ACC stages */
51 #define MAX_ACC_STAGES 20
53 /* Ideally, this should come from CSS headers */
57 * to serialize MMIO access , this is due to ISP2400 silicon issue Sighting
58 * #4684168, if concurrency access happened, system may hard hang.
60 static DEFINE_SPINLOCK(mmio_lock
);
62 enum frame_info_type
{
64 ATOMISP_CSS_SECOND_VF_FRAME
,
65 ATOMISP_CSS_OUTPUT_FRAME
,
66 ATOMISP_CSS_SECOND_OUTPUT_FRAME
,
67 ATOMISP_CSS_RAW_FRAME
,
70 struct bayer_ds_factor
{
71 unsigned int numerator
;
72 unsigned int denominator
;
75 void atomisp_css_debug_dump_sp_sw_debug_info(void)
77 ia_css_debug_dump_sp_sw_debug_info();
80 void atomisp_css_debug_dump_debug_info(const char *context
)
82 ia_css_debug_dump_debug_info(context
);
85 void atomisp_css_debug_set_dtrace_level(const unsigned int trace_level
)
87 ia_css_debug_set_dtrace_level(trace_level
);
90 unsigned int atomisp_css_debug_get_dtrace_level(void)
92 return ia_css_debug_trace_level
;
95 static ia_css_ptr
atomisp_css2_mm_alloc(size_t bytes
, uint32_t attr
)
97 if (attr
& IA_CSS_MEM_ATTR_ZEROED
) {
98 if (attr
& IA_CSS_MEM_ATTR_CACHED
) {
99 if (attr
& IA_CSS_MEM_ATTR_CONTIGUOUS
)
100 return (ia_css_ptr
) hrt_isp_css_mm_calloc_contiguous(bytes
);
102 return (ia_css_ptr
) hrt_isp_css_mm_calloc_cached(bytes
);
104 if (attr
& IA_CSS_MEM_ATTR_CONTIGUOUS
)
105 return (ia_css_ptr
) hrt_isp_css_mm_calloc_contiguous(bytes
);
107 return (ia_css_ptr
) hrt_isp_css_mm_calloc(bytes
);
110 if (attr
& IA_CSS_MEM_ATTR_CACHED
) {
111 if (attr
& IA_CSS_MEM_ATTR_CONTIGUOUS
)
112 return (ia_css_ptr
) hrt_isp_css_mm_alloc_contiguous(bytes
);
114 return (ia_css_ptr
) hrt_isp_css_mm_alloc_cached(bytes
);
116 if (attr
& IA_CSS_MEM_ATTR_CONTIGUOUS
)
117 return (ia_css_ptr
) hrt_isp_css_mm_alloc_contiguous(bytes
);
119 return (ia_css_ptr
) hrt_isp_css_mm_alloc(bytes
);
124 static void atomisp_css2_mm_free(ia_css_ptr ptr
)
126 hrt_isp_css_mm_free(ptr
);
129 static int atomisp_css2_mm_load(ia_css_ptr ptr
, void *data
, size_t bytes
)
131 return hrt_isp_css_mm_load(ptr
, data
, bytes
);
134 static int atomisp_css2_mm_store(ia_css_ptr ptr
, const void *data
, size_t bytes
)
136 return hrt_isp_css_mm_store(ptr
, data
, bytes
);
139 static int atomisp_css2_mm_set(ia_css_ptr ptr
, int c
, size_t bytes
)
141 return hrt_isp_css_mm_set(ptr
, c
, bytes
);
144 static ia_css_ptr
atomisp_css2_mm_mmap(const void *ptr
, const size_t size
,
145 uint16_t attribute
, void *context
)
147 struct hrt_userbuffer_attr
*userbuffer_attr
= context
;
148 return hrt_isp_css_mm_alloc_user_ptr(
149 size
, (void *)ptr
, userbuffer_attr
->pgnr
,
150 userbuffer_attr
->type
,
151 attribute
& HRT_BUF_FLAG_CACHED
);
154 void atomisp_css2_hw_store_8(hrt_address addr
, uint8_t data
)
158 spin_lock_irqsave(&mmio_lock
, flags
);
159 _hrt_master_port_store_8(addr
, data
);
160 spin_unlock_irqrestore(&mmio_lock
, flags
);
163 static void atomisp_css2_hw_store_16(hrt_address addr
, uint16_t data
)
167 spin_lock_irqsave(&mmio_lock
, flags
);
168 _hrt_master_port_store_16(addr
, data
);
169 spin_unlock_irqrestore(&mmio_lock
, flags
);
172 static void atomisp_css2_hw_store_32(hrt_address addr
, uint32_t data
)
176 spin_lock_irqsave(&mmio_lock
, flags
);
177 _hrt_master_port_store_32(addr
, data
);
178 spin_unlock_irqrestore(&mmio_lock
, flags
);
181 static uint8_t atomisp_css2_hw_load_8(hrt_address addr
)
186 spin_lock_irqsave(&mmio_lock
, flags
);
187 ret
= _hrt_master_port_load_8(addr
);
188 spin_unlock_irqrestore(&mmio_lock
, flags
);
192 uint16_t atomisp_css2_hw_load_16(hrt_address addr
)
197 spin_lock_irqsave(&mmio_lock
, flags
);
198 ret
= _hrt_master_port_load_16(addr
);
199 spin_unlock_irqrestore(&mmio_lock
, flags
);
202 uint32_t atomisp_css2_hw_load_32(hrt_address addr
)
207 spin_lock_irqsave(&mmio_lock
, flags
);
208 ret
= _hrt_master_port_load_32(addr
);
209 spin_unlock_irqrestore(&mmio_lock
, flags
);
213 static void atomisp_css2_hw_store(hrt_address addr
,
214 const void *from
, uint32_t n
)
218 unsigned int _to
= (unsigned int)addr
;
219 const char *_from
= (const char *)from
;
221 spin_lock_irqsave(&mmio_lock
, flags
);
222 for (i
= 0; i
< n
; i
++, _to
++, _from
++)
223 _hrt_master_port_store_8(_to
, *_from
);
224 spin_unlock_irqrestore(&mmio_lock
, flags
);
227 static void atomisp_css2_hw_load(hrt_address addr
, void *to
, uint32_t n
)
231 char *_to
= (char *)to
;
232 unsigned int _from
= (unsigned int)addr
;
234 spin_lock_irqsave(&mmio_lock
, flags
);
235 for (i
= 0; i
< n
; i
++, _to
++, _from
++)
236 *_to
= _hrt_master_port_load_8(_from
);
237 spin_unlock_irqrestore(&mmio_lock
, flags
);
240 static int atomisp_css2_dbg_print(const char *fmt
, va_list args
)
246 static int atomisp_css2_dbg_ftrace_print(const char *fmt
, va_list args
)
248 ftrace_vprintk(fmt
, args
);
252 static int atomisp_css2_err_print(const char *fmt
, va_list args
)
258 void atomisp_store_uint32(hrt_address addr
, uint32_t data
)
260 atomisp_css2_hw_store_32(addr
, data
);
263 void atomisp_load_uint32(hrt_address addr
, uint32_t *data
)
265 *data
= atomisp_css2_hw_load_32(addr
);
267 static int hmm_get_mmu_base_addr(unsigned int *mmu_base_addr
)
269 if (sh_mmu_mrfld
.get_pd_base
== NULL
) {
270 dev_err(atomisp_dev
, "get mmu base address failed.\n");
274 *mmu_base_addr
= sh_mmu_mrfld
.get_pd_base(&bo_device
.mmu
,
275 bo_device
.mmu
.base_address
);
279 static void atomisp_isp_parameters_clean_up(
280 struct atomisp_css_isp_config
*config
)
283 * Set NULL to configs pointer to avoid they are set into isp again when
284 * some configs are changed and need to be updated later.
286 memset(config
, 0, sizeof(*config
));
289 static void __dump_pipe_config(struct atomisp_sub_device
*asd
,
290 struct atomisp_stream_env
*stream_env
,
291 unsigned int pipe_id
)
293 struct atomisp_device
*isp
= asd
->isp
;
294 if (stream_env
->pipes
[pipe_id
]) {
295 struct ia_css_pipe_config
*p_config
;
296 struct ia_css_pipe_extra_config
*pe_config
;
297 p_config
= &stream_env
->pipe_configs
[pipe_id
];
298 pe_config
= &stream_env
->pipe_extra_configs
[pipe_id
];
299 dev_dbg(isp
->dev
, "dumping pipe[%d] config:\n", pipe_id
);
301 "pipe_config.pipe_mode:%d.\n", p_config
->mode
);
303 "pipe_config.output_info[0] w=%d, h=%d.\n",
304 p_config
->output_info
[0].res
.width
,
305 p_config
->output_info
[0].res
.height
);
307 "pipe_config.vf_pp_in_res w=%d, h=%d.\n",
308 p_config
->vf_pp_in_res
.width
,
309 p_config
->vf_pp_in_res
.height
);
311 "pipe_config.capt_pp_in_res w=%d, h=%d.\n",
312 p_config
->capt_pp_in_res
.width
,
313 p_config
->capt_pp_in_res
.height
);
315 "pipe_config.output.padded w=%d.\n",
316 p_config
->output_info
[0].padded_width
);
318 "pipe_config.vf_output_info[0] w=%d, h=%d.\n",
319 p_config
->vf_output_info
[0].res
.width
,
320 p_config
->vf_output_info
[0].res
.height
);
322 "pipe_config.bayer_ds_out_res w=%d, h=%d.\n",
323 p_config
->bayer_ds_out_res
.width
,
324 p_config
->bayer_ds_out_res
.height
);
326 "pipe_config.envelope w=%d, h=%d.\n",
327 p_config
->dvs_envelope
.width
,
328 p_config
->dvs_envelope
.height
);
330 "pipe_config.dvs_frame_delay=%d.\n",
331 p_config
->dvs_frame_delay
);
333 "pipe_config.isp_pipe_version:%d.\n",
334 p_config
->isp_pipe_version
);
336 "pipe_config.acc_extension=%p.\n",
337 p_config
->acc_extension
);
339 "pipe_config.acc_stages=%p.\n",
340 p_config
->acc_stages
);
342 "pipe_config.num_acc_stages=%d.\n",
343 p_config
->num_acc_stages
);
345 "pipe_config.acc_num_execs=%d.\n",
346 p_config
->acc_num_execs
);
348 "pipe_config.default_capture_config.capture_mode=%d.\n",
349 p_config
->default_capture_config
.mode
);
351 "pipe_config.enable_dz=%d.\n",
352 p_config
->enable_dz
);
354 "pipe_config.default_capture_config.enable_xnr=%d.\n",
355 p_config
->default_capture_config
.enable_xnr
);
357 "dumping pipe[%d] extra config:\n", pipe_id
);
359 "pipe_extra_config.enable_raw_binning:%d.\n",
360 pe_config
->enable_raw_binning
);
362 "pipe_extra_config.enable_yuv_ds:%d.\n",
363 pe_config
->enable_yuv_ds
);
365 "pipe_extra_config.enable_high_speed:%d.\n",
366 pe_config
->enable_high_speed
);
368 "pipe_extra_config.enable_dvs_6axis:%d.\n",
369 pe_config
->enable_dvs_6axis
);
371 "pipe_extra_config.enable_reduced_pipe:%d.\n",
372 pe_config
->enable_reduced_pipe
);
374 "pipe_(extra_)config.enable_dz:%d.\n",
375 p_config
->enable_dz
);
377 "pipe_extra_config.disable_vf_pp:%d.\n",
378 pe_config
->disable_vf_pp
);
382 static void __dump_stream_config(struct atomisp_sub_device
*asd
,
383 struct atomisp_stream_env
*stream_env
)
385 struct atomisp_device
*isp
= asd
->isp
;
386 struct ia_css_stream_config
*s_config
;
388 bool valid_stream
= false;
390 for (j
= 0; j
< IA_CSS_PIPE_ID_NUM
; j
++) {
391 if (stream_env
->pipes
[j
]) {
392 __dump_pipe_config(asd
, stream_env
, j
);
398 s_config
= &stream_env
->stream_config
;
399 dev_dbg(isp
->dev
, "stream_config.mode=%d.\n", s_config
->mode
);
401 if (s_config
->mode
== IA_CSS_INPUT_MODE_SENSOR
||
402 s_config
->mode
== IA_CSS_INPUT_MODE_BUFFERED_SENSOR
) {
403 dev_dbg(isp
->dev
, "stream_config.source.port.port=%d.\n",
404 s_config
->source
.port
.port
);
405 dev_dbg(isp
->dev
, "stream_config.source.port.num_lanes=%d.\n",
406 s_config
->source
.port
.num_lanes
);
407 dev_dbg(isp
->dev
, "stream_config.source.port.timeout=%d.\n",
408 s_config
->source
.port
.timeout
);
409 dev_dbg(isp
->dev
, "stream_config.source.port.rxcount=0x%x.\n",
410 s_config
->source
.port
.rxcount
);
411 dev_dbg(isp
->dev
, "stream_config.source.port.compression.type=%d.\n",
412 s_config
->source
.port
.compression
.type
);
413 dev_dbg(isp
->dev
, "stream_config.source.port.compression.compressed_bits_per_pixel=%d.\n",
414 s_config
->source
.port
.compression
.
415 compressed_bits_per_pixel
);
416 dev_dbg(isp
->dev
, "stream_config.source.port.compression.uncompressed_bits_per_pixel=%d.\n",
417 s_config
->source
.port
.compression
.
418 uncompressed_bits_per_pixel
);
419 } else if (s_config
->mode
== IA_CSS_INPUT_MODE_TPG
) {
420 dev_dbg(isp
->dev
, "stream_config.source.tpg.id=%d.\n",
421 s_config
->source
.tpg
.id
);
422 dev_dbg(isp
->dev
, "stream_config.source.tpg.mode=%d.\n",
423 s_config
->source
.tpg
.mode
);
424 dev_dbg(isp
->dev
, "stream_config.source.tpg.x_mask=%d.\n",
425 s_config
->source
.tpg
.x_mask
);
426 dev_dbg(isp
->dev
, "stream_config.source.tpg.x_delta=%d.\n",
427 s_config
->source
.tpg
.x_delta
);
428 dev_dbg(isp
->dev
, "stream_config.source.tpg.y_mask=%d.\n",
429 s_config
->source
.tpg
.y_mask
);
430 dev_dbg(isp
->dev
, "stream_config.source.tpg.y_delta=%d.\n",
431 s_config
->source
.tpg
.y_delta
);
432 dev_dbg(isp
->dev
, "stream_config.source.tpg.xy_mask=%d.\n",
433 s_config
->source
.tpg
.xy_mask
);
434 } else if (s_config
->mode
== IA_CSS_INPUT_MODE_PRBS
) {
435 dev_dbg(isp
->dev
, "stream_config.source.prbs.id=%d.\n",
436 s_config
->source
.prbs
.id
);
437 dev_dbg(isp
->dev
, "stream_config.source.prbs.h_blank=%d.\n",
438 s_config
->source
.prbs
.h_blank
);
439 dev_dbg(isp
->dev
, "stream_config.source.prbs.v_blank=%d.\n",
440 s_config
->source
.prbs
.v_blank
);
441 dev_dbg(isp
->dev
, "stream_config.source.prbs.seed=%d.\n",
442 s_config
->source
.prbs
.seed
);
443 dev_dbg(isp
->dev
, "stream_config.source.prbs.seed1=%d.\n",
444 s_config
->source
.prbs
.seed1
);
447 for (j
= 0; j
< IA_CSS_STREAM_MAX_ISYS_STREAM_PER_CH
; j
++) {
448 dev_dbg(isp
->dev
, "stream_configisys_config[%d].input_res w=%d, h=%d.\n",
450 s_config
->isys_config
[j
].input_res
.width
,
451 s_config
->isys_config
[j
].input_res
.height
);
453 dev_dbg(isp
->dev
, "stream_configisys_config[%d].linked_isys_stream_id=%d\n",
455 s_config
->isys_config
[j
].linked_isys_stream_id
);
457 dev_dbg(isp
->dev
, "stream_configisys_config[%d].format=%d\n",
459 s_config
->isys_config
[j
].format
);
461 dev_dbg(isp
->dev
, "stream_configisys_config[%d].valid=%d.\n",
463 s_config
->isys_config
[j
].valid
);
466 dev_dbg(isp
->dev
, "stream_config.input_config.input_res w=%d, h=%d.\n",
467 s_config
->input_config
.input_res
.width
,
468 s_config
->input_config
.input_res
.height
);
470 dev_dbg(isp
->dev
, "stream_config.input_config.effective_res w=%d, h=%d.\n",
471 s_config
->input_config
.effective_res
.width
,
472 s_config
->input_config
.effective_res
.height
);
474 dev_dbg(isp
->dev
, "stream_config.input_config.format=%d\n",
475 s_config
->input_config
.format
);
477 dev_dbg(isp
->dev
, "stream_config.input_config.bayer_order=%d.\n",
478 s_config
->input_config
.bayer_order
);
480 dev_dbg(isp
->dev
, "stream_config.pixels_per_clock=%d.\n",
481 s_config
->pixels_per_clock
);
482 dev_dbg(isp
->dev
, "stream_config.online=%d.\n", s_config
->online
);
483 dev_dbg(isp
->dev
, "stream_config.continuous=%d.\n",
484 s_config
->continuous
);
485 dev_dbg(isp
->dev
, "stream_config.disable_cont_viewfinder=%d.\n",
486 s_config
->disable_cont_viewfinder
);
487 dev_dbg(isp
->dev
, "stream_config.channel_id=%d.\n",
488 s_config
->channel_id
);
489 dev_dbg(isp
->dev
, "stream_config.init_num_cont_raw_buf=%d.\n",
490 s_config
->init_num_cont_raw_buf
);
491 dev_dbg(isp
->dev
, "stream_config.target_num_cont_raw_buf=%d.\n",
492 s_config
->target_num_cont_raw_buf
);
493 dev_dbg(isp
->dev
, "stream_config.left_padding=%d.\n",
494 s_config
->left_padding
);
495 dev_dbg(isp
->dev
, "stream_config.sensor_binning_factor=%d.\n",
496 s_config
->sensor_binning_factor
);
497 dev_dbg(isp
->dev
, "stream_config.pixels_per_clock=%d.\n",
498 s_config
->pixels_per_clock
);
499 dev_dbg(isp
->dev
, "stream_config.pack_raw_pixels=%d.\n",
500 s_config
->pack_raw_pixels
);
501 dev_dbg(isp
->dev
, "stream_config.flash_gpio_pin=%d.\n",
502 s_config
->flash_gpio_pin
);
503 dev_dbg(isp
->dev
, "stream_config.mipi_buffer_config.size_mem_words=%d.\n",
504 s_config
->mipi_buffer_config
.size_mem_words
);
505 dev_dbg(isp
->dev
, "stream_config.mipi_buffer_config.contiguous=%d.\n",
506 s_config
->mipi_buffer_config
.contiguous
);
507 dev_dbg(isp
->dev
, "stream_config.metadata_config.data_type=%d.\n",
508 s_config
->metadata_config
.data_type
);
509 dev_dbg(isp
->dev
, "stream_config.metadata_config.resolution w=%d, h=%d.\n",
510 s_config
->metadata_config
.resolution
.width
,
511 s_config
->metadata_config
.resolution
.height
);
514 static int __destroy_stream(struct atomisp_sub_device
*asd
,
515 struct atomisp_stream_env
*stream_env
, bool force
)
517 struct atomisp_device
*isp
= asd
->isp
;
519 unsigned long timeout
;
521 if (!stream_env
->stream
)
525 for (i
= 0; i
< IA_CSS_PIPE_ID_NUM
; i
++)
526 if (stream_env
->update_pipe
[i
])
529 if (i
== IA_CSS_PIPE_ID_NUM
)
533 if (stream_env
->stream_state
== CSS_STREAM_STARTED
534 && ia_css_stream_stop(stream_env
->stream
) != IA_CSS_SUCCESS
) {
535 dev_err(isp
->dev
, "stop stream failed.\n");
539 if (stream_env
->stream_state
== CSS_STREAM_STARTED
) {
540 timeout
= jiffies
+ msecs_to_jiffies(40);
542 if (ia_css_stream_has_stopped(stream_env
->stream
))
545 if (time_after(jiffies
, timeout
)) {
546 dev_warn(isp
->dev
, "stop stream timeout.\n");
550 usleep_range(100, 200);
554 stream_env
->stream_state
= CSS_STREAM_STOPPED
;
556 if (ia_css_stream_destroy(stream_env
->stream
) != IA_CSS_SUCCESS
) {
557 dev_err(isp
->dev
, "destroy stream failed.\n");
560 stream_env
->stream_state
= CSS_STREAM_UNINIT
;
561 stream_env
->stream
= NULL
;
566 static int __destroy_streams(struct atomisp_sub_device
*asd
, bool force
)
569 for (i
= 0; i
< ATOMISP_INPUT_STREAM_NUM
; i
++) {
570 ret
= __destroy_stream(asd
, &asd
->stream_env
[i
], force
);
574 asd
->stream_prepared
= false;
577 static int __create_stream(struct atomisp_sub_device
*asd
,
578 struct atomisp_stream_env
*stream_env
)
580 int pipe_index
= 0, i
;
581 struct ia_css_pipe
*multi_pipes
[IA_CSS_PIPE_ID_NUM
];
583 for (i
= 0; i
< IA_CSS_PIPE_ID_NUM
; i
++) {
584 if (stream_env
->pipes
[i
])
585 multi_pipes
[pipe_index
++] = stream_env
->pipes
[i
];
590 stream_env
->stream_config
.target_num_cont_raw_buf
=
591 asd
->continuous_raw_buffer_size
->val
;
592 stream_env
->stream_config
.channel_id
= stream_env
->ch_id
;
593 stream_env
->stream_config
.ia_css_enable_raw_buffer_locking
=
594 asd
->enable_raw_buffer_lock
->val
;
596 __dump_stream_config(asd
, stream_env
);
597 if (ia_css_stream_create(&stream_env
->stream_config
,
598 pipe_index
, multi_pipes
, &stream_env
->stream
) != IA_CSS_SUCCESS
)
600 if (ia_css_stream_get_info(stream_env
->stream
,
601 &stream_env
->stream_info
) != IA_CSS_SUCCESS
) {
602 ia_css_stream_destroy(stream_env
->stream
);
603 stream_env
->stream
= NULL
;
607 stream_env
->stream_state
= CSS_STREAM_CREATED
;
611 static int __create_streams(struct atomisp_sub_device
*asd
)
615 for (i
= 0; i
< ATOMISP_INPUT_STREAM_NUM
; i
++) {
616 ret
= __create_stream(asd
, &asd
->stream_env
[i
]);
620 asd
->stream_prepared
= true;
623 for (i
--; i
>= 0; i
--)
624 __destroy_stream(asd
, &asd
->stream_env
[i
], true);
628 static int __destroy_stream_pipes(struct atomisp_sub_device
*asd
,
629 struct atomisp_stream_env
*stream_env
,
632 struct atomisp_device
*isp
= asd
->isp
;
635 for (i
= 0; i
< IA_CSS_PIPE_ID_NUM
; i
++) {
636 if (!stream_env
->pipes
[i
] ||
637 !(force
|| stream_env
->update_pipe
[i
]))
639 if (ia_css_pipe_destroy(stream_env
->pipes
[i
])
642 "destroy pipe[%d]failed.cannot recover.\n", i
);
645 stream_env
->pipes
[i
] = NULL
;
646 stream_env
->update_pipe
[i
] = false;
651 static int __destroy_pipes(struct atomisp_sub_device
*asd
, bool force
)
653 struct atomisp_device
*isp
= asd
->isp
;
657 for (i
= 0; i
< ATOMISP_INPUT_STREAM_NUM
; i
++) {
658 if (asd
->stream_env
[i
].stream
) {
661 "cannot destroy css pipes for stream[%d].\n",
666 ret
= __destroy_stream_pipes(asd
, &asd
->stream_env
[i
], force
);
674 void atomisp_destroy_pipes_stream_force(struct atomisp_sub_device
*asd
)
676 __destroy_streams(asd
, true);
677 __destroy_pipes(asd
, true);
680 static void __apply_additional_pipe_config(
681 struct atomisp_sub_device
*asd
,
682 struct atomisp_stream_env
*stream_env
,
683 enum ia_css_pipe_id pipe_id
)
685 struct atomisp_device
*isp
= asd
->isp
;
687 if (pipe_id
< 0 || pipe_id
>= IA_CSS_PIPE_ID_NUM
) {
689 "wrong pipe_id for additional pipe config.\n");
693 /* apply default pipe config */
694 stream_env
->pipe_configs
[pipe_id
].isp_pipe_version
= 2;
695 stream_env
->pipe_configs
[pipe_id
].enable_dz
=
696 asd
->disable_dz
->val
? false : true;
697 /* apply isp 2.2 specific config for baytrail*/
699 case IA_CSS_PIPE_ID_CAPTURE
:
700 /* enable capture pp/dz manually or digital zoom would
702 if (stream_env
->pipe_configs
[pipe_id
].
703 default_capture_config
.mode
== CSS_CAPTURE_MODE_RAW
)
704 stream_env
->pipe_configs
[pipe_id
].enable_dz
= false;
707 /* the isp default to use ISP2.2 and the camera hal will
708 * control whether use isp2.7 */
709 if (asd
->select_isp_version
->val
==
710 ATOMISP_CSS_ISP_PIPE_VERSION_2_7
)
711 stream_env
->pipe_configs
[pipe_id
].isp_pipe_version
=
712 SH_CSS_ISP_PIPE_VERSION_2_7
;
714 stream_env
->pipe_configs
[pipe_id
].isp_pipe_version
=
715 SH_CSS_ISP_PIPE_VERSION_2_2
;
718 case IA_CSS_PIPE_ID_VIDEO
:
719 /* enable reduced pipe to have binary
720 * video_dz_2_min selected*/
721 stream_env
->pipe_extra_configs
[pipe_id
]
722 .enable_reduced_pipe
= true;
723 stream_env
->pipe_configs
[pipe_id
]
725 if (ATOMISP_SOC_CAMERA(asd
))
726 stream_env
->pipe_configs
[pipe_id
].enable_dz
= true;
728 if (asd
->params
.video_dis_en
) {
729 stream_env
->pipe_extra_configs
[pipe_id
]
730 .enable_dvs_6axis
= true;
731 stream_env
->pipe_configs
[pipe_id
]
733 ATOMISP_CSS2_NUM_DVS_FRAME_DELAY
;
736 case IA_CSS_PIPE_ID_PREVIEW
:
738 case IA_CSS_PIPE_ID_YUVPP
:
739 case IA_CSS_PIPE_ID_COPY
:
740 if (ATOMISP_SOC_CAMERA(asd
))
741 stream_env
->pipe_configs
[pipe_id
].enable_dz
= true;
743 stream_env
->pipe_configs
[pipe_id
].enable_dz
= false;
745 case IA_CSS_PIPE_ID_ACC
:
746 stream_env
->pipe_configs
[pipe_id
].mode
= IA_CSS_PIPE_MODE_ACC
;
747 stream_env
->pipe_configs
[pipe_id
].enable_dz
= false;
754 static bool is_pipe_valid_to_current_run_mode(struct atomisp_sub_device
*asd
,
755 enum ia_css_pipe_id pipe_id
)
760 if (pipe_id
== CSS_PIPE_ID_ACC
|| pipe_id
== CSS_PIPE_ID_YUVPP
)
764 if (asd
->vfpp
->val
== ATOMISP_VFPP_DISABLE_SCALER
) {
765 if (pipe_id
== IA_CSS_PIPE_ID_VIDEO
)
769 } else if (asd
->vfpp
->val
== ATOMISP_VFPP_DISABLE_LOWLAT
) {
770 if (pipe_id
== IA_CSS_PIPE_ID_CAPTURE
)
780 if (asd
->copy_mode
&& pipe_id
== IA_CSS_PIPE_ID_COPY
)
783 switch (asd
->run_mode
->val
) {
784 case ATOMISP_RUN_MODE_STILL_CAPTURE
:
785 if (pipe_id
== IA_CSS_PIPE_ID_CAPTURE
)
789 case ATOMISP_RUN_MODE_PREVIEW
:
790 if (!asd
->continuous_mode
->val
) {
791 if (pipe_id
== IA_CSS_PIPE_ID_PREVIEW
)
796 /* fall through to ATOMISP_RUN_MODE_CONTINUOUS_CAPTURE */
797 case ATOMISP_RUN_MODE_CONTINUOUS_CAPTURE
:
798 if (pipe_id
== IA_CSS_PIPE_ID_CAPTURE
||
799 pipe_id
== IA_CSS_PIPE_ID_PREVIEW
)
803 case ATOMISP_RUN_MODE_VIDEO
:
804 if (!asd
->continuous_mode
->val
) {
805 if (pipe_id
== IA_CSS_PIPE_ID_VIDEO
||
806 pipe_id
== IA_CSS_PIPE_ID_YUVPP
)
811 /* fall through to ATOMISP_RUN_MODE_SDV */
812 case ATOMISP_RUN_MODE_SDV
:
813 if (pipe_id
== IA_CSS_PIPE_ID_CAPTURE
||
814 pipe_id
== IA_CSS_PIPE_ID_VIDEO
)
823 static int __create_pipe(struct atomisp_sub_device
*asd
,
824 struct atomisp_stream_env
*stream_env
,
825 enum ia_css_pipe_id pipe_id
)
827 struct atomisp_device
*isp
= asd
->isp
;
828 struct ia_css_pipe_extra_config extra_config
;
831 if (pipe_id
>= IA_CSS_PIPE_ID_NUM
)
834 if (pipe_id
!= CSS_PIPE_ID_ACC
&&
835 !stream_env
->pipe_configs
[pipe_id
].output_info
[0].res
.width
)
838 if (pipe_id
== CSS_PIPE_ID_ACC
&&
839 !stream_env
->pipe_configs
[pipe_id
].acc_extension
)
842 if (!is_pipe_valid_to_current_run_mode(asd
, pipe_id
))
845 ia_css_pipe_extra_config_defaults(&extra_config
);
847 __apply_additional_pipe_config(asd
, stream_env
, pipe_id
);
848 if (!memcmp(&extra_config
,
849 &stream_env
->pipe_extra_configs
[pipe_id
],
850 sizeof(extra_config
)))
851 ret
= ia_css_pipe_create(
852 &stream_env
->pipe_configs
[pipe_id
],
853 &stream_env
->pipes
[pipe_id
]);
855 ret
= ia_css_pipe_create_extra(
856 &stream_env
->pipe_configs
[pipe_id
],
857 &stream_env
->pipe_extra_configs
[pipe_id
],
858 &stream_env
->pipes
[pipe_id
]);
859 if (ret
!= IA_CSS_SUCCESS
)
860 dev_err(isp
->dev
, "create pipe[%d] error.\n", pipe_id
);
864 static int __create_pipes(struct atomisp_sub_device
*asd
)
869 for (i
= 0; i
< ATOMISP_INPUT_STREAM_NUM
; i
++) {
870 for (j
= 0; j
< IA_CSS_PIPE_ID_NUM
; j
++) {
871 ret
= __create_pipe(asd
, &asd
->stream_env
[i
], j
);
872 if (ret
!= IA_CSS_SUCCESS
)
875 if (j
< IA_CSS_PIPE_ID_NUM
)
880 for (; i
>= 0; i
--) {
881 for (j
--; j
>= 0; j
--) {
882 if (asd
->stream_env
[i
].pipes
[j
]) {
883 ia_css_pipe_destroy(asd
->stream_env
[i
].pipes
[j
]);
884 asd
->stream_env
[i
].pipes
[j
] = NULL
;
887 j
= IA_CSS_PIPE_ID_NUM
;
892 void atomisp_create_pipes_stream(struct atomisp_sub_device
*asd
)
895 __create_streams(asd
);
898 int atomisp_css_update_stream(struct atomisp_sub_device
*asd
)
901 struct atomisp_device
*isp
= asd
->isp
;
903 if (__destroy_streams(asd
, true) != IA_CSS_SUCCESS
)
904 dev_warn(isp
->dev
, "destroy stream failed.\n");
906 if (__destroy_pipes(asd
, true) != IA_CSS_SUCCESS
)
907 dev_warn(isp
->dev
, "destroy pipe failed.\n");
909 ret
= __create_pipes(asd
);
910 if (ret
!= IA_CSS_SUCCESS
) {
911 dev_err(isp
->dev
, "create pipe failed %d.\n", ret
);
915 ret
= __create_streams(asd
);
916 if (ret
!= IA_CSS_SUCCESS
) {
917 dev_warn(isp
->dev
, "create stream failed %d.\n", ret
);
918 __destroy_pipes(asd
, true);
925 int atomisp_css_init(struct atomisp_device
*isp
)
927 unsigned int mmu_base_addr
;
931 ret
= hmm_get_mmu_base_addr(&mmu_base_addr
);
936 err
= ia_css_init(&isp
->css_env
.isp_css_env
, NULL
,
937 (uint32_t)mmu_base_addr
, IA_CSS_IRQ_TYPE_PULSE
);
938 if (err
!= IA_CSS_SUCCESS
) {
939 dev_err(isp
->dev
, "css init failed --- bad firmware?\n");
942 ia_css_enable_isys_event_queue(true);
944 isp
->css_initialized
= true;
945 dev_dbg(isp
->dev
, "sh_css_init success\n");
950 static inline int __set_css_print_env(struct atomisp_device
*isp
, int opt
)
955 isp
->css_env
.isp_css_env
.print_env
.debug_print
= NULL
;
957 isp
->css_env
.isp_css_env
.print_env
.debug_print
=
958 atomisp_css2_dbg_ftrace_print
;
960 isp
->css_env
.isp_css_env
.print_env
.debug_print
=
961 atomisp_css2_dbg_print
;
968 int atomisp_css_check_firmware_version(struct atomisp_device
*isp
)
970 if (!sh_css_check_firmware_version((void *)isp
->firmware
->data
)) {
971 dev_err(isp
->dev
, "Fw version check failed.\n");
977 int atomisp_css_load_firmware(struct atomisp_device
*isp
)
982 isp
->css_env
.isp_css_fw
.data
= (void *)isp
->firmware
->data
;
983 isp
->css_env
.isp_css_fw
.bytes
= isp
->firmware
->size
;
985 isp
->css_env
.isp_css_env
.cpu_mem_env
.alloc
= atomisp_kernel_zalloc
;
986 isp
->css_env
.isp_css_env
.cpu_mem_env
.free
= atomisp_kernel_free
;
988 isp
->css_env
.isp_css_env
.css_mem_env
.alloc
= atomisp_css2_mm_alloc
;
989 isp
->css_env
.isp_css_env
.css_mem_env
.free
= atomisp_css2_mm_free
;
990 isp
->css_env
.isp_css_env
.css_mem_env
.load
= atomisp_css2_mm_load
;
991 isp
->css_env
.isp_css_env
.css_mem_env
.store
= atomisp_css2_mm_store
;
992 isp
->css_env
.isp_css_env
.css_mem_env
.set
= atomisp_css2_mm_set
;
993 isp
->css_env
.isp_css_env
.css_mem_env
.mmap
= atomisp_css2_mm_mmap
;
995 isp
->css_env
.isp_css_env
.hw_access_env
.store_8
=
996 atomisp_css2_hw_store_8
;
997 isp
->css_env
.isp_css_env
.hw_access_env
.store_16
=
998 atomisp_css2_hw_store_16
;
999 isp
->css_env
.isp_css_env
.hw_access_env
.store_32
=
1000 atomisp_css2_hw_store_32
;
1002 isp
->css_env
.isp_css_env
.hw_access_env
.load_8
= atomisp_css2_hw_load_8
;
1003 isp
->css_env
.isp_css_env
.hw_access_env
.load_16
=
1004 atomisp_css2_hw_load_16
;
1005 isp
->css_env
.isp_css_env
.hw_access_env
.load_32
=
1006 atomisp_css2_hw_load_32
;
1008 isp
->css_env
.isp_css_env
.hw_access_env
.load
= atomisp_css2_hw_load
;
1009 isp
->css_env
.isp_css_env
.hw_access_env
.store
= atomisp_css2_hw_store
;
1011 __set_css_print_env(isp
, dbg_func
);
1013 isp
->css_env
.isp_css_env
.print_env
.error_print
= atomisp_css2_err_print
;
1015 /* load isp fw into ISP memory */
1016 err
= ia_css_load_firmware(&isp
->css_env
.isp_css_env
,
1017 &isp
->css_env
.isp_css_fw
);
1018 if (err
!= IA_CSS_SUCCESS
) {
1019 dev_err(isp
->dev
, "css load fw failed.\n");
1026 void atomisp_css_unload_firmware(struct atomisp_device
*isp
)
1028 ia_css_unload_firmware();
1031 void atomisp_css_uninit(struct atomisp_device
*isp
)
1033 struct atomisp_sub_device
*asd
;
1036 for (i
= 0; i
< isp
->num_of_streams
; i
++) {
1038 atomisp_isp_parameters_clean_up(&asd
->params
.config
);
1039 asd
->params
.css_update_params_needed
= false;
1042 isp
->css_initialized
= false;
1046 void atomisp_css_suspend(struct atomisp_device
*isp
)
1048 isp
->css_initialized
= false;
1052 int atomisp_css_resume(struct atomisp_device
*isp
)
1054 unsigned int mmu_base_addr
;
1057 ret
= hmm_get_mmu_base_addr(&mmu_base_addr
);
1059 dev_err(isp
->dev
, "get base address error.\n");
1063 ret
= ia_css_init(&isp
->css_env
.isp_css_env
, NULL
,
1064 mmu_base_addr
, IA_CSS_IRQ_TYPE_PULSE
);
1066 dev_err(isp
->dev
, "re-init css failed.\n");
1069 ia_css_enable_isys_event_queue(true);
1071 isp
->css_initialized
= true;
1075 int atomisp_css_irq_translate(struct atomisp_device
*isp
,
1076 unsigned int *infos
)
1080 err
= ia_css_irq_translate(infos
);
1081 if (err
!= IA_CSS_SUCCESS
) {
1083 "%s:failed to translate irq (err = %d,infos = %d)\n",
1084 __func__
, err
, *infos
);
1091 void atomisp_css_rx_get_irq_info(enum ia_css_csi2_port port
,
1092 unsigned int *infos
)
1094 #ifndef ISP2401_NEW_INPUT_SYSTEM
1095 ia_css_isys_rx_get_irq_info(port
, infos
);
1101 void atomisp_css_rx_clear_irq_info(enum ia_css_csi2_port port
,
1104 #ifndef ISP2401_NEW_INPUT_SYSTEM
1105 ia_css_isys_rx_clear_irq_info(port
, infos
);
1109 int atomisp_css_irq_enable(struct atomisp_device
*isp
,
1110 enum atomisp_css_irq_info info
, bool enable
)
1112 if (ia_css_irq_enable(info
, enable
) != IA_CSS_SUCCESS
) {
1113 dev_warn(isp
->dev
, "%s:Invalid irq info.\n", __func__
);
1120 void atomisp_css_init_struct(struct atomisp_sub_device
*asd
)
1123 for (i
= 0; i
< ATOMISP_INPUT_STREAM_NUM
; i
++) {
1124 asd
->stream_env
[i
].stream
= NULL
;
1125 for (j
= 0; j
< IA_CSS_PIPE_MODE_NUM
; j
++) {
1126 asd
->stream_env
[i
].pipes
[j
] = NULL
;
1127 asd
->stream_env
[i
].update_pipe
[j
] = false;
1128 ia_css_pipe_config_defaults(
1129 &asd
->stream_env
[i
].pipe_configs
[j
]);
1130 ia_css_pipe_extra_config_defaults(
1131 &asd
->stream_env
[i
].pipe_extra_configs
[j
]);
1133 ia_css_stream_config_defaults(&asd
->stream_env
[i
].stream_config
);
1137 int atomisp_q_video_buffer_to_css(struct atomisp_sub_device
*asd
,
1138 struct videobuf_vmalloc_memory
*vm_mem
,
1139 enum atomisp_input_stream_id stream_id
,
1140 enum atomisp_css_buffer_type css_buf_type
,
1141 enum atomisp_css_pipe_id css_pipe_id
)
1143 struct atomisp_stream_env
*stream_env
= &asd
->stream_env
[stream_id
];
1144 struct ia_css_buffer css_buf
= {0};
1145 enum ia_css_err err
;
1147 css_buf
.type
= css_buf_type
;
1148 css_buf
.data
.frame
= vm_mem
->vaddr
;
1150 err
= ia_css_pipe_enqueue_buffer(
1151 stream_env
->pipes
[css_pipe_id
], &css_buf
);
1152 if (err
!= IA_CSS_SUCCESS
)
1158 int atomisp_q_metadata_buffer_to_css(struct atomisp_sub_device
*asd
,
1159 struct atomisp_metadata_buf
*metadata_buf
,
1160 enum atomisp_input_stream_id stream_id
,
1161 enum atomisp_css_pipe_id css_pipe_id
)
1163 struct atomisp_stream_env
*stream_env
= &asd
->stream_env
[stream_id
];
1164 struct ia_css_buffer buffer
= {0};
1165 struct atomisp_device
*isp
= asd
->isp
;
1167 buffer
.type
= IA_CSS_BUFFER_TYPE_METADATA
;
1168 buffer
.data
.metadata
= metadata_buf
->metadata
;
1169 if (ia_css_pipe_enqueue_buffer(stream_env
->pipes
[css_pipe_id
],
1171 dev_err(isp
->dev
, "failed to q meta data buffer\n");
1178 int atomisp_q_s3a_buffer_to_css(struct atomisp_sub_device
*asd
,
1179 struct atomisp_s3a_buf
*s3a_buf
,
1180 enum atomisp_input_stream_id stream_id
,
1181 enum atomisp_css_pipe_id css_pipe_id
)
1183 struct atomisp_stream_env
*stream_env
= &asd
->stream_env
[stream_id
];
1184 struct ia_css_buffer buffer
= {0};
1185 struct atomisp_device
*isp
= asd
->isp
;
1187 buffer
.type
= IA_CSS_BUFFER_TYPE_3A_STATISTICS
;
1188 buffer
.data
.stats_3a
= s3a_buf
->s3a_data
;
1189 if (ia_css_pipe_enqueue_buffer(
1190 stream_env
->pipes
[css_pipe_id
],
1192 dev_dbg(isp
->dev
, "failed to q s3a stat buffer\n");
1199 int atomisp_q_dis_buffer_to_css(struct atomisp_sub_device
*asd
,
1200 struct atomisp_dis_buf
*dis_buf
,
1201 enum atomisp_input_stream_id stream_id
,
1202 enum atomisp_css_pipe_id css_pipe_id
)
1204 struct atomisp_stream_env
*stream_env
= &asd
->stream_env
[stream_id
];
1205 struct ia_css_buffer buffer
= {0};
1206 struct atomisp_device
*isp
= asd
->isp
;
1208 buffer
.type
= IA_CSS_BUFFER_TYPE_DIS_STATISTICS
;
1209 buffer
.data
.stats_dvs
= dis_buf
->dis_data
;
1210 if (ia_css_pipe_enqueue_buffer(
1211 stream_env
->pipes
[css_pipe_id
],
1213 dev_dbg(isp
->dev
, "failed to q dvs stat buffer\n");
1220 void atomisp_css_mmu_invalidate_cache(void)
1222 ia_css_mmu_invalidate_cache();
1225 void atomisp_css_mmu_invalidate_tlb(void)
1227 ia_css_mmu_invalidate_cache();
1230 void atomisp_css_mmu_set_page_table_base_index(unsigned long base_index
)
1235 * Check whether currently running MIPI buffer size fulfill
1236 * the requirement of the stream to be run
1238 bool __need_realloc_mipi_buffer(struct atomisp_device
*isp
)
1242 for (i
= 0; i
< isp
->num_of_streams
; i
++) {
1243 struct atomisp_sub_device
*asd
= &isp
->asd
[i
];
1245 if (asd
->streaming
!=
1246 ATOMISP_DEVICE_STREAMING_ENABLED
)
1248 if (asd
->mipi_frame_size
< isp
->mipi_frame_size
)
1255 int atomisp_css_start(struct atomisp_sub_device
*asd
,
1256 enum atomisp_css_pipe_id pipe_id
, bool in_reset
)
1258 struct atomisp_device
*isp
= asd
->isp
;
1259 bool sp_is_started
= false;
1262 if (__destroy_streams(asd
, true))
1263 dev_warn(isp
->dev
, "destroy stream failed.\n");
1265 if (__destroy_pipes(asd
, true))
1266 dev_warn(isp
->dev
, "destroy pipe failed.\n");
1268 if (__create_pipes(asd
)) {
1269 dev_err(isp
->dev
, "create pipe error.\n");
1272 if (__create_streams(asd
)) {
1273 dev_err(isp
->dev
, "create stream error.\n");
1277 /* in_reset == true, extension firmwares are reloaded after the recovery */
1278 atomisp_acc_load_extensions(asd
);
1282 * For dual steam case, it is possible that:
1283 * 1: for this stream, it is at the stage that:
1284 * - after set_fmt is called
1285 * - before stream on is called
1286 * 2: for the other stream, the stream off is called which css reset
1289 * Thus the stream created in set_fmt get destroyed and need to be
1290 * recreated in the next stream on.
1292 if (asd
->stream_prepared
== false) {
1293 if (__create_pipes(asd
)) {
1294 dev_err(isp
->dev
, "create pipe error.\n");
1297 if (__create_streams(asd
)) {
1298 dev_err(isp
->dev
, "create stream error.\n");
1304 * SP can only be started one time
1305 * if atomisp_subdev_streaming_count() tell there already has some
1306 * subdev at streamming, then SP should already be started previously,
1307 * so need to skip start sp procedure
1309 if (atomisp_streaming_count(isp
)) {
1310 dev_dbg(isp
->dev
, "skip start sp\n");
1312 if (!sh_css_hrt_system_is_idle())
1313 dev_err(isp
->dev
, "CSS HW not idle before starting SP\n");
1314 if (ia_css_start_sp() != IA_CSS_SUCCESS
) {
1315 dev_err(isp
->dev
, "start sp error.\n");
1319 sp_is_started
= true;
1323 for (i
= 0; i
< ATOMISP_INPUT_STREAM_NUM
; i
++) {
1324 if (asd
->stream_env
[i
].stream
) {
1325 if (ia_css_stream_start(asd
->stream_env
[i
]
1326 .stream
) != IA_CSS_SUCCESS
) {
1327 dev_err(isp
->dev
, "stream[%d] start error.\n", i
);
1331 asd
->stream_env
[i
].stream_state
= CSS_STREAM_STARTED
;
1332 dev_dbg(isp
->dev
, "stream[%d] started.\n", i
);
1340 __destroy_streams(asd
, true);
1342 __destroy_pipes(asd
, true);
1344 /* css 2.0 API limitation: ia_css_stop_sp() could be only called after
1348 * SP can not be stop if other streams are in use
1350 if ((atomisp_streaming_count(isp
) == 0) && sp_is_started
)
1356 void atomisp_css_update_isp_params(struct atomisp_sub_device
*asd
)
1360 * for ISP2401 new input system, this api is under development.
1361 * Calling it would cause kernel panic.
1365 * Check if it is Cherry Trail and also new input system
1367 if (asd
->copy_mode
) {
1368 dev_warn(asd
->isp
->dev
,
1369 "%s: ia_css_stream_set_isp_config() not supported in copy mode!.\n",
1374 ia_css_stream_set_isp_config(
1375 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
,
1376 &asd
->params
.config
);
1377 atomisp_isp_parameters_clean_up(&asd
->params
.config
);
1381 void atomisp_css_update_isp_params_on_pipe(struct atomisp_sub_device
*asd
,
1382 struct ia_css_pipe
*pipe
)
1384 enum ia_css_err ret
;
1387 atomisp_css_update_isp_params(asd
);
1391 dev_dbg(asd
->isp
->dev
, "%s: apply parameter for ia_css_frame %p with isp_config_id %d on pipe %p.\n",
1392 __func__
, asd
->params
.config
.output_frame
,
1393 asd
->params
.config
.isp_config_id
, pipe
);
1395 ret
= ia_css_stream_set_isp_config_on_pipe(
1396 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
,
1397 &asd
->params
.config
, pipe
);
1398 if (ret
!= IA_CSS_SUCCESS
)
1399 dev_warn(asd
->isp
->dev
, "%s: ia_css_stream_set_isp_config_on_pipe failed %d\n",
1401 atomisp_isp_parameters_clean_up(&asd
->params
.config
);
1404 int atomisp_css_queue_buffer(struct atomisp_sub_device
*asd
,
1405 enum atomisp_input_stream_id stream_id
,
1406 enum atomisp_css_pipe_id pipe_id
,
1407 enum atomisp_css_buffer_type buf_type
,
1408 struct atomisp_css_buffer
*isp_css_buffer
)
1410 if (ia_css_pipe_enqueue_buffer(
1411 asd
->stream_env
[stream_id
].pipes
[pipe_id
],
1412 &isp_css_buffer
->css_buffer
)
1419 int atomisp_css_dequeue_buffer(struct atomisp_sub_device
*asd
,
1420 enum atomisp_input_stream_id stream_id
,
1421 enum atomisp_css_pipe_id pipe_id
,
1422 enum atomisp_css_buffer_type buf_type
,
1423 struct atomisp_css_buffer
*isp_css_buffer
)
1425 struct atomisp_device
*isp
= asd
->isp
;
1426 enum ia_css_err err
;
1428 err
= ia_css_pipe_dequeue_buffer(
1429 asd
->stream_env
[stream_id
].pipes
[pipe_id
],
1430 &isp_css_buffer
->css_buffer
);
1431 if (err
!= IA_CSS_SUCCESS
) {
1433 "ia_css_pipe_dequeue_buffer failed: 0x%x\n", err
);
1440 int atomisp_css_allocate_stat_buffers(struct atomisp_sub_device
*asd
,
1442 struct atomisp_s3a_buf
*s3a_buf
,
1443 struct atomisp_dis_buf
*dis_buf
,
1444 struct atomisp_metadata_buf
*md_buf
)
1446 struct atomisp_device
*isp
= asd
->isp
;
1447 struct atomisp_css_dvs_grid_info
*dvs_grid_info
=
1448 atomisp_css_get_dvs_grid_info(&asd
->params
.curr_grid_info
);
1450 if (s3a_buf
&& asd
->params
.curr_grid_info
.s3a_grid
.enable
) {
1453 s3a_buf
->s3a_data
= ia_css_isp_3a_statistics_allocate(
1454 &asd
->params
.curr_grid_info
.s3a_grid
);
1455 if (!s3a_buf
->s3a_data
) {
1456 dev_err(isp
->dev
, "3a buf allocation failed.\n");
1460 s3a_ptr
= hmm_vmap(s3a_buf
->s3a_data
->data_ptr
, true);
1461 s3a_buf
->s3a_map
= ia_css_isp_3a_statistics_map_allocate(
1462 s3a_buf
->s3a_data
, s3a_ptr
);
1465 if (dis_buf
&& dvs_grid_info
&& dvs_grid_info
->enable
) {
1468 dis_buf
->dis_data
= ia_css_isp_dvs2_statistics_allocate(
1470 if (!dis_buf
->dis_data
) {
1471 dev_err(isp
->dev
, "dvs buf allocation failed.\n");
1473 ia_css_isp_3a_statistics_free(s3a_buf
->s3a_data
);
1477 dvs_ptr
= hmm_vmap(dis_buf
->dis_data
->data_ptr
, true);
1478 dis_buf
->dvs_map
= ia_css_isp_dvs_statistics_map_allocate(
1479 dis_buf
->dis_data
, dvs_ptr
);
1482 if (asd
->stream_env
[stream_id
].stream_info
.
1483 metadata_info
.size
&& md_buf
) {
1484 md_buf
->metadata
= ia_css_metadata_allocate(
1485 &asd
->stream_env
[stream_id
].stream_info
.metadata_info
);
1486 if (!md_buf
->metadata
) {
1488 ia_css_isp_3a_statistics_free(s3a_buf
->s3a_data
);
1490 ia_css_isp_dvs2_statistics_free(dis_buf
->dis_data
);
1491 dev_err(isp
->dev
, "metadata buf allocation failed.\n");
1494 md_buf
->md_vptr
= hmm_vmap(md_buf
->metadata
->address
, false);
1500 void atomisp_css_free_3a_buffer(struct atomisp_s3a_buf
*s3a_buf
)
1502 if (s3a_buf
->s3a_data
)
1503 hmm_vunmap(s3a_buf
->s3a_data
->data_ptr
);
1505 ia_css_isp_3a_statistics_map_free(s3a_buf
->s3a_map
);
1506 s3a_buf
->s3a_map
= NULL
;
1507 ia_css_isp_3a_statistics_free(s3a_buf
->s3a_data
);
1510 void atomisp_css_free_dis_buffer(struct atomisp_dis_buf
*dis_buf
)
1512 if (dis_buf
->dis_data
)
1513 hmm_vunmap(dis_buf
->dis_data
->data_ptr
);
1515 ia_css_isp_dvs_statistics_map_free(dis_buf
->dvs_map
);
1516 dis_buf
->dvs_map
= NULL
;
1517 ia_css_isp_dvs2_statistics_free(dis_buf
->dis_data
);
1520 void atomisp_css_free_metadata_buffer(struct atomisp_metadata_buf
*metadata_buf
)
1522 if (metadata_buf
->md_vptr
) {
1523 hmm_vunmap(metadata_buf
->metadata
->address
);
1524 metadata_buf
->md_vptr
= NULL
;
1526 ia_css_metadata_free(metadata_buf
->metadata
);
1529 void atomisp_css_free_stat_buffers(struct atomisp_sub_device
*asd
)
1531 struct atomisp_s3a_buf
*s3a_buf
, *_s3a_buf
;
1532 struct atomisp_dis_buf
*dis_buf
, *_dis_buf
;
1533 struct atomisp_metadata_buf
*md_buf
, *_md_buf
;
1534 struct atomisp_css_dvs_grid_info
*dvs_grid_info
=
1535 atomisp_css_get_dvs_grid_info(&asd
->params
.curr_grid_info
);
1538 /* 3A statistics use vmalloc, DIS use kmalloc */
1539 if (dvs_grid_info
&& dvs_grid_info
->enable
) {
1540 ia_css_dvs2_coefficients_free(asd
->params
.css_param
.dvs2_coeff
);
1541 ia_css_dvs2_statistics_free(asd
->params
.dvs_stat
);
1542 asd
->params
.css_param
.dvs2_coeff
= NULL
;
1543 asd
->params
.dvs_stat
= NULL
;
1544 asd
->params
.dvs_hor_proj_bytes
= 0;
1545 asd
->params
.dvs_ver_proj_bytes
= 0;
1546 asd
->params
.dvs_hor_coef_bytes
= 0;
1547 asd
->params
.dvs_ver_coef_bytes
= 0;
1548 asd
->params
.dis_proj_data_valid
= false;
1549 list_for_each_entry_safe(dis_buf
, _dis_buf
,
1550 &asd
->dis_stats
, list
) {
1551 atomisp_css_free_dis_buffer(dis_buf
);
1552 list_del(&dis_buf
->list
);
1555 list_for_each_entry_safe(dis_buf
, _dis_buf
,
1556 &asd
->dis_stats_in_css
, list
) {
1557 atomisp_css_free_dis_buffer(dis_buf
);
1558 list_del(&dis_buf
->list
);
1562 if (asd
->params
.curr_grid_info
.s3a_grid
.enable
) {
1563 ia_css_3a_statistics_free(asd
->params
.s3a_user_stat
);
1564 asd
->params
.s3a_user_stat
= NULL
;
1565 asd
->params
.s3a_output_bytes
= 0;
1566 list_for_each_entry_safe(s3a_buf
, _s3a_buf
,
1567 &asd
->s3a_stats
, list
) {
1568 atomisp_css_free_3a_buffer(s3a_buf
);
1569 list_del(&s3a_buf
->list
);
1572 list_for_each_entry_safe(s3a_buf
, _s3a_buf
,
1573 &asd
->s3a_stats_in_css
, list
) {
1574 atomisp_css_free_3a_buffer(s3a_buf
);
1575 list_del(&s3a_buf
->list
);
1578 list_for_each_entry_safe(s3a_buf
, _s3a_buf
,
1579 &asd
->s3a_stats_ready
, list
) {
1580 atomisp_css_free_3a_buffer(s3a_buf
);
1581 list_del(&s3a_buf
->list
);
1586 if (asd
->params
.css_param
.dvs_6axis
) {
1587 ia_css_dvs2_6axis_config_free(asd
->params
.css_param
.dvs_6axis
);
1588 asd
->params
.css_param
.dvs_6axis
= NULL
;
1591 for (i
= 0; i
< ATOMISP_METADATA_TYPE_NUM
; i
++) {
1592 list_for_each_entry_safe(md_buf
, _md_buf
,
1593 &asd
->metadata
[i
], list
) {
1594 atomisp_css_free_metadata_buffer(md_buf
);
1595 list_del(&md_buf
->list
);
1598 list_for_each_entry_safe(md_buf
, _md_buf
,
1599 &asd
->metadata_in_css
[i
], list
) {
1600 atomisp_css_free_metadata_buffer(md_buf
);
1601 list_del(&md_buf
->list
);
1604 list_for_each_entry_safe(md_buf
, _md_buf
,
1605 &asd
->metadata_ready
[i
], list
) {
1606 atomisp_css_free_metadata_buffer(md_buf
);
1607 list_del(&md_buf
->list
);
1611 asd
->params
.metadata_width_size
= 0;
1612 atomisp_free_metadata_output_buf(asd
);
1615 int atomisp_css_get_grid_info(struct atomisp_sub_device
*asd
,
1616 enum atomisp_css_pipe_id pipe_id
,
1619 struct ia_css_pipe_info p_info
;
1620 struct ia_css_grid_info old_info
;
1621 struct atomisp_device
*isp
= asd
->isp
;
1622 int stream_index
= atomisp_source_pad_to_stream_id(asd
, source_pad
);
1623 int md_width
= asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].
1624 stream_config
.metadata_config
.resolution
.width
;
1626 memset(&p_info
, 0, sizeof(struct ia_css_pipe_info
));
1627 memset(&old_info
, 0, sizeof(struct ia_css_grid_info
));
1629 if (ia_css_pipe_get_info(
1630 asd
->stream_env
[stream_index
].pipes
[pipe_id
],
1631 &p_info
) != IA_CSS_SUCCESS
) {
1632 dev_err(isp
->dev
, "ia_css_pipe_get_info failed\n");
1636 memcpy(&old_info
, &asd
->params
.curr_grid_info
,
1637 sizeof(struct ia_css_grid_info
));
1638 memcpy(&asd
->params
.curr_grid_info
, &p_info
.grid_info
,
1639 sizeof(struct ia_css_grid_info
));
1641 * Record which css pipe enables s3a_grid.
1642 * Currently would have one css pipe that need it
1644 if (asd
->params
.curr_grid_info
.s3a_grid
.enable
) {
1645 if (asd
->params
.s3a_enabled_pipe
!= CSS_PIPE_ID_NUM
)
1646 dev_dbg(isp
->dev
, "css pipe %d enabled s3a grid replaced by: %d.\n",
1647 asd
->params
.s3a_enabled_pipe
, pipe_id
);
1648 asd
->params
.s3a_enabled_pipe
= pipe_id
;
1651 /* If the grid info has not changed and the buffers for 3A and
1652 * DIS statistics buffers are allocated or buffer size would be zero
1653 * then no need to do anything. */
1654 if (((!memcmp(&old_info
, &asd
->params
.curr_grid_info
, sizeof(old_info
))
1655 && asd
->params
.s3a_user_stat
&& asd
->params
.dvs_stat
)
1656 || asd
->params
.curr_grid_info
.s3a_grid
.width
== 0
1657 || asd
->params
.curr_grid_info
.s3a_grid
.height
== 0)
1658 && asd
->params
.metadata_width_size
== md_width
) {
1660 "grid info change escape. memcmp=%d, s3a_user_stat=%d,"
1661 "dvs_stat=%d, s3a.width=%d, s3a.height=%d, metadata width =%d\n",
1662 !memcmp(&old_info
, &asd
->params
.curr_grid_info
,
1664 !!asd
->params
.s3a_user_stat
, !!asd
->params
.dvs_stat
,
1665 asd
->params
.curr_grid_info
.s3a_grid
.width
,
1666 asd
->params
.curr_grid_info
.s3a_grid
.height
,
1667 asd
->params
.metadata_width_size
);
1670 asd
->params
.metadata_width_size
= md_width
;
1675 int atomisp_alloc_3a_output_buf(struct atomisp_sub_device
*asd
)
1677 if (!asd
->params
.curr_grid_info
.s3a_grid
.width
||
1678 !asd
->params
.curr_grid_info
.s3a_grid
.height
)
1681 asd
->params
.s3a_user_stat
= ia_css_3a_statistics_allocate(
1682 &asd
->params
.curr_grid_info
.s3a_grid
);
1683 if (!asd
->params
.s3a_user_stat
)
1685 /* 3A statistics. These can be big, so we use vmalloc. */
1686 asd
->params
.s3a_output_bytes
=
1687 asd
->params
.curr_grid_info
.s3a_grid
.width
*
1688 asd
->params
.curr_grid_info
.s3a_grid
.height
*
1689 sizeof(*asd
->params
.s3a_user_stat
->data
);
1694 int atomisp_alloc_dis_coef_buf(struct atomisp_sub_device
*asd
)
1696 struct atomisp_css_dvs_grid_info
*dvs_grid
=
1697 atomisp_css_get_dvs_grid_info(&asd
->params
.curr_grid_info
);
1702 if (!dvs_grid
->enable
) {
1703 dev_dbg(asd
->isp
->dev
, "%s: dvs_grid not enabled.\n", __func__
);
1707 /* DIS coefficients. */
1708 asd
->params
.css_param
.dvs2_coeff
= ia_css_dvs2_coefficients_allocate(
1710 if (!asd
->params
.css_param
.dvs2_coeff
)
1713 asd
->params
.dvs_hor_coef_bytes
= dvs_grid
->num_hor_coefs
*
1714 sizeof(*asd
->params
.css_param
.dvs2_coeff
->hor_coefs
.odd_real
);
1716 asd
->params
.dvs_ver_coef_bytes
= dvs_grid
->num_ver_coefs
*
1717 sizeof(*asd
->params
.css_param
.dvs2_coeff
->ver_coefs
.odd_real
);
1719 /* DIS projections. */
1720 asd
->params
.dis_proj_data_valid
= false;
1721 asd
->params
.dvs_stat
= ia_css_dvs2_statistics_allocate(dvs_grid
);
1722 if (!asd
->params
.dvs_stat
)
1725 asd
->params
.dvs_hor_proj_bytes
=
1726 dvs_grid
->aligned_height
* dvs_grid
->aligned_width
*
1727 sizeof(*asd
->params
.dvs_stat
->hor_prod
.odd_real
);
1729 asd
->params
.dvs_ver_proj_bytes
=
1730 dvs_grid
->aligned_height
* dvs_grid
->aligned_width
*
1731 sizeof(*asd
->params
.dvs_stat
->ver_prod
.odd_real
);
1736 int atomisp_alloc_metadata_output_buf(struct atomisp_sub_device
*asd
)
1739 int i
; /* Coverity CID 298003 - index var must be signed */
1744 /* We allocate the cpu-side buffer used for communication with user
1746 for (i
= 0; i
< ATOMISP_METADATA_TYPE_NUM
; i
++) {
1747 asd
->params
.metadata_user
[i
] = atomisp_kernel_malloc(
1748 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].
1749 stream_info
.metadata_info
.size
);
1750 if (!asd
->params
.metadata_user
[i
]) {
1752 atomisp_kernel_free(asd
->params
.metadata_user
[i
]);
1753 asd
->params
.metadata_user
[i
] = NULL
;
1762 void atomisp_free_metadata_output_buf(struct atomisp_sub_device
*asd
)
1766 for (i
= 0; i
< ATOMISP_METADATA_TYPE_NUM
; i
++) {
1767 if (asd
->params
.metadata_user
[i
]) {
1768 atomisp_kernel_free(asd
->params
.metadata_user
[i
]);
1769 asd
->params
.metadata_user
[i
] = NULL
;
1774 void atomisp_css_get_dis_statistics(struct atomisp_sub_device
*asd
,
1775 struct atomisp_css_buffer
*isp_css_buffer
,
1776 struct ia_css_isp_dvs_statistics_map
*dvs_map
)
1778 if (asd
->params
.dvs_stat
) {
1780 ia_css_translate_dvs2_statistics(
1781 asd
->params
.dvs_stat
, dvs_map
);
1783 ia_css_get_dvs2_statistics(asd
->params
.dvs_stat
,
1784 isp_css_buffer
->css_buffer
.data
.stats_dvs
);
1789 int atomisp_css_dequeue_event(struct atomisp_css_event
*current_event
)
1791 if (ia_css_dequeue_event(¤t_event
->event
) != IA_CSS_SUCCESS
)
1797 void atomisp_css_temp_pipe_to_pipe_id(struct atomisp_sub_device
*asd
,
1798 struct atomisp_css_event
*current_event
)
1802 * Pipe ID reported in CSS event is not correct for new system's
1806 ia_css_temp_pipe_to_pipe_id(current_event
->event
.pipe
,
1807 ¤t_event
->pipe
);
1808 if (asd
&& asd
->copy_mode
&&
1809 current_event
->pipe
== IA_CSS_PIPE_ID_CAPTURE
)
1810 current_event
->pipe
= IA_CSS_PIPE_ID_COPY
;
1813 int atomisp_css_isys_set_resolution(struct atomisp_sub_device
*asd
,
1814 enum atomisp_input_stream_id stream_id
,
1815 struct v4l2_mbus_framefmt
*ffmt
,
1818 struct ia_css_stream_config
*s_config
=
1819 &asd
->stream_env
[stream_id
].stream_config
;
1821 if (isys_stream
>= IA_CSS_STREAM_MAX_ISYS_STREAM_PER_CH
)
1824 s_config
->isys_config
[isys_stream
].input_res
.width
= ffmt
->width
;
1825 s_config
->isys_config
[isys_stream
].input_res
.height
= ffmt
->height
;
1829 int atomisp_css_input_set_resolution(struct atomisp_sub_device
*asd
,
1830 enum atomisp_input_stream_id stream_id
,
1831 struct v4l2_mbus_framefmt
*ffmt
)
1833 struct ia_css_stream_config
*s_config
=
1834 &asd
->stream_env
[stream_id
].stream_config
;
1836 s_config
->input_config
.input_res
.width
= ffmt
->width
;
1837 s_config
->input_config
.input_res
.height
= ffmt
->height
;
1841 void atomisp_css_input_set_binning_factor(struct atomisp_sub_device
*asd
,
1842 enum atomisp_input_stream_id stream_id
,
1843 unsigned int bin_factor
)
1845 asd
->stream_env
[stream_id
]
1846 .stream_config
.sensor_binning_factor
= bin_factor
;
1849 void atomisp_css_input_set_bayer_order(struct atomisp_sub_device
*asd
,
1850 enum atomisp_input_stream_id stream_id
,
1851 enum atomisp_css_bayer_order bayer_order
)
1853 struct ia_css_stream_config
*s_config
=
1854 &asd
->stream_env
[stream_id
].stream_config
;
1855 s_config
->input_config
.bayer_order
= bayer_order
;
1858 void atomisp_css_isys_set_link(struct atomisp_sub_device
*asd
,
1859 enum atomisp_input_stream_id stream_id
,
1863 struct ia_css_stream_config
*s_config
=
1864 &asd
->stream_env
[stream_id
].stream_config
;
1866 s_config
->isys_config
[isys_stream
].linked_isys_stream_id
= link
;
1869 void atomisp_css_isys_set_valid(struct atomisp_sub_device
*asd
,
1870 enum atomisp_input_stream_id stream_id
,
1874 struct ia_css_stream_config
*s_config
=
1875 &asd
->stream_env
[stream_id
].stream_config
;
1877 s_config
->isys_config
[isys_stream
].valid
= valid
;
1880 void atomisp_css_isys_set_format(struct atomisp_sub_device
*asd
,
1881 enum atomisp_input_stream_id stream_id
,
1882 enum atomisp_css_stream_format format
,
1886 struct ia_css_stream_config
*s_config
=
1887 &asd
->stream_env
[stream_id
].stream_config
;
1889 s_config
->isys_config
[isys_stream
].format
= format
;
1892 void atomisp_css_input_set_format(struct atomisp_sub_device
*asd
,
1893 enum atomisp_input_stream_id stream_id
,
1894 enum atomisp_css_stream_format format
)
1897 struct ia_css_stream_config
*s_config
=
1898 &asd
->stream_env
[stream_id
].stream_config
;
1900 s_config
->input_config
.format
= format
;
1903 int atomisp_css_set_default_isys_config(struct atomisp_sub_device
*asd
,
1904 enum atomisp_input_stream_id stream_id
,
1905 struct v4l2_mbus_framefmt
*ffmt
)
1908 struct ia_css_stream_config
*s_config
=
1909 &asd
->stream_env
[stream_id
].stream_config
;
1911 * Set all isys configs to not valid.
1912 * Currently we support only one stream per channel
1914 for (i
= IA_CSS_STREAM_ISYS_STREAM_0
;
1915 i
< IA_CSS_STREAM_MAX_ISYS_STREAM_PER_CH
; i
++)
1916 s_config
->isys_config
[i
].valid
= false;
1918 atomisp_css_isys_set_resolution(asd
, stream_id
, ffmt
,
1919 IA_CSS_STREAM_DEFAULT_ISYS_STREAM_IDX
);
1920 atomisp_css_isys_set_format(asd
, stream_id
,
1921 s_config
->input_config
.format
,
1922 IA_CSS_STREAM_DEFAULT_ISYS_STREAM_IDX
);
1923 atomisp_css_isys_set_link(asd
, stream_id
, NO_LINK
,
1924 IA_CSS_STREAM_DEFAULT_ISYS_STREAM_IDX
);
1925 atomisp_css_isys_set_valid(asd
, stream_id
, true,
1926 IA_CSS_STREAM_DEFAULT_ISYS_STREAM_IDX
);
1931 int atomisp_css_isys_two_stream_cfg(struct atomisp_sub_device
*asd
,
1932 enum atomisp_input_stream_id stream_id
,
1933 enum atomisp_css_stream_format input_format
)
1935 struct ia_css_stream_config
*s_config
=
1936 &asd
->stream_env
[stream_id
].stream_config
;
1938 s_config
->isys_config
[IA_CSS_STREAM_ISYS_STREAM_1
].input_res
.width
=
1939 s_config
->isys_config
[IA_CSS_STREAM_ISYS_STREAM_0
].input_res
.width
;
1941 s_config
->isys_config
[IA_CSS_STREAM_ISYS_STREAM_1
].input_res
.height
=
1942 s_config
->isys_config
[IA_CSS_STREAM_ISYS_STREAM_0
].input_res
.height
/ 2;
1944 s_config
->isys_config
[IA_CSS_STREAM_ISYS_STREAM_1
].linked_isys_stream_id
1945 = IA_CSS_STREAM_ISYS_STREAM_0
;
1946 s_config
->isys_config
[IA_CSS_STREAM_ISYS_STREAM_0
].format
=
1947 IA_CSS_STREAM_FORMAT_USER_DEF1
;
1948 s_config
->isys_config
[IA_CSS_STREAM_ISYS_STREAM_1
].format
=
1949 IA_CSS_STREAM_FORMAT_USER_DEF2
;
1950 s_config
->isys_config
[IA_CSS_STREAM_ISYS_STREAM_1
].valid
= true;
1954 void atomisp_css_isys_two_stream_cfg_update_stream1(
1955 struct atomisp_sub_device
*asd
,
1956 enum atomisp_input_stream_id stream_id
,
1957 enum atomisp_css_stream_format input_format
,
1958 unsigned int width
, unsigned int height
)
1960 struct ia_css_stream_config
*s_config
=
1961 &asd
->stream_env
[stream_id
].stream_config
;
1963 s_config
->isys_config
[IA_CSS_STREAM_ISYS_STREAM_0
].input_res
.width
=
1965 s_config
->isys_config
[IA_CSS_STREAM_ISYS_STREAM_0
].input_res
.height
=
1967 s_config
->isys_config
[IA_CSS_STREAM_ISYS_STREAM_0
].format
=
1969 s_config
->isys_config
[IA_CSS_STREAM_ISYS_STREAM_0
].valid
= true;
1972 void atomisp_css_isys_two_stream_cfg_update_stream2(
1973 struct atomisp_sub_device
*asd
,
1974 enum atomisp_input_stream_id stream_id
,
1975 enum atomisp_css_stream_format input_format
,
1976 unsigned int width
, unsigned int height
)
1978 struct ia_css_stream_config
*s_config
=
1979 &asd
->stream_env
[stream_id
].stream_config
;
1981 s_config
->isys_config
[IA_CSS_STREAM_ISYS_STREAM_1
].input_res
.width
=
1983 s_config
->isys_config
[IA_CSS_STREAM_ISYS_STREAM_1
].input_res
.height
=
1985 s_config
->isys_config
[IA_CSS_STREAM_ISYS_STREAM_1
].linked_isys_stream_id
1986 = IA_CSS_STREAM_ISYS_STREAM_0
;
1987 s_config
->isys_config
[IA_CSS_STREAM_ISYS_STREAM_1
].format
=
1989 s_config
->isys_config
[IA_CSS_STREAM_ISYS_STREAM_1
].valid
= true;
1992 int atomisp_css_input_set_effective_resolution(
1993 struct atomisp_sub_device
*asd
,
1994 enum atomisp_input_stream_id stream_id
,
1995 unsigned int width
, unsigned int height
)
1997 struct ia_css_stream_config
*s_config
=
1998 &asd
->stream_env
[stream_id
].stream_config
;
1999 s_config
->input_config
.effective_res
.width
= width
;
2000 s_config
->input_config
.effective_res
.height
= height
;
2004 void atomisp_css_video_set_dis_envelope(struct atomisp_sub_device
*asd
,
2005 unsigned int dvs_w
, unsigned int dvs_h
)
2007 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
]
2008 .pipe_configs
[IA_CSS_PIPE_ID_VIDEO
].dvs_envelope
.width
= dvs_w
;
2009 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
]
2010 .pipe_configs
[IA_CSS_PIPE_ID_VIDEO
].dvs_envelope
.height
= dvs_h
;
2013 void atomisp_css_input_set_two_pixels_per_clock(
2014 struct atomisp_sub_device
*asd
,
2019 if (asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
]
2020 .stream_config
.pixels_per_clock
== (two_ppc
? 2 : 1))
2023 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
]
2024 .stream_config
.pixels_per_clock
= (two_ppc
? 2 : 1);
2025 for (i
= 0; i
< IA_CSS_PIPE_ID_NUM
; i
++)
2026 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
]
2027 .update_pipe
[i
] = true;
2030 void atomisp_css_enable_raw_binning(struct atomisp_sub_device
*asd
,
2033 struct atomisp_stream_env
*stream_env
=
2034 &asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
];
2037 if (asd
->run_mode
->val
== ATOMISP_RUN_MODE_VIDEO
)
2038 pipe
= IA_CSS_PIPE_ID_VIDEO
;
2040 pipe
= IA_CSS_PIPE_ID_PREVIEW
;
2042 stream_env
->pipe_extra_configs
[pipe
].enable_raw_binning
= enable
;
2043 stream_env
->update_pipe
[pipe
] = true;
2045 stream_env
->pipe_configs
[pipe
].output_info
[0].padded_width
=
2046 stream_env
->stream_config
.input_config
.effective_res
.width
;
2049 void atomisp_css_enable_dz(struct atomisp_sub_device
*asd
, bool enable
)
2052 for (i
= 0; i
< IA_CSS_PIPE_ID_NUM
; i
++)
2053 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
]
2054 .pipe_configs
[i
].enable_dz
= enable
;
2057 void atomisp_css_capture_set_mode(struct atomisp_sub_device
*asd
,
2058 enum atomisp_css_capture_mode mode
)
2060 struct atomisp_stream_env
*stream_env
=
2061 &asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
];
2063 if (stream_env
->pipe_configs
[IA_CSS_PIPE_ID_CAPTURE
]
2064 .default_capture_config
.mode
== mode
)
2067 stream_env
->pipe_configs
[IA_CSS_PIPE_ID_CAPTURE
].
2068 default_capture_config
.mode
= mode
;
2069 stream_env
->update_pipe
[IA_CSS_PIPE_ID_CAPTURE
] = true;
2072 void atomisp_css_input_set_mode(struct atomisp_sub_device
*asd
,
2073 enum atomisp_css_input_mode mode
)
2076 struct atomisp_device
*isp
= asd
->isp
;
2077 unsigned int size_mem_words
;
2078 for (i
= 0; i
< ATOMISP_INPUT_STREAM_NUM
; i
++)
2079 asd
->stream_env
[i
].stream_config
.mode
= mode
;
2081 if (isp
->inputs
[asd
->input_curr
].type
== TEST_PATTERN
) {
2082 struct ia_css_stream_config
*s_config
=
2083 &asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream_config
;
2084 s_config
->mode
= IA_CSS_INPUT_MODE_TPG
;
2085 s_config
->source
.tpg
.mode
= IA_CSS_TPG_MODE_CHECKERBOARD
;
2086 s_config
->source
.tpg
.x_mask
= (1 << 4) - 1;
2087 s_config
->source
.tpg
.x_delta
= -2;
2088 s_config
->source
.tpg
.y_mask
= (1 << 4) - 1;
2089 s_config
->source
.tpg
.y_delta
= 3;
2090 s_config
->source
.tpg
.xy_mask
= (1 << 8) - 1;
2094 if (mode
!= IA_CSS_INPUT_MODE_BUFFERED_SENSOR
)
2097 for (i
= 0; i
< ATOMISP_INPUT_STREAM_NUM
; i
++) {
2099 * TODO: sensor needs to export the embedded_data_size_words
2100 * information to atomisp for each setting.
2101 * Here using a large safe value.
2103 struct ia_css_stream_config
*s_config
=
2104 &asd
->stream_env
[i
].stream_config
;
2106 if (s_config
->input_config
.input_res
.width
== 0)
2109 if (ia_css_mipi_frame_calculate_size(
2110 s_config
->input_config
.input_res
.width
,
2111 s_config
->input_config
.input_res
.height
,
2112 s_config
->input_config
.format
,
2115 &size_mem_words
) != IA_CSS_SUCCESS
) {
2116 if (intel_mid_identify_cpu() ==
2117 INTEL_MID_CPU_CHIP_TANGIER
)
2118 size_mem_words
= CSS_MIPI_FRAME_BUFFER_SIZE_2
;
2120 size_mem_words
= CSS_MIPI_FRAME_BUFFER_SIZE_1
;
2121 dev_warn(asd
->isp
->dev
,
2122 "ia_css_mipi_frame_calculate_size failed,"
2123 "applying pre-defined MIPI buffer size %u.\n",
2126 s_config
->mipi_buffer_config
.size_mem_words
= size_mem_words
;
2127 s_config
->mipi_buffer_config
.nof_mipi_buffers
= 2;
2131 void atomisp_css_capture_enable_online(struct atomisp_sub_device
*asd
,
2132 unsigned short stream_index
, bool enable
)
2134 struct atomisp_stream_env
*stream_env
=
2135 &asd
->stream_env
[stream_index
];
2137 if (stream_env
->stream_config
.online
== !!enable
)
2140 stream_env
->stream_config
.online
= !!enable
;
2141 stream_env
->update_pipe
[IA_CSS_PIPE_ID_CAPTURE
] = true;
2144 void atomisp_css_preview_enable_online(struct atomisp_sub_device
*asd
,
2145 unsigned short stream_index
, bool enable
)
2147 struct atomisp_stream_env
*stream_env
=
2148 &asd
->stream_env
[stream_index
];
2151 if (stream_env
->stream_config
.online
!= !!enable
) {
2152 stream_env
->stream_config
.online
= !!enable
;
2153 for (i
= 0; i
< IA_CSS_PIPE_ID_NUM
; i
++)
2154 stream_env
->update_pipe
[i
] = true;
2158 void atomisp_css_video_enable_online(struct atomisp_sub_device
*asd
,
2161 struct atomisp_stream_env
*stream_env
=
2162 &asd
->stream_env
[ATOMISP_INPUT_STREAM_VIDEO
];
2165 if (stream_env
->stream_config
.online
!= enable
) {
2166 stream_env
->stream_config
.online
= enable
;
2167 for (i
= 0; i
< IA_CSS_PIPE_ID_NUM
; i
++)
2168 stream_env
->update_pipe
[i
] = true;
2172 void atomisp_css_enable_continuous(struct atomisp_sub_device
*asd
,
2175 struct atomisp_stream_env
*stream_env
=
2176 &asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
];
2180 * To SOC camera, there is only one YUVPP pipe in any case
2181 * including ZSL/SDV/continuous viewfinder, so always set
2182 * stream_config.continuous to 0.
2184 if (ATOMISP_USE_YUVPP(asd
)) {
2185 stream_env
->stream_config
.continuous
= 0;
2186 stream_env
->stream_config
.online
= 1;
2190 if (stream_env
->stream_config
.continuous
!= !!enable
) {
2191 stream_env
->stream_config
.continuous
= !!enable
;
2192 stream_env
->stream_config
.pack_raw_pixels
= true;
2193 for (i
= 0; i
< IA_CSS_PIPE_ID_NUM
; i
++)
2194 stream_env
->update_pipe
[i
] = true;
2198 void atomisp_css_enable_cvf(struct atomisp_sub_device
*asd
,
2201 struct atomisp_stream_env
*stream_env
=
2202 &asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
];
2205 if (stream_env
->stream_config
.disable_cont_viewfinder
!= !enable
) {
2206 stream_env
->stream_config
.disable_cont_viewfinder
= !enable
;
2207 for (i
= 0; i
< IA_CSS_PIPE_ID_NUM
; i
++)
2208 stream_env
->update_pipe
[i
] = true;
2212 int atomisp_css_input_configure_port(
2213 struct atomisp_sub_device
*asd
,
2214 mipi_port_ID_t port
,
2215 unsigned int num_lanes
,
2216 unsigned int timeout
,
2217 unsigned int mipi_freq
,
2218 enum atomisp_css_stream_format metadata_format
,
2219 unsigned int metadata_width
,
2220 unsigned int metadata_height
)
2223 struct atomisp_stream_env
*stream_env
;
2225 * Calculate rx_count as follows:
2226 * Input: mipi_freq : CSI-2 bus frequency in Hz
2227 * UI = 1 / (2 * mipi_freq) : period of one bit on the bus
2228 * min = 85e-9 + 6 * UI : Limits for rx_count in seconds
2229 * max = 145e-9 + 10 * UI
2230 * rxcount0 = min / (4 / mipi_freq) : convert seconds to byte clocks
2231 * rxcount = rxcount0 - 2 : adjust for better results
2232 * The formula below is simplified version of the above with
2233 * 10-bit fixed points for improved accuracy.
2235 const unsigned int rxcount
=
2236 min(((mipi_freq
/ 46000) - 1280) >> 10, 0xffU
) * 0x01010101U
;
2238 for (i
= 0; i
< ATOMISP_INPUT_STREAM_NUM
; i
++) {
2239 stream_env
= &asd
->stream_env
[i
];
2240 stream_env
->stream_config
.source
.port
.port
= port
;
2241 stream_env
->stream_config
.source
.port
.num_lanes
= num_lanes
;
2242 stream_env
->stream_config
.source
.port
.timeout
= timeout
;
2244 stream_env
->stream_config
.source
.port
.rxcount
= rxcount
;
2245 stream_env
->stream_config
.
2246 metadata_config
.data_type
= metadata_format
;
2247 stream_env
->stream_config
.
2248 metadata_config
.resolution
.width
= metadata_width
;
2249 stream_env
->stream_config
.
2250 metadata_config
.resolution
.height
= metadata_height
;
2256 int atomisp_css_frame_allocate(struct atomisp_css_frame
**frame
,
2257 unsigned int width
, unsigned int height
,
2258 enum atomisp_css_frame_format format
,
2259 unsigned int padded_width
,
2260 unsigned int raw_bit_depth
)
2262 if (ia_css_frame_allocate(frame
, width
, height
, format
,
2263 padded_width
, raw_bit_depth
) != IA_CSS_SUCCESS
)
2269 int atomisp_css_frame_allocate_from_info(struct atomisp_css_frame
**frame
,
2270 const struct atomisp_css_frame_info
*info
)
2272 if (ia_css_frame_allocate_from_info(frame
, info
) != IA_CSS_SUCCESS
)
2278 void atomisp_css_frame_free(struct atomisp_css_frame
*frame
)
2280 ia_css_frame_free(frame
);
2283 int atomisp_css_frame_map(struct atomisp_css_frame
**frame
,
2284 const struct atomisp_css_frame_info
*info
,
2285 const void *data
, uint16_t attribute
,
2288 if (ia_css_frame_map(frame
, info
, data
, attribute
, context
)
2295 int atomisp_css_set_black_frame(struct atomisp_sub_device
*asd
,
2296 const struct atomisp_css_frame
*raw_black_frame
)
2298 if (sh_css_set_black_frame(
2299 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
,
2300 raw_black_frame
) != IA_CSS_SUCCESS
)
2306 int atomisp_css_allocate_continuous_frames(bool init_time
,
2307 struct atomisp_sub_device
*asd
)
2309 if (ia_css_alloc_continuous_frame_remain(
2310 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
)
2316 void atomisp_css_update_continuous_frames(struct atomisp_sub_device
*asd
)
2318 ia_css_update_continuous_frames(
2319 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
);
2322 int atomisp_css_stop(struct atomisp_sub_device
*asd
,
2323 enum atomisp_css_pipe_id pipe_id
, bool in_reset
)
2325 struct atomisp_device
*isp
= asd
->isp
;
2326 struct atomisp_s3a_buf
*s3a_buf
;
2327 struct atomisp_dis_buf
*dis_buf
;
2328 struct atomisp_metadata_buf
*md_buf
;
2329 unsigned long irqflags
;
2332 /* if is called in atomisp_reset(), force destroy stream */
2333 if (__destroy_streams(asd
, true))
2334 dev_err(isp
->dev
, "destroy stream failed.\n");
2336 /* if is called in atomisp_reset(), force destroy all pipes */
2337 if (__destroy_pipes(asd
, true))
2338 dev_err(isp
->dev
, "destroy pipes failed.\n");
2340 atomisp_init_raw_buffer_bitmap(asd
);
2343 * SP can not be stop if other streams are in use
2345 if (atomisp_streaming_count(isp
) == 0)
2349 struct atomisp_stream_env
*stream_env
;
2351 for (i
= 0; i
< ATOMISP_INPUT_STREAM_NUM
; i
++) {
2352 stream_env
= &asd
->stream_env
[i
];
2353 for (j
= 0; j
< IA_CSS_PIPE_ID_NUM
; j
++) {
2354 ia_css_pipe_config_defaults(
2355 &stream_env
->pipe_configs
[j
]);
2356 ia_css_pipe_extra_config_defaults(
2357 &stream_env
->pipe_extra_configs
[j
]);
2359 ia_css_stream_config_defaults(
2360 &stream_env
->stream_config
);
2362 atomisp_isp_parameters_clean_up(&asd
->params
.config
);
2363 asd
->params
.css_update_params_needed
= false;
2366 /* move stats buffers to free queue list */
2367 while (!list_empty(&asd
->s3a_stats_in_css
)) {
2368 s3a_buf
= list_entry(asd
->s3a_stats_in_css
.next
,
2369 struct atomisp_s3a_buf
, list
);
2370 list_del(&s3a_buf
->list
);
2371 list_add_tail(&s3a_buf
->list
, &asd
->s3a_stats
);
2373 while (!list_empty(&asd
->s3a_stats_ready
)) {
2374 s3a_buf
= list_entry(asd
->s3a_stats_ready
.next
,
2375 struct atomisp_s3a_buf
, list
);
2376 list_del(&s3a_buf
->list
);
2377 list_add_tail(&s3a_buf
->list
, &asd
->s3a_stats
);
2380 spin_lock_irqsave(&asd
->dis_stats_lock
, irqflags
);
2381 while (!list_empty(&asd
->dis_stats_in_css
)) {
2382 dis_buf
= list_entry(asd
->dis_stats_in_css
.next
,
2383 struct atomisp_dis_buf
, list
);
2384 list_del(&dis_buf
->list
);
2385 list_add_tail(&dis_buf
->list
, &asd
->dis_stats
);
2387 asd
->params
.dis_proj_data_valid
= false;
2388 spin_unlock_irqrestore(&asd
->dis_stats_lock
, irqflags
);
2390 for (i
= 0; i
< ATOMISP_METADATA_TYPE_NUM
; i
++) {
2391 while (!list_empty(&asd
->metadata_in_css
[i
])) {
2392 md_buf
= list_entry(asd
->metadata_in_css
[i
].next
,
2393 struct atomisp_metadata_buf
, list
);
2394 list_del(&md_buf
->list
);
2395 list_add_tail(&md_buf
->list
, &asd
->metadata
[i
]);
2397 while (!list_empty(&asd
->metadata_ready
[i
])) {
2398 md_buf
= list_entry(asd
->metadata_ready
[i
].next
,
2399 struct atomisp_metadata_buf
, list
);
2400 list_del(&md_buf
->list
);
2401 list_add_tail(&md_buf
->list
, &asd
->metadata
[i
]);
2405 atomisp_flush_params_queue(&asd
->video_out_capture
);
2406 atomisp_flush_params_queue(&asd
->video_out_vf
);
2407 atomisp_flush_params_queue(&asd
->video_out_preview
);
2408 atomisp_flush_params_queue(&asd
->video_out_video_capture
);
2409 atomisp_free_css_parameters(&asd
->params
.css_param
);
2410 memset(&asd
->params
.css_param
, 0, sizeof(asd
->params
.css_param
));
2414 int atomisp_css_continuous_set_num_raw_frames(
2415 struct atomisp_sub_device
*asd
,
2418 if (asd
->enable_raw_buffer_lock
->val
) {
2419 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
]
2420 .stream_config
.init_num_cont_raw_buf
=
2421 ATOMISP_CSS2_NUM_OFFLINE_INIT_CONTINUOUS_FRAMES_LOCK_EN
;
2422 if (asd
->run_mode
->val
== ATOMISP_RUN_MODE_VIDEO
&&
2423 asd
->params
.video_dis_en
)
2424 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
]
2425 .stream_config
.init_num_cont_raw_buf
+=
2426 ATOMISP_CSS2_NUM_DVS_FRAME_DELAY
;
2428 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
]
2429 .stream_config
.init_num_cont_raw_buf
=
2430 ATOMISP_CSS2_NUM_OFFLINE_INIT_CONTINUOUS_FRAMES
;
2433 if (asd
->params
.video_dis_en
)
2434 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
]
2435 .stream_config
.init_num_cont_raw_buf
+=
2436 ATOMISP_CSS2_NUM_DVS_FRAME_DELAY
;
2438 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
]
2439 .stream_config
.target_num_cont_raw_buf
= num_frames
;
2443 void atomisp_css_disable_vf_pp(struct atomisp_sub_device
*asd
,
2448 for (i
= 0; i
< IA_CSS_PIPE_ID_NUM
; i
++)
2449 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
]
2450 .pipe_extra_configs
[i
].disable_vf_pp
= !!disable
;
2453 static enum ia_css_pipe_mode
__pipe_id_to_pipe_mode(
2454 struct atomisp_sub_device
*asd
,
2455 enum ia_css_pipe_id pipe_id
)
2457 struct atomisp_device
*isp
= asd
->isp
;
2458 struct camera_mipi_info
*mipi_info
= atomisp_to_sensor_mipi_info(
2459 isp
->inputs
[asd
->input_curr
].camera
);
2462 case IA_CSS_PIPE_ID_COPY
:
2463 /* Currently only YUVPP mode supports YUV420_Legacy format.
2464 * Revert this when other pipe modes can support
2465 * YUV420_Legacy format.
2467 if (mipi_info
&& mipi_info
->input_format
==
2468 ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY
)
2469 return IA_CSS_PIPE_MODE_YUVPP
;
2470 return IA_CSS_PIPE_MODE_COPY
;
2471 case IA_CSS_PIPE_ID_PREVIEW
:
2472 return IA_CSS_PIPE_MODE_PREVIEW
;
2473 case IA_CSS_PIPE_ID_CAPTURE
:
2474 return IA_CSS_PIPE_MODE_CAPTURE
;
2475 case IA_CSS_PIPE_ID_VIDEO
:
2476 return IA_CSS_PIPE_MODE_VIDEO
;
2477 case IA_CSS_PIPE_ID_ACC
:
2478 return IA_CSS_PIPE_MODE_ACC
;
2479 case IA_CSS_PIPE_ID_YUVPP
:
2480 return IA_CSS_PIPE_MODE_YUVPP
;
2483 return IA_CSS_PIPE_MODE_PREVIEW
;
2488 static void __configure_output(struct atomisp_sub_device
*asd
,
2489 unsigned int stream_index
,
2490 unsigned int width
, unsigned int height
,
2491 unsigned int min_width
,
2492 enum ia_css_frame_format format
,
2493 enum ia_css_pipe_id pipe_id
)
2495 struct atomisp_device
*isp
= asd
->isp
;
2496 struct atomisp_stream_env
*stream_env
=
2497 &asd
->stream_env
[stream_index
];
2498 struct ia_css_stream_config
*s_config
= &stream_env
->stream_config
;
2500 stream_env
->pipe_configs
[pipe_id
].mode
=
2501 __pipe_id_to_pipe_mode(asd
, pipe_id
);
2502 stream_env
->update_pipe
[pipe_id
] = true;
2504 stream_env
->pipe_configs
[pipe_id
].output_info
[0].res
.width
= width
;
2505 stream_env
->pipe_configs
[pipe_id
].output_info
[0].res
.height
= height
;
2506 stream_env
->pipe_configs
[pipe_id
].output_info
[0].format
= format
;
2507 stream_env
->pipe_configs
[pipe_id
].output_info
[0].padded_width
= min_width
;
2509 /* isp binary 2.2 specific setting*/
2510 if (width
> s_config
->input_config
.effective_res
.width
||
2511 height
> s_config
->input_config
.effective_res
.height
) {
2512 s_config
->input_config
.effective_res
.width
= width
;
2513 s_config
->input_config
.effective_res
.height
= height
;
2516 dev_dbg(isp
->dev
, "configuring pipe[%d] output info w=%d.h=%d.f=%d.\n",
2517 pipe_id
, width
, height
, format
);
2520 static void __configure_video_preview_output(struct atomisp_sub_device
*asd
,
2521 unsigned int stream_index
,
2522 unsigned int width
, unsigned int height
,
2523 unsigned int min_width
,
2524 enum ia_css_frame_format format
,
2525 enum ia_css_pipe_id pipe_id
)
2527 struct atomisp_device
*isp
= asd
->isp
;
2528 struct atomisp_stream_env
*stream_env
=
2529 &asd
->stream_env
[stream_index
];
2530 struct ia_css_frame_info
*css_output_info
;
2531 struct ia_css_stream_config
*stream_config
= &stream_env
->stream_config
;
2533 stream_env
->pipe_configs
[pipe_id
].mode
=
2534 __pipe_id_to_pipe_mode(asd
, pipe_id
);
2535 stream_env
->update_pipe
[pipe_id
] = true;
2538 * second_output will be as video main output in SDV mode
2539 * with SOC camera. output will be as video main output in
2540 * normal video mode.
2542 if (asd
->continuous_mode
->val
)
2543 css_output_info
= &stream_env
->pipe_configs
[pipe_id
].
2544 output_info
[ATOMISP_CSS_OUTPUT_SECOND_INDEX
];
2546 css_output_info
= &stream_env
->pipe_configs
[pipe_id
].
2547 output_info
[ATOMISP_CSS_OUTPUT_DEFAULT_INDEX
];
2549 css_output_info
->res
.width
= width
;
2550 css_output_info
->res
.height
= height
;
2551 css_output_info
->format
= format
;
2552 css_output_info
->padded_width
= min_width
;
2554 /* isp binary 2.2 specific setting*/
2555 if (width
> stream_config
->input_config
.effective_res
.width
||
2556 height
> stream_config
->input_config
.effective_res
.height
) {
2557 stream_config
->input_config
.effective_res
.width
= width
;
2558 stream_config
->input_config
.effective_res
.height
= height
;
2561 dev_dbg(isp
->dev
, "configuring pipe[%d] output info w=%d.h=%d.f=%d.\n",
2562 pipe_id
, width
, height
, format
);
2566 * For CSS2.1, capture pipe uses capture_pp_in_res to configure yuv
2567 * downscaling input resolution.
2569 static void __configure_capture_pp_input(struct atomisp_sub_device
*asd
,
2570 unsigned int width
, unsigned int height
,
2571 enum ia_css_pipe_id pipe_id
)
2573 struct atomisp_device
*isp
= asd
->isp
;
2574 struct atomisp_stream_env
*stream_env
=
2575 &asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
];
2576 struct ia_css_stream_config
*stream_config
= &stream_env
->stream_config
;
2577 struct ia_css_pipe_config
*pipe_configs
=
2578 &stream_env
->pipe_configs
[pipe_id
];
2579 struct ia_css_pipe_extra_config
*pipe_extra_configs
=
2580 &stream_env
->pipe_extra_configs
[pipe_id
];
2581 unsigned int hor_ds_factor
= 0, ver_ds_factor
= 0;
2582 #define CEIL_DIV(a, b) ((b) ? ((a) + (b) - 1) / (b) : 0)
2584 if (width
== 0 && height
== 0)
2587 if (width
* 9 / 10 < pipe_configs
->output_info
[0].res
.width
||
2588 height
* 9 / 10 < pipe_configs
->output_info
[0].res
.height
)
2590 /* here just copy the calculation in css */
2591 hor_ds_factor
= CEIL_DIV(width
>> 1,
2592 pipe_configs
->output_info
[0].res
.width
);
2593 ver_ds_factor
= CEIL_DIV(height
>> 1,
2594 pipe_configs
->output_info
[0].res
.height
);
2596 if ((asd
->isp
->media_dev
.hw_revision
<
2597 (ATOMISP_HW_REVISION_ISP2401
<< ATOMISP_HW_REVISION_SHIFT
) ||
2598 IS_CHT
) && hor_ds_factor
!= ver_ds_factor
) {
2599 dev_warn(asd
->isp
->dev
,
2600 "Cropping for capture due to FW limitation");
2604 pipe_configs
->mode
= __pipe_id_to_pipe_mode(asd
, pipe_id
);
2605 stream_env
->update_pipe
[pipe_id
] = true;
2607 pipe_extra_configs
->enable_yuv_ds
= true;
2609 pipe_configs
->capt_pp_in_res
.width
=
2610 stream_config
->input_config
.effective_res
.width
;
2611 pipe_configs
->capt_pp_in_res
.height
=
2612 stream_config
->input_config
.effective_res
.height
;
2614 dev_dbg(isp
->dev
, "configuring pipe[%d]capture pp input w=%d.h=%d.\n",
2615 pipe_id
, width
, height
);
2619 * For CSS2.1, preview pipe could support bayer downscaling, yuv decimation and
2620 * yuv downscaling, which needs addtional configurations.
2622 static void __configure_preview_pp_input(struct atomisp_sub_device
*asd
,
2623 unsigned int width
, unsigned int height
,
2624 enum ia_css_pipe_id pipe_id
)
2626 struct atomisp_device
*isp
= asd
->isp
;
2627 int out_width
, out_height
, yuv_ds_in_width
, yuv_ds_in_height
;
2628 struct atomisp_stream_env
*stream_env
=
2629 &asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
];
2630 struct ia_css_stream_config
*stream_config
= &stream_env
->stream_config
;
2631 struct ia_css_pipe_config
*pipe_configs
=
2632 &stream_env
->pipe_configs
[pipe_id
];
2633 struct ia_css_pipe_extra_config
*pipe_extra_configs
=
2634 &stream_env
->pipe_extra_configs
[pipe_id
];
2635 struct ia_css_resolution
*bayer_ds_out_res
=
2636 &pipe_configs
->bayer_ds_out_res
;
2637 struct ia_css_resolution
*vf_pp_in_res
=
2638 &pipe_configs
->vf_pp_in_res
;
2639 struct ia_css_resolution
*effective_res
=
2640 &stream_config
->input_config
.effective_res
;
2642 const struct bayer_ds_factor bds_fct
[] = {{2, 1}, {3, 2}, {5, 4} };
2644 * BZ201033: YUV decimation factor of 4 causes couple of rightmost
2645 * columns to be shaded. Remove this factor to work around the CSS bug.
2646 * const unsigned int yuv_dec_fct[] = {4, 2};
2648 const unsigned int yuv_dec_fct
[] = { 2 };
2651 if (width
== 0 && height
== 0)
2654 pipe_configs
->mode
= __pipe_id_to_pipe_mode(asd
, pipe_id
);
2655 stream_env
->update_pipe
[pipe_id
] = true;
2657 out_width
= pipe_configs
->output_info
[0].res
.width
;
2658 out_height
= pipe_configs
->output_info
[0].res
.height
;
2661 * The ISP could do bayer downscaling, yuv decimation and yuv
2663 * 1: Bayer Downscaling: between effective resolution and
2665 * 2: YUV Decimation: between bayer_ds_res_out and vf_pp_in_res;
2666 * 3: YUV Downscaling: between vf_pp_in_res and final vf output
2668 * Rule for Bayer Downscaling: support factor 2, 1.5 and 1.25
2669 * Rule for YUV Decimation: support factor 2, 4
2670 * Rule for YUV Downscaling: arbitary value below 2
2672 * General rule of factor distribution among these stages:
2673 * 1: try to do Bayer downscaling first if not in online mode.
2674 * 2: try to do maximum of 2 for YUV downscaling
2675 * 3: the remainling for YUV decimation
2678 * Do not configure bayer_ds_out_res if:
2679 * online == 1 or continuous == 0 or raw_binning = 0
2681 if (stream_config
->online
|| !stream_config
->continuous
||
2682 !pipe_extra_configs
->enable_raw_binning
) {
2683 bayer_ds_out_res
->width
= 0;
2684 bayer_ds_out_res
->height
= 0;
2686 bayer_ds_out_res
->width
= effective_res
->width
;
2687 bayer_ds_out_res
->height
= effective_res
->height
;
2689 for (i
= 0; i
< ARRAY_SIZE(bds_fct
); i
++) {
2690 if (effective_res
->width
>= out_width
*
2691 bds_fct
[i
].numerator
/ bds_fct
[i
].denominator
&&
2692 effective_res
->height
>= out_height
*
2693 bds_fct
[i
].numerator
/ bds_fct
[i
].denominator
) {
2694 bayer_ds_out_res
->width
=
2695 effective_res
->width
*
2696 bds_fct
[i
].denominator
/
2697 bds_fct
[i
].numerator
;
2698 bayer_ds_out_res
->height
=
2699 effective_res
->height
*
2700 bds_fct
[i
].denominator
/
2701 bds_fct
[i
].numerator
;
2707 * calculate YUV Decimation, YUV downscaling facor:
2708 * YUV Downscaling factor must not exceed 2.
2709 * YUV Decimation factor could be 2, 4.
2711 /* first decide the yuv_ds input resolution */
2712 if (bayer_ds_out_res
->width
== 0) {
2713 yuv_ds_in_width
= effective_res
->width
;
2714 yuv_ds_in_height
= effective_res
->height
;
2716 yuv_ds_in_width
= bayer_ds_out_res
->width
;
2717 yuv_ds_in_height
= bayer_ds_out_res
->height
;
2720 vf_pp_in_res
->width
= yuv_ds_in_width
;
2721 vf_pp_in_res
->height
= yuv_ds_in_height
;
2723 /* find out the yuv decimation factor */
2724 for (i
= 0; i
< ARRAY_SIZE(yuv_dec_fct
); i
++) {
2725 if (yuv_ds_in_width
>= out_width
* yuv_dec_fct
[i
] &&
2726 yuv_ds_in_height
>= out_height
* yuv_dec_fct
[i
]) {
2727 vf_pp_in_res
->width
= yuv_ds_in_width
/ yuv_dec_fct
[i
];
2728 vf_pp_in_res
->height
= yuv_ds_in_height
/ yuv_dec_fct
[i
];
2733 if (vf_pp_in_res
->width
== out_width
&&
2734 vf_pp_in_res
->height
== out_height
) {
2735 pipe_extra_configs
->enable_yuv_ds
= false;
2736 vf_pp_in_res
->width
= 0;
2737 vf_pp_in_res
->height
= 0;
2739 pipe_extra_configs
->enable_yuv_ds
= true;
2742 dev_dbg(isp
->dev
, "configuring pipe[%d]preview pp input w=%d.h=%d.\n",
2743 pipe_id
, width
, height
);
2747 * For CSS2.1, offline video pipe could support bayer decimation, and
2748 * yuv downscaling, which needs addtional configurations.
2750 static void __configure_video_pp_input(struct atomisp_sub_device
*asd
,
2751 unsigned int width
, unsigned int height
,
2752 enum ia_css_pipe_id pipe_id
)
2754 struct atomisp_device
*isp
= asd
->isp
;
2755 int out_width
, out_height
;
2756 struct atomisp_stream_env
*stream_env
=
2757 &asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
];
2758 struct ia_css_stream_config
*stream_config
= &stream_env
->stream_config
;
2759 struct ia_css_pipe_config
*pipe_configs
=
2760 &stream_env
->pipe_configs
[pipe_id
];
2761 struct ia_css_pipe_extra_config
*pipe_extra_configs
=
2762 &stream_env
->pipe_extra_configs
[pipe_id
];
2763 struct ia_css_resolution
*bayer_ds_out_res
=
2764 &pipe_configs
->bayer_ds_out_res
;
2765 struct ia_css_resolution
*effective_res
=
2766 &stream_config
->input_config
.effective_res
;
2768 const struct bayer_ds_factor bds_factors
[] = {
2769 {8, 1}, {6, 1}, {4, 1}, {3, 1}, {2, 1}, {3, 2} };
2772 if (width
== 0 && height
== 0)
2775 pipe_configs
->mode
= __pipe_id_to_pipe_mode(asd
, pipe_id
);
2776 stream_env
->update_pipe
[pipe_id
] = true;
2778 pipe_extra_configs
->enable_yuv_ds
= false;
2781 * If DVS is enabled, video binary will take care the dvs envelope
2782 * and usually the bayer_ds_out_res should be larger than 120% of
2783 * destination resolution, the extra 20% will be cropped as DVS
2784 * envelope. But, if the bayer_ds_out_res is less than 120% of the
2785 * destination. The ISP can still work, but DVS quality is not good.
2787 /* taking at least 10% as envelope */
2788 if (asd
->params
.video_dis_en
) {
2789 out_width
= pipe_configs
->output_info
[0].res
.width
* 110 / 100;
2790 out_height
= pipe_configs
->output_info
[0].res
.height
* 110 / 100;
2792 out_width
= pipe_configs
->output_info
[0].res
.width
;
2793 out_height
= pipe_configs
->output_info
[0].res
.height
;
2797 * calculate bayer decimate factor:
2798 * 1: only 1.5, 2, 4 and 8 get supported
2799 * 2: Do not configure bayer_ds_out_res if:
2800 * online == 1 or continuous == 0 or raw_binning = 0
2802 if (stream_config
->online
|| !stream_config
->continuous
) {
2803 bayer_ds_out_res
->width
= 0;
2804 bayer_ds_out_res
->height
= 0;
2808 pipe_extra_configs
->enable_raw_binning
= true;
2809 bayer_ds_out_res
->width
= effective_res
->width
;
2810 bayer_ds_out_res
->height
= effective_res
->height
;
2812 for (i
= 0; i
< sizeof(bds_factors
) / sizeof(struct bayer_ds_factor
);
2814 if (effective_res
->width
>= out_width
*
2815 bds_factors
[i
].numerator
/ bds_factors
[i
].denominator
&&
2816 effective_res
->height
>= out_height
*
2817 bds_factors
[i
].numerator
/ bds_factors
[i
].denominator
) {
2818 bayer_ds_out_res
->width
= effective_res
->width
*
2819 bds_factors
[i
].denominator
/
2820 bds_factors
[i
].numerator
;
2821 bayer_ds_out_res
->height
= effective_res
->height
*
2822 bds_factors
[i
].denominator
/
2823 bds_factors
[i
].numerator
;
2829 * DVS is cropped from BDS output, so we do not really need to set the
2830 * envelope to 20% of output resolution here. always set it to 12x12
2831 * per firmware requirement.
2833 pipe_configs
->dvs_envelope
.width
= 12;
2834 pipe_configs
->dvs_envelope
.height
= 12;
2837 if (pipe_id
== IA_CSS_PIPE_ID_YUVPP
)
2838 stream_config
->left_padding
= -1;
2840 stream_config
->left_padding
= 12;
2841 dev_dbg(isp
->dev
, "configuring pipe[%d]video pp input w=%d.h=%d.\n",
2842 pipe_id
, width
, height
);
2845 static void __configure_vf_output(struct atomisp_sub_device
*asd
,
2846 unsigned int width
, unsigned int height
,
2847 unsigned int min_width
,
2848 enum atomisp_css_frame_format format
,
2849 enum ia_css_pipe_id pipe_id
)
2851 struct atomisp_device
*isp
= asd
->isp
;
2852 struct atomisp_stream_env
*stream_env
=
2853 &asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
];
2854 stream_env
->pipe_configs
[pipe_id
].mode
=
2855 __pipe_id_to_pipe_mode(asd
, pipe_id
);
2856 stream_env
->update_pipe
[pipe_id
] = true;
2858 stream_env
->pipe_configs
[pipe_id
].vf_output_info
[0].res
.width
= width
;
2859 stream_env
->pipe_configs
[pipe_id
].vf_output_info
[0].res
.height
= height
;
2860 stream_env
->pipe_configs
[pipe_id
].vf_output_info
[0].format
= format
;
2861 stream_env
->pipe_configs
[pipe_id
].vf_output_info
[0].padded_width
=
2864 "configuring pipe[%d] vf output info w=%d.h=%d.f=%d.\n",
2865 pipe_id
, width
, height
, format
);
2868 static void __configure_video_vf_output(struct atomisp_sub_device
*asd
,
2869 unsigned int width
, unsigned int height
,
2870 unsigned int min_width
,
2871 enum atomisp_css_frame_format format
,
2872 enum ia_css_pipe_id pipe_id
)
2874 struct atomisp_device
*isp
= asd
->isp
;
2875 struct atomisp_stream_env
*stream_env
=
2876 &asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
];
2877 struct ia_css_frame_info
*css_output_info
;
2878 stream_env
->pipe_configs
[pipe_id
].mode
=
2879 __pipe_id_to_pipe_mode(asd
, pipe_id
);
2880 stream_env
->update_pipe
[pipe_id
] = true;
2883 * second_vf_output will be as video viewfinder in SDV mode
2884 * with SOC camera. vf_output will be as video viewfinder in
2885 * normal video mode.
2887 if (asd
->continuous_mode
->val
)
2888 css_output_info
= &stream_env
->pipe_configs
[pipe_id
].
2889 vf_output_info
[ATOMISP_CSS_OUTPUT_SECOND_INDEX
];
2891 css_output_info
= &stream_env
->pipe_configs
[pipe_id
].
2892 vf_output_info
[ATOMISP_CSS_OUTPUT_DEFAULT_INDEX
];
2894 css_output_info
->res
.width
= width
;
2895 css_output_info
->res
.height
= height
;
2896 css_output_info
->format
= format
;
2897 css_output_info
->padded_width
= min_width
;
2899 "configuring pipe[%d] vf output info w=%d.h=%d.f=%d.\n",
2900 pipe_id
, width
, height
, format
);
2903 static int __get_frame_info(struct atomisp_sub_device
*asd
,
2904 unsigned int stream_index
,
2905 struct atomisp_css_frame_info
*info
,
2906 enum frame_info_type type
,
2907 enum ia_css_pipe_id pipe_id
)
2909 struct atomisp_device
*isp
= asd
->isp
;
2910 enum ia_css_err ret
;
2911 struct ia_css_pipe_info p_info
;
2913 /* FIXME! No need to destroy/recreate all streams */
2914 if (__destroy_streams(asd
, true))
2915 dev_warn(isp
->dev
, "destroy stream failed.\n");
2917 if (__destroy_pipes(asd
, true))
2918 dev_warn(isp
->dev
, "destroy pipe failed.\n");
2920 if (__create_pipes(asd
))
2923 if (__create_streams(asd
))
2926 ret
= ia_css_pipe_get_info(
2927 asd
->stream_env
[stream_index
]
2928 .pipes
[pipe_id
], &p_info
);
2929 if (ret
== IA_CSS_SUCCESS
) {
2931 case ATOMISP_CSS_VF_FRAME
:
2932 *info
= p_info
.vf_output_info
[0];
2933 dev_dbg(isp
->dev
, "getting vf frame info.\n");
2935 case ATOMISP_CSS_SECOND_VF_FRAME
:
2936 *info
= p_info
.vf_output_info
[1];
2937 dev_dbg(isp
->dev
, "getting second vf frame info.\n");
2939 case ATOMISP_CSS_OUTPUT_FRAME
:
2940 *info
= p_info
.output_info
[0];
2941 dev_dbg(isp
->dev
, "getting main frame info.\n");
2943 case ATOMISP_CSS_SECOND_OUTPUT_FRAME
:
2944 *info
= p_info
.output_info
[1];
2945 dev_dbg(isp
->dev
, "getting second main frame info.\n");
2947 case ATOMISP_CSS_RAW_FRAME
:
2948 *info
= p_info
.raw_output_info
;
2949 dev_dbg(isp
->dev
, "getting raw frame info.\n");
2951 dev_dbg(isp
->dev
, "get frame info: w=%d, h=%d, num_invalid_frames %d.\n",
2952 info
->res
.width
, info
->res
.height
, p_info
.num_invalid_frames
);
2957 __destroy_pipes(asd
, true);
2961 unsigned int atomisp_get_pipe_index(struct atomisp_sub_device
*asd
,
2962 uint16_t source_pad
)
2964 struct atomisp_device
*isp
= asd
->isp
;
2966 * to SOC camera, use yuvpp pipe.
2968 if (ATOMISP_USE_YUVPP(asd
))
2969 return IA_CSS_PIPE_ID_YUVPP
;
2971 switch (source_pad
) {
2972 case ATOMISP_SUBDEV_PAD_SOURCE_VIDEO
:
2973 if (asd
->yuvpp_mode
)
2974 return IA_CSS_PIPE_ID_YUVPP
;
2976 return IA_CSS_PIPE_ID_COPY
;
2977 if (asd
->run_mode
->val
== ATOMISP_RUN_MODE_VIDEO
2978 || asd
->vfpp
->val
== ATOMISP_VFPP_DISABLE_SCALER
)
2979 return IA_CSS_PIPE_ID_VIDEO
;
2981 return IA_CSS_PIPE_ID_CAPTURE
;
2982 case ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE
:
2984 return IA_CSS_PIPE_ID_COPY
;
2985 return IA_CSS_PIPE_ID_CAPTURE
;
2986 case ATOMISP_SUBDEV_PAD_SOURCE_VF
:
2987 if (!atomisp_is_mbuscode_raw(
2988 asd
->fmt
[asd
->capture_pad
].fmt
.code
))
2989 return IA_CSS_PIPE_ID_CAPTURE
;
2990 case ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW
:
2991 if (asd
->yuvpp_mode
)
2992 return IA_CSS_PIPE_ID_YUVPP
;
2994 return IA_CSS_PIPE_ID_COPY
;
2995 if (asd
->run_mode
->val
== ATOMISP_RUN_MODE_VIDEO
)
2996 return IA_CSS_PIPE_ID_VIDEO
;
2998 return IA_CSS_PIPE_ID_PREVIEW
;
3001 "invalid source pad:%d, return default preview pipe index.\n",
3003 return IA_CSS_PIPE_ID_PREVIEW
;
3006 int atomisp_get_css_frame_info(struct atomisp_sub_device
*asd
,
3007 uint16_t source_pad
,
3008 struct atomisp_css_frame_info
*frame_info
)
3010 struct ia_css_pipe_info info
;
3011 int pipe_index
= atomisp_get_pipe_index(asd
, source_pad
);
3013 struct atomisp_device
*isp
= asd
->isp
;
3015 if (ATOMISP_SOC_CAMERA(asd
))
3016 stream_index
= atomisp_source_pad_to_stream_id(asd
, source_pad
);
3018 stream_index
= (pipe_index
== IA_CSS_PIPE_ID_YUVPP
) ?
3019 ATOMISP_INPUT_STREAM_VIDEO
:
3020 atomisp_source_pad_to_stream_id(asd
, source_pad
);
3023 if (IA_CSS_SUCCESS
!= ia_css_pipe_get_info(asd
->stream_env
[stream_index
]
3024 .pipes
[pipe_index
], &info
)) {
3025 dev_err(isp
->dev
, "ia_css_pipe_get_info FAILED");
3029 switch (source_pad
) {
3030 case ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE
:
3031 *frame_info
= info
.output_info
[0];
3033 case ATOMISP_SUBDEV_PAD_SOURCE_VIDEO
:
3034 if (ATOMISP_USE_YUVPP(asd
) && asd
->continuous_mode
->val
)
3036 output_info
[ATOMISP_CSS_OUTPUT_SECOND_INDEX
];
3039 output_info
[ATOMISP_CSS_OUTPUT_DEFAULT_INDEX
];
3041 case ATOMISP_SUBDEV_PAD_SOURCE_VF
:
3042 if (stream_index
== ATOMISP_INPUT_STREAM_POSTVIEW
)
3043 *frame_info
= info
.output_info
[0];
3045 *frame_info
= info
.vf_output_info
[0];
3047 case ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW
:
3048 if (asd
->run_mode
->val
== ATOMISP_RUN_MODE_VIDEO
&&
3049 (pipe_index
== IA_CSS_PIPE_ID_VIDEO
||
3050 pipe_index
== IA_CSS_PIPE_ID_YUVPP
))
3051 if (ATOMISP_USE_YUVPP(asd
) && asd
->continuous_mode
->val
)
3053 vf_output_info
[ATOMISP_CSS_OUTPUT_SECOND_INDEX
];
3056 vf_output_info
[ATOMISP_CSS_OUTPUT_DEFAULT_INDEX
];
3057 else if (ATOMISP_USE_YUVPP(asd
) && asd
->continuous_mode
->val
)
3059 info
.output_info
[ATOMISP_CSS_OUTPUT_SECOND_INDEX
];
3062 info
.output_info
[ATOMISP_CSS_OUTPUT_DEFAULT_INDEX
];
3069 return frame_info
? 0 : -EINVAL
;
3072 int atomisp_css_copy_configure_output(struct atomisp_sub_device
*asd
,
3073 unsigned int stream_index
,
3074 unsigned int width
, unsigned int height
,
3075 unsigned int padded_width
,
3076 enum atomisp_css_frame_format format
)
3078 asd
->stream_env
[stream_index
].pipe_configs
[IA_CSS_PIPE_ID_COPY
].
3079 default_capture_config
.mode
=
3080 CSS_CAPTURE_MODE_RAW
;
3082 __configure_output(asd
, stream_index
, width
, height
, padded_width
,
3083 format
, IA_CSS_PIPE_ID_COPY
);
3087 int atomisp_css_yuvpp_configure_output(struct atomisp_sub_device
*asd
,
3088 unsigned int stream_index
,
3089 unsigned int width
, unsigned int height
,
3090 unsigned int padded_width
,
3091 enum atomisp_css_frame_format format
)
3093 asd
->stream_env
[stream_index
].pipe_configs
[IA_CSS_PIPE_ID_YUVPP
].
3094 default_capture_config
.mode
=
3095 CSS_CAPTURE_MODE_RAW
;
3097 __configure_output(asd
, stream_index
, width
, height
, padded_width
,
3098 format
, IA_CSS_PIPE_ID_YUVPP
);
3102 int atomisp_css_yuvpp_configure_viewfinder(
3103 struct atomisp_sub_device
*asd
,
3104 unsigned int stream_index
,
3105 unsigned int width
, unsigned int height
,
3106 unsigned int min_width
,
3107 enum atomisp_css_frame_format format
)
3109 struct atomisp_stream_env
*stream_env
=
3110 &asd
->stream_env
[stream_index
];
3111 enum ia_css_pipe_id pipe_id
= IA_CSS_PIPE_ID_YUVPP
;
3113 stream_env
->pipe_configs
[pipe_id
].mode
=
3114 __pipe_id_to_pipe_mode(asd
, pipe_id
);
3115 stream_env
->update_pipe
[pipe_id
] = true;
3117 stream_env
->pipe_configs
[pipe_id
].vf_output_info
[0].res
.width
= width
;
3118 stream_env
->pipe_configs
[pipe_id
].vf_output_info
[0].res
.height
= height
;
3119 stream_env
->pipe_configs
[pipe_id
].vf_output_info
[0].format
= format
;
3120 stream_env
->pipe_configs
[pipe_id
].vf_output_info
[0].padded_width
=
3125 int atomisp_css_yuvpp_get_output_frame_info(
3126 struct atomisp_sub_device
*asd
,
3127 unsigned int stream_index
,
3128 struct atomisp_css_frame_info
*info
)
3130 return __get_frame_info(asd
, stream_index
, info
,
3131 ATOMISP_CSS_OUTPUT_FRAME
, IA_CSS_PIPE_ID_YUVPP
);
3134 int atomisp_css_yuvpp_get_viewfinder_frame_info(
3135 struct atomisp_sub_device
*asd
,
3136 unsigned int stream_index
,
3137 struct atomisp_css_frame_info
*info
)
3139 return __get_frame_info(asd
, stream_index
, info
,
3140 ATOMISP_CSS_VF_FRAME
, IA_CSS_PIPE_ID_YUVPP
);
3143 int atomisp_css_preview_configure_output(struct atomisp_sub_device
*asd
,
3144 unsigned int width
, unsigned int height
,
3145 unsigned int min_width
,
3146 enum atomisp_css_frame_format format
)
3149 * to SOC camera, use yuvpp pipe.
3151 if (ATOMISP_USE_YUVPP(asd
))
3152 __configure_video_preview_output(asd
, ATOMISP_INPUT_STREAM_GENERAL
, width
, height
,
3153 min_width
, format
, IA_CSS_PIPE_ID_YUVPP
);
3155 __configure_output(asd
, ATOMISP_INPUT_STREAM_GENERAL
, width
, height
,
3156 min_width
, format
, IA_CSS_PIPE_ID_PREVIEW
);
3160 int atomisp_css_capture_configure_output(struct atomisp_sub_device
*asd
,
3161 unsigned int width
, unsigned int height
,
3162 unsigned int min_width
,
3163 enum atomisp_css_frame_format format
)
3165 enum ia_css_pipe_id pipe_id
;
3168 * to SOC camera, use yuvpp pipe.
3170 if (ATOMISP_USE_YUVPP(asd
))
3171 pipe_id
= IA_CSS_PIPE_ID_YUVPP
;
3173 pipe_id
= IA_CSS_PIPE_ID_CAPTURE
;
3175 __configure_output(asd
, ATOMISP_INPUT_STREAM_GENERAL
, width
, height
,
3176 min_width
, format
, pipe_id
);
3180 int atomisp_css_video_configure_output(struct atomisp_sub_device
*asd
,
3181 unsigned int width
, unsigned int height
,
3182 unsigned int min_width
,
3183 enum atomisp_css_frame_format format
)
3186 * to SOC camera, use yuvpp pipe.
3188 if (ATOMISP_USE_YUVPP(asd
))
3189 __configure_video_preview_output(asd
, ATOMISP_INPUT_STREAM_GENERAL
, width
, height
,
3190 min_width
, format
, IA_CSS_PIPE_ID_YUVPP
);
3192 __configure_output(asd
, ATOMISP_INPUT_STREAM_GENERAL
, width
, height
,
3193 min_width
, format
, IA_CSS_PIPE_ID_VIDEO
);
3197 int atomisp_css_video_configure_viewfinder(
3198 struct atomisp_sub_device
*asd
,
3199 unsigned int width
, unsigned int height
,
3200 unsigned int min_width
,
3201 enum atomisp_css_frame_format format
)
3204 * to SOC camera, video will use yuvpp pipe.
3206 if (ATOMISP_USE_YUVPP(asd
))
3207 __configure_video_vf_output(asd
, width
, height
, min_width
, format
,
3208 IA_CSS_PIPE_ID_YUVPP
);
3210 __configure_vf_output(asd
, width
, height
, min_width
, format
,
3211 IA_CSS_PIPE_ID_VIDEO
);
3215 int atomisp_css_capture_configure_viewfinder(
3216 struct atomisp_sub_device
*asd
,
3217 unsigned int width
, unsigned int height
,
3218 unsigned int min_width
,
3219 enum atomisp_css_frame_format format
)
3221 enum ia_css_pipe_id pipe_id
;
3224 * to SOC camera, video will use yuvpp pipe.
3226 if (ATOMISP_USE_YUVPP(asd
))
3227 pipe_id
= IA_CSS_PIPE_ID_YUVPP
;
3229 pipe_id
= IA_CSS_PIPE_ID_CAPTURE
;
3231 __configure_vf_output(asd
, width
, height
, min_width
, format
,
3236 int atomisp_css_video_get_viewfinder_frame_info(
3237 struct atomisp_sub_device
*asd
,
3238 struct atomisp_css_frame_info
*info
)
3240 enum ia_css_pipe_id pipe_id
;
3241 enum frame_info_type frame_type
= ATOMISP_CSS_VF_FRAME
;
3243 if (ATOMISP_USE_YUVPP(asd
)) {
3244 pipe_id
= IA_CSS_PIPE_ID_YUVPP
;
3245 if (asd
->continuous_mode
->val
)
3246 frame_type
= ATOMISP_CSS_SECOND_VF_FRAME
;
3248 pipe_id
= IA_CSS_PIPE_ID_VIDEO
;
3251 return __get_frame_info(asd
, ATOMISP_INPUT_STREAM_GENERAL
, info
,
3252 frame_type
, pipe_id
);
3255 int atomisp_css_capture_get_viewfinder_frame_info(
3256 struct atomisp_sub_device
*asd
,
3257 struct atomisp_css_frame_info
*info
)
3259 enum ia_css_pipe_id pipe_id
;
3261 if (ATOMISP_USE_YUVPP(asd
))
3262 pipe_id
= IA_CSS_PIPE_ID_YUVPP
;
3264 pipe_id
= IA_CSS_PIPE_ID_CAPTURE
;
3266 return __get_frame_info(asd
, ATOMISP_INPUT_STREAM_GENERAL
, info
,
3267 ATOMISP_CSS_VF_FRAME
, pipe_id
);
3270 int atomisp_css_capture_get_output_raw_frame_info(
3271 struct atomisp_sub_device
*asd
,
3272 struct atomisp_css_frame_info
*info
)
3274 if (ATOMISP_USE_YUVPP(asd
))
3277 return __get_frame_info(asd
, ATOMISP_INPUT_STREAM_GENERAL
, info
,
3278 ATOMISP_CSS_RAW_FRAME
, IA_CSS_PIPE_ID_CAPTURE
);
3281 int atomisp_css_copy_get_output_frame_info(
3282 struct atomisp_sub_device
*asd
,
3283 unsigned int stream_index
,
3284 struct atomisp_css_frame_info
*info
)
3286 return __get_frame_info(asd
, stream_index
, info
,
3287 ATOMISP_CSS_OUTPUT_FRAME
, IA_CSS_PIPE_ID_COPY
);
3290 int atomisp_css_preview_get_output_frame_info(
3291 struct atomisp_sub_device
*asd
,
3292 struct atomisp_css_frame_info
*info
)
3294 enum ia_css_pipe_id pipe_id
;
3295 enum frame_info_type frame_type
= ATOMISP_CSS_OUTPUT_FRAME
;
3297 if (ATOMISP_USE_YUVPP(asd
)) {
3298 pipe_id
= IA_CSS_PIPE_ID_YUVPP
;
3299 if (asd
->continuous_mode
->val
)
3300 frame_type
= ATOMISP_CSS_SECOND_OUTPUT_FRAME
;
3302 pipe_id
= IA_CSS_PIPE_ID_PREVIEW
;
3305 return __get_frame_info(asd
, ATOMISP_INPUT_STREAM_GENERAL
, info
,
3306 frame_type
, pipe_id
);
3309 int atomisp_css_capture_get_output_frame_info(
3310 struct atomisp_sub_device
*asd
,
3311 struct atomisp_css_frame_info
*info
)
3313 enum ia_css_pipe_id pipe_id
;
3315 if (ATOMISP_USE_YUVPP(asd
))
3316 pipe_id
= IA_CSS_PIPE_ID_YUVPP
;
3318 pipe_id
= IA_CSS_PIPE_ID_CAPTURE
;
3320 return __get_frame_info(asd
, ATOMISP_INPUT_STREAM_GENERAL
, info
,
3321 ATOMISP_CSS_OUTPUT_FRAME
, pipe_id
);
3324 int atomisp_css_video_get_output_frame_info(
3325 struct atomisp_sub_device
*asd
,
3326 struct atomisp_css_frame_info
*info
)
3328 enum ia_css_pipe_id pipe_id
;
3329 enum frame_info_type frame_type
= ATOMISP_CSS_OUTPUT_FRAME
;
3331 if (ATOMISP_USE_YUVPP(asd
)) {
3332 pipe_id
= IA_CSS_PIPE_ID_YUVPP
;
3333 if (asd
->continuous_mode
->val
)
3334 frame_type
= ATOMISP_CSS_SECOND_OUTPUT_FRAME
;
3336 pipe_id
= IA_CSS_PIPE_ID_VIDEO
;
3339 return __get_frame_info(asd
, ATOMISP_INPUT_STREAM_GENERAL
, info
,
3340 frame_type
, pipe_id
);
3343 int atomisp_css_preview_configure_pp_input(
3344 struct atomisp_sub_device
*asd
,
3345 unsigned int width
, unsigned int height
)
3347 struct atomisp_stream_env
*stream_env
=
3348 &asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
];
3349 __configure_preview_pp_input(asd
, width
, height
,
3350 ATOMISP_USE_YUVPP(asd
) ?
3351 IA_CSS_PIPE_ID_YUVPP
: IA_CSS_PIPE_ID_PREVIEW
);
3353 if (width
> stream_env
->pipe_configs
[IA_CSS_PIPE_ID_CAPTURE
].
3354 capt_pp_in_res
.width
)
3355 __configure_capture_pp_input(asd
, width
, height
,
3356 ATOMISP_USE_YUVPP(asd
) ?
3357 IA_CSS_PIPE_ID_YUVPP
: IA_CSS_PIPE_ID_CAPTURE
);
3361 int atomisp_css_capture_configure_pp_input(
3362 struct atomisp_sub_device
*asd
,
3363 unsigned int width
, unsigned int height
)
3365 __configure_capture_pp_input(asd
, width
, height
,
3366 ATOMISP_USE_YUVPP(asd
) ?
3367 IA_CSS_PIPE_ID_YUVPP
: IA_CSS_PIPE_ID_CAPTURE
);
3371 int atomisp_css_video_configure_pp_input(
3372 struct atomisp_sub_device
*asd
,
3373 unsigned int width
, unsigned int height
)
3375 struct atomisp_stream_env
*stream_env
=
3376 &asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
];
3378 __configure_video_pp_input(asd
, width
, height
,
3379 ATOMISP_USE_YUVPP(asd
) ?
3380 IA_CSS_PIPE_ID_YUVPP
: IA_CSS_PIPE_ID_VIDEO
);
3382 if (width
> stream_env
->pipe_configs
[IA_CSS_PIPE_ID_CAPTURE
].
3383 capt_pp_in_res
.width
)
3384 __configure_capture_pp_input(asd
, width
, height
,
3385 ATOMISP_USE_YUVPP(asd
) ?
3386 IA_CSS_PIPE_ID_YUVPP
: IA_CSS_PIPE_ID_CAPTURE
);
3390 int atomisp_css_offline_capture_configure(struct atomisp_sub_device
*asd
,
3391 int num_captures
, unsigned int skip
, int offset
)
3393 enum ia_css_err ret
;
3396 dev_dbg(asd
->isp
->dev
, "%s num_capture:%d skip:%d offset:%d\n",
3397 __func__
, num_captures
, skip
, offset
);
3399 ret
= ia_css_stream_capture(
3400 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
,
3401 num_captures
, skip
, offset
);
3402 if (ret
!= IA_CSS_SUCCESS
)
3408 int atomisp_css_exp_id_capture(struct atomisp_sub_device
*asd
, int exp_id
)
3410 enum ia_css_err ret
;
3412 ret
= ia_css_stream_capture_frame(
3413 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
,
3415 if (ret
== IA_CSS_ERR_QUEUE_IS_FULL
) {
3416 /* capture cmd queue is full */
3418 } else if (ret
!= IA_CSS_SUCCESS
) {
3425 int atomisp_css_exp_id_unlock(struct atomisp_sub_device
*asd
, int exp_id
)
3427 enum ia_css_err ret
;
3429 ret
= ia_css_unlock_raw_frame(
3430 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
,
3432 if (ret
== IA_CSS_ERR_QUEUE_IS_FULL
)
3434 else if (ret
!= IA_CSS_SUCCESS
)
3440 int atomisp_css_capture_enable_xnr(struct atomisp_sub_device
*asd
,
3443 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
]
3444 .pipe_configs
[IA_CSS_PIPE_ID_CAPTURE
]
3445 .default_capture_config
.enable_xnr
= enable
;
3446 asd
->params
.capture_config
.enable_xnr
= enable
;
3447 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
]
3448 .update_pipe
[IA_CSS_PIPE_ID_CAPTURE
] = true;
3453 void atomisp_css_send_input_frame(struct atomisp_sub_device
*asd
,
3454 unsigned short *data
, unsigned int width
,
3455 unsigned int height
)
3457 ia_css_stream_send_input_frame(
3458 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
,
3459 data
, width
, height
);
3462 bool atomisp_css_isp_has_started(void)
3464 return ia_css_isp_has_started();
3467 void atomisp_css_request_flash(struct atomisp_sub_device
*asd
)
3469 ia_css_stream_request_flash(
3470 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
);
3473 void atomisp_css_set_wb_config(struct atomisp_sub_device
*asd
,
3474 struct atomisp_css_wb_config
*wb_config
)
3476 asd
->params
.config
.wb_config
= wb_config
;
3479 void atomisp_css_set_ob_config(struct atomisp_sub_device
*asd
,
3480 struct atomisp_css_ob_config
*ob_config
)
3482 asd
->params
.config
.ob_config
= ob_config
;
3485 void atomisp_css_set_dp_config(struct atomisp_sub_device
*asd
,
3486 struct atomisp_css_dp_config
*dp_config
)
3488 asd
->params
.config
.dp_config
= dp_config
;
3491 void atomisp_css_set_de_config(struct atomisp_sub_device
*asd
,
3492 struct atomisp_css_de_config
*de_config
)
3494 asd
->params
.config
.de_config
= de_config
;
3497 void atomisp_css_set_dz_config(struct atomisp_sub_device
*asd
,
3498 struct atomisp_css_dz_config
*dz_config
)
3500 asd
->params
.config
.dz_config
= dz_config
;
3503 void atomisp_css_set_default_de_config(struct atomisp_sub_device
*asd
)
3505 asd
->params
.config
.de_config
= NULL
;
3508 void atomisp_css_set_ce_config(struct atomisp_sub_device
*asd
,
3509 struct atomisp_css_ce_config
*ce_config
)
3511 asd
->params
.config
.ce_config
= ce_config
;
3514 void atomisp_css_set_nr_config(struct atomisp_sub_device
*asd
,
3515 struct atomisp_css_nr_config
*nr_config
)
3517 asd
->params
.config
.nr_config
= nr_config
;
3520 void atomisp_css_set_ee_config(struct atomisp_sub_device
*asd
,
3521 struct atomisp_css_ee_config
*ee_config
)
3523 asd
->params
.config
.ee_config
= ee_config
;
3526 void atomisp_css_set_tnr_config(struct atomisp_sub_device
*asd
,
3527 struct atomisp_css_tnr_config
*tnr_config
)
3529 asd
->params
.config
.tnr_config
= tnr_config
;
3532 void atomisp_css_set_cc_config(struct atomisp_sub_device
*asd
,
3533 struct atomisp_css_cc_config
*cc_config
)
3535 asd
->params
.config
.cc_config
= cc_config
;
3538 void atomisp_css_set_macc_table(struct atomisp_sub_device
*asd
,
3539 struct atomisp_css_macc_table
*macc_table
)
3541 asd
->params
.config
.macc_table
= macc_table
;
3544 void atomisp_css_set_macc_config(struct atomisp_sub_device
*asd
,
3545 struct atomisp_css_macc_config
*macc_config
)
3547 asd
->params
.config
.macc_config
= macc_config
;
3550 void atomisp_css_set_ecd_config(struct atomisp_sub_device
*asd
,
3551 struct atomisp_css_ecd_config
*ecd_config
)
3553 asd
->params
.config
.ecd_config
= ecd_config
;
3556 void atomisp_css_set_ynr_config(struct atomisp_sub_device
*asd
,
3557 struct atomisp_css_ynr_config
*ynr_config
)
3559 asd
->params
.config
.ynr_config
= ynr_config
;
3562 void atomisp_css_set_fc_config(struct atomisp_sub_device
*asd
,
3563 struct atomisp_css_fc_config
*fc_config
)
3565 asd
->params
.config
.fc_config
= fc_config
;
3568 void atomisp_css_set_ctc_config(struct atomisp_sub_device
*asd
,
3569 struct atomisp_css_ctc_config
*ctc_config
)
3571 asd
->params
.config
.ctc_config
= ctc_config
;
3574 void atomisp_css_set_cnr_config(struct atomisp_sub_device
*asd
,
3575 struct atomisp_css_cnr_config
*cnr_config
)
3577 asd
->params
.config
.cnr_config
= cnr_config
;
3580 void atomisp_css_set_aa_config(struct atomisp_sub_device
*asd
,
3581 struct atomisp_css_aa_config
*aa_config
)
3583 asd
->params
.config
.aa_config
= aa_config
;
3586 void atomisp_css_set_baa_config(struct atomisp_sub_device
*asd
,
3587 struct atomisp_css_baa_config
*baa_config
)
3589 asd
->params
.config
.baa_config
= baa_config
;
3592 void atomisp_css_set_anr_config(struct atomisp_sub_device
*asd
,
3593 struct atomisp_css_anr_config
*anr_config
)
3595 asd
->params
.config
.anr_config
= anr_config
;
3598 void atomisp_css_set_xnr_config(struct atomisp_sub_device
*asd
,
3599 struct atomisp_css_xnr_config
*xnr_config
)
3601 asd
->params
.config
.xnr_config
= xnr_config
;
3604 void atomisp_css_set_yuv2rgb_cc_config(struct atomisp_sub_device
*asd
,
3605 struct atomisp_css_cc_config
*yuv2rgb_cc_config
)
3607 asd
->params
.config
.yuv2rgb_cc_config
= yuv2rgb_cc_config
;
3610 void atomisp_css_set_rgb2yuv_cc_config(struct atomisp_sub_device
*asd
,
3611 struct atomisp_css_cc_config
*rgb2yuv_cc_config
)
3613 asd
->params
.config
.rgb2yuv_cc_config
= rgb2yuv_cc_config
;
3616 void atomisp_css_set_xnr_table(struct atomisp_sub_device
*asd
,
3617 struct atomisp_css_xnr_table
*xnr_table
)
3619 asd
->params
.config
.xnr_table
= xnr_table
;
3622 void atomisp_css_set_r_gamma_table(struct atomisp_sub_device
*asd
,
3623 struct atomisp_css_rgb_gamma_table
*r_gamma_table
)
3625 asd
->params
.config
.r_gamma_table
= r_gamma_table
;
3628 void atomisp_css_set_g_gamma_table(struct atomisp_sub_device
*asd
,
3629 struct atomisp_css_rgb_gamma_table
*g_gamma_table
)
3631 asd
->params
.config
.g_gamma_table
= g_gamma_table
;
3634 void atomisp_css_set_b_gamma_table(struct atomisp_sub_device
*asd
,
3635 struct atomisp_css_rgb_gamma_table
*b_gamma_table
)
3637 asd
->params
.config
.b_gamma_table
= b_gamma_table
;
3640 void atomisp_css_set_gamma_table(struct atomisp_sub_device
*asd
,
3641 struct atomisp_css_gamma_table
*gamma_table
)
3643 asd
->params
.config
.gamma_table
= gamma_table
;
3646 void atomisp_css_set_ctc_table(struct atomisp_sub_device
*asd
,
3647 struct atomisp_css_ctc_table
*ctc_table
)
3650 uint16_t *vamem_ptr
= ctc_table
->data
.vamem_1
;
3651 int data_size
= IA_CSS_VAMEM_1_CTC_TABLE_SIZE
;
3654 /* workaround: if ctc_table is all 0, do not apply it */
3655 if (ctc_table
->vamem_type
== IA_CSS_VAMEM_TYPE_2
) {
3656 vamem_ptr
= ctc_table
->data
.vamem_2
;
3657 data_size
= IA_CSS_VAMEM_2_CTC_TABLE_SIZE
;
3660 for (i
= 0; i
< data_size
; i
++) {
3661 if (*(vamem_ptr
+ i
)) {
3668 asd
->params
.config
.ctc_table
= ctc_table
;
3670 dev_warn(asd
->isp
->dev
, "Bypass the invalid ctc_table.\n");
3673 void atomisp_css_set_anr_thres(struct atomisp_sub_device
*asd
,
3674 struct atomisp_css_anr_thres
*anr_thres
)
3676 asd
->params
.config
.anr_thres
= anr_thres
;
3679 void atomisp_css_set_dvs_6axis(struct atomisp_sub_device
*asd
,
3680 struct atomisp_css_dvs_6axis
*dvs_6axis
)
3682 asd
->params
.config
.dvs_6axis_config
= dvs_6axis
;
3685 void atomisp_css_set_gc_config(struct atomisp_sub_device
*asd
,
3686 struct atomisp_css_gc_config
*gc_config
)
3688 asd
->params
.config
.gc_config
= gc_config
;
3691 void atomisp_css_set_3a_config(struct atomisp_sub_device
*asd
,
3692 struct atomisp_css_3a_config
*s3a_config
)
3694 asd
->params
.config
.s3a_config
= s3a_config
;
3697 void atomisp_css_video_set_dis_vector(struct atomisp_sub_device
*asd
,
3698 struct atomisp_dis_vector
*vector
)
3700 if (!asd
->params
.config
.motion_vector
)
3701 asd
->params
.config
.motion_vector
= &asd
->params
.css_param
.motion_vector
;
3703 memset(asd
->params
.config
.motion_vector
,
3704 0, sizeof(struct ia_css_vector
));
3705 asd
->params
.css_param
.motion_vector
.x
= vector
->x
;
3706 asd
->params
.css_param
.motion_vector
.y
= vector
->y
;
3709 static int atomisp_compare_dvs_grid(struct atomisp_sub_device
*asd
,
3710 struct atomisp_dvs_grid_info
*atomgrid
)
3712 struct atomisp_css_dvs_grid_info
*cur
=
3713 atomisp_css_get_dvs_grid_info(&asd
->params
.curr_grid_info
);
3716 dev_err(asd
->isp
->dev
, "dvs grid not available!\n");
3720 if (sizeof(*cur
) != sizeof(*atomgrid
)) {
3721 dev_err(asd
->isp
->dev
, "dvs grid mis-match!\n");
3726 dev_err(asd
->isp
->dev
, "dvs not enabled!\n");
3730 return memcmp(atomgrid
, cur
, sizeof(*cur
));
3733 void atomisp_css_set_dvs2_coefs(struct atomisp_sub_device
*asd
,
3734 struct ia_css_dvs2_coefficients
*coefs
)
3736 asd
->params
.config
.dvs2_coefs
= coefs
;
3739 int atomisp_css_set_dis_coefs(struct atomisp_sub_device
*asd
,
3740 struct atomisp_dis_coefficients
*coefs
)
3742 if (atomisp_compare_dvs_grid(asd
, &coefs
->grid_info
) != 0)
3743 /* If the grid info in the argument differs from the current
3744 grid info, we tell the caller to reset the grid size and
3748 if (coefs
->hor_coefs
.odd_real
== NULL
||
3749 coefs
->hor_coefs
.odd_imag
== NULL
||
3750 coefs
->hor_coefs
.even_real
== NULL
||
3751 coefs
->hor_coefs
.even_imag
== NULL
||
3752 coefs
->ver_coefs
.odd_real
== NULL
||
3753 coefs
->ver_coefs
.odd_imag
== NULL
||
3754 coefs
->ver_coefs
.even_real
== NULL
||
3755 coefs
->ver_coefs
.even_imag
== NULL
||
3756 asd
->params
.css_param
.dvs2_coeff
->hor_coefs
.odd_real
== NULL
||
3757 asd
->params
.css_param
.dvs2_coeff
->hor_coefs
.odd_imag
== NULL
||
3758 asd
->params
.css_param
.dvs2_coeff
->hor_coefs
.even_real
== NULL
||
3759 asd
->params
.css_param
.dvs2_coeff
->hor_coefs
.even_imag
== NULL
||
3760 asd
->params
.css_param
.dvs2_coeff
->ver_coefs
.odd_real
== NULL
||
3761 asd
->params
.css_param
.dvs2_coeff
->ver_coefs
.odd_imag
== NULL
||
3762 asd
->params
.css_param
.dvs2_coeff
->ver_coefs
.even_real
== NULL
||
3763 asd
->params
.css_param
.dvs2_coeff
->ver_coefs
.even_imag
== NULL
)
3766 if (copy_from_user(asd
->params
.css_param
.dvs2_coeff
->hor_coefs
.odd_real
,
3767 coefs
->hor_coefs
.odd_real
, asd
->params
.dvs_hor_coef_bytes
))
3769 if (copy_from_user(asd
->params
.css_param
.dvs2_coeff
->hor_coefs
.odd_imag
,
3770 coefs
->hor_coefs
.odd_imag
, asd
->params
.dvs_hor_coef_bytes
))
3772 if (copy_from_user(asd
->params
.css_param
.dvs2_coeff
->hor_coefs
.even_real
,
3773 coefs
->hor_coefs
.even_real
, asd
->params
.dvs_hor_coef_bytes
))
3775 if (copy_from_user(asd
->params
.css_param
.dvs2_coeff
->hor_coefs
.even_imag
,
3776 coefs
->hor_coefs
.even_imag
, asd
->params
.dvs_hor_coef_bytes
))
3779 if (copy_from_user(asd
->params
.css_param
.dvs2_coeff
->ver_coefs
.odd_real
,
3780 coefs
->ver_coefs
.odd_real
, asd
->params
.dvs_ver_coef_bytes
))
3782 if (copy_from_user(asd
->params
.css_param
.dvs2_coeff
->ver_coefs
.odd_imag
,
3783 coefs
->ver_coefs
.odd_imag
, asd
->params
.dvs_ver_coef_bytes
))
3785 if (copy_from_user(asd
->params
.css_param
.dvs2_coeff
->ver_coefs
.even_real
,
3786 coefs
->ver_coefs
.even_real
, asd
->params
.dvs_ver_coef_bytes
))
3788 if (copy_from_user(asd
->params
.css_param
.dvs2_coeff
->ver_coefs
.even_imag
,
3789 coefs
->ver_coefs
.even_imag
, asd
->params
.dvs_ver_coef_bytes
))
3792 asd
->params
.css_param
.update_flag
.dvs2_coefs
=
3793 (struct atomisp_dvs2_coefficients
*)
3794 asd
->params
.css_param
.dvs2_coeff
;
3796 /* asd->params.dis_proj_data_valid = false; */
3797 asd
->params
.css_update_params_needed
= true;
3802 void atomisp_css_set_zoom_factor(struct atomisp_sub_device
*asd
,
3805 struct atomisp_device
*isp
= asd
->isp
;
3807 if (zoom
== asd
->params
.css_param
.dz_config
.dx
&&
3808 zoom
== asd
->params
.css_param
.dz_config
.dy
) {
3809 dev_dbg(isp
->dev
, "same zoom scale. skipped.\n");
3813 memset(&asd
->params
.css_param
.dz_config
, 0,
3814 sizeof(struct ia_css_dz_config
));
3815 asd
->params
.css_param
.dz_config
.dx
= zoom
;
3816 asd
->params
.css_param
.dz_config
.dy
= zoom
;
3818 asd
->params
.css_param
.update_flag
.dz_config
=
3819 (struct atomisp_dz_config
*) &asd
->params
.css_param
.dz_config
;
3820 asd
->params
.css_update_params_needed
= true;
3823 void atomisp_css_set_formats_config(struct atomisp_sub_device
*asd
,
3824 struct atomisp_css_formats_config
*formats_config
)
3826 asd
->params
.config
.formats_config
= formats_config
;
3829 int atomisp_css_get_wb_config(struct atomisp_sub_device
*asd
,
3830 struct atomisp_wb_config
*config
)
3832 struct atomisp_css_wb_config wb_config
;
3833 struct ia_css_isp_config isp_config
;
3834 struct atomisp_device
*isp
= asd
->isp
;
3836 if (!asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
) {
3837 dev_err(isp
->dev
, "%s called after streamoff, skipping.\n",
3841 memset(&wb_config
, 0, sizeof(struct atomisp_css_wb_config
));
3842 memset(&isp_config
, 0, sizeof(struct ia_css_isp_config
));
3843 isp_config
.wb_config
= &wb_config
;
3844 ia_css_stream_get_isp_config(
3845 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
,
3847 memcpy(config
, &wb_config
, sizeof(*config
));
3852 int atomisp_css_get_ob_config(struct atomisp_sub_device
*asd
,
3853 struct atomisp_ob_config
*config
)
3855 struct atomisp_css_ob_config ob_config
;
3856 struct ia_css_isp_config isp_config
;
3857 struct atomisp_device
*isp
= asd
->isp
;
3859 if (!asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
) {
3860 dev_err(isp
->dev
, "%s called after streamoff, skipping.\n",
3864 memset(&ob_config
, 0, sizeof(struct atomisp_css_ob_config
));
3865 memset(&isp_config
, 0, sizeof(struct ia_css_isp_config
));
3866 isp_config
.ob_config
= &ob_config
;
3867 ia_css_stream_get_isp_config(
3868 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
,
3870 memcpy(config
, &ob_config
, sizeof(*config
));
3875 int atomisp_css_get_dp_config(struct atomisp_sub_device
*asd
,
3876 struct atomisp_dp_config
*config
)
3878 struct atomisp_css_dp_config dp_config
;
3879 struct ia_css_isp_config isp_config
;
3880 struct atomisp_device
*isp
= asd
->isp
;
3882 if (!asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
) {
3883 dev_err(isp
->dev
, "%s called after streamoff, skipping.\n",
3887 memset(&dp_config
, 0, sizeof(struct atomisp_css_dp_config
));
3888 memset(&isp_config
, 0, sizeof(struct ia_css_isp_config
));
3889 isp_config
.dp_config
= &dp_config
;
3890 ia_css_stream_get_isp_config(
3891 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
,
3893 memcpy(config
, &dp_config
, sizeof(*config
));
3898 int atomisp_css_get_de_config(struct atomisp_sub_device
*asd
,
3899 struct atomisp_de_config
*config
)
3901 struct atomisp_css_de_config de_config
;
3902 struct ia_css_isp_config isp_config
;
3903 struct atomisp_device
*isp
= asd
->isp
;
3905 if (!asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
) {
3906 dev_err(isp
->dev
, "%s called after streamoff, skipping.\n",
3910 memset(&de_config
, 0, sizeof(struct atomisp_css_de_config
));
3911 memset(&isp_config
, 0, sizeof(struct ia_css_isp_config
));
3912 isp_config
.de_config
= &de_config
;
3913 ia_css_stream_get_isp_config(
3914 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
,
3916 memcpy(config
, &de_config
, sizeof(*config
));
3921 int atomisp_css_get_nr_config(struct atomisp_sub_device
*asd
,
3922 struct atomisp_nr_config
*config
)
3924 struct atomisp_css_nr_config nr_config
;
3925 struct ia_css_isp_config isp_config
;
3926 struct atomisp_device
*isp
= asd
->isp
;
3928 if (!asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
) {
3929 dev_err(isp
->dev
, "%s called after streamoff, skipping.\n",
3933 memset(&nr_config
, 0, sizeof(struct atomisp_css_nr_config
));
3934 memset(&isp_config
, 0, sizeof(struct ia_css_isp_config
));
3936 isp_config
.nr_config
= &nr_config
;
3937 ia_css_stream_get_isp_config(
3938 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
,
3940 memcpy(config
, &nr_config
, sizeof(*config
));
3945 int atomisp_css_get_ee_config(struct atomisp_sub_device
*asd
,
3946 struct atomisp_ee_config
*config
)
3948 struct atomisp_css_ee_config ee_config
;
3949 struct ia_css_isp_config isp_config
;
3950 struct atomisp_device
*isp
= asd
->isp
;
3952 if (!asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
) {
3953 dev_err(isp
->dev
, "%s called after streamoff, skipping.\n",
3957 memset(&ee_config
, 0, sizeof(struct atomisp_css_ee_config
));
3958 memset(&isp_config
, 0, sizeof(struct ia_css_isp_config
));
3959 isp_config
.ee_config
= &ee_config
;
3960 ia_css_stream_get_isp_config(
3961 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
,
3963 memcpy(config
, &ee_config
, sizeof(*config
));
3968 int atomisp_css_get_tnr_config(struct atomisp_sub_device
*asd
,
3969 struct atomisp_tnr_config
*config
)
3971 struct atomisp_css_tnr_config tnr_config
;
3972 struct ia_css_isp_config isp_config
;
3973 struct atomisp_device
*isp
= asd
->isp
;
3975 if (!asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
) {
3976 dev_err(isp
->dev
, "%s called after streamoff, skipping.\n",
3980 memset(&tnr_config
, 0, sizeof(struct atomisp_css_tnr_config
));
3981 memset(&isp_config
, 0, sizeof(struct ia_css_isp_config
));
3982 isp_config
.tnr_config
= &tnr_config
;
3983 ia_css_stream_get_isp_config(
3984 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
,
3986 memcpy(config
, &tnr_config
, sizeof(*config
));
3991 int atomisp_css_get_ctc_table(struct atomisp_sub_device
*asd
,
3992 struct atomisp_ctc_table
*config
)
3994 struct atomisp_css_ctc_table
*tab
;
3995 struct ia_css_isp_config isp_config
;
3996 struct atomisp_device
*isp
= asd
->isp
;
3998 if (!asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
) {
3999 dev_err(isp
->dev
, "%s called after streamoff, skipping.\n",
4004 tab
= vzalloc(sizeof(struct atomisp_css_ctc_table
));
4008 memset(&isp_config
, 0, sizeof(struct ia_css_isp_config
));
4009 isp_config
.ctc_table
= tab
;
4010 ia_css_stream_get_isp_config(
4011 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
,
4013 memcpy(config
, tab
, sizeof(*tab
));
4019 int atomisp_css_get_gamma_table(struct atomisp_sub_device
*asd
,
4020 struct atomisp_gamma_table
*config
)
4022 struct atomisp_css_gamma_table
*tab
;
4023 struct ia_css_isp_config isp_config
;
4024 struct atomisp_device
*isp
= asd
->isp
;
4026 if (!asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
) {
4027 dev_err(isp
->dev
, "%s called after streamoff, skipping.\n",
4032 tab
= vzalloc(sizeof(struct atomisp_css_gamma_table
));
4036 memset(&isp_config
, 0, sizeof(struct ia_css_isp_config
));
4037 isp_config
.gamma_table
= tab
;
4038 ia_css_stream_get_isp_config(
4039 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
,
4041 memcpy(config
, tab
, sizeof(*tab
));
4047 int atomisp_css_get_gc_config(struct atomisp_sub_device
*asd
,
4048 struct atomisp_gc_config
*config
)
4050 struct atomisp_css_gc_config gc_config
;
4051 struct ia_css_isp_config isp_config
;
4052 struct atomisp_device
*isp
= asd
->isp
;
4054 if (!asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
) {
4055 dev_err(isp
->dev
, "%s called after streamoff, skipping.\n",
4059 memset(&gc_config
, 0, sizeof(struct atomisp_css_gc_config
));
4060 memset(&isp_config
, 0, sizeof(struct ia_css_isp_config
));
4061 isp_config
.gc_config
= &gc_config
;
4062 ia_css_stream_get_isp_config(
4063 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
,
4065 /* Get gamma correction params from current setup */
4066 memcpy(config
, &gc_config
, sizeof(*config
));
4071 int atomisp_css_get_3a_config(struct atomisp_sub_device
*asd
,
4072 struct atomisp_3a_config
*config
)
4074 struct atomisp_css_3a_config s3a_config
;
4075 struct ia_css_isp_config isp_config
;
4076 struct atomisp_device
*isp
= asd
->isp
;
4078 if (!asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
) {
4079 dev_err(isp
->dev
, "%s called after streamoff, skipping.\n",
4083 memset(&s3a_config
, 0, sizeof(struct atomisp_css_3a_config
));
4084 memset(&isp_config
, 0, sizeof(struct ia_css_isp_config
));
4085 isp_config
.s3a_config
= &s3a_config
;
4086 ia_css_stream_get_isp_config(
4087 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
,
4089 /* Get white balance from current setup */
4090 memcpy(config
, &s3a_config
, sizeof(*config
));
4095 int atomisp_css_get_formats_config(struct atomisp_sub_device
*asd
,
4096 struct atomisp_formats_config
*config
)
4098 struct atomisp_css_formats_config formats_config
;
4099 struct ia_css_isp_config isp_config
;
4100 struct atomisp_device
*isp
= asd
->isp
;
4102 if (!asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
) {
4103 dev_err(isp
->dev
, "%s called after streamoff, skipping.\n",
4107 memset(&formats_config
, 0, sizeof(formats_config
));
4108 memset(&isp_config
, 0, sizeof(isp_config
));
4109 isp_config
.formats_config
= &formats_config
;
4110 ia_css_stream_get_isp_config(
4111 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
,
4113 /* Get narrow gamma from current setup */
4114 memcpy(config
, &formats_config
, sizeof(*config
));
4119 int atomisp_css_get_zoom_factor(struct atomisp_sub_device
*asd
,
4122 struct ia_css_dz_config dz_config
; /**< Digital Zoom */
4123 struct ia_css_isp_config isp_config
;
4124 struct atomisp_device
*isp
= asd
->isp
;
4126 if (!asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
) {
4127 dev_err(isp
->dev
, "%s called after streamoff, skipping.\n",
4131 memset(&dz_config
, 0, sizeof(struct ia_css_dz_config
));
4132 memset(&isp_config
, 0, sizeof(struct ia_css_isp_config
));
4133 isp_config
.dz_config
= &dz_config
;
4134 ia_css_stream_get_isp_config(
4135 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
,
4137 *zoom
= dz_config
.dx
;
4144 * Function to set/get image stablization statistics
4146 int atomisp_css_get_dis_stat(struct atomisp_sub_device
*asd
,
4147 struct atomisp_dis_statistics
*stats
)
4149 struct atomisp_device
*isp
= asd
->isp
;
4150 struct atomisp_dis_buf
*dis_buf
;
4151 unsigned long flags
;
4153 if (asd
->params
.dvs_stat
->hor_prod
.odd_real
== NULL
||
4154 asd
->params
.dvs_stat
->hor_prod
.odd_imag
== NULL
||
4155 asd
->params
.dvs_stat
->hor_prod
.even_real
== NULL
||
4156 asd
->params
.dvs_stat
->hor_prod
.even_imag
== NULL
||
4157 asd
->params
.dvs_stat
->ver_prod
.odd_real
== NULL
||
4158 asd
->params
.dvs_stat
->ver_prod
.odd_imag
== NULL
||
4159 asd
->params
.dvs_stat
->ver_prod
.even_real
== NULL
||
4160 asd
->params
.dvs_stat
->ver_prod
.even_imag
== NULL
)
4163 /* isp needs to be streaming to get DIS statistics */
4164 spin_lock_irqsave(&isp
->lock
, flags
);
4165 if (asd
->streaming
!= ATOMISP_DEVICE_STREAMING_ENABLED
) {
4166 spin_unlock_irqrestore(&isp
->lock
, flags
);
4169 spin_unlock_irqrestore(&isp
->lock
, flags
);
4171 if (atomisp_compare_dvs_grid(asd
, &stats
->dvs2_stat
.grid_info
) != 0)
4172 /* If the grid info in the argument differs from the current
4173 grid info, we tell the caller to reset the grid size and
4177 spin_lock_irqsave(&asd
->dis_stats_lock
, flags
);
4178 if (!asd
->params
.dis_proj_data_valid
|| list_empty(&asd
->dis_stats
)) {
4179 spin_unlock_irqrestore(&asd
->dis_stats_lock
, flags
);
4180 dev_err(isp
->dev
, "dis statistics is not valid.\n");
4184 dis_buf
= list_entry(asd
->dis_stats
.next
,
4185 struct atomisp_dis_buf
, list
);
4186 list_del_init(&dis_buf
->list
);
4187 spin_unlock_irqrestore(&asd
->dis_stats_lock
, flags
);
4189 if (dis_buf
->dvs_map
)
4190 ia_css_translate_dvs2_statistics(
4191 asd
->params
.dvs_stat
, dis_buf
->dvs_map
);
4193 ia_css_get_dvs2_statistics(asd
->params
.dvs_stat
,
4195 stats
->exp_id
= dis_buf
->dis_data
->exp_id
;
4197 spin_lock_irqsave(&asd
->dis_stats_lock
, flags
);
4198 list_add_tail(&dis_buf
->list
, &asd
->dis_stats
);
4199 spin_unlock_irqrestore(&asd
->dis_stats_lock
, flags
);
4201 if (copy_to_user(stats
->dvs2_stat
.ver_prod
.odd_real
,
4202 asd
->params
.dvs_stat
->ver_prod
.odd_real
,
4203 asd
->params
.dvs_ver_proj_bytes
))
4205 if (copy_to_user(stats
->dvs2_stat
.ver_prod
.odd_imag
,
4206 asd
->params
.dvs_stat
->ver_prod
.odd_imag
,
4207 asd
->params
.dvs_ver_proj_bytes
))
4209 if (copy_to_user(stats
->dvs2_stat
.ver_prod
.even_real
,
4210 asd
->params
.dvs_stat
->ver_prod
.even_real
,
4211 asd
->params
.dvs_ver_proj_bytes
))
4213 if (copy_to_user(stats
->dvs2_stat
.ver_prod
.even_imag
,
4214 asd
->params
.dvs_stat
->ver_prod
.even_imag
,
4215 asd
->params
.dvs_ver_proj_bytes
))
4217 if (copy_to_user(stats
->dvs2_stat
.hor_prod
.odd_real
,
4218 asd
->params
.dvs_stat
->hor_prod
.odd_real
,
4219 asd
->params
.dvs_hor_proj_bytes
))
4221 if (copy_to_user(stats
->dvs2_stat
.hor_prod
.odd_imag
,
4222 asd
->params
.dvs_stat
->hor_prod
.odd_imag
,
4223 asd
->params
.dvs_hor_proj_bytes
))
4225 if (copy_to_user(stats
->dvs2_stat
.hor_prod
.even_real
,
4226 asd
->params
.dvs_stat
->hor_prod
.even_real
,
4227 asd
->params
.dvs_hor_proj_bytes
))
4229 if (copy_to_user(stats
->dvs2_stat
.hor_prod
.even_imag
,
4230 asd
->params
.dvs_stat
->hor_prod
.even_imag
,
4231 asd
->params
.dvs_hor_proj_bytes
))
4237 struct atomisp_css_shading_table
*atomisp_css_shading_table_alloc(
4238 unsigned int width
, unsigned int height
)
4240 return ia_css_shading_table_alloc(width
, height
);
4243 void atomisp_css_set_shading_table(struct atomisp_sub_device
*asd
,
4244 struct atomisp_css_shading_table
*table
)
4246 asd
->params
.config
.shading_table
= table
;
4249 void atomisp_css_shading_table_free(struct atomisp_css_shading_table
*table
)
4251 ia_css_shading_table_free(table
);
4254 struct atomisp_css_morph_table
*atomisp_css_morph_table_allocate(
4255 unsigned int width
, unsigned int height
)
4257 return ia_css_morph_table_allocate(width
, height
);
4260 void atomisp_css_set_morph_table(struct atomisp_sub_device
*asd
,
4261 struct atomisp_css_morph_table
*table
)
4263 asd
->params
.config
.morph_table
= table
;
4266 void atomisp_css_get_morph_table(struct atomisp_sub_device
*asd
,
4267 struct atomisp_css_morph_table
*table
)
4269 struct ia_css_isp_config isp_config
;
4270 struct atomisp_device
*isp
= asd
->isp
;
4272 if (!asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
) {
4274 "%s called after streamoff, skipping.\n", __func__
);
4277 memset(table
, 0, sizeof(struct atomisp_css_morph_table
));
4278 memset(&isp_config
, 0, sizeof(struct ia_css_isp_config
));
4279 isp_config
.morph_table
= table
;
4280 ia_css_stream_get_isp_config(
4281 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
,
4285 void atomisp_css_morph_table_free(struct atomisp_css_morph_table
*table
)
4287 ia_css_morph_table_free(table
);
4290 void atomisp_css_set_cont_prev_start_time(struct atomisp_device
*isp
,
4291 unsigned int overlap
)
4293 /* CSS 2.0 doesn't support this API. */
4294 dev_dbg(isp
->dev
, "set cont prev start time is not supported.\n");
4298 void atomisp_css_acc_done(struct atomisp_sub_device
*asd
)
4300 complete(&asd
->acc
.acc_done
);
4303 int atomisp_css_wait_acc_finish(struct atomisp_sub_device
*asd
)
4306 struct atomisp_device
*isp
= asd
->isp
;
4308 /* Unlock the isp mutex taken in IOCTL handler before sleeping! */
4309 rt_mutex_unlock(&isp
->mutex
);
4310 if (wait_for_completion_interruptible_timeout(&asd
->acc
.acc_done
,
4311 ATOMISP_ISP_TIMEOUT_DURATION
) == 0) {
4312 dev_err(isp
->dev
, "<%s: completion timeout\n", __func__
);
4313 atomisp_css_debug_dump_sp_sw_debug_info();
4314 atomisp_css_debug_dump_debug_info(__func__
);
4317 rt_mutex_lock(&isp
->mutex
);
4322 /* Set the ACC binary arguments */
4323 int atomisp_css_set_acc_parameters(struct atomisp_acc_fw
*acc_fw
)
4327 for (mem
= 0; mem
< ATOMISP_ACC_NR_MEMORY
; mem
++) {
4328 if (acc_fw
->args
[mem
].length
== 0)
4331 ia_css_isp_param_set_css_mem_init(&acc_fw
->fw
->mem_initializers
,
4332 IA_CSS_PARAM_CLASS_PARAM
, mem
,
4333 acc_fw
->args
[mem
].css_ptr
,
4334 acc_fw
->args
[mem
].length
);
4340 /* Load acc binary extension */
4341 int atomisp_css_load_acc_extension(struct atomisp_sub_device
*asd
,
4342 struct atomisp_css_fw_info
*fw
,
4343 enum atomisp_css_pipe_id pipe_id
,
4346 struct atomisp_css_fw_info
**hd
;
4349 hd
= &(asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
]
4350 .pipe_configs
[pipe_id
].acc_extension
);
4355 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
]
4356 .update_pipe
[pipe_id
] = true;
4360 /* Unload acc binary extension */
4361 void atomisp_css_unload_acc_extension(struct atomisp_sub_device
*asd
,
4362 struct atomisp_css_fw_info
*fw
,
4363 enum atomisp_css_pipe_id pipe_id
)
4365 struct atomisp_css_fw_info
**hd
;
4367 hd
= &(asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
]
4368 .pipe_configs
[pipe_id
].acc_extension
);
4369 while (*hd
&& *hd
!= fw
)
4372 dev_err(asd
->isp
->dev
, "did not find acc fw for removal\n");
4378 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
]
4379 .update_pipe
[pipe_id
] = true;
4382 int atomisp_css_create_acc_pipe(struct atomisp_sub_device
*asd
)
4384 struct atomisp_device
*isp
= asd
->isp
;
4385 struct ia_css_pipe_config
*pipe_config
;
4386 struct atomisp_stream_env
*stream_env
=
4387 &asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
];
4389 if (stream_env
->acc_stream
) {
4390 if (stream_env
->acc_stream_state
== CSS_STREAM_STARTED
) {
4391 if (ia_css_stream_stop(stream_env
->acc_stream
)
4392 != IA_CSS_SUCCESS
) {
4393 dev_err(isp
->dev
, "stop acc_stream failed.\n");
4398 if (ia_css_stream_destroy(stream_env
->acc_stream
)
4399 != IA_CSS_SUCCESS
) {
4400 dev_err(isp
->dev
, "destroy acc_stream failed.\n");
4403 stream_env
->acc_stream
= NULL
;
4406 pipe_config
= &stream_env
->pipe_configs
[CSS_PIPE_ID_ACC
];
4407 ia_css_pipe_config_defaults(pipe_config
);
4408 asd
->acc
.acc_stages
= kzalloc(MAX_ACC_STAGES
*
4409 sizeof(void *), GFP_KERNEL
);
4410 if (!asd
->acc
.acc_stages
)
4412 pipe_config
->acc_stages
= asd
->acc
.acc_stages
;
4413 pipe_config
->mode
= IA_CSS_PIPE_MODE_ACC
;
4414 pipe_config
->num_acc_stages
= 0;
4417 * We delay the ACC pipeline creation to atomisp_css_start_acc_pipe,
4418 * because pipe configuration will soon be changed by
4419 * atomisp_css_load_acc_binary()
4424 int atomisp_css_start_acc_pipe(struct atomisp_sub_device
*asd
)
4426 struct atomisp_device
*isp
= asd
->isp
;
4427 struct atomisp_stream_env
*stream_env
=
4428 &asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
];
4429 struct ia_css_pipe_config
*pipe_config
=
4430 &stream_env
->pipe_configs
[IA_CSS_PIPE_ID_ACC
];
4432 if (ia_css_pipe_create(pipe_config
,
4433 &stream_env
->pipes
[IA_CSS_PIPE_ID_ACC
]) != IA_CSS_SUCCESS
) {
4434 dev_err(isp
->dev
, "%s: ia_css_pipe_create failed\n",
4439 memset(&stream_env
->acc_stream_config
, 0,
4440 sizeof(struct ia_css_stream_config
));
4441 if (ia_css_stream_create(&stream_env
->acc_stream_config
, 1,
4442 &stream_env
->pipes
[IA_CSS_PIPE_ID_ACC
],
4443 &stream_env
->acc_stream
) != IA_CSS_SUCCESS
) {
4444 dev_err(isp
->dev
, "%s: create acc_stream error.\n", __func__
);
4447 stream_env
->acc_stream_state
= CSS_STREAM_CREATED
;
4449 init_completion(&asd
->acc
.acc_done
);
4450 asd
->acc
.pipeline
= stream_env
->pipes
[IA_CSS_PIPE_ID_ACC
];
4452 atomisp_freq_scaling(isp
, ATOMISP_DFS_MODE_MAX
, false);
4454 if (ia_css_start_sp() != IA_CSS_SUCCESS
) {
4455 dev_err(isp
->dev
, "start sp error.\n");
4459 if (ia_css_stream_start(stream_env
->acc_stream
)
4460 != IA_CSS_SUCCESS
) {
4461 dev_err(isp
->dev
, "acc_stream start error.\n");
4465 stream_env
->acc_stream_state
= CSS_STREAM_STARTED
;
4469 int atomisp_css_stop_acc_pipe(struct atomisp_sub_device
*asd
)
4471 struct atomisp_stream_env
*stream_env
=
4472 &asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
];
4473 if (stream_env
->acc_stream_state
== CSS_STREAM_STARTED
) {
4474 ia_css_stream_stop(stream_env
->acc_stream
);
4475 stream_env
->acc_stream_state
= CSS_STREAM_STOPPED
;
4480 void atomisp_css_destroy_acc_pipe(struct atomisp_sub_device
*asd
)
4482 struct atomisp_stream_env
*stream_env
=
4483 &asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
];
4484 if (stream_env
->acc_stream
) {
4485 if (ia_css_stream_destroy(stream_env
->acc_stream
)
4487 dev_warn(asd
->isp
->dev
,
4488 "destroy acc_stream failed.\n");
4489 stream_env
->acc_stream
= NULL
;
4492 if (stream_env
->pipes
[IA_CSS_PIPE_ID_ACC
]) {
4493 if (ia_css_pipe_destroy(stream_env
->pipes
[IA_CSS_PIPE_ID_ACC
])
4495 dev_warn(asd
->isp
->dev
,
4496 "destroy ACC pipe failed.\n");
4497 stream_env
->pipes
[IA_CSS_PIPE_ID_ACC
] = NULL
;
4498 stream_env
->update_pipe
[IA_CSS_PIPE_ID_ACC
] = false;
4499 ia_css_pipe_config_defaults(
4500 &stream_env
->pipe_configs
[IA_CSS_PIPE_ID_ACC
]);
4501 ia_css_pipe_extra_config_defaults(
4502 &stream_env
->pipe_extra_configs
[IA_CSS_PIPE_ID_ACC
]);
4504 asd
->acc
.pipeline
= NULL
;
4506 /* css 2.0 API limitation: ia_css_stop_sp() could be only called after
4511 kfree(asd
->acc
.acc_stages
);
4512 asd
->acc
.acc_stages
= NULL
;
4514 atomisp_freq_scaling(asd
->isp
, ATOMISP_DFS_MODE_LOW
, false);
4517 int atomisp_css_load_acc_binary(struct atomisp_sub_device
*asd
,
4518 struct atomisp_css_fw_info
*fw
,
4521 struct ia_css_pipe_config
*pipe_config
=
4522 &asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
]
4523 .pipe_configs
[IA_CSS_PIPE_ID_ACC
];
4525 if (index
>= MAX_ACC_STAGES
) {
4526 dev_dbg(asd
->isp
->dev
, "%s: index(%d) out of range\n",
4531 pipe_config
->acc_stages
[index
] = fw
;
4532 pipe_config
->num_acc_stages
= index
+ 1;
4533 pipe_config
->acc_num_execs
= 1;
4538 static struct atomisp_sub_device
*__get_atomisp_subdev(
4539 struct ia_css_pipe
*css_pipe
,
4540 struct atomisp_device
*isp
,
4541 enum atomisp_input_stream_id
*stream_id
) {
4543 struct atomisp_sub_device
*asd
;
4544 struct atomisp_stream_env
*stream_env
;
4546 for (i
= 0; i
< isp
->num_of_streams
; i
++) {
4548 if (asd
->streaming
== ATOMISP_DEVICE_STREAMING_DISABLED
&&
4551 for (j
= 0; j
< ATOMISP_INPUT_STREAM_NUM
; j
++) {
4552 stream_env
= &asd
->stream_env
[j
];
4553 for (k
= 0; k
< IA_CSS_PIPE_ID_NUM
; k
++) {
4554 if (stream_env
->pipes
[k
] &&
4555 stream_env
->pipes
[k
] == css_pipe
) {
4566 int atomisp_css_isr_thread(struct atomisp_device
*isp
,
4567 bool *frame_done_found
,
4568 bool *css_pipe_done
)
4570 enum atomisp_input_stream_id stream_id
= 0;
4571 struct atomisp_css_event current_event
;
4572 struct atomisp_sub_device
*asd
= &isp
->asd
[0];
4574 bool reset_wdt_timer
[MAX_STREAM_NUM
] = {false};
4578 while (!atomisp_css_dequeue_event(¤t_event
)) {
4579 if (current_event
.event
.type
==
4580 IA_CSS_EVENT_TYPE_FW_ASSERT
) {
4582 * Received FW assertion signal,
4583 * trigger WDT to recover
4585 dev_err(isp
->dev
, "%s: ISP reports FW_ASSERT event! fw_assert_module_id %d fw_assert_line_no %d\n",
4587 current_event
.event
.fw_assert_module_id
,
4588 current_event
.event
.fw_assert_line_no
);
4589 for (i
= 0; i
< isp
->num_of_streams
; i
++)
4590 atomisp_wdt_stop(&isp
->asd
[i
], 0);
4592 atomisp_wdt((unsigned long)isp
);
4594 queue_work(isp
->wdt_work_queue
, &isp
->wdt_work
);
4597 } else if (current_event
.event
.type
== IA_CSS_EVENT_TYPE_FW_WARNING
) {
4598 dev_warn(isp
->dev
, "%s: ISP reports warning, code is %d, exp_id %d\n",
4599 __func__
, current_event
.event
.fw_warning
,
4600 current_event
.event
.exp_id
);
4604 asd
= __get_atomisp_subdev(current_event
.event
.pipe
,
4607 if (current_event
.event
.type
== CSS_EVENT_TIMER
)
4609 "event: Timer event.");
4611 dev_warn(isp
->dev
, "%s:no subdev.event:%d",
4613 current_event
.event
.type
);
4617 atomisp_css_temp_pipe_to_pipe_id(asd
, ¤t_event
);
4618 switch (current_event
.event
.type
) {
4619 case CSS_EVENT_OUTPUT_FRAME_DONE
:
4620 frame_done_found
[asd
->index
] = true;
4621 atomisp_buf_done(asd
, 0, CSS_BUFFER_TYPE_OUTPUT_FRAME
,
4622 current_event
.pipe
, true, stream_id
);
4624 reset_wdt_timer
[asd
->index
] = true; /* ISP running */
4627 case CSS_EVENT_SEC_OUTPUT_FRAME_DONE
:
4628 frame_done_found
[asd
->index
] = true;
4629 atomisp_buf_done(asd
, 0, CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME
,
4630 current_event
.pipe
, true, stream_id
);
4632 reset_wdt_timer
[asd
->index
] = true; /* ISP running */
4635 case CSS_EVENT_3A_STATISTICS_DONE
:
4636 atomisp_buf_done(asd
, 0,
4637 CSS_BUFFER_TYPE_3A_STATISTICS
,
4641 case CSS_EVENT_METADATA_DONE
:
4642 atomisp_buf_done(asd
, 0,
4643 CSS_BUFFER_TYPE_METADATA
,
4647 case CSS_EVENT_VF_OUTPUT_FRAME_DONE
:
4648 atomisp_buf_done(asd
, 0,
4649 CSS_BUFFER_TYPE_VF_OUTPUT_FRAME
,
4650 current_event
.pipe
, true, stream_id
);
4652 reset_wdt_timer
[asd
->index
] = true; /* ISP running */
4655 case CSS_EVENT_SEC_VF_OUTPUT_FRAME_DONE
:
4656 atomisp_buf_done(asd
, 0,
4657 CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME
,
4658 current_event
.pipe
, true, stream_id
);
4660 reset_wdt_timer
[asd
->index
] = true; /* ISP running */
4663 case CSS_EVENT_DIS_STATISTICS_DONE
:
4664 atomisp_buf_done(asd
, 0,
4665 CSS_BUFFER_TYPE_DIS_STATISTICS
,
4669 case CSS_EVENT_PIPELINE_DONE
:
4670 css_pipe_done
[asd
->index
] = true;
4672 case CSS_EVENT_ACC_STAGE_COMPLETE
:
4673 atomisp_acc_done(asd
, current_event
.event
.fw_handle
);
4676 dev_dbg(isp
->dev
, "unhandled css stored event: 0x%x\n",
4677 current_event
.event
.type
);
4682 /* If there are no buffers queued then
4683 * delete wdt timer. */
4684 for (i
= 0; i
< isp
->num_of_streams
; i
++) {
4688 if (asd
->streaming
!= ATOMISP_DEVICE_STREAMING_ENABLED
)
4690 if (!atomisp_buffers_queued(asd
))
4691 atomisp_wdt_stop(asd
, false);
4692 else if (reset_wdt_timer
[i
])
4693 /* SOF irq should not reset wdt timer. */
4694 atomisp_wdt_refresh(asd
,
4695 ATOMISP_WDT_KEEP_CURRENT_DELAY
);
4702 void atomisp_set_stop_timeout(unsigned int timeout
)
4707 bool atomisp_css_valid_sof(struct atomisp_device
*isp
)
4711 /* Loop for each css stream */
4712 for (i
= 0; i
< isp
->num_of_streams
; i
++) {
4713 struct atomisp_sub_device
*asd
= &isp
->asd
[i
];
4714 /* Loop for each css vc stream */
4715 for (j
= 0; j
< ATOMISP_INPUT_STREAM_NUM
; j
++) {
4716 if (asd
->stream_env
[j
].stream
&&
4717 asd
->stream_env
[j
].stream_config
.mode
==
4718 IA_CSS_INPUT_MODE_BUFFERED_SENSOR
)
4726 int atomisp_css_debug_dump_isp_binary(void)
4728 ia_css_debug_dump_isp_binary();
4732 int atomisp_css_dump_sp_raw_copy_linecount(bool reduced
)
4734 sh_css_dump_sp_raw_copy_linecount(reduced
);
4738 int atomisp_css_dump_blob_infor(void)
4740 struct ia_css_blob_descr
*bd
= sh_css_blob_info
;
4741 unsigned i
, nm
= sh_css_num_binaries
;
4748 for (i
= 1; i
< sh_css_num_binaries
; i
++)
4749 dev_dbg(atomisp_dev
, "Num%d binary id is %d, name is %s\n", i
,
4750 bd
[i
-1].header
.info
.isp
.sp
.id
, bd
[i
-1].name
);
4755 void atomisp_css_set_isp_config_id(struct atomisp_sub_device
*asd
,
4756 uint32_t isp_config_id
)
4758 asd
->params
.config
.isp_config_id
= isp_config_id
;
4761 void atomisp_css_set_isp_config_applied_frame(struct atomisp_sub_device
*asd
,
4762 struct atomisp_css_frame
*output_frame
)
4764 asd
->params
.config
.output_frame
= output_frame
;
4767 int atomisp_get_css_dbgfunc(void)
4772 int atomisp_set_css_dbgfunc(struct atomisp_device
*isp
, int opt
)
4776 ret
= __set_css_print_env(isp
, opt
);
4782 void atomisp_en_dz_capt_pipe(struct atomisp_sub_device
*asd
, bool enable
)
4784 ia_css_en_dz_capt_pipe(
4785 asd
->stream_env
[ATOMISP_INPUT_STREAM_GENERAL
].stream
,
4789 struct atomisp_css_dvs_grid_info
*atomisp_css_get_dvs_grid_info(
4790 struct atomisp_css_grid_info
*grid_info
)
4795 #ifdef IA_CSS_DVS_STAT_GRID_INFO_SUPPORTED
4796 return &grid_info
->dvs_grid
.dvs_grid_info
;
4798 return &grid_info
->dvs_grid
;