1 // SPDX-License-Identifier: GPL-2.0
3 * Support for Clovertrail PNW Camera Imaging ISP subsystem.
5 * Copyright (c) 2013 Intel Corporation. All Rights Reserved.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License version
9 * 2 as published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
19 #include <media/videobuf-vmalloc.h>
20 #include <media/v4l2-dev.h>
21 #include <media/v4l2-event.h>
23 #include "mmu/isp_mmu.h"
24 #include "mmu/sh_mmu_mrfld.h"
25 #include "hmm/hmm_bo.h"
28 #include "atomisp_compat.h"
29 #include "atomisp_internal.h"
30 #include "atomisp_cmd.h"
31 #include "atomisp-regs.h"
32 #include "atomisp_fops.h"
33 #include "atomisp_ioctl.h"
35 #include "ia_css_debug.h"
36 #include "ia_css_isp_param.h"
37 #include "sh_css_hrt.h"
38 #include "ia_css_isys.h"
41 #include <linux/pm_runtime.h>
43 /* Assume max number of ACC stages */
44 #define MAX_ACC_STAGES 20
46 /* Ideally, this should come from CSS headers */
50 * to serialize MMIO access , this is due to ISP2400 silicon issue Sighting
51 * #4684168, if concurrency access happened, system may hard hang.
53 static DEFINE_SPINLOCK(mmio_lock);
55 enum frame_info_type {
57 ATOMISP_CSS_SECOND_VF_FRAME,
58 ATOMISP_CSS_OUTPUT_FRAME,
59 ATOMISP_CSS_SECOND_OUTPUT_FRAME,
60 ATOMISP_CSS_RAW_FRAME,
63 struct bayer_ds_factor {
64 unsigned int numerator;
65 unsigned int denominator;
68 static void atomisp_css2_hw_store_8(hrt_address addr, uint8_t data)
70 struct atomisp_device *isp = dev_get_drvdata(atomisp_dev);
73 spin_lock_irqsave(&mmio_lock, flags);
74 writeb(data, isp->base + (addr & 0x003FFFFF));
75 spin_unlock_irqrestore(&mmio_lock, flags);
78 static void atomisp_css2_hw_store_16(hrt_address addr, uint16_t data)
80 struct atomisp_device *isp = dev_get_drvdata(atomisp_dev);
83 spin_lock_irqsave(&mmio_lock, flags);
84 writew(data, isp->base + (addr & 0x003FFFFF));
85 spin_unlock_irqrestore(&mmio_lock, flags);
88 void atomisp_css2_hw_store_32(hrt_address addr, uint32_t data)
90 struct atomisp_device *isp = dev_get_drvdata(atomisp_dev);
93 spin_lock_irqsave(&mmio_lock, flags);
94 writel(data, isp->base + (addr & 0x003FFFFF));
95 spin_unlock_irqrestore(&mmio_lock, flags);
98 static uint8_t atomisp_css2_hw_load_8(hrt_address addr)
100 struct atomisp_device *isp = dev_get_drvdata(atomisp_dev);
104 spin_lock_irqsave(&mmio_lock, flags);
105 ret = readb(isp->base + (addr & 0x003FFFFF));
106 spin_unlock_irqrestore(&mmio_lock, flags);
110 static uint16_t atomisp_css2_hw_load_16(hrt_address addr)
112 struct atomisp_device *isp = dev_get_drvdata(atomisp_dev);
116 spin_lock_irqsave(&mmio_lock, flags);
117 ret = readw(isp->base + (addr & 0x003FFFFF));
118 spin_unlock_irqrestore(&mmio_lock, flags);
122 static uint32_t atomisp_css2_hw_load_32(hrt_address addr)
124 struct atomisp_device *isp = dev_get_drvdata(atomisp_dev);
128 spin_lock_irqsave(&mmio_lock, flags);
129 ret = readl(isp->base + (addr & 0x003FFFFF));
130 spin_unlock_irqrestore(&mmio_lock, flags);
134 static void atomisp_css2_hw_store(hrt_address addr, const void *from, uint32_t n)
136 struct atomisp_device *isp = dev_get_drvdata(atomisp_dev);
141 spin_lock_irqsave(&mmio_lock, flags);
142 for (i = 0; i < n; i++, from++)
143 writeb(*(s8 *)from, isp->base + addr + i);
145 spin_unlock_irqrestore(&mmio_lock, flags);
148 static void atomisp_css2_hw_load(hrt_address addr, void *to, uint32_t n)
150 struct atomisp_device *isp = dev_get_drvdata(atomisp_dev);
155 spin_lock_irqsave(&mmio_lock, flags);
156 for (i = 0; i < n; i++, to++)
157 *(s8 *)to = readb(isp->base + addr + i);
158 spin_unlock_irqrestore(&mmio_lock, flags);
161 static int __printf(1, 0) atomisp_vprintk(const char *fmt, va_list args)
167 void atomisp_load_uint32(hrt_address addr, uint32_t *data)
169 *data = atomisp_css2_hw_load_32(addr);
172 static int hmm_get_mmu_base_addr(struct device *dev, unsigned int *mmu_base_addr)
174 if (!sh_mmu_mrfld.get_pd_base) {
175 dev_err(dev, "get mmu base address failed.\n");
179 *mmu_base_addr = sh_mmu_mrfld.get_pd_base(&bo_device.mmu,
180 bo_device.mmu.base_address);
184 static void __dump_pipe_config(struct atomisp_sub_device *asd,
185 struct atomisp_stream_env *stream_env,
186 unsigned int pipe_id)
188 struct atomisp_device *isp = asd->isp;
190 if (stream_env->pipes[pipe_id]) {
191 struct ia_css_pipe_config *p_config;
192 struct ia_css_pipe_extra_config *pe_config;
194 p_config = &stream_env->pipe_configs[pipe_id];
195 pe_config = &stream_env->pipe_extra_configs[pipe_id];
196 dev_dbg(isp->dev, "dumping pipe[%d] config:\n", pipe_id);
198 "pipe_config.pipe_mode:%d.\n", p_config->mode);
200 "pipe_config.output_info[0] w=%d, h=%d.\n",
201 p_config->output_info[0].res.width,
202 p_config->output_info[0].res.height);
204 "pipe_config.vf_pp_in_res w=%d, h=%d.\n",
205 p_config->vf_pp_in_res.width,
206 p_config->vf_pp_in_res.height);
208 "pipe_config.capt_pp_in_res w=%d, h=%d.\n",
209 p_config->capt_pp_in_res.width,
210 p_config->capt_pp_in_res.height);
212 "pipe_config.output.padded w=%d.\n",
213 p_config->output_info[0].padded_width);
215 "pipe_config.vf_output_info[0] w=%d, h=%d.\n",
216 p_config->vf_output_info[0].res.width,
217 p_config->vf_output_info[0].res.height);
219 "pipe_config.bayer_ds_out_res w=%d, h=%d.\n",
220 p_config->bayer_ds_out_res.width,
221 p_config->bayer_ds_out_res.height);
223 "pipe_config.envelope w=%d, h=%d.\n",
224 p_config->dvs_envelope.width,
225 p_config->dvs_envelope.height);
227 "pipe_config.dvs_frame_delay=%d.\n",
228 p_config->dvs_frame_delay);
230 "pipe_config.isp_pipe_version:%d.\n",
231 p_config->isp_pipe_version);
233 "pipe_config.default_capture_config.capture_mode=%d.\n",
234 p_config->default_capture_config.mode);
236 "pipe_config.enable_dz=%d.\n",
237 p_config->enable_dz);
239 "pipe_config.default_capture_config.enable_xnr=%d.\n",
240 p_config->default_capture_config.enable_xnr);
242 "dumping pipe[%d] extra config:\n", pipe_id);
244 "pipe_extra_config.enable_raw_binning:%d.\n",
245 pe_config->enable_raw_binning);
247 "pipe_extra_config.enable_yuv_ds:%d.\n",
248 pe_config->enable_yuv_ds);
250 "pipe_extra_config.enable_high_speed:%d.\n",
251 pe_config->enable_high_speed);
253 "pipe_extra_config.enable_dvs_6axis:%d.\n",
254 pe_config->enable_dvs_6axis);
256 "pipe_extra_config.enable_reduced_pipe:%d.\n",
257 pe_config->enable_reduced_pipe);
259 "pipe_(extra_)config.enable_dz:%d.\n",
260 p_config->enable_dz);
262 "pipe_extra_config.disable_vf_pp:%d.\n",
263 pe_config->disable_vf_pp);
267 static void __dump_stream_config(struct atomisp_sub_device *asd,
268 struct atomisp_stream_env *stream_env)
270 struct atomisp_device *isp = asd->isp;
271 struct ia_css_stream_config *s_config;
273 bool valid_stream = false;
275 for (j = 0; j < IA_CSS_PIPE_ID_NUM; j++) {
276 if (stream_env->pipes[j]) {
277 __dump_pipe_config(asd, stream_env, j);
283 s_config = &stream_env->stream_config;
284 dev_dbg(isp->dev, "stream_config.mode=%d.\n", s_config->mode);
286 if (s_config->mode == IA_CSS_INPUT_MODE_SENSOR ||
287 s_config->mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR) {
288 dev_dbg(isp->dev, "stream_config.source.port.port=%d.\n",
289 s_config->source.port.port);
290 dev_dbg(isp->dev, "stream_config.source.port.num_lanes=%d.\n",
291 s_config->source.port.num_lanes);
292 dev_dbg(isp->dev, "stream_config.source.port.timeout=%d.\n",
293 s_config->source.port.timeout);
294 dev_dbg(isp->dev, "stream_config.source.port.rxcount=0x%x.\n",
295 s_config->source.port.rxcount);
296 dev_dbg(isp->dev, "stream_config.source.port.compression.type=%d.\n",
297 s_config->source.port.compression.type);
299 "stream_config.source.port.compression.compressed_bits_per_pixel=%d.\n",
300 s_config->source.port.compression.
301 compressed_bits_per_pixel);
303 "stream_config.source.port.compression.uncompressed_bits_per_pixel=%d.\n",
304 s_config->source.port.compression.
305 uncompressed_bits_per_pixel);
306 } else if (s_config->mode == IA_CSS_INPUT_MODE_TPG) {
307 dev_dbg(isp->dev, "stream_config.source.tpg.id=%d.\n",
308 s_config->source.tpg.id);
309 dev_dbg(isp->dev, "stream_config.source.tpg.mode=%d.\n",
310 s_config->source.tpg.mode);
311 dev_dbg(isp->dev, "stream_config.source.tpg.x_mask=%d.\n",
312 s_config->source.tpg.x_mask);
313 dev_dbg(isp->dev, "stream_config.source.tpg.x_delta=%d.\n",
314 s_config->source.tpg.x_delta);
315 dev_dbg(isp->dev, "stream_config.source.tpg.y_mask=%d.\n",
316 s_config->source.tpg.y_mask);
317 dev_dbg(isp->dev, "stream_config.source.tpg.y_delta=%d.\n",
318 s_config->source.tpg.y_delta);
319 dev_dbg(isp->dev, "stream_config.source.tpg.xy_mask=%d.\n",
320 s_config->source.tpg.xy_mask);
321 } else if (s_config->mode == IA_CSS_INPUT_MODE_PRBS) {
322 dev_dbg(isp->dev, "stream_config.source.prbs.id=%d.\n",
323 s_config->source.prbs.id);
324 dev_dbg(isp->dev, "stream_config.source.prbs.h_blank=%d.\n",
325 s_config->source.prbs.h_blank);
326 dev_dbg(isp->dev, "stream_config.source.prbs.v_blank=%d.\n",
327 s_config->source.prbs.v_blank);
328 dev_dbg(isp->dev, "stream_config.source.prbs.seed=%d.\n",
329 s_config->source.prbs.seed);
330 dev_dbg(isp->dev, "stream_config.source.prbs.seed1=%d.\n",
331 s_config->source.prbs.seed1);
334 for (j = 0; j < IA_CSS_STREAM_MAX_ISYS_STREAM_PER_CH; j++) {
335 dev_dbg(isp->dev, "stream_configisys_config[%d].input_res w=%d, h=%d.\n",
337 s_config->isys_config[j].input_res.width,
338 s_config->isys_config[j].input_res.height);
340 dev_dbg(isp->dev, "stream_configisys_config[%d].linked_isys_stream_id=%d\n",
342 s_config->isys_config[j].linked_isys_stream_id);
344 dev_dbg(isp->dev, "stream_configisys_config[%d].format=%d\n",
346 s_config->isys_config[j].format);
348 dev_dbg(isp->dev, "stream_configisys_config[%d].valid=%d.\n",
350 s_config->isys_config[j].valid);
353 dev_dbg(isp->dev, "stream_config.input_config.input_res w=%d, h=%d.\n",
354 s_config->input_config.input_res.width,
355 s_config->input_config.input_res.height);
357 dev_dbg(isp->dev, "stream_config.input_config.effective_res w=%d, h=%d.\n",
358 s_config->input_config.effective_res.width,
359 s_config->input_config.effective_res.height);
361 dev_dbg(isp->dev, "stream_config.input_config.format=%d\n",
362 s_config->input_config.format);
364 dev_dbg(isp->dev, "stream_config.input_config.bayer_order=%d.\n",
365 s_config->input_config.bayer_order);
367 dev_dbg(isp->dev, "stream_config.pixels_per_clock=%d.\n",
368 s_config->pixels_per_clock);
369 dev_dbg(isp->dev, "stream_config.online=%d.\n", s_config->online);
370 dev_dbg(isp->dev, "stream_config.continuous=%d.\n",
371 s_config->continuous);
372 dev_dbg(isp->dev, "stream_config.disable_cont_viewfinder=%d.\n",
373 s_config->disable_cont_viewfinder);
374 dev_dbg(isp->dev, "stream_config.channel_id=%d.\n",
375 s_config->channel_id);
376 dev_dbg(isp->dev, "stream_config.init_num_cont_raw_buf=%d.\n",
377 s_config->init_num_cont_raw_buf);
378 dev_dbg(isp->dev, "stream_config.target_num_cont_raw_buf=%d.\n",
379 s_config->target_num_cont_raw_buf);
380 dev_dbg(isp->dev, "stream_config.left_padding=%d.\n",
381 s_config->left_padding);
382 dev_dbg(isp->dev, "stream_config.sensor_binning_factor=%d.\n",
383 s_config->sensor_binning_factor);
384 dev_dbg(isp->dev, "stream_config.pixels_per_clock=%d.\n",
385 s_config->pixels_per_clock);
386 dev_dbg(isp->dev, "stream_config.pack_raw_pixels=%d.\n",
387 s_config->pack_raw_pixels);
388 dev_dbg(isp->dev, "stream_config.flash_gpio_pin=%d.\n",
389 s_config->flash_gpio_pin);
390 dev_dbg(isp->dev, "stream_config.mipi_buffer_config.size_mem_words=%d.\n",
391 s_config->mipi_buffer_config.size_mem_words);
392 dev_dbg(isp->dev, "stream_config.mipi_buffer_config.contiguous=%d.\n",
393 s_config->mipi_buffer_config.contiguous);
394 dev_dbg(isp->dev, "stream_config.metadata_config.data_type=%d.\n",
395 s_config->metadata_config.data_type);
396 dev_dbg(isp->dev, "stream_config.metadata_config.resolution w=%d, h=%d.\n",
397 s_config->metadata_config.resolution.width,
398 s_config->metadata_config.resolution.height);
401 static int __destroy_stream(struct atomisp_sub_device *asd,
402 struct atomisp_stream_env *stream_env)
404 struct atomisp_device *isp = asd->isp;
405 unsigned long timeout;
407 if (!stream_env->stream)
410 if (stream_env->stream_state == CSS_STREAM_STARTED
411 && ia_css_stream_stop(stream_env->stream) != 0) {
412 dev_err(isp->dev, "stop stream failed.\n");
416 if (stream_env->stream_state == CSS_STREAM_STARTED) {
417 timeout = jiffies + msecs_to_jiffies(40);
419 if (ia_css_stream_has_stopped(stream_env->stream))
422 if (time_after(jiffies, timeout)) {
423 dev_warn(isp->dev, "stop stream timeout.\n");
427 usleep_range(100, 200);
431 stream_env->stream_state = CSS_STREAM_STOPPED;
433 if (ia_css_stream_destroy(stream_env->stream)) {
434 dev_err(isp->dev, "destroy stream failed.\n");
437 stream_env->stream_state = CSS_STREAM_UNINIT;
438 stream_env->stream = NULL;
443 static int __destroy_streams(struct atomisp_sub_device *asd)
447 for (i = 0; i < ATOMISP_INPUT_STREAM_NUM; i++) {
448 ret = __destroy_stream(asd, &asd->stream_env[i]);
452 asd->stream_prepared = false;
456 static int __create_stream(struct atomisp_sub_device *asd,
457 struct atomisp_stream_env *stream_env)
459 int pipe_index = 0, i;
460 struct ia_css_pipe *multi_pipes[IA_CSS_PIPE_ID_NUM];
462 for (i = 0; i < IA_CSS_PIPE_ID_NUM; i++) {
463 if (stream_env->pipes[i])
464 multi_pipes[pipe_index++] = stream_env->pipes[i];
469 stream_env->stream_config.target_num_cont_raw_buf =
470 asd->continuous_raw_buffer_size->val;
471 stream_env->stream_config.channel_id = stream_env->ch_id;
472 stream_env->stream_config.ia_css_enable_raw_buffer_locking =
473 asd->enable_raw_buffer_lock->val;
475 __dump_stream_config(asd, stream_env);
476 if (ia_css_stream_create(&stream_env->stream_config,
477 pipe_index, multi_pipes, &stream_env->stream) != 0)
479 if (ia_css_stream_get_info(stream_env->stream,
480 &stream_env->stream_info) != 0) {
481 ia_css_stream_destroy(stream_env->stream);
482 stream_env->stream = NULL;
486 stream_env->stream_state = CSS_STREAM_CREATED;
490 static int __create_streams(struct atomisp_sub_device *asd)
494 for (i = 0; i < ATOMISP_INPUT_STREAM_NUM; i++) {
495 ret = __create_stream(asd, &asd->stream_env[i]);
499 asd->stream_prepared = true;
502 for (i--; i >= 0; i--)
503 __destroy_stream(asd, &asd->stream_env[i]);
507 static int __destroy_stream_pipes(struct atomisp_sub_device *asd,
508 struct atomisp_stream_env *stream_env)
510 struct atomisp_device *isp = asd->isp;
514 for (i = 0; i < IA_CSS_PIPE_ID_NUM; i++) {
515 if (!stream_env->pipes[i])
517 if (ia_css_pipe_destroy(stream_env->pipes[i])
520 "destroy pipe[%d]failed.cannot recover.\n", i);
523 stream_env->pipes[i] = NULL;
524 stream_env->update_pipe[i] = false;
529 static int __destroy_pipes(struct atomisp_sub_device *asd)
531 struct atomisp_device *isp = asd->isp;
535 for (i = 0; i < ATOMISP_INPUT_STREAM_NUM; i++) {
536 if (asd->stream_env[i].stream) {
538 "cannot destroy css pipes for stream[%d].\n",
543 ret = __destroy_stream_pipes(asd, &asd->stream_env[i]);
551 void atomisp_destroy_pipes_stream_force(struct atomisp_sub_device *asd)
553 if (__destroy_streams(asd))
554 dev_warn(asd->isp->dev, "destroy stream failed.\n");
556 if (__destroy_pipes(asd))
557 dev_warn(asd->isp->dev, "destroy pipe failed.\n");
560 static void __apply_additional_pipe_config(
561 struct atomisp_sub_device *asd,
562 struct atomisp_stream_env *stream_env,
563 enum ia_css_pipe_id pipe_id)
565 struct atomisp_device *isp = asd->isp;
567 if (pipe_id < 0 || pipe_id >= IA_CSS_PIPE_ID_NUM) {
569 "wrong pipe_id for additional pipe config.\n");
573 /* apply default pipe config */
574 stream_env->pipe_configs[pipe_id].isp_pipe_version = 2;
575 stream_env->pipe_configs[pipe_id].enable_dz =
576 asd->disable_dz->val ? false : true;
577 /* apply isp 2.2 specific config for baytrail*/
579 case IA_CSS_PIPE_ID_CAPTURE:
580 /* enable capture pp/dz manually or digital zoom would
582 if (stream_env->pipe_configs[pipe_id].
583 default_capture_config.mode == IA_CSS_CAPTURE_MODE_RAW)
584 stream_env->pipe_configs[pipe_id].enable_dz = false;
586 case IA_CSS_PIPE_ID_VIDEO:
587 /* enable reduced pipe to have binary
588 * video_dz_2_min selected*/
589 stream_env->pipe_extra_configs[pipe_id]
590 .enable_reduced_pipe = true;
591 stream_env->pipe_configs[pipe_id]
594 if (asd->params.video_dis_en) {
595 stream_env->pipe_extra_configs[pipe_id]
596 .enable_dvs_6axis = true;
597 stream_env->pipe_configs[pipe_id]
599 ATOMISP_CSS2_NUM_DVS_FRAME_DELAY;
602 case IA_CSS_PIPE_ID_PREVIEW:
604 case IA_CSS_PIPE_ID_YUVPP:
605 case IA_CSS_PIPE_ID_COPY:
606 stream_env->pipe_configs[pipe_id].enable_dz = false;
613 static bool is_pipe_valid_to_current_run_mode(struct atomisp_sub_device *asd,
614 enum ia_css_pipe_id pipe_id)
619 if (pipe_id == IA_CSS_PIPE_ID_YUVPP)
623 if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_SCALER) {
624 if (pipe_id == IA_CSS_PIPE_ID_VIDEO)
628 } else if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_LOWLAT) {
629 if (pipe_id == IA_CSS_PIPE_ID_CAPTURE)
639 if (asd->copy_mode && pipe_id == IA_CSS_PIPE_ID_COPY)
642 switch (asd->run_mode->val) {
643 case ATOMISP_RUN_MODE_STILL_CAPTURE:
644 if (pipe_id == IA_CSS_PIPE_ID_CAPTURE)
648 case ATOMISP_RUN_MODE_PREVIEW:
649 if (pipe_id == IA_CSS_PIPE_ID_PREVIEW)
653 case ATOMISP_RUN_MODE_VIDEO:
654 if (pipe_id == IA_CSS_PIPE_ID_VIDEO || pipe_id == IA_CSS_PIPE_ID_YUVPP)
663 static int __create_pipe(struct atomisp_sub_device *asd,
664 struct atomisp_stream_env *stream_env,
665 enum ia_css_pipe_id pipe_id)
667 struct atomisp_device *isp = asd->isp;
668 struct ia_css_pipe_extra_config extra_config;
671 if (pipe_id >= IA_CSS_PIPE_ID_NUM)
674 if (!stream_env->pipe_configs[pipe_id].output_info[0].res.width)
677 if (!is_pipe_valid_to_current_run_mode(asd, pipe_id))
680 ia_css_pipe_extra_config_defaults(&extra_config);
682 __apply_additional_pipe_config(asd, stream_env, pipe_id);
683 if (!memcmp(&extra_config,
684 &stream_env->pipe_extra_configs[pipe_id],
685 sizeof(extra_config)))
686 ret = ia_css_pipe_create(
687 &stream_env->pipe_configs[pipe_id],
688 &stream_env->pipes[pipe_id]);
690 ret = ia_css_pipe_create_extra(
691 &stream_env->pipe_configs[pipe_id],
692 &stream_env->pipe_extra_configs[pipe_id],
693 &stream_env->pipes[pipe_id]);
695 dev_err(isp->dev, "create pipe[%d] error.\n", pipe_id);
699 static int __create_pipes(struct atomisp_sub_device *asd)
704 for (i = 0; i < ATOMISP_INPUT_STREAM_NUM; i++) {
705 for (j = 0; j < IA_CSS_PIPE_ID_NUM; j++) {
706 ret = __create_pipe(asd, &asd->stream_env[i], j);
710 if (j < IA_CSS_PIPE_ID_NUM)
715 for (; i >= 0; i--) {
716 for (j--; j >= 0; j--) {
717 if (asd->stream_env[i].pipes[j]) {
718 ia_css_pipe_destroy(asd->stream_env[i].pipes[j]);
719 asd->stream_env[i].pipes[j] = NULL;
722 j = IA_CSS_PIPE_ID_NUM;
727 int atomisp_create_pipes_stream(struct atomisp_sub_device *asd)
731 ret = __create_pipes(asd);
733 dev_err(asd->isp->dev, "create pipe failed %d.\n", ret);
737 ret = __create_streams(asd);
739 dev_warn(asd->isp->dev, "create stream failed %d.\n", ret);
740 __destroy_pipes(asd);
747 int atomisp_css_update_stream(struct atomisp_sub_device *asd)
749 atomisp_destroy_pipes_stream_force(asd);
750 return atomisp_create_pipes_stream(asd);
753 int atomisp_css_init(struct atomisp_device *isp)
755 unsigned int mmu_base_addr;
759 ret = hmm_get_mmu_base_addr(isp->dev, &mmu_base_addr);
764 err = ia_css_init(isp->dev, &isp->css_env.isp_css_env, NULL,
765 (uint32_t)mmu_base_addr, IA_CSS_IRQ_TYPE_PULSE);
767 dev_err(isp->dev, "css init failed --- bad firmware?\n");
770 ia_css_enable_isys_event_queue(true);
772 isp->css_initialized = true;
773 dev_dbg(isp->dev, "sh_css_init success\n");
778 static inline int __set_css_print_env(struct atomisp_device *isp, int opt)
783 isp->css_env.isp_css_env.print_env.debug_print = NULL;
785 isp->css_env.isp_css_env.print_env.debug_print = atomisp_vprintk;
792 int atomisp_css_load_firmware(struct atomisp_device *isp)
797 isp->css_env.isp_css_fw.data = (void *)isp->firmware->data;
798 isp->css_env.isp_css_fw.bytes = isp->firmware->size;
800 isp->css_env.isp_css_env.hw_access_env.store_8 =
801 atomisp_css2_hw_store_8;
802 isp->css_env.isp_css_env.hw_access_env.store_16 =
803 atomisp_css2_hw_store_16;
804 isp->css_env.isp_css_env.hw_access_env.store_32 =
805 atomisp_css2_hw_store_32;
807 isp->css_env.isp_css_env.hw_access_env.load_8 = atomisp_css2_hw_load_8;
808 isp->css_env.isp_css_env.hw_access_env.load_16 =
809 atomisp_css2_hw_load_16;
810 isp->css_env.isp_css_env.hw_access_env.load_32 =
811 atomisp_css2_hw_load_32;
813 isp->css_env.isp_css_env.hw_access_env.load = atomisp_css2_hw_load;
814 isp->css_env.isp_css_env.hw_access_env.store = atomisp_css2_hw_store;
816 __set_css_print_env(isp, dbg_func);
818 isp->css_env.isp_css_env.print_env.error_print = atomisp_vprintk;
820 /* load isp fw into ISP memory */
821 err = ia_css_load_firmware(isp->dev, &isp->css_env.isp_css_env,
822 &isp->css_env.isp_css_fw);
824 dev_err(isp->dev, "css load fw failed.\n");
831 void atomisp_css_uninit(struct atomisp_device *isp)
833 isp->css_initialized = false;
837 int atomisp_css_irq_translate(struct atomisp_device *isp,
842 err = ia_css_irq_translate(infos);
845 "%s:failed to translate irq (err = %d,infos = %d)\n",
846 __func__, err, *infos);
853 void atomisp_css_rx_get_irq_info(enum mipi_port_id port,
857 ia_css_isys_rx_get_irq_info(port, infos);
863 void atomisp_css_rx_clear_irq_info(enum mipi_port_id port,
867 ia_css_isys_rx_clear_irq_info(port, infos);
871 int atomisp_css_irq_enable(struct atomisp_device *isp,
872 enum ia_css_irq_info info, bool enable)
874 dev_dbg(isp->dev, "%s: css irq info 0x%08x: %s (%d).\n",
876 enable ? "enable" : "disable", enable);
877 if (ia_css_irq_enable(info, enable)) {
878 dev_warn(isp->dev, "%s:Invalid irq info: 0x%08x when %s.\n",
880 enable ? "enabling" : "disabling");
887 void atomisp_css_init_struct(struct atomisp_sub_device *asd)
891 for (i = 0; i < ATOMISP_INPUT_STREAM_NUM; i++) {
892 asd->stream_env[i].stream = NULL;
893 for (j = 0; j < IA_CSS_PIPE_MODE_NUM; j++) {
894 asd->stream_env[i].pipes[j] = NULL;
895 asd->stream_env[i].update_pipe[j] = false;
896 ia_css_pipe_config_defaults(
897 &asd->stream_env[i].pipe_configs[j]);
898 ia_css_pipe_extra_config_defaults(
899 &asd->stream_env[i].pipe_extra_configs[j]);
901 ia_css_stream_config_defaults(&asd->stream_env[i].stream_config);
905 int atomisp_q_video_buffer_to_css(struct atomisp_sub_device *asd,
906 struct ia_css_frame *frame,
907 enum atomisp_input_stream_id stream_id,
908 enum ia_css_buffer_type css_buf_type,
909 enum ia_css_pipe_id css_pipe_id)
911 struct atomisp_stream_env *stream_env = &asd->stream_env[stream_id];
912 struct ia_css_buffer css_buf = {0};
915 css_buf.type = css_buf_type;
916 css_buf.data.frame = frame;
918 err = ia_css_pipe_enqueue_buffer(
919 stream_env->pipes[css_pipe_id], &css_buf);
926 int atomisp_q_metadata_buffer_to_css(struct atomisp_sub_device *asd,
927 struct atomisp_metadata_buf *metadata_buf,
928 enum atomisp_input_stream_id stream_id,
929 enum ia_css_pipe_id css_pipe_id)
931 struct atomisp_stream_env *stream_env = &asd->stream_env[stream_id];
932 struct ia_css_buffer buffer = {0};
933 struct atomisp_device *isp = asd->isp;
935 buffer.type = IA_CSS_BUFFER_TYPE_METADATA;
936 buffer.data.metadata = metadata_buf->metadata;
937 if (ia_css_pipe_enqueue_buffer(stream_env->pipes[css_pipe_id],
939 dev_err(isp->dev, "failed to q meta data buffer\n");
946 int atomisp_q_s3a_buffer_to_css(struct atomisp_sub_device *asd,
947 struct atomisp_s3a_buf *s3a_buf,
948 enum atomisp_input_stream_id stream_id,
949 enum ia_css_pipe_id css_pipe_id)
951 struct atomisp_stream_env *stream_env = &asd->stream_env[stream_id];
952 struct ia_css_buffer buffer = {0};
953 struct atomisp_device *isp = asd->isp;
955 buffer.type = IA_CSS_BUFFER_TYPE_3A_STATISTICS;
956 buffer.data.stats_3a = s3a_buf->s3a_data;
957 if (ia_css_pipe_enqueue_buffer(
958 stream_env->pipes[css_pipe_id],
960 dev_dbg(isp->dev, "failed to q s3a stat buffer\n");
967 int atomisp_q_dis_buffer_to_css(struct atomisp_sub_device *asd,
968 struct atomisp_dis_buf *dis_buf,
969 enum atomisp_input_stream_id stream_id,
970 enum ia_css_pipe_id css_pipe_id)
972 struct atomisp_stream_env *stream_env = &asd->stream_env[stream_id];
973 struct ia_css_buffer buffer = {0};
974 struct atomisp_device *isp = asd->isp;
976 buffer.type = IA_CSS_BUFFER_TYPE_DIS_STATISTICS;
977 buffer.data.stats_dvs = dis_buf->dis_data;
978 if (ia_css_pipe_enqueue_buffer(
979 stream_env->pipes[css_pipe_id],
981 dev_dbg(isp->dev, "failed to q dvs stat buffer\n");
988 int atomisp_css_start(struct atomisp_sub_device *asd,
989 enum ia_css_pipe_id pipe_id, bool in_reset)
991 struct atomisp_device *isp = asd->isp;
992 bool sp_is_started = false;
996 ret = atomisp_css_update_stream(asd);
1000 /* Invalidate caches. FIXME: should flush only necessary buffers */
1004 if (!sh_css_hrt_system_is_idle())
1005 dev_err(isp->dev, "CSS HW not idle before starting SP\n");
1007 if (ia_css_start_sp()) {
1008 dev_err(isp->dev, "start sp error.\n");
1013 sp_is_started = true;
1015 for (i = 0; i < ATOMISP_INPUT_STREAM_NUM; i++) {
1016 if (asd->stream_env[i].stream) {
1017 if (ia_css_stream_start(asd->stream_env[i]
1019 dev_err(isp->dev, "stream[%d] start error.\n", i);
1023 asd->stream_env[i].stream_state = CSS_STREAM_STARTED;
1024 dev_dbg(isp->dev, "stream[%d] started.\n", i);
1033 * CSS 2.0 API limitation: ia_css_stop_sp() can only be called after
1034 * destroying all pipes.
1036 if (sp_is_started) {
1037 atomisp_destroy_pipes_stream_force(asd);
1039 atomisp_create_pipes_stream(asd);
1045 void atomisp_css_update_isp_params(struct atomisp_sub_device *asd)
1049 * for ISP2401 new input system, this api is under development.
1050 * Calling it would cause kernel panic.
1054 * Check if it is Cherry Trail and also new input system
1056 if (asd->copy_mode) {
1057 dev_warn(asd->isp->dev,
1058 "%s: ia_css_stream_set_isp_config() not supported in copy mode!.\n",
1063 ia_css_stream_set_isp_config(
1064 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
1065 &asd->params.config);
1066 memset(&asd->params.config, 0, sizeof(asd->params.config));
1069 void atomisp_css_update_isp_params_on_pipe(struct atomisp_sub_device *asd,
1070 struct ia_css_pipe *pipe)
1075 atomisp_css_update_isp_params(asd);
1079 dev_dbg(asd->isp->dev,
1080 "%s: apply parameter for ia_css_frame %p with isp_config_id %d on pipe %p.\n",
1081 __func__, asd->params.config.output_frame,
1082 asd->params.config.isp_config_id, pipe);
1084 ret = ia_css_stream_set_isp_config_on_pipe(
1085 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
1086 &asd->params.config, pipe);
1088 dev_warn(asd->isp->dev, "%s: ia_css_stream_set_isp_config_on_pipe failed %d\n",
1090 memset(&asd->params.config, 0, sizeof(asd->params.config));
1093 int atomisp_css_queue_buffer(struct atomisp_sub_device *asd,
1094 enum atomisp_input_stream_id stream_id,
1095 enum ia_css_pipe_id pipe_id,
1096 enum ia_css_buffer_type buf_type,
1097 struct atomisp_css_buffer *isp_css_buffer)
1099 if (ia_css_pipe_enqueue_buffer(
1100 asd->stream_env[stream_id].pipes[pipe_id],
1101 &isp_css_buffer->css_buffer)
1108 int atomisp_css_dequeue_buffer(struct atomisp_sub_device *asd,
1109 enum atomisp_input_stream_id stream_id,
1110 enum ia_css_pipe_id pipe_id,
1111 enum ia_css_buffer_type buf_type,
1112 struct atomisp_css_buffer *isp_css_buffer)
1114 struct atomisp_device *isp = asd->isp;
1117 err = ia_css_pipe_dequeue_buffer(
1118 asd->stream_env[stream_id].pipes[pipe_id],
1119 &isp_css_buffer->css_buffer);
1122 "ia_css_pipe_dequeue_buffer failed: 0x%x\n", err);
1129 int atomisp_css_allocate_stat_buffers(struct atomisp_sub_device *asd,
1131 struct atomisp_s3a_buf *s3a_buf,
1132 struct atomisp_dis_buf *dis_buf,
1133 struct atomisp_metadata_buf *md_buf)
1135 struct atomisp_device *isp = asd->isp;
1136 struct ia_css_dvs_grid_info *dvs_grid_info =
1137 atomisp_css_get_dvs_grid_info(&asd->params.curr_grid_info);
1139 if (s3a_buf && asd->params.curr_grid_info.s3a_grid.enable) {
1142 s3a_buf->s3a_data = ia_css_isp_3a_statistics_allocate(
1143 &asd->params.curr_grid_info.s3a_grid);
1144 if (!s3a_buf->s3a_data) {
1145 dev_err(isp->dev, "3a buf allocation failed.\n");
1149 s3a_ptr = hmm_vmap(s3a_buf->s3a_data->data_ptr, true);
1150 s3a_buf->s3a_map = ia_css_isp_3a_statistics_map_allocate(
1151 s3a_buf->s3a_data, s3a_ptr);
1154 if (dis_buf && dvs_grid_info && dvs_grid_info->enable) {
1157 dis_buf->dis_data = ia_css_isp_dvs2_statistics_allocate(
1159 if (!dis_buf->dis_data) {
1160 dev_err(isp->dev, "dvs buf allocation failed.\n");
1162 ia_css_isp_3a_statistics_free(s3a_buf->s3a_data);
1166 dvs_ptr = hmm_vmap(dis_buf->dis_data->data_ptr, true);
1167 dis_buf->dvs_map = ia_css_isp_dvs_statistics_map_allocate(
1168 dis_buf->dis_data, dvs_ptr);
1171 if (asd->stream_env[stream_id].stream_info.
1172 metadata_info.size && md_buf) {
1173 md_buf->metadata = ia_css_metadata_allocate(
1174 &asd->stream_env[stream_id].stream_info.metadata_info);
1175 if (!md_buf->metadata) {
1177 ia_css_isp_3a_statistics_free(s3a_buf->s3a_data);
1179 ia_css_isp_dvs2_statistics_free(dis_buf->dis_data);
1180 dev_err(isp->dev, "metadata buf allocation failed.\n");
1183 md_buf->md_vptr = hmm_vmap(md_buf->metadata->address, false);
1189 void atomisp_css_free_3a_buffer(struct atomisp_s3a_buf *s3a_buf)
1191 if (s3a_buf->s3a_data)
1192 hmm_vunmap(s3a_buf->s3a_data->data_ptr);
1194 ia_css_isp_3a_statistics_map_free(s3a_buf->s3a_map);
1195 s3a_buf->s3a_map = NULL;
1196 ia_css_isp_3a_statistics_free(s3a_buf->s3a_data);
1199 void atomisp_css_free_dis_buffer(struct atomisp_dis_buf *dis_buf)
1201 if (dis_buf->dis_data)
1202 hmm_vunmap(dis_buf->dis_data->data_ptr);
1204 ia_css_isp_dvs_statistics_map_free(dis_buf->dvs_map);
1205 dis_buf->dvs_map = NULL;
1206 ia_css_isp_dvs2_statistics_free(dis_buf->dis_data);
1209 void atomisp_css_free_metadata_buffer(struct atomisp_metadata_buf *metadata_buf)
1211 if (metadata_buf->md_vptr) {
1212 hmm_vunmap(metadata_buf->metadata->address);
1213 metadata_buf->md_vptr = NULL;
1215 ia_css_metadata_free(metadata_buf->metadata);
1218 void atomisp_css_free_stat_buffers(struct atomisp_sub_device *asd)
1220 struct atomisp_s3a_buf *s3a_buf, *_s3a_buf;
1221 struct atomisp_dis_buf *dis_buf, *_dis_buf;
1222 struct atomisp_metadata_buf *md_buf, *_md_buf;
1223 struct ia_css_dvs_grid_info *dvs_grid_info =
1224 atomisp_css_get_dvs_grid_info(&asd->params.curr_grid_info);
1227 /* 3A statistics use vmalloc, DIS use kmalloc */
1228 if (dvs_grid_info && dvs_grid_info->enable) {
1229 ia_css_dvs2_coefficients_free(asd->params.css_param.dvs2_coeff);
1230 ia_css_dvs2_statistics_free(asd->params.dvs_stat);
1231 asd->params.css_param.dvs2_coeff = NULL;
1232 asd->params.dvs_stat = NULL;
1233 asd->params.dvs_hor_proj_bytes = 0;
1234 asd->params.dvs_ver_proj_bytes = 0;
1235 asd->params.dvs_hor_coef_bytes = 0;
1236 asd->params.dvs_ver_coef_bytes = 0;
1237 asd->params.dis_proj_data_valid = false;
1238 list_for_each_entry_safe(dis_buf, _dis_buf,
1239 &asd->dis_stats, list) {
1240 atomisp_css_free_dis_buffer(dis_buf);
1241 list_del(&dis_buf->list);
1244 list_for_each_entry_safe(dis_buf, _dis_buf,
1245 &asd->dis_stats_in_css, list) {
1246 atomisp_css_free_dis_buffer(dis_buf);
1247 list_del(&dis_buf->list);
1251 if (asd->params.curr_grid_info.s3a_grid.enable) {
1252 ia_css_3a_statistics_free(asd->params.s3a_user_stat);
1253 asd->params.s3a_user_stat = NULL;
1254 asd->params.s3a_output_bytes = 0;
1255 list_for_each_entry_safe(s3a_buf, _s3a_buf,
1256 &asd->s3a_stats, list) {
1257 atomisp_css_free_3a_buffer(s3a_buf);
1258 list_del(&s3a_buf->list);
1261 list_for_each_entry_safe(s3a_buf, _s3a_buf,
1262 &asd->s3a_stats_in_css, list) {
1263 atomisp_css_free_3a_buffer(s3a_buf);
1264 list_del(&s3a_buf->list);
1267 list_for_each_entry_safe(s3a_buf, _s3a_buf,
1268 &asd->s3a_stats_ready, list) {
1269 atomisp_css_free_3a_buffer(s3a_buf);
1270 list_del(&s3a_buf->list);
1275 if (asd->params.css_param.dvs_6axis) {
1276 ia_css_dvs2_6axis_config_free(asd->params.css_param.dvs_6axis);
1277 asd->params.css_param.dvs_6axis = NULL;
1280 for (i = 0; i < ATOMISP_METADATA_TYPE_NUM; i++) {
1281 list_for_each_entry_safe(md_buf, _md_buf,
1282 &asd->metadata[i], list) {
1283 atomisp_css_free_metadata_buffer(md_buf);
1284 list_del(&md_buf->list);
1287 list_for_each_entry_safe(md_buf, _md_buf,
1288 &asd->metadata_in_css[i], list) {
1289 atomisp_css_free_metadata_buffer(md_buf);
1290 list_del(&md_buf->list);
1293 list_for_each_entry_safe(md_buf, _md_buf,
1294 &asd->metadata_ready[i], list) {
1295 atomisp_css_free_metadata_buffer(md_buf);
1296 list_del(&md_buf->list);
1300 asd->params.metadata_width_size = 0;
1301 atomisp_free_metadata_output_buf(asd);
1304 int atomisp_css_get_grid_info(struct atomisp_sub_device *asd,
1305 enum ia_css_pipe_id pipe_id)
1307 struct ia_css_pipe_info p_info;
1308 struct ia_css_grid_info old_info;
1309 struct atomisp_device *isp = asd->isp;
1310 int md_width = asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].
1311 stream_config.metadata_config.resolution.width;
1313 memset(&p_info, 0, sizeof(struct ia_css_pipe_info));
1314 memset(&old_info, 0, sizeof(struct ia_css_grid_info));
1316 if (ia_css_pipe_get_info(
1317 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].pipes[pipe_id],
1319 dev_err(isp->dev, "ia_css_pipe_get_info failed\n");
1323 memcpy(&old_info, &asd->params.curr_grid_info,
1324 sizeof(struct ia_css_grid_info));
1325 memcpy(&asd->params.curr_grid_info, &p_info.grid_info,
1326 sizeof(struct ia_css_grid_info));
1328 * Record which css pipe enables s3a_grid.
1329 * Currently would have one css pipe that need it
1331 if (asd->params.curr_grid_info.s3a_grid.enable) {
1332 if (asd->params.s3a_enabled_pipe != IA_CSS_PIPE_ID_NUM)
1333 dev_dbg(isp->dev, "css pipe %d enabled s3a grid replaced by: %d.\n",
1334 asd->params.s3a_enabled_pipe, pipe_id);
1335 asd->params.s3a_enabled_pipe = pipe_id;
1338 /* If the grid info has not changed and the buffers for 3A and
1339 * DIS statistics buffers are allocated or buffer size would be zero
1340 * then no need to do anything. */
1341 if (((!memcmp(&old_info, &asd->params.curr_grid_info, sizeof(old_info))
1342 && asd->params.s3a_user_stat && asd->params.dvs_stat)
1343 || asd->params.curr_grid_info.s3a_grid.width == 0
1344 || asd->params.curr_grid_info.s3a_grid.height == 0)
1345 && asd->params.metadata_width_size == md_width) {
1347 "grid info change escape. memcmp=%d, s3a_user_stat=%d,dvs_stat=%d, s3a.width=%d, s3a.height=%d, metadata width =%d\n",
1348 !memcmp(&old_info, &asd->params.curr_grid_info,
1350 !!asd->params.s3a_user_stat, !!asd->params.dvs_stat,
1351 asd->params.curr_grid_info.s3a_grid.width,
1352 asd->params.curr_grid_info.s3a_grid.height,
1353 asd->params.metadata_width_size);
1356 asd->params.metadata_width_size = md_width;
1361 int atomisp_alloc_3a_output_buf(struct atomisp_sub_device *asd)
1363 if (!asd->params.curr_grid_info.s3a_grid.width ||
1364 !asd->params.curr_grid_info.s3a_grid.height)
1367 asd->params.s3a_user_stat = ia_css_3a_statistics_allocate(
1368 &asd->params.curr_grid_info.s3a_grid);
1369 if (!asd->params.s3a_user_stat)
1371 /* 3A statistics. These can be big, so we use vmalloc. */
1372 asd->params.s3a_output_bytes =
1373 asd->params.curr_grid_info.s3a_grid.width *
1374 asd->params.curr_grid_info.s3a_grid.height *
1375 sizeof(*asd->params.s3a_user_stat->data);
1380 int atomisp_alloc_dis_coef_buf(struct atomisp_sub_device *asd)
1382 struct ia_css_dvs_grid_info *dvs_grid =
1383 atomisp_css_get_dvs_grid_info(&asd->params.curr_grid_info);
1388 if (!dvs_grid->enable) {
1389 dev_dbg(asd->isp->dev, "%s: dvs_grid not enabled.\n", __func__);
1393 /* DIS coefficients. */
1394 asd->params.css_param.dvs2_coeff = ia_css_dvs2_coefficients_allocate(
1396 if (!asd->params.css_param.dvs2_coeff)
1399 asd->params.dvs_hor_coef_bytes = dvs_grid->num_hor_coefs *
1400 sizeof(*asd->params.css_param.dvs2_coeff->hor_coefs.odd_real);
1402 asd->params.dvs_ver_coef_bytes = dvs_grid->num_ver_coefs *
1403 sizeof(*asd->params.css_param.dvs2_coeff->ver_coefs.odd_real);
1405 /* DIS projections. */
1406 asd->params.dis_proj_data_valid = false;
1407 asd->params.dvs_stat = ia_css_dvs2_statistics_allocate(dvs_grid);
1408 if (!asd->params.dvs_stat)
1411 asd->params.dvs_hor_proj_bytes =
1412 dvs_grid->aligned_height * dvs_grid->aligned_width *
1413 sizeof(*asd->params.dvs_stat->hor_prod.odd_real);
1415 asd->params.dvs_ver_proj_bytes =
1416 dvs_grid->aligned_height * dvs_grid->aligned_width *
1417 sizeof(*asd->params.dvs_stat->ver_prod.odd_real);
1422 int atomisp_alloc_metadata_output_buf(struct atomisp_sub_device *asd)
1426 /* We allocate the cpu-side buffer used for communication with user
1428 for (i = 0; i < ATOMISP_METADATA_TYPE_NUM; i++) {
1429 asd->params.metadata_user[i] = kvmalloc(
1430 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].
1431 stream_info.metadata_info.size, GFP_KERNEL);
1432 if (!asd->params.metadata_user[i]) {
1434 kvfree(asd->params.metadata_user[i]);
1435 asd->params.metadata_user[i] = NULL;
1444 void atomisp_free_metadata_output_buf(struct atomisp_sub_device *asd)
1448 for (i = 0; i < ATOMISP_METADATA_TYPE_NUM; i++) {
1449 if (asd->params.metadata_user[i]) {
1450 kvfree(asd->params.metadata_user[i]);
1451 asd->params.metadata_user[i] = NULL;
1456 void atomisp_css_temp_pipe_to_pipe_id(struct atomisp_sub_device *asd,
1457 struct atomisp_css_event *current_event)
1461 * Pipe ID reported in CSS event is not correct for new system's
1465 ia_css_temp_pipe_to_pipe_id(current_event->event.pipe,
1466 ¤t_event->pipe);
1467 if (asd && asd->copy_mode &&
1468 current_event->pipe == IA_CSS_PIPE_ID_CAPTURE)
1469 current_event->pipe = IA_CSS_PIPE_ID_COPY;
1472 int atomisp_css_isys_set_resolution(struct atomisp_sub_device *asd,
1473 enum atomisp_input_stream_id stream_id,
1474 struct v4l2_mbus_framefmt *ffmt,
1477 struct ia_css_stream_config *s_config =
1478 &asd->stream_env[stream_id].stream_config;
1480 if (isys_stream >= IA_CSS_STREAM_MAX_ISYS_STREAM_PER_CH)
1483 s_config->isys_config[isys_stream].input_res.width = ffmt->width;
1484 s_config->isys_config[isys_stream].input_res.height = ffmt->height;
1488 int atomisp_css_input_set_resolution(struct atomisp_sub_device *asd,
1489 enum atomisp_input_stream_id stream_id,
1490 struct v4l2_mbus_framefmt *ffmt)
1492 struct ia_css_stream_config *s_config =
1493 &asd->stream_env[stream_id].stream_config;
1495 s_config->input_config.input_res.width = ffmt->width;
1496 s_config->input_config.input_res.height = ffmt->height;
1500 void atomisp_css_input_set_binning_factor(struct atomisp_sub_device *asd,
1501 enum atomisp_input_stream_id stream_id,
1502 unsigned int bin_factor)
1504 asd->stream_env[stream_id]
1505 .stream_config.sensor_binning_factor = bin_factor;
1508 void atomisp_css_input_set_bayer_order(struct atomisp_sub_device *asd,
1509 enum atomisp_input_stream_id stream_id,
1510 enum ia_css_bayer_order bayer_order)
1512 struct ia_css_stream_config *s_config =
1513 &asd->stream_env[stream_id].stream_config;
1514 s_config->input_config.bayer_order = bayer_order;
1517 void atomisp_css_isys_set_link(struct atomisp_sub_device *asd,
1518 enum atomisp_input_stream_id stream_id,
1522 struct ia_css_stream_config *s_config =
1523 &asd->stream_env[stream_id].stream_config;
1525 s_config->isys_config[isys_stream].linked_isys_stream_id = link;
1528 void atomisp_css_isys_set_valid(struct atomisp_sub_device *asd,
1529 enum atomisp_input_stream_id stream_id,
1533 struct ia_css_stream_config *s_config =
1534 &asd->stream_env[stream_id].stream_config;
1536 s_config->isys_config[isys_stream].valid = valid;
1539 void atomisp_css_isys_set_format(struct atomisp_sub_device *asd,
1540 enum atomisp_input_stream_id stream_id,
1541 enum atomisp_input_format format,
1544 struct ia_css_stream_config *s_config =
1545 &asd->stream_env[stream_id].stream_config;
1547 s_config->isys_config[isys_stream].format = format;
1550 void atomisp_css_input_set_format(struct atomisp_sub_device *asd,
1551 enum atomisp_input_stream_id stream_id,
1552 enum atomisp_input_format format)
1554 struct ia_css_stream_config *s_config =
1555 &asd->stream_env[stream_id].stream_config;
1557 s_config->input_config.format = format;
1560 int atomisp_css_set_default_isys_config(struct atomisp_sub_device *asd,
1561 enum atomisp_input_stream_id stream_id,
1562 struct v4l2_mbus_framefmt *ffmt)
1565 struct ia_css_stream_config *s_config =
1566 &asd->stream_env[stream_id].stream_config;
1568 * Set all isys configs to not valid.
1569 * Currently we support only one stream per channel
1571 for (i = IA_CSS_STREAM_ISYS_STREAM_0;
1572 i < IA_CSS_STREAM_MAX_ISYS_STREAM_PER_CH; i++)
1573 s_config->isys_config[i].valid = false;
1575 atomisp_css_isys_set_resolution(asd, stream_id, ffmt,
1576 IA_CSS_STREAM_DEFAULT_ISYS_STREAM_IDX);
1577 atomisp_css_isys_set_format(asd, stream_id,
1578 s_config->input_config.format,
1579 IA_CSS_STREAM_DEFAULT_ISYS_STREAM_IDX);
1580 atomisp_css_isys_set_link(asd, stream_id, NO_LINK,
1581 IA_CSS_STREAM_DEFAULT_ISYS_STREAM_IDX);
1582 atomisp_css_isys_set_valid(asd, stream_id, true,
1583 IA_CSS_STREAM_DEFAULT_ISYS_STREAM_IDX);
1588 void atomisp_css_isys_two_stream_cfg_update_stream1(
1589 struct atomisp_sub_device *asd,
1590 enum atomisp_input_stream_id stream_id,
1591 enum atomisp_input_format input_format,
1592 unsigned int width, unsigned int height)
1594 struct ia_css_stream_config *s_config =
1595 &asd->stream_env[stream_id].stream_config;
1597 s_config->isys_config[IA_CSS_STREAM_ISYS_STREAM_0].input_res.width =
1599 s_config->isys_config[IA_CSS_STREAM_ISYS_STREAM_0].input_res.height =
1601 s_config->isys_config[IA_CSS_STREAM_ISYS_STREAM_0].format =
1603 s_config->isys_config[IA_CSS_STREAM_ISYS_STREAM_0].valid = true;
1606 void atomisp_css_isys_two_stream_cfg_update_stream2(
1607 struct atomisp_sub_device *asd,
1608 enum atomisp_input_stream_id stream_id,
1609 enum atomisp_input_format input_format,
1610 unsigned int width, unsigned int height)
1612 struct ia_css_stream_config *s_config =
1613 &asd->stream_env[stream_id].stream_config;
1615 s_config->isys_config[IA_CSS_STREAM_ISYS_STREAM_1].input_res.width =
1617 s_config->isys_config[IA_CSS_STREAM_ISYS_STREAM_1].input_res.height =
1619 s_config->isys_config[IA_CSS_STREAM_ISYS_STREAM_1].linked_isys_stream_id
1620 = IA_CSS_STREAM_ISYS_STREAM_0;
1621 s_config->isys_config[IA_CSS_STREAM_ISYS_STREAM_1].format =
1623 s_config->isys_config[IA_CSS_STREAM_ISYS_STREAM_1].valid = true;
1626 int atomisp_css_input_set_effective_resolution(
1627 struct atomisp_sub_device *asd,
1628 enum atomisp_input_stream_id stream_id,
1629 unsigned int width, unsigned int height)
1631 struct ia_css_stream_config *s_config =
1632 &asd->stream_env[stream_id].stream_config;
1633 s_config->input_config.effective_res.width = width;
1634 s_config->input_config.effective_res.height = height;
1638 void atomisp_css_video_set_dis_envelope(struct atomisp_sub_device *asd,
1639 unsigned int dvs_w, unsigned int dvs_h)
1641 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL]
1642 .pipe_configs[IA_CSS_PIPE_ID_VIDEO].dvs_envelope.width = dvs_w;
1643 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL]
1644 .pipe_configs[IA_CSS_PIPE_ID_VIDEO].dvs_envelope.height = dvs_h;
1647 void atomisp_css_input_set_two_pixels_per_clock(
1648 struct atomisp_sub_device *asd,
1653 if (asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL]
1654 .stream_config.pixels_per_clock == (two_ppc ? 2 : 1))
1657 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL]
1658 .stream_config.pixels_per_clock = (two_ppc ? 2 : 1);
1659 for (i = 0; i < IA_CSS_PIPE_ID_NUM; i++)
1660 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL]
1661 .update_pipe[i] = true;
1664 void atomisp_css_enable_dz(struct atomisp_sub_device *asd, bool enable)
1668 for (i = 0; i < IA_CSS_PIPE_ID_NUM; i++)
1669 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL]
1670 .pipe_configs[i].enable_dz = enable;
1673 void atomisp_css_capture_set_mode(struct atomisp_sub_device *asd,
1674 enum ia_css_capture_mode mode)
1676 struct atomisp_stream_env *stream_env =
1677 &asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL];
1679 if (stream_env->pipe_configs[IA_CSS_PIPE_ID_CAPTURE]
1680 .default_capture_config.mode == mode)
1683 stream_env->pipe_configs[IA_CSS_PIPE_ID_CAPTURE].
1684 default_capture_config.mode = mode;
1685 stream_env->update_pipe[IA_CSS_PIPE_ID_CAPTURE] = true;
1688 void atomisp_css_input_set_mode(struct atomisp_sub_device *asd,
1689 enum ia_css_input_mode mode)
1692 struct atomisp_device *isp = asd->isp;
1693 unsigned int size_mem_words;
1695 for (i = 0; i < ATOMISP_INPUT_STREAM_NUM; i++)
1696 asd->stream_env[i].stream_config.mode = mode;
1698 if (isp->inputs[asd->input_curr].type == TEST_PATTERN) {
1699 struct ia_css_stream_config *s_config =
1700 &asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream_config;
1701 s_config->mode = IA_CSS_INPUT_MODE_TPG;
1702 s_config->source.tpg.mode = IA_CSS_TPG_MODE_CHECKERBOARD;
1703 s_config->source.tpg.x_mask = (1 << 4) - 1;
1704 s_config->source.tpg.x_delta = -2;
1705 s_config->source.tpg.y_mask = (1 << 4) - 1;
1706 s_config->source.tpg.y_delta = 3;
1707 s_config->source.tpg.xy_mask = (1 << 8) - 1;
1711 if (mode != IA_CSS_INPUT_MODE_BUFFERED_SENSOR)
1714 for (i = 0; i < ATOMISP_INPUT_STREAM_NUM; i++) {
1716 * TODO: sensor needs to export the embedded_data_size_words
1717 * information to atomisp for each setting.
1718 * Here using a large safe value.
1720 struct ia_css_stream_config *s_config =
1721 &asd->stream_env[i].stream_config;
1723 if (s_config->input_config.input_res.width == 0)
1726 if (ia_css_mipi_frame_calculate_size(
1727 s_config->input_config.input_res.width,
1728 s_config->input_config.input_res.height,
1729 s_config->input_config.format,
1732 &size_mem_words) != 0) {
1734 size_mem_words = CSS_MIPI_FRAME_BUFFER_SIZE_2;
1736 size_mem_words = CSS_MIPI_FRAME_BUFFER_SIZE_1;
1737 dev_warn(asd->isp->dev,
1738 "ia_css_mipi_frame_calculate_size failed,applying pre-defined MIPI buffer size %u.\n",
1741 s_config->mipi_buffer_config.size_mem_words = size_mem_words;
1742 s_config->mipi_buffer_config.nof_mipi_buffers = 2;
1746 void atomisp_css_capture_enable_online(struct atomisp_sub_device *asd,
1747 unsigned short stream_index, bool enable)
1749 struct atomisp_stream_env *stream_env =
1750 &asd->stream_env[stream_index];
1752 if (stream_env->stream_config.online == !!enable)
1755 stream_env->stream_config.online = !!enable;
1756 stream_env->update_pipe[IA_CSS_PIPE_ID_CAPTURE] = true;
1759 void atomisp_css_preview_enable_online(struct atomisp_sub_device *asd,
1760 unsigned short stream_index, bool enable)
1762 struct atomisp_stream_env *stream_env =
1763 &asd->stream_env[stream_index];
1766 if (stream_env->stream_config.online != !!enable) {
1767 stream_env->stream_config.online = !!enable;
1768 for (i = 0; i < IA_CSS_PIPE_ID_NUM; i++)
1769 stream_env->update_pipe[i] = true;
1773 int atomisp_css_input_configure_port(
1774 struct atomisp_sub_device *asd,
1775 enum mipi_port_id port,
1776 unsigned int num_lanes,
1777 unsigned int timeout,
1778 unsigned int mipi_freq,
1779 enum atomisp_input_format metadata_format,
1780 unsigned int metadata_width,
1781 unsigned int metadata_height)
1784 struct atomisp_stream_env *stream_env;
1786 * Calculate rx_count as follows:
1787 * Input: mipi_freq : CSI-2 bus frequency in Hz
1788 * UI = 1 / (2 * mipi_freq) : period of one bit on the bus
1789 * min = 85e-9 + 6 * UI : Limits for rx_count in seconds
1790 * max = 145e-9 + 10 * UI
1791 * rxcount0 = min / (4 / mipi_freq) : convert seconds to byte clocks
1792 * rxcount = rxcount0 - 2 : adjust for better results
1793 * The formula below is simplified version of the above with
1794 * 10-bit fixed points for improved accuracy.
1796 const unsigned int rxcount =
1797 min(((mipi_freq / 46000) - 1280) >> 10, 0xffU) * 0x01010101U;
1799 for (i = 0; i < ATOMISP_INPUT_STREAM_NUM; i++) {
1800 stream_env = &asd->stream_env[i];
1801 stream_env->stream_config.source.port.port = port;
1802 stream_env->stream_config.source.port.num_lanes = num_lanes;
1803 stream_env->stream_config.source.port.timeout = timeout;
1805 stream_env->stream_config.source.port.rxcount = rxcount;
1806 stream_env->stream_config.
1807 metadata_config.data_type = metadata_format;
1808 stream_env->stream_config.
1809 metadata_config.resolution.width = metadata_width;
1810 stream_env->stream_config.
1811 metadata_config.resolution.height = metadata_height;
1817 void atomisp_css_stop(struct atomisp_sub_device *asd,
1818 enum ia_css_pipe_id pipe_id, bool in_reset)
1820 unsigned long irqflags;
1824 * CSS 2.0 API limitation: ia_css_stop_sp() can only be called after
1825 * destroying all pipes.
1827 atomisp_destroy_pipes_stream_force(asd);
1829 atomisp_init_raw_buffer_bitmap(asd);
1834 struct atomisp_stream_env *stream_env;
1837 for (i = 0; i < ATOMISP_INPUT_STREAM_NUM; i++) {
1838 stream_env = &asd->stream_env[i];
1839 for (j = 0; j < IA_CSS_PIPE_ID_NUM; j++) {
1840 ia_css_pipe_config_defaults(
1841 &stream_env->pipe_configs[j]);
1842 ia_css_pipe_extra_config_defaults(
1843 &stream_env->pipe_extra_configs[j]);
1845 ia_css_stream_config_defaults(
1846 &stream_env->stream_config);
1848 memset(&asd->params.config, 0, sizeof(asd->params.config));
1849 asd->params.css_update_params_needed = false;
1852 /* move stats buffers to free queue list */
1853 list_splice_init(&asd->s3a_stats_in_css, &asd->s3a_stats);
1854 list_splice_init(&asd->s3a_stats_ready, &asd->s3a_stats);
1856 spin_lock_irqsave(&asd->dis_stats_lock, irqflags);
1857 list_splice_init(&asd->dis_stats_in_css, &asd->dis_stats);
1858 asd->params.dis_proj_data_valid = false;
1859 spin_unlock_irqrestore(&asd->dis_stats_lock, irqflags);
1861 for (i = 0; i < ATOMISP_METADATA_TYPE_NUM; i++) {
1862 list_splice_init(&asd->metadata_in_css[i], &asd->metadata[i]);
1863 list_splice_init(&asd->metadata_ready[i], &asd->metadata[i]);
1866 atomisp_flush_params_queue(&asd->video_out);
1867 atomisp_free_css_parameters(&asd->params.css_param);
1868 memset(&asd->params.css_param, 0, sizeof(asd->params.css_param));
1871 void atomisp_css_continuous_set_num_raw_frames(
1872 struct atomisp_sub_device *asd,
1875 if (asd->enable_raw_buffer_lock->val) {
1876 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL]
1877 .stream_config.init_num_cont_raw_buf =
1878 ATOMISP_CSS2_NUM_OFFLINE_INIT_CONTINUOUS_FRAMES_LOCK_EN;
1879 if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO &&
1880 asd->params.video_dis_en)
1881 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL]
1882 .stream_config.init_num_cont_raw_buf +=
1883 ATOMISP_CSS2_NUM_DVS_FRAME_DELAY;
1885 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL]
1886 .stream_config.init_num_cont_raw_buf =
1887 ATOMISP_CSS2_NUM_OFFLINE_INIT_CONTINUOUS_FRAMES;
1890 if (asd->params.video_dis_en)
1891 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL]
1892 .stream_config.init_num_cont_raw_buf +=
1893 ATOMISP_CSS2_NUM_DVS_FRAME_DELAY;
1895 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL]
1896 .stream_config.target_num_cont_raw_buf = num_frames;
1899 static enum ia_css_pipe_mode __pipe_id_to_pipe_mode(
1900 struct atomisp_sub_device *asd,
1901 enum ia_css_pipe_id pipe_id)
1903 struct atomisp_device *isp = asd->isp;
1904 struct camera_mipi_info *mipi_info = atomisp_to_sensor_mipi_info(
1905 isp->inputs[asd->input_curr].camera);
1908 case IA_CSS_PIPE_ID_COPY:
1909 /* Currently only YUVPP mode supports YUV420_Legacy format.
1910 * Revert this when other pipe modes can support
1911 * YUV420_Legacy format.
1913 if (mipi_info && mipi_info->input_format ==
1914 ATOMISP_INPUT_FORMAT_YUV420_8_LEGACY)
1915 return IA_CSS_PIPE_MODE_YUVPP;
1916 return IA_CSS_PIPE_MODE_COPY;
1917 case IA_CSS_PIPE_ID_PREVIEW:
1918 return IA_CSS_PIPE_MODE_PREVIEW;
1919 case IA_CSS_PIPE_ID_CAPTURE:
1920 return IA_CSS_PIPE_MODE_CAPTURE;
1921 case IA_CSS_PIPE_ID_VIDEO:
1922 return IA_CSS_PIPE_MODE_VIDEO;
1923 case IA_CSS_PIPE_ID_YUVPP:
1924 return IA_CSS_PIPE_MODE_YUVPP;
1927 return IA_CSS_PIPE_MODE_PREVIEW;
1931 static void __configure_output(struct atomisp_sub_device *asd,
1932 unsigned int stream_index,
1933 unsigned int width, unsigned int height,
1934 unsigned int min_width,
1935 enum ia_css_frame_format format,
1936 enum ia_css_pipe_id pipe_id)
1938 struct atomisp_device *isp = asd->isp;
1939 struct atomisp_stream_env *stream_env =
1940 &asd->stream_env[stream_index];
1941 struct ia_css_stream_config *s_config = &stream_env->stream_config;
1943 stream_env->pipe_configs[pipe_id].mode =
1944 __pipe_id_to_pipe_mode(asd, pipe_id);
1945 stream_env->update_pipe[pipe_id] = true;
1947 stream_env->pipe_configs[pipe_id].output_info[0].res.width = width;
1948 stream_env->pipe_configs[pipe_id].output_info[0].res.height = height;
1949 stream_env->pipe_configs[pipe_id].output_info[0].format = format;
1950 stream_env->pipe_configs[pipe_id].output_info[0].padded_width = min_width;
1952 /* isp binary 2.2 specific setting*/
1953 if (width > s_config->input_config.effective_res.width ||
1954 height > s_config->input_config.effective_res.height) {
1955 s_config->input_config.effective_res.width = width;
1956 s_config->input_config.effective_res.height = height;
1959 dev_dbg(isp->dev, "configuring pipe[%d] output info w=%d.h=%d.f=%d.\n",
1960 pipe_id, width, height, format);
1964 * For CSS2.1, capture pipe uses capture_pp_in_res to configure yuv
1965 * downscaling input resolution.
1967 static void __configure_capture_pp_input(struct atomisp_sub_device *asd,
1968 unsigned int width, unsigned int height,
1969 enum ia_css_pipe_id pipe_id)
1971 struct atomisp_device *isp = asd->isp;
1972 struct atomisp_stream_env *stream_env =
1973 &asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL];
1974 struct ia_css_stream_config *stream_config = &stream_env->stream_config;
1975 struct ia_css_pipe_config *pipe_configs =
1976 &stream_env->pipe_configs[pipe_id];
1977 struct ia_css_pipe_extra_config *pipe_extra_configs =
1978 &stream_env->pipe_extra_configs[pipe_id];
1979 unsigned int hor_ds_factor = 0, ver_ds_factor = 0;
1981 if (width == 0 && height == 0)
1984 if (width * 9 / 10 < pipe_configs->output_info[0].res.width ||
1985 height * 9 / 10 < pipe_configs->output_info[0].res.height)
1987 /* here just copy the calculation in css */
1988 hor_ds_factor = CEIL_DIV(width >> 1,
1989 pipe_configs->output_info[0].res.width);
1990 ver_ds_factor = CEIL_DIV(height >> 1,
1991 pipe_configs->output_info[0].res.height);
1993 if ((asd->isp->media_dev.hw_revision <
1994 (ATOMISP_HW_REVISION_ISP2401 << ATOMISP_HW_REVISION_SHIFT) ||
1995 IS_CHT) && hor_ds_factor != ver_ds_factor) {
1996 dev_warn(asd->isp->dev,
1997 "Cropping for capture due to FW limitation");
2001 pipe_configs->mode = __pipe_id_to_pipe_mode(asd, pipe_id);
2002 stream_env->update_pipe[pipe_id] = true;
2004 pipe_extra_configs->enable_yuv_ds = true;
2006 pipe_configs->capt_pp_in_res.width =
2007 stream_config->input_config.effective_res.width;
2008 pipe_configs->capt_pp_in_res.height =
2009 stream_config->input_config.effective_res.height;
2011 dev_dbg(isp->dev, "configuring pipe[%d]capture pp input w=%d.h=%d.\n",
2012 pipe_id, width, height);
2016 * For CSS2.1, preview pipe could support bayer downscaling, yuv decimation and
2017 * yuv downscaling, which needs addtional configurations.
2019 static void __configure_preview_pp_input(struct atomisp_sub_device *asd,
2020 unsigned int width, unsigned int height,
2021 enum ia_css_pipe_id pipe_id)
2023 struct atomisp_device *isp = asd->isp;
2024 int out_width, out_height, yuv_ds_in_width, yuv_ds_in_height;
2025 struct atomisp_stream_env *stream_env =
2026 &asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL];
2027 struct ia_css_stream_config *stream_config = &stream_env->stream_config;
2028 struct ia_css_pipe_config *pipe_configs =
2029 &stream_env->pipe_configs[pipe_id];
2030 struct ia_css_pipe_extra_config *pipe_extra_configs =
2031 &stream_env->pipe_extra_configs[pipe_id];
2032 struct ia_css_resolution *bayer_ds_out_res =
2033 &pipe_configs->bayer_ds_out_res;
2034 struct ia_css_resolution *vf_pp_in_res =
2035 &pipe_configs->vf_pp_in_res;
2036 struct ia_css_resolution *effective_res =
2037 &stream_config->input_config.effective_res;
2039 static const struct bayer_ds_factor bds_fct[] = {{2, 1}, {3, 2}, {5, 4} };
2041 * BZ201033: YUV decimation factor of 4 causes couple of rightmost
2042 * columns to be shaded. Remove this factor to work around the CSS bug.
2043 * const unsigned int yuv_dec_fct[] = {4, 2};
2045 static const unsigned int yuv_dec_fct[] = { 2 };
2048 if (width == 0 && height == 0)
2051 pipe_configs->mode = __pipe_id_to_pipe_mode(asd, pipe_id);
2052 stream_env->update_pipe[pipe_id] = true;
2054 out_width = pipe_configs->output_info[0].res.width;
2055 out_height = pipe_configs->output_info[0].res.height;
2058 * The ISP could do bayer downscaling, yuv decimation and yuv
2060 * 1: Bayer Downscaling: between effective resolution and
2062 * 2: YUV Decimation: between bayer_ds_res_out and vf_pp_in_res;
2063 * 3: YUV Downscaling: between vf_pp_in_res and final vf output
2065 * Rule for Bayer Downscaling: support factor 2, 1.5 and 1.25
2066 * Rule for YUV Decimation: support factor 2, 4
2067 * Rule for YUV Downscaling: arbitrary value below 2
2069 * General rule of factor distribution among these stages:
2070 * 1: try to do Bayer downscaling first if not in online mode.
2071 * 2: try to do maximum of 2 for YUV downscaling
2072 * 3: the remainling for YUV decimation
2075 * Do not configure bayer_ds_out_res if:
2076 * online == 1 or continuous == 0 or raw_binning = 0
2078 if (stream_config->online || !stream_config->continuous ||
2079 !pipe_extra_configs->enable_raw_binning) {
2080 bayer_ds_out_res->width = 0;
2081 bayer_ds_out_res->height = 0;
2083 bayer_ds_out_res->width = effective_res->width;
2084 bayer_ds_out_res->height = effective_res->height;
2086 for (i = 0; i < ARRAY_SIZE(bds_fct); i++) {
2087 if (effective_res->width >= out_width *
2088 bds_fct[i].numerator / bds_fct[i].denominator &&
2089 effective_res->height >= out_height *
2090 bds_fct[i].numerator / bds_fct[i].denominator) {
2091 bayer_ds_out_res->width =
2092 effective_res->width *
2093 bds_fct[i].denominator /
2094 bds_fct[i].numerator;
2095 bayer_ds_out_res->height =
2096 effective_res->height *
2097 bds_fct[i].denominator /
2098 bds_fct[i].numerator;
2104 * calculate YUV Decimation, YUV downscaling facor:
2105 * YUV Downscaling factor must not exceed 2.
2106 * YUV Decimation factor could be 2, 4.
2108 /* first decide the yuv_ds input resolution */
2109 if (bayer_ds_out_res->width == 0) {
2110 yuv_ds_in_width = effective_res->width;
2111 yuv_ds_in_height = effective_res->height;
2113 yuv_ds_in_width = bayer_ds_out_res->width;
2114 yuv_ds_in_height = bayer_ds_out_res->height;
2117 vf_pp_in_res->width = yuv_ds_in_width;
2118 vf_pp_in_res->height = yuv_ds_in_height;
2120 /* find out the yuv decimation factor */
2121 for (i = 0; i < ARRAY_SIZE(yuv_dec_fct); i++) {
2122 if (yuv_ds_in_width >= out_width * yuv_dec_fct[i] &&
2123 yuv_ds_in_height >= out_height * yuv_dec_fct[i]) {
2124 vf_pp_in_res->width = yuv_ds_in_width / yuv_dec_fct[i];
2125 vf_pp_in_res->height = yuv_ds_in_height / yuv_dec_fct[i];
2130 if (vf_pp_in_res->width == out_width &&
2131 vf_pp_in_res->height == out_height) {
2132 pipe_extra_configs->enable_yuv_ds = false;
2133 vf_pp_in_res->width = 0;
2134 vf_pp_in_res->height = 0;
2136 pipe_extra_configs->enable_yuv_ds = true;
2139 dev_dbg(isp->dev, "configuring pipe[%d]preview pp input w=%d.h=%d.\n",
2140 pipe_id, width, height);
2144 * For CSS2.1, offline video pipe could support bayer decimation, and
2145 * yuv downscaling, which needs addtional configurations.
2147 static void __configure_video_pp_input(struct atomisp_sub_device *asd,
2148 unsigned int width, unsigned int height,
2149 enum ia_css_pipe_id pipe_id)
2151 struct atomisp_device *isp = asd->isp;
2152 int out_width, out_height;
2153 struct atomisp_stream_env *stream_env =
2154 &asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL];
2155 struct ia_css_stream_config *stream_config = &stream_env->stream_config;
2156 struct ia_css_pipe_config *pipe_configs =
2157 &stream_env->pipe_configs[pipe_id];
2158 struct ia_css_pipe_extra_config *pipe_extra_configs =
2159 &stream_env->pipe_extra_configs[pipe_id];
2160 struct ia_css_resolution *bayer_ds_out_res =
2161 &pipe_configs->bayer_ds_out_res;
2162 struct ia_css_resolution *effective_res =
2163 &stream_config->input_config.effective_res;
2165 static const struct bayer_ds_factor bds_factors[] = {
2166 {8, 1}, {6, 1}, {4, 1}, {3, 1}, {2, 1}, {3, 2}
2170 if (width == 0 && height == 0)
2173 pipe_configs->mode = __pipe_id_to_pipe_mode(asd, pipe_id);
2174 stream_env->update_pipe[pipe_id] = true;
2176 pipe_extra_configs->enable_yuv_ds = false;
2179 * If DVS is enabled, video binary will take care the dvs envelope
2180 * and usually the bayer_ds_out_res should be larger than 120% of
2181 * destination resolution, the extra 20% will be cropped as DVS
2182 * envelope. But, if the bayer_ds_out_res is less than 120% of the
2183 * destination. The ISP can still work, but DVS quality is not good.
2185 /* taking at least 10% as envelope */
2186 if (asd->params.video_dis_en) {
2187 out_width = pipe_configs->output_info[0].res.width * 110 / 100;
2188 out_height = pipe_configs->output_info[0].res.height * 110 / 100;
2190 out_width = pipe_configs->output_info[0].res.width;
2191 out_height = pipe_configs->output_info[0].res.height;
2195 * calculate bayer decimate factor:
2196 * 1: only 1.5, 2, 4 and 8 get supported
2197 * 2: Do not configure bayer_ds_out_res if:
2198 * online == 1 or continuous == 0 or raw_binning = 0
2200 if (stream_config->online || !stream_config->continuous) {
2201 bayer_ds_out_res->width = 0;
2202 bayer_ds_out_res->height = 0;
2206 pipe_extra_configs->enable_raw_binning = true;
2207 bayer_ds_out_res->width = effective_res->width;
2208 bayer_ds_out_res->height = effective_res->height;
2210 for (i = 0; i < sizeof(bds_factors) / sizeof(struct bayer_ds_factor);
2212 if (effective_res->width >= out_width *
2213 bds_factors[i].numerator / bds_factors[i].denominator &&
2214 effective_res->height >= out_height *
2215 bds_factors[i].numerator / bds_factors[i].denominator) {
2216 bayer_ds_out_res->width = effective_res->width *
2217 bds_factors[i].denominator /
2218 bds_factors[i].numerator;
2219 bayer_ds_out_res->height = effective_res->height *
2220 bds_factors[i].denominator /
2221 bds_factors[i].numerator;
2227 * DVS is cropped from BDS output, so we do not really need to set the
2228 * envelope to 20% of output resolution here. always set it to 12x12
2229 * per firmware requirement.
2231 pipe_configs->dvs_envelope.width = 12;
2232 pipe_configs->dvs_envelope.height = 12;
2235 if (pipe_id == IA_CSS_PIPE_ID_YUVPP)
2236 stream_config->left_padding = -1;
2238 stream_config->left_padding = 12;
2239 dev_dbg(isp->dev, "configuring pipe[%d]video pp input w=%d.h=%d.\n",
2240 pipe_id, width, height);
2243 static void __configure_vf_output(struct atomisp_sub_device *asd,
2244 unsigned int width, unsigned int height,
2245 unsigned int min_width,
2246 enum ia_css_frame_format format,
2247 enum ia_css_pipe_id pipe_id)
2249 struct atomisp_device *isp = asd->isp;
2250 struct atomisp_stream_env *stream_env =
2251 &asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL];
2252 stream_env->pipe_configs[pipe_id].mode =
2253 __pipe_id_to_pipe_mode(asd, pipe_id);
2254 stream_env->update_pipe[pipe_id] = true;
2256 stream_env->pipe_configs[pipe_id].vf_output_info[0].res.width = width;
2257 stream_env->pipe_configs[pipe_id].vf_output_info[0].res.height = height;
2258 stream_env->pipe_configs[pipe_id].vf_output_info[0].format = format;
2259 stream_env->pipe_configs[pipe_id].vf_output_info[0].padded_width =
2262 "configuring pipe[%d] vf output info w=%d.h=%d.f=%d.\n",
2263 pipe_id, width, height, format);
2266 static int __get_frame_info(struct atomisp_sub_device *asd,
2267 unsigned int stream_index,
2268 struct ia_css_frame_info *info,
2269 enum frame_info_type type,
2270 enum ia_css_pipe_id pipe_id)
2272 struct atomisp_device *isp = asd->isp;
2274 struct ia_css_pipe_info p_info;
2276 /* FIXME! No need to destroy/recreate all streams */
2277 ret = atomisp_css_update_stream(asd);
2281 ret = ia_css_pipe_get_info(asd->stream_env[stream_index].pipes[pipe_id],
2284 dev_err(isp->dev, "can't get info from pipe\n");
2289 case ATOMISP_CSS_VF_FRAME:
2290 *info = p_info.vf_output_info[0];
2291 dev_dbg(isp->dev, "getting vf frame info.\n");
2293 case ATOMISP_CSS_SECOND_VF_FRAME:
2294 *info = p_info.vf_output_info[1];
2295 dev_dbg(isp->dev, "getting second vf frame info.\n");
2297 case ATOMISP_CSS_OUTPUT_FRAME:
2298 *info = p_info.output_info[0];
2299 dev_dbg(isp->dev, "getting main frame info.\n");
2301 case ATOMISP_CSS_SECOND_OUTPUT_FRAME:
2302 *info = p_info.output_info[1];
2303 dev_dbg(isp->dev, "getting second main frame info.\n");
2306 case ATOMISP_CSS_RAW_FRAME:
2307 *info = p_info.raw_output_info;
2308 dev_dbg(isp->dev, "getting raw frame info.\n");
2311 dev_dbg(isp->dev, "get frame info: w=%d, h=%d, num_invalid_frames %d.\n",
2312 info->res.width, info->res.height, p_info.num_invalid_frames);
2317 atomisp_destroy_pipes_stream_force(asd);
2321 static unsigned int atomisp_get_pipe_index(struct atomisp_sub_device *asd)
2324 return IA_CSS_PIPE_ID_COPY;
2326 switch (asd->run_mode->val) {
2327 case ATOMISP_RUN_MODE_VIDEO:
2328 return IA_CSS_PIPE_ID_VIDEO;
2329 case ATOMISP_RUN_MODE_STILL_CAPTURE:
2330 return IA_CSS_PIPE_ID_CAPTURE;
2331 case ATOMISP_RUN_MODE_PREVIEW:
2332 return IA_CSS_PIPE_ID_PREVIEW;
2335 dev_warn(asd->isp->dev, "cannot determine pipe-index return default preview pipe\n");
2336 return IA_CSS_PIPE_ID_PREVIEW;
2339 int atomisp_get_css_frame_info(struct atomisp_sub_device *asd,
2340 struct ia_css_frame_info *frame_info)
2342 struct ia_css_pipe_info info;
2343 int pipe_index = atomisp_get_pipe_index(asd);
2345 struct atomisp_device *isp = asd->isp;
2347 stream_index = (pipe_index == IA_CSS_PIPE_ID_YUVPP) ?
2348 ATOMISP_INPUT_STREAM_VIDEO :
2349 ATOMISP_INPUT_STREAM_GENERAL;
2351 if (0 != ia_css_pipe_get_info(asd->stream_env[stream_index]
2352 .pipes[pipe_index], &info)) {
2353 dev_dbg(isp->dev, "ia_css_pipe_get_info FAILED");
2357 *frame_info = info.output_info[0];
2361 int atomisp_css_copy_configure_output(struct atomisp_sub_device *asd,
2362 unsigned int stream_index,
2363 unsigned int width, unsigned int height,
2364 unsigned int padded_width,
2365 enum ia_css_frame_format format)
2367 asd->stream_env[stream_index].pipe_configs[IA_CSS_PIPE_ID_COPY].
2368 default_capture_config.mode =
2369 IA_CSS_CAPTURE_MODE_RAW;
2371 __configure_output(asd, stream_index, width, height, padded_width,
2372 format, IA_CSS_PIPE_ID_COPY);
2376 int atomisp_css_preview_configure_output(struct atomisp_sub_device *asd,
2377 unsigned int width, unsigned int height,
2378 unsigned int min_width,
2379 enum ia_css_frame_format format)
2381 __configure_output(asd, ATOMISP_INPUT_STREAM_GENERAL, width, height,
2382 min_width, format, IA_CSS_PIPE_ID_PREVIEW);
2386 int atomisp_css_capture_configure_output(struct atomisp_sub_device *asd,
2387 unsigned int width, unsigned int height,
2388 unsigned int min_width,
2389 enum ia_css_frame_format format)
2391 __configure_output(asd, ATOMISP_INPUT_STREAM_GENERAL, width, height,
2392 min_width, format, IA_CSS_PIPE_ID_CAPTURE);
2396 int atomisp_css_video_configure_output(struct atomisp_sub_device *asd,
2397 unsigned int width, unsigned int height,
2398 unsigned int min_width,
2399 enum ia_css_frame_format format)
2401 __configure_output(asd, ATOMISP_INPUT_STREAM_GENERAL, width, height,
2402 min_width, format, IA_CSS_PIPE_ID_VIDEO);
2406 int atomisp_css_video_configure_viewfinder(
2407 struct atomisp_sub_device *asd,
2408 unsigned int width, unsigned int height,
2409 unsigned int min_width,
2410 enum ia_css_frame_format format)
2412 __configure_vf_output(asd, width, height, min_width, format,
2413 IA_CSS_PIPE_ID_VIDEO);
2417 int atomisp_css_capture_configure_viewfinder(
2418 struct atomisp_sub_device *asd,
2419 unsigned int width, unsigned int height,
2420 unsigned int min_width,
2421 enum ia_css_frame_format format)
2423 __configure_vf_output(asd, width, height, min_width, format, IA_CSS_PIPE_ID_CAPTURE);
2427 int atomisp_css_video_get_viewfinder_frame_info(
2428 struct atomisp_sub_device *asd,
2429 struct ia_css_frame_info *info)
2431 return __get_frame_info(asd, ATOMISP_INPUT_STREAM_GENERAL, info,
2432 ATOMISP_CSS_VF_FRAME, IA_CSS_PIPE_ID_VIDEO);
2435 int atomisp_css_capture_get_viewfinder_frame_info(
2436 struct atomisp_sub_device *asd,
2437 struct ia_css_frame_info *info)
2439 return __get_frame_info(asd, ATOMISP_INPUT_STREAM_GENERAL, info,
2440 ATOMISP_CSS_VF_FRAME, IA_CSS_PIPE_ID_CAPTURE);
2443 int atomisp_css_copy_get_output_frame_info(
2444 struct atomisp_sub_device *asd,
2445 unsigned int stream_index,
2446 struct ia_css_frame_info *info)
2448 return __get_frame_info(asd, stream_index, info,
2449 ATOMISP_CSS_OUTPUT_FRAME, IA_CSS_PIPE_ID_COPY);
2452 int atomisp_css_preview_get_output_frame_info(
2453 struct atomisp_sub_device *asd,
2454 struct ia_css_frame_info *info)
2456 return __get_frame_info(asd, ATOMISP_INPUT_STREAM_GENERAL, info,
2457 ATOMISP_CSS_OUTPUT_FRAME, IA_CSS_PIPE_ID_PREVIEW);
2460 int atomisp_css_capture_get_output_frame_info(
2461 struct atomisp_sub_device *asd,
2462 struct ia_css_frame_info *info)
2464 return __get_frame_info(asd, ATOMISP_INPUT_STREAM_GENERAL, info,
2465 ATOMISP_CSS_OUTPUT_FRAME, IA_CSS_PIPE_ID_CAPTURE);
2468 int atomisp_css_video_get_output_frame_info(
2469 struct atomisp_sub_device *asd,
2470 struct ia_css_frame_info *info)
2472 return __get_frame_info(asd, ATOMISP_INPUT_STREAM_GENERAL, info,
2473 ATOMISP_CSS_OUTPUT_FRAME, IA_CSS_PIPE_ID_VIDEO);
2476 int atomisp_css_preview_configure_pp_input(
2477 struct atomisp_sub_device *asd,
2478 unsigned int width, unsigned int height)
2480 struct atomisp_stream_env *stream_env =
2481 &asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL];
2482 __configure_preview_pp_input(asd, width, height, IA_CSS_PIPE_ID_PREVIEW);
2484 if (width > stream_env->pipe_configs[IA_CSS_PIPE_ID_CAPTURE].
2485 capt_pp_in_res.width)
2486 __configure_capture_pp_input(asd, width, height, IA_CSS_PIPE_ID_CAPTURE);
2491 int atomisp_css_capture_configure_pp_input(
2492 struct atomisp_sub_device *asd,
2493 unsigned int width, unsigned int height)
2495 __configure_capture_pp_input(asd, width, height, IA_CSS_PIPE_ID_CAPTURE);
2499 int atomisp_css_video_configure_pp_input(
2500 struct atomisp_sub_device *asd,
2501 unsigned int width, unsigned int height)
2503 struct atomisp_stream_env *stream_env =
2504 &asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL];
2506 __configure_video_pp_input(asd, width, height, IA_CSS_PIPE_ID_VIDEO);
2508 if (width > stream_env->pipe_configs[IA_CSS_PIPE_ID_CAPTURE].
2509 capt_pp_in_res.width)
2510 __configure_capture_pp_input(asd, width, height, IA_CSS_PIPE_ID_CAPTURE);
2515 int atomisp_css_offline_capture_configure(struct atomisp_sub_device *asd,
2516 int num_captures, unsigned int skip, int offset)
2520 dev_dbg(asd->isp->dev, "%s num_capture:%d skip:%d offset:%d\n",
2521 __func__, num_captures, skip, offset);
2523 ret = ia_css_stream_capture(
2524 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
2525 num_captures, skip, offset);
2532 int atomisp_css_exp_id_capture(struct atomisp_sub_device *asd, int exp_id)
2536 ret = ia_css_stream_capture_frame(
2537 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
2539 if (ret == -ENOBUFS) {
2540 /* capture cmd queue is full */
2549 int atomisp_css_exp_id_unlock(struct atomisp_sub_device *asd, int exp_id)
2553 ret = ia_css_unlock_raw_frame(
2554 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
2556 if (ret == -ENOBUFS)
2564 int atomisp_css_capture_enable_xnr(struct atomisp_sub_device *asd,
2567 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL]
2568 .pipe_configs[IA_CSS_PIPE_ID_CAPTURE]
2569 .default_capture_config.enable_xnr = enable;
2570 asd->params.capture_config.enable_xnr = enable;
2571 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL]
2572 .update_pipe[IA_CSS_PIPE_ID_CAPTURE] = true;
2577 void atomisp_css_set_ctc_table(struct atomisp_sub_device *asd,
2578 struct ia_css_ctc_table *ctc_table)
2581 u16 *vamem_ptr = ctc_table->data.vamem_1;
2582 int data_size = IA_CSS_VAMEM_1_CTC_TABLE_SIZE;
2585 /* workaround: if ctc_table is all 0, do not apply it */
2586 if (ctc_table->vamem_type == IA_CSS_VAMEM_TYPE_2) {
2587 vamem_ptr = ctc_table->data.vamem_2;
2588 data_size = IA_CSS_VAMEM_2_CTC_TABLE_SIZE;
2591 for (i = 0; i < data_size; i++) {
2592 if (*(vamem_ptr + i)) {
2599 asd->params.config.ctc_table = ctc_table;
2601 dev_warn(asd->isp->dev, "Bypass the invalid ctc_table.\n");
2604 void atomisp_css_set_anr_thres(struct atomisp_sub_device *asd,
2605 struct ia_css_anr_thres *anr_thres)
2607 asd->params.config.anr_thres = anr_thres;
2610 void atomisp_css_set_dvs_6axis(struct atomisp_sub_device *asd,
2611 struct ia_css_dvs_6axis_config *dvs_6axis)
2613 asd->params.config.dvs_6axis_config = dvs_6axis;
2616 void atomisp_css_video_set_dis_vector(struct atomisp_sub_device *asd,
2617 struct atomisp_dis_vector *vector)
2619 if (!asd->params.config.motion_vector)
2620 asd->params.config.motion_vector = &asd->params.css_param.motion_vector;
2622 memset(asd->params.config.motion_vector,
2623 0, sizeof(struct ia_css_vector));
2624 asd->params.css_param.motion_vector.x = vector->x;
2625 asd->params.css_param.motion_vector.y = vector->y;
2628 static int atomisp_compare_dvs_grid(struct atomisp_sub_device *asd,
2629 struct atomisp_dvs_grid_info *atomgrid)
2631 struct ia_css_dvs_grid_info *cur =
2632 atomisp_css_get_dvs_grid_info(&asd->params.curr_grid_info);
2635 dev_err(asd->isp->dev, "dvs grid not available!\n");
2639 if (sizeof(*cur) != sizeof(*atomgrid)) {
2640 dev_err(asd->isp->dev, "dvs grid mismatch!\n");
2645 dev_err(asd->isp->dev, "dvs not enabled!\n");
2649 return memcmp(atomgrid, cur, sizeof(*cur));
2652 void atomisp_css_set_dvs2_coefs(struct atomisp_sub_device *asd,
2653 struct ia_css_dvs2_coefficients *coefs)
2655 asd->params.config.dvs2_coefs = coefs;
2658 int atomisp_css_set_dis_coefs(struct atomisp_sub_device *asd,
2659 struct atomisp_dis_coefficients *coefs)
2661 if (atomisp_compare_dvs_grid(asd, &coefs->grid_info) != 0)
2662 /* If the grid info in the argument differs from the current
2663 grid info, we tell the caller to reset the grid size and
2667 if (!coefs->hor_coefs.odd_real ||
2668 !coefs->hor_coefs.odd_imag ||
2669 !coefs->hor_coefs.even_real ||
2670 !coefs->hor_coefs.even_imag ||
2671 !coefs->ver_coefs.odd_real ||
2672 !coefs->ver_coefs.odd_imag ||
2673 !coefs->ver_coefs.even_real ||
2674 !coefs->ver_coefs.even_imag ||
2675 !asd->params.css_param.dvs2_coeff->hor_coefs.odd_real ||
2676 !asd->params.css_param.dvs2_coeff->hor_coefs.odd_imag ||
2677 !asd->params.css_param.dvs2_coeff->hor_coefs.even_real ||
2678 !asd->params.css_param.dvs2_coeff->hor_coefs.even_imag ||
2679 !asd->params.css_param.dvs2_coeff->ver_coefs.odd_real ||
2680 !asd->params.css_param.dvs2_coeff->ver_coefs.odd_imag ||
2681 !asd->params.css_param.dvs2_coeff->ver_coefs.even_real ||
2682 !asd->params.css_param.dvs2_coeff->ver_coefs.even_imag)
2685 if (copy_from_user(asd->params.css_param.dvs2_coeff->hor_coefs.odd_real,
2686 coefs->hor_coefs.odd_real, asd->params.dvs_hor_coef_bytes))
2688 if (copy_from_user(asd->params.css_param.dvs2_coeff->hor_coefs.odd_imag,
2689 coefs->hor_coefs.odd_imag, asd->params.dvs_hor_coef_bytes))
2691 if (copy_from_user(asd->params.css_param.dvs2_coeff->hor_coefs.even_real,
2692 coefs->hor_coefs.even_real, asd->params.dvs_hor_coef_bytes))
2694 if (copy_from_user(asd->params.css_param.dvs2_coeff->hor_coefs.even_imag,
2695 coefs->hor_coefs.even_imag, asd->params.dvs_hor_coef_bytes))
2698 if (copy_from_user(asd->params.css_param.dvs2_coeff->ver_coefs.odd_real,
2699 coefs->ver_coefs.odd_real, asd->params.dvs_ver_coef_bytes))
2701 if (copy_from_user(asd->params.css_param.dvs2_coeff->ver_coefs.odd_imag,
2702 coefs->ver_coefs.odd_imag, asd->params.dvs_ver_coef_bytes))
2704 if (copy_from_user(asd->params.css_param.dvs2_coeff->ver_coefs.even_real,
2705 coefs->ver_coefs.even_real, asd->params.dvs_ver_coef_bytes))
2707 if (copy_from_user(asd->params.css_param.dvs2_coeff->ver_coefs.even_imag,
2708 coefs->ver_coefs.even_imag, asd->params.dvs_ver_coef_bytes))
2711 asd->params.css_param.update_flag.dvs2_coefs =
2712 (struct atomisp_dis_coefficients *)
2713 asd->params.css_param.dvs2_coeff;
2715 /* asd->params.dis_proj_data_valid = false; */
2716 asd->params.css_update_params_needed = true;
2721 void atomisp_css_set_zoom_factor(struct atomisp_sub_device *asd,
2724 struct atomisp_device *isp = asd->isp;
2726 if (zoom == asd->params.css_param.dz_config.dx &&
2727 zoom == asd->params.css_param.dz_config.dy) {
2728 dev_dbg(isp->dev, "same zoom scale. skipped.\n");
2732 memset(&asd->params.css_param.dz_config, 0,
2733 sizeof(struct ia_css_dz_config));
2734 asd->params.css_param.dz_config.dx = zoom;
2735 asd->params.css_param.dz_config.dy = zoom;
2737 asd->params.css_param.update_flag.dz_config =
2738 (struct atomisp_dz_config *)&asd->params.css_param.dz_config;
2739 asd->params.css_update_params_needed = true;
2742 void atomisp_css_set_formats_config(struct atomisp_sub_device *asd,
2743 struct ia_css_formats_config *formats_config)
2745 asd->params.config.formats_config = formats_config;
2748 int atomisp_css_get_wb_config(struct atomisp_sub_device *asd,
2749 struct atomisp_wb_config *config)
2751 struct ia_css_wb_config wb_config;
2752 struct ia_css_isp_config isp_config;
2753 struct atomisp_device *isp = asd->isp;
2755 if (!asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream) {
2756 dev_err(isp->dev, "%s called after streamoff, skipping.\n",
2760 memset(&wb_config, 0, sizeof(struct ia_css_wb_config));
2761 memset(&isp_config, 0, sizeof(struct ia_css_isp_config));
2762 isp_config.wb_config = &wb_config;
2763 ia_css_stream_get_isp_config(
2764 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
2766 memcpy(config, &wb_config, sizeof(*config));
2771 int atomisp_css_get_ob_config(struct atomisp_sub_device *asd,
2772 struct atomisp_ob_config *config)
2774 struct ia_css_ob_config ob_config;
2775 struct ia_css_isp_config isp_config;
2776 struct atomisp_device *isp = asd->isp;
2778 if (!asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream) {
2779 dev_err(isp->dev, "%s called after streamoff, skipping.\n",
2783 memset(&ob_config, 0, sizeof(struct ia_css_ob_config));
2784 memset(&isp_config, 0, sizeof(struct ia_css_isp_config));
2785 isp_config.ob_config = &ob_config;
2786 ia_css_stream_get_isp_config(
2787 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
2789 memcpy(config, &ob_config, sizeof(*config));
2794 int atomisp_css_get_dp_config(struct atomisp_sub_device *asd,
2795 struct atomisp_dp_config *config)
2797 struct ia_css_dp_config dp_config;
2798 struct ia_css_isp_config isp_config;
2799 struct atomisp_device *isp = asd->isp;
2801 if (!asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream) {
2802 dev_err(isp->dev, "%s called after streamoff, skipping.\n",
2806 memset(&dp_config, 0, sizeof(struct ia_css_dp_config));
2807 memset(&isp_config, 0, sizeof(struct ia_css_isp_config));
2808 isp_config.dp_config = &dp_config;
2809 ia_css_stream_get_isp_config(
2810 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
2812 memcpy(config, &dp_config, sizeof(*config));
2817 int atomisp_css_get_de_config(struct atomisp_sub_device *asd,
2818 struct atomisp_de_config *config)
2820 struct ia_css_de_config de_config;
2821 struct ia_css_isp_config isp_config;
2822 struct atomisp_device *isp = asd->isp;
2824 if (!asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream) {
2825 dev_err(isp->dev, "%s called after streamoff, skipping.\n",
2829 memset(&de_config, 0, sizeof(struct ia_css_de_config));
2830 memset(&isp_config, 0, sizeof(struct ia_css_isp_config));
2831 isp_config.de_config = &de_config;
2832 ia_css_stream_get_isp_config(
2833 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
2835 memcpy(config, &de_config, sizeof(*config));
2840 int atomisp_css_get_nr_config(struct atomisp_sub_device *asd,
2841 struct atomisp_nr_config *config)
2843 struct ia_css_nr_config nr_config;
2844 struct ia_css_isp_config isp_config;
2845 struct atomisp_device *isp = asd->isp;
2847 if (!asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream) {
2848 dev_err(isp->dev, "%s called after streamoff, skipping.\n",
2852 memset(&nr_config, 0, sizeof(struct ia_css_nr_config));
2853 memset(&isp_config, 0, sizeof(struct ia_css_isp_config));
2855 isp_config.nr_config = &nr_config;
2856 ia_css_stream_get_isp_config(
2857 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
2859 memcpy(config, &nr_config, sizeof(*config));
2864 int atomisp_css_get_ee_config(struct atomisp_sub_device *asd,
2865 struct atomisp_ee_config *config)
2867 struct ia_css_ee_config ee_config;
2868 struct ia_css_isp_config isp_config;
2869 struct atomisp_device *isp = asd->isp;
2871 if (!asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream) {
2872 dev_err(isp->dev, "%s called after streamoff, skipping.\n",
2876 memset(&ee_config, 0, sizeof(struct ia_css_ee_config));
2877 memset(&isp_config, 0, sizeof(struct ia_css_isp_config));
2878 isp_config.ee_config = &ee_config;
2879 ia_css_stream_get_isp_config(
2880 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
2882 memcpy(config, &ee_config, sizeof(*config));
2887 int atomisp_css_get_tnr_config(struct atomisp_sub_device *asd,
2888 struct atomisp_tnr_config *config)
2890 struct ia_css_tnr_config tnr_config;
2891 struct ia_css_isp_config isp_config;
2892 struct atomisp_device *isp = asd->isp;
2894 if (!asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream) {
2895 dev_err(isp->dev, "%s called after streamoff, skipping.\n",
2899 memset(&tnr_config, 0, sizeof(struct ia_css_tnr_config));
2900 memset(&isp_config, 0, sizeof(struct ia_css_isp_config));
2901 isp_config.tnr_config = &tnr_config;
2902 ia_css_stream_get_isp_config(
2903 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
2905 memcpy(config, &tnr_config, sizeof(*config));
2910 int atomisp_css_get_ctc_table(struct atomisp_sub_device *asd,
2911 struct atomisp_ctc_table *config)
2913 struct ia_css_ctc_table *tab;
2914 struct ia_css_isp_config isp_config;
2915 struct atomisp_device *isp = asd->isp;
2917 if (!asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream) {
2918 dev_err(isp->dev, "%s called after streamoff, skipping.\n",
2923 tab = vzalloc(sizeof(struct ia_css_ctc_table));
2927 memset(&isp_config, 0, sizeof(struct ia_css_isp_config));
2928 isp_config.ctc_table = tab;
2929 ia_css_stream_get_isp_config(
2930 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
2932 memcpy(config, tab, sizeof(*tab));
2938 int atomisp_css_get_gamma_table(struct atomisp_sub_device *asd,
2939 struct atomisp_gamma_table *config)
2941 struct ia_css_gamma_table *tab;
2942 struct ia_css_isp_config isp_config;
2943 struct atomisp_device *isp = asd->isp;
2945 if (!asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream) {
2946 dev_err(isp->dev, "%s called after streamoff, skipping.\n",
2951 tab = vzalloc(sizeof(struct ia_css_gamma_table));
2955 memset(&isp_config, 0, sizeof(struct ia_css_isp_config));
2956 isp_config.gamma_table = tab;
2957 ia_css_stream_get_isp_config(
2958 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
2960 memcpy(config, tab, sizeof(*tab));
2966 int atomisp_css_get_gc_config(struct atomisp_sub_device *asd,
2967 struct atomisp_gc_config *config)
2969 struct ia_css_gc_config gc_config;
2970 struct ia_css_isp_config isp_config;
2971 struct atomisp_device *isp = asd->isp;
2973 if (!asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream) {
2974 dev_err(isp->dev, "%s called after streamoff, skipping.\n",
2978 memset(&gc_config, 0, sizeof(struct ia_css_gc_config));
2979 memset(&isp_config, 0, sizeof(struct ia_css_isp_config));
2980 isp_config.gc_config = &gc_config;
2981 ia_css_stream_get_isp_config(
2982 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
2984 /* Get gamma correction params from current setup */
2985 memcpy(config, &gc_config, sizeof(*config));
2990 int atomisp_css_get_3a_config(struct atomisp_sub_device *asd,
2991 struct atomisp_3a_config *config)
2993 struct ia_css_3a_config s3a_config;
2994 struct ia_css_isp_config isp_config;
2995 struct atomisp_device *isp = asd->isp;
2997 if (!asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream) {
2998 dev_err(isp->dev, "%s called after streamoff, skipping.\n",
3002 memset(&s3a_config, 0, sizeof(struct ia_css_3a_config));
3003 memset(&isp_config, 0, sizeof(struct ia_css_isp_config));
3004 isp_config.s3a_config = &s3a_config;
3005 ia_css_stream_get_isp_config(
3006 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
3008 /* Get white balance from current setup */
3009 memcpy(config, &s3a_config, sizeof(*config));
3014 int atomisp_css_get_formats_config(struct atomisp_sub_device *asd,
3015 struct atomisp_formats_config *config)
3017 struct ia_css_formats_config formats_config;
3018 struct ia_css_isp_config isp_config;
3019 struct atomisp_device *isp = asd->isp;
3021 if (!asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream) {
3022 dev_err(isp->dev, "%s called after streamoff, skipping.\n",
3026 memset(&formats_config, 0, sizeof(formats_config));
3027 memset(&isp_config, 0, sizeof(isp_config));
3028 isp_config.formats_config = &formats_config;
3029 ia_css_stream_get_isp_config(
3030 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
3032 /* Get narrow gamma from current setup */
3033 memcpy(config, &formats_config, sizeof(*config));
3038 int atomisp_css_get_zoom_factor(struct atomisp_sub_device *asd,
3041 struct ia_css_dz_config dz_config; /** Digital Zoom */
3042 struct ia_css_isp_config isp_config;
3043 struct atomisp_device *isp = asd->isp;
3045 if (!asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream) {
3046 dev_err(isp->dev, "%s called after streamoff, skipping.\n",
3050 memset(&dz_config, 0, sizeof(struct ia_css_dz_config));
3051 memset(&isp_config, 0, sizeof(struct ia_css_isp_config));
3052 isp_config.dz_config = &dz_config;
3053 ia_css_stream_get_isp_config(
3054 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
3056 *zoom = dz_config.dx;
3062 * Function to set/get image stablization statistics
3064 int atomisp_css_get_dis_stat(struct atomisp_sub_device *asd,
3065 struct atomisp_dis_statistics *stats)
3067 struct atomisp_device *isp = asd->isp;
3068 struct atomisp_dis_buf *dis_buf;
3069 unsigned long flags;
3071 lockdep_assert_held(&isp->mutex);
3073 if (!asd->params.dvs_stat->hor_prod.odd_real ||
3074 !asd->params.dvs_stat->hor_prod.odd_imag ||
3075 !asd->params.dvs_stat->hor_prod.even_real ||
3076 !asd->params.dvs_stat->hor_prod.even_imag ||
3077 !asd->params.dvs_stat->ver_prod.odd_real ||
3078 !asd->params.dvs_stat->ver_prod.odd_imag ||
3079 !asd->params.dvs_stat->ver_prod.even_real ||
3080 !asd->params.dvs_stat->ver_prod.even_imag)
3083 /* isp needs to be streaming to get DIS statistics */
3084 if (!asd->streaming)
3087 if (atomisp_compare_dvs_grid(asd, &stats->dvs2_stat.grid_info) != 0)
3088 /* If the grid info in the argument differs from the current
3089 grid info, we tell the caller to reset the grid size and
3093 spin_lock_irqsave(&asd->dis_stats_lock, flags);
3094 if (!asd->params.dis_proj_data_valid || list_empty(&asd->dis_stats)) {
3095 spin_unlock_irqrestore(&asd->dis_stats_lock, flags);
3096 dev_err(isp->dev, "dis statistics is not valid.\n");
3100 dis_buf = list_entry(asd->dis_stats.next,
3101 struct atomisp_dis_buf, list);
3102 list_del_init(&dis_buf->list);
3103 spin_unlock_irqrestore(&asd->dis_stats_lock, flags);
3105 if (dis_buf->dvs_map)
3106 ia_css_translate_dvs2_statistics(
3107 asd->params.dvs_stat, dis_buf->dvs_map);
3109 ia_css_get_dvs2_statistics(asd->params.dvs_stat,
3111 stats->exp_id = dis_buf->dis_data->exp_id;
3113 spin_lock_irqsave(&asd->dis_stats_lock, flags);
3114 list_add_tail(&dis_buf->list, &asd->dis_stats);
3115 spin_unlock_irqrestore(&asd->dis_stats_lock, flags);
3117 if (copy_to_user(stats->dvs2_stat.ver_prod.odd_real,
3118 asd->params.dvs_stat->ver_prod.odd_real,
3119 asd->params.dvs_ver_proj_bytes))
3121 if (copy_to_user(stats->dvs2_stat.ver_prod.odd_imag,
3122 asd->params.dvs_stat->ver_prod.odd_imag,
3123 asd->params.dvs_ver_proj_bytes))
3125 if (copy_to_user(stats->dvs2_stat.ver_prod.even_real,
3126 asd->params.dvs_stat->ver_prod.even_real,
3127 asd->params.dvs_ver_proj_bytes))
3129 if (copy_to_user(stats->dvs2_stat.ver_prod.even_imag,
3130 asd->params.dvs_stat->ver_prod.even_imag,
3131 asd->params.dvs_ver_proj_bytes))
3133 if (copy_to_user(stats->dvs2_stat.hor_prod.odd_real,
3134 asd->params.dvs_stat->hor_prod.odd_real,
3135 asd->params.dvs_hor_proj_bytes))
3137 if (copy_to_user(stats->dvs2_stat.hor_prod.odd_imag,
3138 asd->params.dvs_stat->hor_prod.odd_imag,
3139 asd->params.dvs_hor_proj_bytes))
3141 if (copy_to_user(stats->dvs2_stat.hor_prod.even_real,
3142 asd->params.dvs_stat->hor_prod.even_real,
3143 asd->params.dvs_hor_proj_bytes))
3145 if (copy_to_user(stats->dvs2_stat.hor_prod.even_imag,
3146 asd->params.dvs_stat->hor_prod.even_imag,
3147 asd->params.dvs_hor_proj_bytes))
3153 struct ia_css_shading_table *atomisp_css_shading_table_alloc(
3154 unsigned int width, unsigned int height)
3156 return ia_css_shading_table_alloc(width, height);
3159 void atomisp_css_set_shading_table(struct atomisp_sub_device *asd,
3160 struct ia_css_shading_table *table)
3162 asd->params.config.shading_table = table;
3165 void atomisp_css_shading_table_free(struct ia_css_shading_table *table)
3167 ia_css_shading_table_free(table);
3170 struct ia_css_morph_table *atomisp_css_morph_table_allocate(
3171 unsigned int width, unsigned int height)
3173 return ia_css_morph_table_allocate(width, height);
3176 void atomisp_css_set_morph_table(struct atomisp_sub_device *asd,
3177 struct ia_css_morph_table *table)
3179 asd->params.config.morph_table = table;
3182 void atomisp_css_get_morph_table(struct atomisp_sub_device *asd,
3183 struct ia_css_morph_table *table)
3185 struct ia_css_isp_config isp_config;
3186 struct atomisp_device *isp = asd->isp;
3188 if (!asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream) {
3190 "%s called after streamoff, skipping.\n", __func__);
3193 memset(table, 0, sizeof(struct ia_css_morph_table));
3194 memset(&isp_config, 0, sizeof(struct ia_css_isp_config));
3195 isp_config.morph_table = table;
3196 ia_css_stream_get_isp_config(
3197 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
3201 void atomisp_css_morph_table_free(struct ia_css_morph_table *table)
3203 ia_css_morph_table_free(table);
3206 static bool atomisp_css_isr_get_stream_id(struct ia_css_pipe *css_pipe,
3207 struct atomisp_device *isp,
3208 enum atomisp_input_stream_id *stream_id)
3210 struct atomisp_stream_env *stream_env;
3213 if (!isp->asd.streaming)
3216 for (i = 0; i < ATOMISP_INPUT_STREAM_NUM; i++) {
3217 stream_env = &isp->asd.stream_env[i];
3218 for (j = 0; j < IA_CSS_PIPE_ID_NUM; j++) {
3219 if (stream_env->pipes[j] && stream_env->pipes[j] == css_pipe) {
3229 int atomisp_css_isr_thread(struct atomisp_device *isp)
3231 enum atomisp_input_stream_id stream_id = 0;
3232 struct atomisp_css_event current_event;
3234 lockdep_assert_held(&isp->mutex);
3236 while (!ia_css_dequeue_psys_event(¤t_event.event)) {
3237 if (current_event.event.type ==
3238 IA_CSS_EVENT_TYPE_FW_ASSERT) {
3240 * Received FW assertion signal,
3241 * trigger WDT to recover
3244 "%s: ISP reports FW_ASSERT event! fw_assert_module_id %d fw_assert_line_no %d\n",
3246 current_event.event.fw_assert_module_id,
3247 current_event.event.fw_assert_line_no);
3249 queue_work(system_long_wq, &isp->assert_recovery_work);
3251 } else if (current_event.event.type == IA_CSS_EVENT_TYPE_FW_WARNING) {
3252 dev_warn(isp->dev, "%s: ISP reports warning, code is %d, exp_id %d\n",
3253 __func__, current_event.event.fw_warning,
3254 current_event.event.exp_id);
3258 if (!atomisp_css_isr_get_stream_id(current_event.event.pipe, isp, &stream_id)) {
3259 if (current_event.event.type == IA_CSS_EVENT_TYPE_TIMER)
3261 "event: Timer event.");
3263 dev_warn(isp->dev, "%s:no subdev.event:%d",
3265 current_event.event.type);
3269 atomisp_css_temp_pipe_to_pipe_id(&isp->asd, ¤t_event);
3270 switch (current_event.event.type) {
3271 case IA_CSS_EVENT_TYPE_OUTPUT_FRAME_DONE:
3272 dev_dbg(isp->dev, "event: Output frame done");
3273 atomisp_buf_done(&isp->asd, 0, IA_CSS_BUFFER_TYPE_OUTPUT_FRAME,
3274 current_event.pipe, true, stream_id);
3276 case IA_CSS_EVENT_TYPE_SECOND_OUTPUT_FRAME_DONE:
3277 dev_dbg(isp->dev, "event: Second output frame done");
3278 atomisp_buf_done(&isp->asd, 0, IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME,
3279 current_event.pipe, true, stream_id);
3281 case IA_CSS_EVENT_TYPE_3A_STATISTICS_DONE:
3282 dev_dbg(isp->dev, "event: 3A stats frame done");
3283 atomisp_buf_done(&isp->asd, 0,
3284 IA_CSS_BUFFER_TYPE_3A_STATISTICS,
3288 case IA_CSS_EVENT_TYPE_METADATA_DONE:
3289 dev_dbg(isp->dev, "event: metadata frame done");
3290 atomisp_buf_done(&isp->asd, 0,
3291 IA_CSS_BUFFER_TYPE_METADATA,
3295 case IA_CSS_EVENT_TYPE_VF_OUTPUT_FRAME_DONE:
3296 dev_dbg(isp->dev, "event: VF output frame done");
3297 atomisp_buf_done(&isp->asd, 0,
3298 IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME,
3299 current_event.pipe, true, stream_id);
3301 case IA_CSS_EVENT_TYPE_SECOND_VF_OUTPUT_FRAME_DONE:
3302 dev_dbg(isp->dev, "event: second VF output frame done");
3303 atomisp_buf_done(&isp->asd, 0,
3304 IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME,
3305 current_event.pipe, true, stream_id);
3307 case IA_CSS_EVENT_TYPE_DIS_STATISTICS_DONE:
3308 dev_dbg(isp->dev, "event: dis stats frame done");
3309 atomisp_buf_done(&isp->asd, 0,
3310 IA_CSS_BUFFER_TYPE_DIS_STATISTICS,
3314 case IA_CSS_EVENT_TYPE_PIPELINE_DONE:
3315 dev_dbg(isp->dev, "event: pipeline done");
3317 case IA_CSS_EVENT_TYPE_ACC_STAGE_COMPLETE:
3318 dev_warn(isp->dev, "unexpected event: acc stage done");
3321 dev_dbg(isp->dev, "unhandled css stored event: 0x%x\n",
3322 current_event.event.type);
3330 bool atomisp_css_valid_sof(struct atomisp_device *isp)
3334 /* Loop for each css vc stream */
3335 for (i = 0; i < ATOMISP_INPUT_STREAM_NUM; i++) {
3336 if (!isp->asd.stream_env[i].stream)
3339 dev_dbg(isp->dev, "stream #%d: mode: %d\n",
3340 i, isp->asd.stream_env[i].stream_config.mode);
3341 if (isp->asd.stream_env[i].stream_config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR)
3348 int atomisp_css_debug_dump_isp_binary(void)
3350 ia_css_debug_dump_isp_binary();
3354 int atomisp_css_dump_sp_raw_copy_linecount(bool reduced)
3356 sh_css_dump_sp_raw_copy_linecount(reduced);
3360 static const char * const fw_type_name[] = {
3361 [ia_css_sp_firmware] = "SP",
3362 [ia_css_isp_firmware] = "ISP",
3363 [ia_css_bootloader_firmware] = "BootLoader",
3364 [ia_css_acc_firmware] = "accel",
3367 static const char * const fw_acc_type_name[] = {
3368 [IA_CSS_ACC_NONE] = "Normal",
3369 [IA_CSS_ACC_OUTPUT] = "Accel stage on output",
3370 [IA_CSS_ACC_VIEWFINDER] = "Accel stage on viewfinder",
3371 [IA_CSS_ACC_STANDALONE] = "Stand-alone acceleration",
3374 int atomisp_css_dump_blob_infor(struct atomisp_device *isp)
3376 struct ia_css_blob_descr *bd = sh_css_blob_info;
3377 unsigned int i, nm = sh_css_num_binaries;
3385 * The sh_css_load_firmware function discard the initial
3388 for (i = 0; i < sh_css_num_binaries - NUM_OF_SPS; i++) {
3389 switch (bd[i].header.type) {
3390 case ia_css_isp_firmware:
3391 dev_dbg(isp->dev, "Num%2d type %s (%s), binary id is %2d, name is %s\n",
3393 fw_type_name[bd[i].header.type],
3394 fw_acc_type_name[bd[i].header.info.isp.type],
3395 bd[i].header.info.isp.sp.id,
3399 dev_dbg(isp->dev, "Num%2d type %s, name is %s\n",
3400 i + NUM_OF_SPS, fw_type_name[bd[i].header.type],
3408 void atomisp_css_set_isp_config_id(struct atomisp_sub_device *asd,
3409 uint32_t isp_config_id)
3411 asd->params.config.isp_config_id = isp_config_id;
3414 void atomisp_css_set_isp_config_applied_frame(struct atomisp_sub_device *asd,
3415 struct ia_css_frame *output_frame)
3417 asd->params.config.output_frame = output_frame;
3420 int atomisp_get_css_dbgfunc(void)
3425 int atomisp_set_css_dbgfunc(struct atomisp_device *isp, int opt)
3429 ret = __set_css_print_env(isp, opt);
3436 void atomisp_en_dz_capt_pipe(struct atomisp_sub_device *asd, bool enable)
3438 ia_css_en_dz_capt_pipe(
3439 asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream,
3443 struct ia_css_dvs_grid_info *atomisp_css_get_dvs_grid_info(
3444 struct ia_css_grid_info *grid_info)
3449 #ifdef IA_CSS_DVS_STAT_GRID_INFO_SUPPORTED
3450 return &grid_info->dvs_grid.dvs_grid_info;
3452 return &grid_info->dvs_grid;