1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Support for Medifield PNW Camera Imaging ISP subsystem.
4  *
5  * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
6  *
7  * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License version
11  * 2 as published by the Free Software Foundation.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  *
19  */
20 
21 #include <linux/module.h>
22 #include <linux/pm_runtime.h>
23 
24 #include <media/v4l2-ioctl.h>
25 #include <media/videobuf2-vmalloc.h>
26 
27 #include "atomisp_cmd.h"
28 #include "atomisp_common.h"
29 #include "atomisp_fops.h"
30 #include "atomisp_internal.h"
31 #include "atomisp_ioctl.h"
32 #include "atomisp_compat.h"
33 #include "atomisp_subdev.h"
34 #include "atomisp_v4l2.h"
35 #include "atomisp-regs.h"
36 #include "hmm/hmm.h"
37 
38 #include "ia_css_frame.h"
39 #include "type_support.h"
40 #include "device_access/device_access.h"
41 
42 /*
43  * Videobuf2 ops
44  */
45 static int atomisp_queue_setup(struct vb2_queue *vq,
46 			       unsigned int *nbuffers, unsigned int *nplanes,
47 			       unsigned int sizes[], struct device *alloc_devs[])
48 {
49 	struct atomisp_video_pipe *pipe = container_of(vq, struct atomisp_video_pipe, vb_queue);
50 	u16 source_pad = atomisp_subdev_source_pad(&pipe->vdev);
51 	int ret;
52 
53 	mutex_lock(&pipe->asd->isp->mutex); /* for get_css_frame_info() / set_fmt() */
54 
55 	/*
56 	 * When VIDIOC_S_FMT has not been called before VIDIOC_REQBUFS, then
57 	 * this will fail. Call atomisp_set_fmt() ourselves and try again.
58 	 */
59 	ret = atomisp_get_css_frame_info(pipe->asd, source_pad, &pipe->frame_info);
60 	if (ret) {
61 		struct v4l2_format f = {
62 			.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420,
63 			.fmt.pix.width = 10000,
64 			.fmt.pix.height = 10000,
65 		};
66 
67 		ret = atomisp_set_fmt(&pipe->vdev, &f);
68 		if (ret)
69 			goto out;
70 
71 		ret = atomisp_get_css_frame_info(pipe->asd, source_pad, &pipe->frame_info);
72 		if (ret)
73 			goto out;
74 	}
75 
76 	atomisp_alloc_css_stat_bufs(pipe->asd, ATOMISP_INPUT_STREAM_GENERAL);
77 
78 	*nplanes = 1;
79 	sizes[0] = PAGE_ALIGN(pipe->pix.sizeimage);
80 
81 out:
82 	mutex_unlock(&pipe->asd->isp->mutex);
83 	return 0;
84 }
85 
86 static int atomisp_buf_init(struct vb2_buffer *vb)
87 {
88 	struct atomisp_video_pipe *pipe = vb_to_pipe(vb);
89 	struct ia_css_frame *frame = vb_to_frame(vb);
90 	int ret;
91 
92 	ret = ia_css_frame_init_from_info(frame, &pipe->frame_info);
93 	if (ret)
94 		return ret;
95 
96 	if (frame->data_bytes > vb2_plane_size(vb, 0)) {
97 		dev_err(pipe->asd->isp->dev, "Internal error frame.data_bytes(%u) > vb.length(%lu)\n",
98 			frame->data_bytes, vb2_plane_size(vb, 0));
99 		return -EIO;
100 	}
101 
102 	frame->data = hmm_create_from_vmalloc_buf(vb2_plane_size(vb, 0),
103 						  vb2_plane_vaddr(vb, 0));
104 	if (frame->data == mmgr_NULL)
105 		return -ENOMEM;
106 
107 	return 0;
108 }
109 
110 static int atomisp_q_one_metadata_buffer(struct atomisp_sub_device *asd,
111 	enum atomisp_input_stream_id stream_id,
112 	enum ia_css_pipe_id css_pipe_id)
113 {
114 	struct atomisp_metadata_buf *metadata_buf;
115 	enum atomisp_metadata_type md_type =
116 	    atomisp_get_metadata_type(asd, css_pipe_id);
117 	struct list_head *metadata_list;
118 
119 	if (asd->metadata_bufs_in_css[stream_id][css_pipe_id] >=
120 	    ATOMISP_CSS_Q_DEPTH)
121 		return 0; /* we have reached CSS queue depth */
122 
123 	if (!list_empty(&asd->metadata[md_type])) {
124 		metadata_list = &asd->metadata[md_type];
125 	} else if (!list_empty(&asd->metadata_ready[md_type])) {
126 		metadata_list = &asd->metadata_ready[md_type];
127 	} else {
128 		dev_warn(asd->isp->dev, "%s: No metadata buffers available for type %d!\n",
129 			 __func__, md_type);
130 		return -EINVAL;
131 	}
132 
133 	metadata_buf = list_entry(metadata_list->next,
134 				  struct atomisp_metadata_buf, list);
135 	list_del_init(&metadata_buf->list);
136 
137 	if (atomisp_q_metadata_buffer_to_css(asd, metadata_buf,
138 					     stream_id, css_pipe_id)) {
139 		list_add(&metadata_buf->list, metadata_list);
140 		return -EINVAL;
141 	} else {
142 		list_add_tail(&metadata_buf->list,
143 			      &asd->metadata_in_css[md_type]);
144 	}
145 	asd->metadata_bufs_in_css[stream_id][css_pipe_id]++;
146 
147 	return 0;
148 }
149 
150 static int atomisp_q_one_s3a_buffer(struct atomisp_sub_device *asd,
151 				    enum atomisp_input_stream_id stream_id,
152 				    enum ia_css_pipe_id css_pipe_id)
153 {
154 	struct atomisp_s3a_buf *s3a_buf;
155 	struct list_head *s3a_list;
156 	unsigned int exp_id;
157 
158 	if (asd->s3a_bufs_in_css[css_pipe_id] >= ATOMISP_CSS_Q_DEPTH)
159 		return 0; /* we have reached CSS queue depth */
160 
161 	if (!list_empty(&asd->s3a_stats)) {
162 		s3a_list = &asd->s3a_stats;
163 	} else if (!list_empty(&asd->s3a_stats_ready)) {
164 		s3a_list = &asd->s3a_stats_ready;
165 	} else {
166 		dev_warn(asd->isp->dev, "%s: No s3a buffers available!\n",
167 			 __func__);
168 		return -EINVAL;
169 	}
170 
171 	s3a_buf = list_entry(s3a_list->next, struct atomisp_s3a_buf, list);
172 	list_del_init(&s3a_buf->list);
173 	exp_id = s3a_buf->s3a_data->exp_id;
174 
175 	hmm_flush_vmap(s3a_buf->s3a_data->data_ptr);
176 	if (atomisp_q_s3a_buffer_to_css(asd, s3a_buf,
177 					stream_id, css_pipe_id)) {
178 		/* got from head, so return back to the head */
179 		list_add(&s3a_buf->list, s3a_list);
180 		return -EINVAL;
181 	} else {
182 		list_add_tail(&s3a_buf->list, &asd->s3a_stats_in_css);
183 		if (s3a_list == &asd->s3a_stats_ready)
184 			dev_dbg(asd->isp->dev, "drop one s3a stat with exp_id %d\n", exp_id);
185 	}
186 
187 	asd->s3a_bufs_in_css[css_pipe_id]++;
188 	return 0;
189 }
190 
191 static int atomisp_q_one_dis_buffer(struct atomisp_sub_device *asd,
192 				    enum atomisp_input_stream_id stream_id,
193 				    enum ia_css_pipe_id css_pipe_id)
194 {
195 	struct atomisp_dis_buf *dis_buf;
196 	unsigned long irqflags;
197 
198 	if (asd->dis_bufs_in_css >=  ATOMISP_CSS_Q_DEPTH)
199 		return 0; /* we have reached CSS queue depth */
200 
201 	spin_lock_irqsave(&asd->dis_stats_lock, irqflags);
202 	if (list_empty(&asd->dis_stats)) {
203 		spin_unlock_irqrestore(&asd->dis_stats_lock, irqflags);
204 		dev_warn(asd->isp->dev, "%s: No dis buffers available!\n",
205 			 __func__);
206 		return -EINVAL;
207 	}
208 
209 	dis_buf = list_entry(asd->dis_stats.prev,
210 			     struct atomisp_dis_buf, list);
211 	list_del_init(&dis_buf->list);
212 	spin_unlock_irqrestore(&asd->dis_stats_lock, irqflags);
213 
214 	hmm_flush_vmap(dis_buf->dis_data->data_ptr);
215 	if (atomisp_q_dis_buffer_to_css(asd, dis_buf,
216 					stream_id, css_pipe_id)) {
217 		spin_lock_irqsave(&asd->dis_stats_lock, irqflags);
218 		/* got from tail, so return back to the tail */
219 		list_add_tail(&dis_buf->list, &asd->dis_stats);
220 		spin_unlock_irqrestore(&asd->dis_stats_lock, irqflags);
221 		return -EINVAL;
222 	} else {
223 		spin_lock_irqsave(&asd->dis_stats_lock, irqflags);
224 		list_add_tail(&dis_buf->list, &asd->dis_stats_in_css);
225 		spin_unlock_irqrestore(&asd->dis_stats_lock, irqflags);
226 	}
227 
228 	asd->dis_bufs_in_css++;
229 
230 	return 0;
231 }
232 
233 static int atomisp_q_video_buffers_to_css(struct atomisp_sub_device *asd,
234 					  struct atomisp_video_pipe *pipe,
235 					  enum atomisp_input_stream_id stream_id,
236 					  enum ia_css_buffer_type css_buf_type,
237 					  enum ia_css_pipe_id css_pipe_id)
238 {
239 	struct atomisp_css_params_with_list *param;
240 	struct ia_css_dvs_grid_info *dvs_grid =
241 	    atomisp_css_get_dvs_grid_info(&asd->params.curr_grid_info);
242 	unsigned long irqflags;
243 	int space, err = 0;
244 
245 	lockdep_assert_held(&asd->isp->mutex);
246 
247 	if (WARN_ON(css_pipe_id >= IA_CSS_PIPE_ID_NUM))
248 		return -EINVAL;
249 
250 	if (pipe->stopping)
251 		return -EINVAL;
252 
253 	space = ATOMISP_CSS_Q_DEPTH - atomisp_buffers_in_css(pipe);
254 	while (space--) {
255 		struct ia_css_frame *frame;
256 
257 		spin_lock_irqsave(&pipe->irq_lock, irqflags);
258 		frame = list_first_entry_or_null(&pipe->activeq, struct ia_css_frame, queue);
259 		if (frame)
260 			list_move_tail(&frame->queue, &pipe->buffers_in_css);
261 		spin_unlock_irqrestore(&pipe->irq_lock, irqflags);
262 
263 		if (!frame)
264 			return -EINVAL;
265 
266 		/*
267 		 * If there is a per_frame setting to apply on the buffer,
268 		 * do it before buffer en-queueing.
269 		 */
270 		param = pipe->frame_params[frame->vb.vb2_buf.index];
271 		if (param) {
272 			atomisp_makeup_css_parameters(asd,
273 						      &asd->params.css_param.update_flag,
274 						      &param->params);
275 			atomisp_apply_css_parameters(asd, &param->params);
276 
277 			if (param->params.update_flag.dz_config &&
278 			    asd->run_mode->val != ATOMISP_RUN_MODE_VIDEO) {
279 				err = atomisp_calculate_real_zoom_region(asd,
280 					&param->params.dz_config, css_pipe_id);
281 				if (!err)
282 					asd->params.config.dz_config = &param->params.dz_config;
283 			}
284 			atomisp_css_set_isp_config_applied_frame(asd, frame);
285 			atomisp_css_update_isp_params_on_pipe(asd,
286 							      asd->stream_env[stream_id].pipes[css_pipe_id]);
287 			asd->params.dvs_6axis = (struct ia_css_dvs_6axis_config *)
288 						param->params.dvs_6axis;
289 
290 			/*
291 			 * WORKAROUND:
292 			 * Because the camera halv3 can't ensure to set zoom
293 			 * region to per_frame setting and global setting at
294 			 * same time and only set zoom region to pre_frame
295 			 * setting now.so when the pre_frame setting include
296 			 * zoom region,I will set it to global setting.
297 			 */
298 			if (param->params.update_flag.dz_config &&
299 			    asd->run_mode->val != ATOMISP_RUN_MODE_VIDEO
300 			    && !err) {
301 				memcpy(&asd->params.css_param.dz_config,
302 				       &param->params.dz_config,
303 				       sizeof(struct ia_css_dz_config));
304 				asd->params.css_param.update_flag.dz_config =
305 				    (struct atomisp_dz_config *)
306 				    &asd->params.css_param.dz_config;
307 				asd->params.css_update_params_needed = true;
308 			}
309 			pipe->frame_params[frame->vb.vb2_buf.index] = NULL;
310 		}
311 		/* Enqueue buffer */
312 		err = atomisp_q_video_buffer_to_css(asd, frame, stream_id,
313 						    css_buf_type, css_pipe_id);
314 		if (err) {
315 			spin_lock_irqsave(&pipe->irq_lock, irqflags);
316 			list_move_tail(&frame->queue, &pipe->activeq);
317 			spin_unlock_irqrestore(&pipe->irq_lock, irqflags);
318 			dev_err(asd->isp->dev, "%s, css q fails: %d\n",
319 				__func__, err);
320 			return -EINVAL;
321 		}
322 
323 		/* enqueue 3A/DIS/metadata buffers */
324 		if (asd->params.curr_grid_info.s3a_grid.enable &&
325 		    css_pipe_id == asd->params.s3a_enabled_pipe &&
326 		    css_buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME)
327 			atomisp_q_one_s3a_buffer(asd, stream_id,
328 						 css_pipe_id);
329 
330 		if (asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream_info.
331 		    metadata_info.size &&
332 		    css_buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME)
333 			atomisp_q_one_metadata_buffer(asd, stream_id,
334 						      css_pipe_id);
335 
336 		if (dvs_grid && dvs_grid->enable &&
337 		    css_pipe_id == IA_CSS_PIPE_ID_VIDEO &&
338 		    css_buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME)
339 			atomisp_q_one_dis_buffer(asd, stream_id,
340 						 css_pipe_id);
341 	}
342 
343 	return 0;
344 }
345 
346 static int atomisp_get_css_buf_type(struct atomisp_sub_device *asd,
347 				    enum ia_css_pipe_id pipe_id,
348 				    uint16_t source_pad)
349 {
350 	if (ATOMISP_USE_YUVPP(asd)) {
351 		/* when run ZSL case */
352 		if (asd->continuous_mode->val &&
353 		    asd->run_mode->val == ATOMISP_RUN_MODE_PREVIEW) {
354 			if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE)
355 				return IA_CSS_BUFFER_TYPE_OUTPUT_FRAME;
356 			else if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW)
357 				return IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME;
358 			else
359 				return IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME;
360 		}
361 
362 		/*when run SDV case*/
363 		if (asd->continuous_mode->val &&
364 		    asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) {
365 			if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE)
366 				return IA_CSS_BUFFER_TYPE_OUTPUT_FRAME;
367 			else if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW)
368 				return IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME;
369 			else if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_VIDEO)
370 				return IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME;
371 			else
372 				return IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME;
373 		}
374 
375 		/*other case: default setting*/
376 		if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE ||
377 		    source_pad == ATOMISP_SUBDEV_PAD_SOURCE_VIDEO ||
378 		    (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW &&
379 		     asd->run_mode->val != ATOMISP_RUN_MODE_VIDEO))
380 			return IA_CSS_BUFFER_TYPE_OUTPUT_FRAME;
381 		else
382 			return IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME;
383 	}
384 
385 	if (pipe_id == IA_CSS_PIPE_ID_COPY ||
386 	    source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE ||
387 	    source_pad == ATOMISP_SUBDEV_PAD_SOURCE_VIDEO ||
388 	    (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW &&
389 	     asd->run_mode->val != ATOMISP_RUN_MODE_VIDEO))
390 		return IA_CSS_BUFFER_TYPE_OUTPUT_FRAME;
391 	else
392 		return IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME;
393 }
394 
395 /* queue all available buffers to css */
396 int atomisp_qbuffers_to_css(struct atomisp_sub_device *asd)
397 {
398 	enum ia_css_buffer_type buf_type;
399 	enum ia_css_pipe_id css_capture_pipe_id = IA_CSS_PIPE_ID_NUM;
400 	enum ia_css_pipe_id css_preview_pipe_id = IA_CSS_PIPE_ID_NUM;
401 	enum ia_css_pipe_id css_video_pipe_id = IA_CSS_PIPE_ID_NUM;
402 	enum atomisp_input_stream_id input_stream_id;
403 	struct atomisp_video_pipe *capture_pipe = NULL;
404 	struct atomisp_video_pipe *vf_pipe = NULL;
405 	struct atomisp_video_pipe *preview_pipe = NULL;
406 	struct atomisp_video_pipe *video_pipe = NULL;
407 	bool raw_mode = atomisp_is_mbuscode_raw(
408 			    asd->fmt[asd->capture_pad].fmt.code);
409 
410 	if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_SCALER) {
411 		video_pipe = &asd->video_out_video_capture;
412 		css_video_pipe_id = IA_CSS_PIPE_ID_VIDEO;
413 	} else if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_LOWLAT) {
414 		preview_pipe = &asd->video_out_capture;
415 		css_preview_pipe_id = IA_CSS_PIPE_ID_CAPTURE;
416 	} else if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) {
417 		if (asd->continuous_mode->val) {
418 			capture_pipe = &asd->video_out_capture;
419 			vf_pipe = &asd->video_out_vf;
420 			css_capture_pipe_id = IA_CSS_PIPE_ID_CAPTURE;
421 		}
422 		video_pipe = &asd->video_out_video_capture;
423 		preview_pipe = &asd->video_out_preview;
424 		css_video_pipe_id = IA_CSS_PIPE_ID_VIDEO;
425 		css_preview_pipe_id = IA_CSS_PIPE_ID_VIDEO;
426 	} else if (asd->continuous_mode->val) {
427 		capture_pipe = &asd->video_out_capture;
428 		vf_pipe = &asd->video_out_vf;
429 		preview_pipe = &asd->video_out_preview;
430 
431 		css_preview_pipe_id = IA_CSS_PIPE_ID_PREVIEW;
432 		css_capture_pipe_id = IA_CSS_PIPE_ID_CAPTURE;
433 	} else if (asd->run_mode->val == ATOMISP_RUN_MODE_PREVIEW) {
434 		preview_pipe = &asd->video_out_preview;
435 		css_preview_pipe_id = IA_CSS_PIPE_ID_PREVIEW;
436 	} else {
437 		/* ATOMISP_RUN_MODE_STILL_CAPTURE */
438 		capture_pipe = &asd->video_out_capture;
439 		if (!raw_mode)
440 			vf_pipe = &asd->video_out_vf;
441 		css_capture_pipe_id = IA_CSS_PIPE_ID_CAPTURE;
442 	}
443 
444 	if (IS_ISP2401 && asd->copy_mode) {
445 		css_capture_pipe_id = IA_CSS_PIPE_ID_COPY;
446 		css_preview_pipe_id = IA_CSS_PIPE_ID_COPY;
447 		css_video_pipe_id = IA_CSS_PIPE_ID_COPY;
448 	}
449 
450 	if (asd->yuvpp_mode) {
451 		capture_pipe = &asd->video_out_capture;
452 		video_pipe   = &asd->video_out_video_capture;
453 		preview_pipe = &asd->video_out_preview;
454 		css_capture_pipe_id = IA_CSS_PIPE_ID_COPY;
455 		css_video_pipe_id   = IA_CSS_PIPE_ID_YUVPP;
456 		css_preview_pipe_id = IA_CSS_PIPE_ID_YUVPP;
457 	}
458 
459 	if (capture_pipe) {
460 		buf_type = atomisp_get_css_buf_type(
461 			       asd, css_capture_pipe_id,
462 			       atomisp_subdev_source_pad(&capture_pipe->vdev));
463 		input_stream_id = ATOMISP_INPUT_STREAM_GENERAL;
464 
465 		/*
466 		 * use yuvpp pipe for SOC camera.
467 		 */
468 		if (ATOMISP_USE_YUVPP(asd))
469 			css_capture_pipe_id = IA_CSS_PIPE_ID_YUVPP;
470 
471 		atomisp_q_video_buffers_to_css(asd, capture_pipe,
472 					       input_stream_id,
473 					       buf_type, css_capture_pipe_id);
474 	}
475 
476 	if (vf_pipe) {
477 		buf_type = atomisp_get_css_buf_type(
478 			       asd, css_capture_pipe_id,
479 			       atomisp_subdev_source_pad(&vf_pipe->vdev));
480 		if (asd->stream_env[ATOMISP_INPUT_STREAM_POSTVIEW].stream)
481 			input_stream_id = ATOMISP_INPUT_STREAM_POSTVIEW;
482 		else
483 			input_stream_id = ATOMISP_INPUT_STREAM_GENERAL;
484 
485 		/*
486 		 * use yuvpp pipe for SOC camera.
487 		 */
488 		if (ATOMISP_USE_YUVPP(asd))
489 			css_capture_pipe_id = IA_CSS_PIPE_ID_YUVPP;
490 		atomisp_q_video_buffers_to_css(asd, vf_pipe,
491 					       input_stream_id,
492 					       buf_type, css_capture_pipe_id);
493 	}
494 
495 	if (preview_pipe) {
496 		buf_type = atomisp_get_css_buf_type(
497 			       asd, css_preview_pipe_id,
498 			       atomisp_subdev_source_pad(&preview_pipe->vdev));
499 		if (ATOMISP_SOC_CAMERA(asd) && css_preview_pipe_id == IA_CSS_PIPE_ID_YUVPP)
500 			input_stream_id = ATOMISP_INPUT_STREAM_GENERAL;
501 		/* else for ext isp use case */
502 		else if (css_preview_pipe_id == IA_CSS_PIPE_ID_YUVPP)
503 			input_stream_id = ATOMISP_INPUT_STREAM_VIDEO;
504 		else if (asd->stream_env[ATOMISP_INPUT_STREAM_PREVIEW].stream)
505 			input_stream_id = ATOMISP_INPUT_STREAM_PREVIEW;
506 		else
507 			input_stream_id = ATOMISP_INPUT_STREAM_GENERAL;
508 
509 		/*
510 		 * use yuvpp pipe for SOC camera.
511 		 */
512 		if (ATOMISP_USE_YUVPP(asd))
513 			css_preview_pipe_id = IA_CSS_PIPE_ID_YUVPP;
514 
515 		atomisp_q_video_buffers_to_css(asd, preview_pipe,
516 					       input_stream_id,
517 					       buf_type, css_preview_pipe_id);
518 	}
519 
520 	if (video_pipe) {
521 		buf_type = atomisp_get_css_buf_type(
522 			       asd, css_video_pipe_id,
523 			       atomisp_subdev_source_pad(&video_pipe->vdev));
524 		if (asd->stream_env[ATOMISP_INPUT_STREAM_VIDEO].stream)
525 			input_stream_id = ATOMISP_INPUT_STREAM_VIDEO;
526 		else
527 			input_stream_id = ATOMISP_INPUT_STREAM_GENERAL;
528 
529 		/*
530 		 * use yuvpp pipe for SOC camera.
531 		 */
532 		if (ATOMISP_USE_YUVPP(asd))
533 			css_video_pipe_id = IA_CSS_PIPE_ID_YUVPP;
534 
535 		atomisp_q_video_buffers_to_css(asd, video_pipe,
536 					       input_stream_id,
537 					       buf_type, css_video_pipe_id);
538 	}
539 
540 	return 0;
541 }
542 
543 static void atomisp_buf_queue(struct vb2_buffer *vb)
544 {
545 	struct atomisp_video_pipe *pipe = vb_to_pipe(vb);
546 	struct ia_css_frame *frame = vb_to_frame(vb);
547 	struct atomisp_sub_device *asd = pipe->asd;
548 	u16 source_pad = atomisp_subdev_source_pad(&pipe->vdev);
549 	unsigned long irqflags;
550 	int ret;
551 
552 	mutex_lock(&asd->isp->mutex);
553 
554 	ret = atomisp_pipe_check(pipe, false);
555 	if (ret || pipe->stopping) {
556 		spin_lock_irqsave(&pipe->irq_lock, irqflags);
557 		atomisp_buffer_done(frame, VB2_BUF_STATE_ERROR);
558 		spin_unlock_irqrestore(&pipe->irq_lock, irqflags);
559 		goto out_unlock;
560 	}
561 
562 	/* FIXME this ugliness comes from the original atomisp buffer handling */
563 	if (!(vb->skip_cache_sync_on_finish && vb->skip_cache_sync_on_prepare))
564 		wbinvd();
565 
566 	pipe->frame_params[vb->index] = NULL;
567 
568 	spin_lock_irqsave(&pipe->irq_lock, irqflags);
569 	/*
570 	 * when a frame buffer meets following conditions, it should be put into
571 	 * the waiting list:
572 	 * 1.  It is not a main output frame, and it has a per-frame parameter
573 	 *     to go with it.
574 	 * 2.  It is not a main output frame, and the waiting buffer list is not
575 	 *     empty, to keep the FIFO sequence of frame buffer processing, it
576 	 *     is put to waiting list until previous per-frame parameter buffers
577 	 *     get enqueued.
578 	 */
579 	if (!atomisp_is_vf_pipe(pipe) &&
580 	    (pipe->frame_request_config_id[vb->index] ||
581 	     !list_empty(&pipe->buffers_waiting_for_param)))
582 		list_add_tail(&frame->queue, &pipe->buffers_waiting_for_param);
583 	else
584 		list_add_tail(&frame->queue, &pipe->activeq);
585 
586 	spin_unlock_irqrestore(&pipe->irq_lock, irqflags);
587 
588 	/* TODO: do this better, not best way to queue to css */
589 	if (asd->streaming == ATOMISP_DEVICE_STREAMING_ENABLED) {
590 		if (!list_empty(&pipe->buffers_waiting_for_param))
591 			atomisp_handle_parameter_and_buffer(pipe);
592 		else
593 			atomisp_qbuffers_to_css(asd);
594 	}
595 
596 	/*
597 	 * Workaround: Due to the design of HALv3,
598 	 * sometimes in ZSL or SDV mode HAL needs to
599 	 * capture multiple images within one streaming cycle.
600 	 * But the capture number cannot be determined by HAL.
601 	 * So HAL only sets the capture number to be 1 and queue multiple
602 	 * buffers. Atomisp driver needs to check this case and re-trigger
603 	 * CSS to do capture when new buffer is queued.
604 	 */
605 	if (asd->continuous_mode->val && source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE &&
606 	    !asd->enable_raw_buffer_lock->val && asd->params.offline_parm.num_captures == 1) {
607 		asd->pending_capture_request++;
608 		dev_dbg(asd->isp->dev, "Add one pending capture request.\n");
609 	}
610 
611 out_unlock:
612 	mutex_unlock(&asd->isp->mutex);
613 }
614 
615 static void atomisp_buf_cleanup(struct vb2_buffer *vb)
616 {
617 	struct atomisp_video_pipe *pipe = vb_to_pipe(vb);
618 	struct ia_css_frame *frame = vb_to_frame(vb);
619 	int index = frame->vb.vb2_buf.index;
620 
621 	pipe->frame_request_config_id[index] = 0;
622 	pipe->frame_params[index] = NULL;
623 
624 	hmm_free(frame->data);
625 }
626 
627 static const struct vb2_ops atomisp_vb2_ops = {
628 	.queue_setup		= atomisp_queue_setup,
629 	.buf_init		= atomisp_buf_init,
630 	.buf_cleanup		= atomisp_buf_cleanup,
631 	.buf_queue		= atomisp_buf_queue,
632 	.start_streaming	= atomisp_start_streaming,
633 	.stop_streaming		= atomisp_stop_streaming,
634 };
635 
636 static int atomisp_init_pipe(struct atomisp_video_pipe *pipe)
637 {
638 	int ret;
639 
640 	/* init locks */
641 	spin_lock_init(&pipe->irq_lock);
642 	mutex_init(&pipe->vb_queue_mutex);
643 
644 	/* Init videobuf2 queue structure */
645 	pipe->vb_queue.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
646 	pipe->vb_queue.io_modes = VB2_MMAP | VB2_USERPTR;
647 	pipe->vb_queue.buf_struct_size = sizeof(struct ia_css_frame);
648 	pipe->vb_queue.ops = &atomisp_vb2_ops;
649 	pipe->vb_queue.mem_ops = &vb2_vmalloc_memops;
650 	pipe->vb_queue.timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC;
651 	ret = vb2_queue_init(&pipe->vb_queue);
652 	if (ret)
653 		return ret;
654 
655 	pipe->vdev.queue = &pipe->vb_queue;
656 	pipe->vdev.queue->lock = &pipe->vb_queue_mutex;
657 
658 	INIT_LIST_HEAD(&pipe->activeq);
659 	INIT_LIST_HEAD(&pipe->buffers_waiting_for_param);
660 	INIT_LIST_HEAD(&pipe->per_frame_params);
661 	memset(pipe->frame_request_config_id, 0,
662 	       VIDEO_MAX_FRAME * sizeof(unsigned int));
663 	memset(pipe->frame_params, 0,
664 	       VIDEO_MAX_FRAME *
665 	       sizeof(struct atomisp_css_params_with_list *));
666 
667 	return 0;
668 }
669 
670 static void atomisp_dev_init_struct(struct atomisp_device *isp)
671 {
672 	unsigned int i;
673 
674 	isp->need_gfx_throttle = true;
675 	isp->isp_fatal_error = false;
676 	isp->mipi_frame_size = 0;
677 
678 	for (i = 0; i < isp->input_cnt; i++)
679 		isp->inputs[i].asd = NULL;
680 	/*
681 	 * For Merrifield, frequency is scalable.
682 	 * After boot-up, the default frequency is 200MHz.
683 	 */
684 	isp->sw_contex.running_freq = ISP_FREQ_200MHZ;
685 }
686 
687 static void atomisp_subdev_init_struct(struct atomisp_sub_device *asd)
688 {
689 	v4l2_ctrl_s_ctrl(asd->run_mode, ATOMISP_RUN_MODE_STILL_CAPTURE);
690 	memset(&asd->params.css_param, 0, sizeof(asd->params.css_param));
691 	asd->params.color_effect = V4L2_COLORFX_NONE;
692 	asd->params.bad_pixel_en = true;
693 	asd->params.gdc_cac_en = false;
694 	asd->params.video_dis_en = false;
695 	asd->params.sc_en = false;
696 	asd->params.fpn_en = false;
697 	asd->params.xnr_en = false;
698 	asd->params.false_color = 0;
699 	asd->params.online_process = 1;
700 	asd->params.yuv_ds_en = 0;
701 	/* s3a grid not enabled for any pipe */
702 	asd->params.s3a_enabled_pipe = IA_CSS_PIPE_ID_NUM;
703 
704 	asd->params.offline_parm.num_captures = 1;
705 	asd->params.offline_parm.skip_frames = 0;
706 	asd->params.offline_parm.offset = 0;
707 	asd->delayed_init = ATOMISP_DELAYED_INIT_NOT_QUEUED;
708 	/* Add for channel */
709 	asd->input_curr = 0;
710 
711 	asd->mipi_frame_size = 0;
712 	asd->copy_mode = false;
713 	asd->yuvpp_mode = false;
714 
715 	asd->stream_prepared = false;
716 	asd->high_speed_mode = false;
717 	asd->sensor_array_res.height = 0;
718 	asd->sensor_array_res.width = 0;
719 	atomisp_css_init_struct(asd);
720 }
721 
722 /*
723  * file operation functions
724  */
725 static unsigned int atomisp_subdev_users(struct atomisp_sub_device *asd)
726 {
727 	return asd->video_out_preview.users +
728 	       asd->video_out_vf.users +
729 	       asd->video_out_capture.users +
730 	       asd->video_out_video_capture.users;
731 }
732 
733 unsigned int atomisp_dev_users(struct atomisp_device *isp)
734 {
735 	unsigned int i, sum;
736 
737 	for (i = 0, sum = 0; i < isp->num_of_streams; i++)
738 		sum += atomisp_subdev_users(&isp->asd[i]);
739 
740 	return sum;
741 }
742 
743 static int atomisp_open(struct file *file)
744 {
745 	struct video_device *vdev = video_devdata(file);
746 	struct atomisp_device *isp = video_get_drvdata(vdev);
747 	struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
748 	struct atomisp_sub_device *asd = pipe->asd;
749 	int ret;
750 
751 	dev_dbg(isp->dev, "open device %s\n", vdev->name);
752 
753 	ret = v4l2_fh_open(file);
754 	if (ret)
755 		return ret;
756 
757 	mutex_lock(&isp->mutex);
758 
759 	asd->subdev.devnode = vdev;
760 	/* Deferred firmware loading case. */
761 	if (isp->css_env.isp_css_fw.bytes == 0) {
762 		dev_err(isp->dev, "Deferred firmware load.\n");
763 		isp->firmware = atomisp_load_firmware(isp);
764 		if (!isp->firmware) {
765 			dev_err(isp->dev, "Failed to load ISP firmware.\n");
766 			ret = -ENOENT;
767 			goto error;
768 		}
769 		ret = atomisp_css_load_firmware(isp);
770 		if (ret) {
771 			dev_err(isp->dev, "Failed to init css.\n");
772 			goto error;
773 		}
774 		/* No need to keep FW in memory anymore. */
775 		release_firmware(isp->firmware);
776 		isp->firmware = NULL;
777 		isp->css_env.isp_css_fw.data = NULL;
778 	}
779 
780 	if (!isp->input_cnt) {
781 		dev_err(isp->dev, "no camera attached\n");
782 		ret = -EINVAL;
783 		goto error;
784 	}
785 
786 	/*
787 	 * atomisp does not allow multiple open
788 	 */
789 	if (pipe->users) {
790 		dev_dbg(isp->dev, "video node already opened\n");
791 		mutex_unlock(&isp->mutex);
792 		return -EBUSY;
793 	}
794 
795 	ret = atomisp_init_pipe(pipe);
796 	if (ret)
797 		goto error;
798 
799 	if (atomisp_dev_users(isp)) {
800 		dev_dbg(isp->dev, "skip init isp in open\n");
801 		goto init_subdev;
802 	}
803 
804 	/* runtime power management, turn on ISP */
805 	ret = pm_runtime_resume_and_get(vdev->v4l2_dev->dev);
806 	if (ret < 0) {
807 		dev_err(isp->dev, "Failed to power on device\n");
808 		goto error;
809 	}
810 
811 	atomisp_dev_init_struct(isp);
812 
813 	ret = v4l2_subdev_call(isp->flash, core, s_power, 1);
814 	if (ret < 0 && ret != -ENODEV && ret != -ENOIOCTLCMD) {
815 		dev_err(isp->dev, "Failed to power-on flash\n");
816 		goto css_error;
817 	}
818 
819 init_subdev:
820 	if (atomisp_subdev_users(asd))
821 		goto done;
822 
823 	atomisp_subdev_init_struct(asd);
824 
825 done:
826 	pipe->users++;
827 	mutex_unlock(&isp->mutex);
828 
829 	/* Ensure that a mode is set */
830 	v4l2_ctrl_s_ctrl(asd->run_mode, pipe->default_run_mode);
831 
832 	return 0;
833 
834 css_error:
835 	pm_runtime_put(vdev->v4l2_dev->dev);
836 error:
837 	mutex_unlock(&isp->mutex);
838 	v4l2_fh_release(file);
839 	return ret;
840 }
841 
842 static int atomisp_release(struct file *file)
843 {
844 	struct video_device *vdev = video_devdata(file);
845 	struct atomisp_device *isp = video_get_drvdata(vdev);
846 	struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
847 	struct atomisp_sub_device *asd = pipe->asd;
848 	struct v4l2_subdev_fh fh;
849 	struct v4l2_rect clear_compose = {0};
850 	unsigned long flags;
851 	int ret;
852 
853 	v4l2_fh_init(&fh.vfh, vdev);
854 
855 	dev_dbg(isp->dev, "release device %s\n", vdev->name);
856 
857 	asd->subdev.devnode = vdev;
858 
859 	/* Note file must not be used after this! */
860 	vb2_fop_release(file);
861 
862 	mutex_lock(&isp->mutex);
863 
864 	pipe->users--;
865 	if (pipe->users)
866 		goto done;
867 
868 	/*
869 	 * A little trick here:
870 	 * file injection input resolution is recorded in the sink pad,
871 	 * therefore can not be cleared when releaseing one device node.
872 	 * The sink pad setting can only be cleared when all device nodes
873 	 * get released.
874 	 */
875 	if (asd->fmt_auto->val) {
876 		struct v4l2_mbus_framefmt isp_sink_fmt = { 0 };
877 
878 		atomisp_subdev_set_ffmt(&asd->subdev, fh.state,
879 					V4L2_SUBDEV_FORMAT_ACTIVE,
880 					ATOMISP_SUBDEV_PAD_SINK, &isp_sink_fmt);
881 	}
882 
883 	if (atomisp_subdev_users(asd))
884 		goto done;
885 
886 	atomisp_css_free_stat_buffers(asd);
887 	atomisp_free_internal_buffers(asd);
888 	ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
889 			       core, s_power, 0);
890 	if (ret)
891 		dev_warn(isp->dev, "Failed to power-off sensor\n");
892 
893 	/* clear the asd field to show this camera is not used */
894 	isp->inputs[asd->input_curr].asd = NULL;
895 	spin_lock_irqsave(&isp->lock, flags);
896 	asd->streaming = ATOMISP_DEVICE_STREAMING_DISABLED;
897 	spin_unlock_irqrestore(&isp->lock, flags);
898 
899 	if (atomisp_dev_users(isp))
900 		goto done;
901 
902 	atomisp_destroy_pipes_stream_force(asd);
903 
904 	if (defer_fw_load) {
905 		ia_css_unload_firmware();
906 		isp->css_env.isp_css_fw.data = NULL;
907 		isp->css_env.isp_css_fw.bytes = 0;
908 	}
909 
910 	ret = v4l2_subdev_call(isp->flash, core, s_power, 0);
911 	if (ret < 0 && ret != -ENODEV && ret != -ENOIOCTLCMD)
912 		dev_warn(isp->dev, "Failed to power-off flash\n");
913 
914 	if (pm_runtime_put_sync(vdev->v4l2_dev->dev) < 0)
915 		dev_err(isp->dev, "Failed to power off device\n");
916 
917 done:
918 	atomisp_subdev_set_selection(&asd->subdev, fh.state,
919 				     V4L2_SUBDEV_FORMAT_ACTIVE,
920 				     atomisp_subdev_source_pad(vdev),
921 				     V4L2_SEL_TGT_COMPOSE, 0,
922 				     &clear_compose);
923 	mutex_unlock(&isp->mutex);
924 	return 0;
925 }
926 
927 const struct v4l2_file_operations atomisp_fops = {
928 	.owner = THIS_MODULE,
929 	.open = atomisp_open,
930 	.release = atomisp_release,
931 	.mmap = vb2_fop_mmap,
932 	.poll = vb2_fop_poll,
933 	.unlocked_ioctl = video_ioctl2,
934 #ifdef CONFIG_COMPAT
935 	/*
936 	 * this was removed because of bugs, the interface
937 	 * needs to be made safe for compat tasks instead.
938 	.compat_ioctl32 = atomisp_compat_ioctl32,
939 	 */
940 #endif
941 };
942