1 /*
2  * Support for Medifield PNW Camera Imaging ISP subsystem.
3  *
4  * Copyright (c) 2010 Intel Corporation. All Rights Reserved.
5  *
6  * Copyright (c) 2010 Silicon Hive www.siliconhive.com.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License version
10  * 2 as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  *
18  */
19 
20 #include <linux/module.h>
21 #include <linux/pm_runtime.h>
22 
23 #include <media/v4l2-ioctl.h>
24 #include <media/videobuf-vmalloc.h>
25 
26 #include "atomisp_cmd.h"
27 #include "atomisp_common.h"
28 #include "atomisp_fops.h"
29 #include "atomisp_internal.h"
30 #include "atomisp_ioctl.h"
31 #include "atomisp_compat.h"
32 #include "atomisp_subdev.h"
33 #include "atomisp_v4l2.h"
34 #include "atomisp-regs.h"
35 #include "hmm/hmm.h"
36 
37 #include "type_support.h"
38 #include "device_access/device_access.h"
39 
40 #include "atomisp_acc.h"
41 
42 #define ISP_LEFT_PAD			128	/* equal to 2*NWAY */
43 
44 /*
45  * input image data, and current frame resolution for test
46  */
47 #define	ISP_PARAM_MMAP_OFFSET	0xfffff000
48 
49 #define MAGIC_CHECK(is, should)	\
50 	do { \
51 		if (unlikely((is) != (should))) { \
52 			pr_err("magic mismatch: %x (expected %x)\n", \
53 				is, should); \
54 			BUG(); \
55 		} \
56 	} while (0)
57 
58 /*
59  * Videobuf ops
60  */
61 static int atomisp_buf_setup(struct videobuf_queue *vq, unsigned int *count,
62 			     unsigned int *size)
63 {
64 	struct atomisp_video_pipe *pipe = vq->priv_data;
65 
66 	*size = pipe->pix.sizeimage;
67 
68 	return 0;
69 }
70 
71 static int atomisp_buf_prepare(struct videobuf_queue *vq,
72 			       struct videobuf_buffer *vb,
73 			       enum v4l2_field field)
74 {
75 	struct atomisp_video_pipe *pipe = vq->priv_data;
76 
77 	vb->size = pipe->pix.sizeimage;
78 	vb->width = pipe->pix.width;
79 	vb->height = pipe->pix.height;
80 	vb->field = field;
81 	vb->state = VIDEOBUF_PREPARED;
82 
83 	return 0;
84 }
85 
86 static int atomisp_q_one_metadata_buffer(struct atomisp_sub_device *asd,
87 	enum atomisp_input_stream_id stream_id,
88 	enum ia_css_pipe_id css_pipe_id)
89 {
90 	struct atomisp_metadata_buf *metadata_buf;
91 	enum atomisp_metadata_type md_type =
92 	    atomisp_get_metadata_type(asd, css_pipe_id);
93 	struct list_head *metadata_list;
94 
95 	if (asd->metadata_bufs_in_css[stream_id][css_pipe_id] >=
96 	    ATOMISP_CSS_Q_DEPTH)
97 		return 0; /* we have reached CSS queue depth */
98 
99 	if (!list_empty(&asd->metadata[md_type])) {
100 		metadata_list = &asd->metadata[md_type];
101 	} else if (!list_empty(&asd->metadata_ready[md_type])) {
102 		metadata_list = &asd->metadata_ready[md_type];
103 	} else {
104 		dev_warn(asd->isp->dev, "%s: No metadata buffers available for type %d!\n",
105 			 __func__, md_type);
106 		return -EINVAL;
107 	}
108 
109 	metadata_buf = list_entry(metadata_list->next,
110 				  struct atomisp_metadata_buf, list);
111 	list_del_init(&metadata_buf->list);
112 
113 	if (atomisp_q_metadata_buffer_to_css(asd, metadata_buf,
114 					     stream_id, css_pipe_id)) {
115 		list_add(&metadata_buf->list, metadata_list);
116 		return -EINVAL;
117 	} else {
118 		list_add_tail(&metadata_buf->list,
119 			      &asd->metadata_in_css[md_type]);
120 	}
121 	asd->metadata_bufs_in_css[stream_id][css_pipe_id]++;
122 
123 	return 0;
124 }
125 
126 static int atomisp_q_one_s3a_buffer(struct atomisp_sub_device *asd,
127 				    enum atomisp_input_stream_id stream_id,
128 				    enum ia_css_pipe_id css_pipe_id)
129 {
130 	struct atomisp_s3a_buf *s3a_buf;
131 	struct list_head *s3a_list;
132 	unsigned int exp_id;
133 
134 	if (asd->s3a_bufs_in_css[css_pipe_id] >= ATOMISP_CSS_Q_DEPTH)
135 		return 0; /* we have reached CSS queue depth */
136 
137 	if (!list_empty(&asd->s3a_stats)) {
138 		s3a_list = &asd->s3a_stats;
139 	} else if (!list_empty(&asd->s3a_stats_ready)) {
140 		s3a_list = &asd->s3a_stats_ready;
141 	} else {
142 		dev_warn(asd->isp->dev, "%s: No s3a buffers available!\n",
143 			 __func__);
144 		return -EINVAL;
145 	}
146 
147 	s3a_buf = list_entry(s3a_list->next, struct atomisp_s3a_buf, list);
148 	list_del_init(&s3a_buf->list);
149 	exp_id = s3a_buf->s3a_data->exp_id;
150 
151 	hmm_flush_vmap(s3a_buf->s3a_data->data_ptr);
152 	if (atomisp_q_s3a_buffer_to_css(asd, s3a_buf,
153 					stream_id, css_pipe_id)) {
154 		/* got from head, so return back to the head */
155 		list_add(&s3a_buf->list, s3a_list);
156 		return -EINVAL;
157 	} else {
158 		list_add_tail(&s3a_buf->list, &asd->s3a_stats_in_css);
159 		if (s3a_list == &asd->s3a_stats_ready)
160 			dev_warn(asd->isp->dev, "%s: drop one s3a stat which has exp_id %d!\n",
161 				 __func__, exp_id);
162 	}
163 
164 	asd->s3a_bufs_in_css[css_pipe_id]++;
165 	return 0;
166 }
167 
168 static int atomisp_q_one_dis_buffer(struct atomisp_sub_device *asd,
169 				    enum atomisp_input_stream_id stream_id,
170 				    enum ia_css_pipe_id css_pipe_id)
171 {
172 	struct atomisp_dis_buf *dis_buf;
173 	unsigned long irqflags;
174 
175 	if (asd->dis_bufs_in_css >=  ATOMISP_CSS_Q_DEPTH)
176 		return 0; /* we have reached CSS queue depth */
177 
178 	spin_lock_irqsave(&asd->dis_stats_lock, irqflags);
179 	if (list_empty(&asd->dis_stats)) {
180 		spin_unlock_irqrestore(&asd->dis_stats_lock, irqflags);
181 		dev_warn(asd->isp->dev, "%s: No dis buffers available!\n",
182 			 __func__);
183 		return -EINVAL;
184 	}
185 
186 	dis_buf = list_entry(asd->dis_stats.prev,
187 			     struct atomisp_dis_buf, list);
188 	list_del_init(&dis_buf->list);
189 	spin_unlock_irqrestore(&asd->dis_stats_lock, irqflags);
190 
191 	hmm_flush_vmap(dis_buf->dis_data->data_ptr);
192 	if (atomisp_q_dis_buffer_to_css(asd, dis_buf,
193 					stream_id, css_pipe_id)) {
194 		spin_lock_irqsave(&asd->dis_stats_lock, irqflags);
195 		/* got from tail, so return back to the tail */
196 		list_add_tail(&dis_buf->list, &asd->dis_stats);
197 		spin_unlock_irqrestore(&asd->dis_stats_lock, irqflags);
198 		return -EINVAL;
199 	} else {
200 		spin_lock_irqsave(&asd->dis_stats_lock, irqflags);
201 		list_add_tail(&dis_buf->list, &asd->dis_stats_in_css);
202 		spin_unlock_irqrestore(&asd->dis_stats_lock, irqflags);
203 	}
204 
205 	asd->dis_bufs_in_css++;
206 
207 	return 0;
208 }
209 
210 int atomisp_q_video_buffers_to_css(struct atomisp_sub_device *asd,
211 				   struct atomisp_video_pipe *pipe,
212 				   enum atomisp_input_stream_id stream_id,
213 				   enum ia_css_buffer_type css_buf_type,
214 				   enum ia_css_pipe_id css_pipe_id)
215 {
216 	struct videobuf_vmalloc_memory *vm_mem;
217 	struct atomisp_css_params_with_list *param;
218 	struct ia_css_dvs_grid_info *dvs_grid =
219 	    atomisp_css_get_dvs_grid_info(&asd->params.curr_grid_info);
220 	unsigned long irqflags;
221 	int err = 0;
222 
223 	while (pipe->buffers_in_css < ATOMISP_CSS_Q_DEPTH) {
224 		struct videobuf_buffer *vb;
225 
226 		spin_lock_irqsave(&pipe->irq_lock, irqflags);
227 		if (list_empty(&pipe->activeq)) {
228 			spin_unlock_irqrestore(&pipe->irq_lock, irqflags);
229 			return -EINVAL;
230 		}
231 		vb = list_entry(pipe->activeq.next,
232 				struct videobuf_buffer, queue);
233 		list_del_init(&vb->queue);
234 		vb->state = VIDEOBUF_ACTIVE;
235 		spin_unlock_irqrestore(&pipe->irq_lock, irqflags);
236 
237 		/*
238 		 * If there is a per_frame setting to apply on the buffer,
239 		 * do it before buffer en-queueing.
240 		 */
241 		vm_mem = vb->priv;
242 
243 		param = pipe->frame_params[vb->i];
244 		if (param) {
245 			atomisp_makeup_css_parameters(asd,
246 						      &asd->params.css_param.update_flag,
247 						      &param->params);
248 			atomisp_apply_css_parameters(asd, &param->params);
249 
250 			if (param->params.update_flag.dz_config &&
251 			    asd->run_mode->val != ATOMISP_RUN_MODE_VIDEO) {
252 				err = atomisp_calculate_real_zoom_region(asd,
253 					&param->params.dz_config, css_pipe_id);
254 				if (!err)
255 					atomisp_css_set_dz_config(asd,
256 								  &param->params.dz_config);
257 			}
258 			atomisp_css_set_isp_config_applied_frame(asd,
259 				vm_mem->vaddr);
260 			atomisp_css_update_isp_params_on_pipe(asd,
261 							      asd->stream_env[stream_id].pipes[css_pipe_id]);
262 			asd->params.dvs_6axis = (struct ia_css_dvs_6axis_config *)
263 						param->params.dvs_6axis;
264 
265 			/*
266 			 * WORKAROUND:
267 			 * Because the camera halv3 can't ensure to set zoom
268 			 * region to per_frame setting and global setting at
269 			 * same time and only set zoom region to pre_frame
270 			 * setting now.so when the pre_frame setting include
271 			 * zoom region,I will set it to global setting.
272 			 */
273 			if (param->params.update_flag.dz_config &&
274 			    asd->run_mode->val != ATOMISP_RUN_MODE_VIDEO
275 			    && !err) {
276 				memcpy(&asd->params.css_param.dz_config,
277 				       &param->params.dz_config,
278 				       sizeof(struct ia_css_dz_config));
279 				asd->params.css_param.update_flag.dz_config =
280 				    (struct atomisp_dz_config *)
281 				    &asd->params.css_param.dz_config;
282 				asd->params.css_update_params_needed = true;
283 			}
284 		}
285 		/* Enqueue buffer */
286 		err = atomisp_q_video_buffer_to_css(asd, vm_mem, stream_id,
287 						    css_buf_type, css_pipe_id);
288 		if (err) {
289 			spin_lock_irqsave(&pipe->irq_lock, irqflags);
290 			list_add_tail(&vb->queue, &pipe->activeq);
291 			vb->state = VIDEOBUF_QUEUED;
292 			spin_unlock_irqrestore(&pipe->irq_lock, irqflags);
293 			dev_err(asd->isp->dev, "%s, css q fails: %d\n",
294 				__func__, err);
295 			return -EINVAL;
296 		}
297 		pipe->buffers_in_css++;
298 
299 		/* enqueue 3A/DIS/metadata buffers */
300 		if (asd->params.curr_grid_info.s3a_grid.enable &&
301 		    css_pipe_id == asd->params.s3a_enabled_pipe &&
302 		    css_buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME)
303 			atomisp_q_one_s3a_buffer(asd, stream_id,
304 						 css_pipe_id);
305 
306 		if (asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream_info.
307 		    metadata_info.size &&
308 		    css_buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME)
309 			atomisp_q_one_metadata_buffer(asd, stream_id,
310 						      css_pipe_id);
311 
312 		if (dvs_grid && dvs_grid->enable &&
313 		    css_pipe_id == IA_CSS_PIPE_ID_VIDEO &&
314 		    css_buf_type == IA_CSS_BUFFER_TYPE_OUTPUT_FRAME)
315 			atomisp_q_one_dis_buffer(asd, stream_id,
316 						 css_pipe_id);
317 	}
318 
319 	return 0;
320 }
321 
322 static int atomisp_get_css_buf_type(struct atomisp_sub_device *asd,
323 				    enum ia_css_pipe_id pipe_id,
324 				    uint16_t source_pad)
325 {
326 	if (ATOMISP_USE_YUVPP(asd)) {
327 		/* when run ZSL case */
328 		if (asd->continuous_mode->val &&
329 		    asd->run_mode->val == ATOMISP_RUN_MODE_PREVIEW) {
330 			if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE)
331 				return IA_CSS_BUFFER_TYPE_OUTPUT_FRAME;
332 			else if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW)
333 				return IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME;
334 			else
335 				return IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME;
336 		}
337 
338 		/*when run SDV case*/
339 		if (asd->continuous_mode->val &&
340 		    asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) {
341 			if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE)
342 				return IA_CSS_BUFFER_TYPE_OUTPUT_FRAME;
343 			else if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW)
344 				return IA_CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME;
345 			else if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_VIDEO)
346 				return IA_CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME;
347 			else
348 				return IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME;
349 		}
350 
351 		/*other case: default setting*/
352 		if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE ||
353 		    source_pad == ATOMISP_SUBDEV_PAD_SOURCE_VIDEO ||
354 		    (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW &&
355 		     asd->run_mode->val != ATOMISP_RUN_MODE_VIDEO))
356 			return IA_CSS_BUFFER_TYPE_OUTPUT_FRAME;
357 		else
358 			return IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME;
359 	}
360 
361 	if (pipe_id == IA_CSS_PIPE_ID_COPY ||
362 	    source_pad == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE ||
363 	    source_pad == ATOMISP_SUBDEV_PAD_SOURCE_VIDEO ||
364 	    (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW &&
365 	     asd->run_mode->val != ATOMISP_RUN_MODE_VIDEO))
366 		return IA_CSS_BUFFER_TYPE_OUTPUT_FRAME;
367 	else
368 		return IA_CSS_BUFFER_TYPE_VF_OUTPUT_FRAME;
369 }
370 
371 static int atomisp_qbuffers_to_css_for_all_pipes(struct atomisp_sub_device *asd)
372 {
373 	enum ia_css_buffer_type buf_type;
374 	enum ia_css_pipe_id css_capture_pipe_id = IA_CSS_PIPE_ID_COPY;
375 	enum ia_css_pipe_id css_preview_pipe_id = IA_CSS_PIPE_ID_COPY;
376 	enum ia_css_pipe_id css_video_pipe_id = IA_CSS_PIPE_ID_COPY;
377 	enum atomisp_input_stream_id input_stream_id;
378 	struct atomisp_video_pipe *capture_pipe;
379 	struct atomisp_video_pipe *preview_pipe;
380 	struct atomisp_video_pipe *video_pipe;
381 
382 	capture_pipe = &asd->video_out_capture;
383 	preview_pipe = &asd->video_out_preview;
384 	video_pipe = &asd->video_out_video_capture;
385 
386 	buf_type = atomisp_get_css_buf_type(
387 		       asd, css_preview_pipe_id,
388 		       atomisp_subdev_source_pad(&preview_pipe->vdev));
389 	input_stream_id = ATOMISP_INPUT_STREAM_PREVIEW;
390 	atomisp_q_video_buffers_to_css(asd, preview_pipe,
391 				       input_stream_id,
392 				       buf_type, css_preview_pipe_id);
393 
394 	buf_type = atomisp_get_css_buf_type(asd, css_capture_pipe_id,
395 					    atomisp_subdev_source_pad(&capture_pipe->vdev));
396 	input_stream_id = ATOMISP_INPUT_STREAM_GENERAL;
397 	atomisp_q_video_buffers_to_css(asd, capture_pipe,
398 				       input_stream_id,
399 				       buf_type, css_capture_pipe_id);
400 
401 	buf_type = atomisp_get_css_buf_type(asd, css_video_pipe_id,
402 					    atomisp_subdev_source_pad(&video_pipe->vdev));
403 	input_stream_id = ATOMISP_INPUT_STREAM_VIDEO;
404 	atomisp_q_video_buffers_to_css(asd, video_pipe,
405 				       input_stream_id,
406 				       buf_type, css_video_pipe_id);
407 	return 0;
408 }
409 
410 /* queue all available buffers to css */
411 int atomisp_qbuffers_to_css(struct atomisp_sub_device *asd)
412 {
413 	enum ia_css_buffer_type buf_type;
414 	enum ia_css_pipe_id css_capture_pipe_id = IA_CSS_PIPE_ID_NUM;
415 	enum ia_css_pipe_id css_preview_pipe_id = IA_CSS_PIPE_ID_NUM;
416 	enum ia_css_pipe_id css_video_pipe_id = IA_CSS_PIPE_ID_NUM;
417 	enum atomisp_input_stream_id input_stream_id;
418 	struct atomisp_video_pipe *capture_pipe = NULL;
419 	struct atomisp_video_pipe *vf_pipe = NULL;
420 	struct atomisp_video_pipe *preview_pipe = NULL;
421 	struct atomisp_video_pipe *video_pipe = NULL;
422 	bool raw_mode = atomisp_is_mbuscode_raw(
423 			    asd->fmt[asd->capture_pad].fmt.code);
424 
425 	if (asd->isp->inputs[asd->input_curr].camera_caps->
426 	    sensor[asd->sensor_curr].stream_num == 2 &&
427 	    !asd->yuvpp_mode)
428 		return atomisp_qbuffers_to_css_for_all_pipes(asd);
429 
430 	if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_SCALER) {
431 		video_pipe = &asd->video_out_video_capture;
432 		css_video_pipe_id = IA_CSS_PIPE_ID_VIDEO;
433 	} else if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_LOWLAT) {
434 		preview_pipe = &asd->video_out_capture;
435 		css_preview_pipe_id = IA_CSS_PIPE_ID_CAPTURE;
436 	} else if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) {
437 		if (asd->continuous_mode->val) {
438 			capture_pipe = &asd->video_out_capture;
439 			vf_pipe = &asd->video_out_vf;
440 			css_capture_pipe_id = IA_CSS_PIPE_ID_CAPTURE;
441 		}
442 		video_pipe = &asd->video_out_video_capture;
443 		preview_pipe = &asd->video_out_preview;
444 		css_video_pipe_id = IA_CSS_PIPE_ID_VIDEO;
445 		css_preview_pipe_id = IA_CSS_PIPE_ID_VIDEO;
446 	} else if (asd->continuous_mode->val) {
447 		capture_pipe = &asd->video_out_capture;
448 		vf_pipe = &asd->video_out_vf;
449 		preview_pipe = &asd->video_out_preview;
450 
451 		css_preview_pipe_id = IA_CSS_PIPE_ID_PREVIEW;
452 		css_capture_pipe_id = IA_CSS_PIPE_ID_CAPTURE;
453 	} else if (asd->run_mode->val == ATOMISP_RUN_MODE_PREVIEW) {
454 		preview_pipe = &asd->video_out_preview;
455 		css_preview_pipe_id = IA_CSS_PIPE_ID_PREVIEW;
456 	} else {
457 		/* ATOMISP_RUN_MODE_STILL_CAPTURE */
458 		capture_pipe = &asd->video_out_capture;
459 		if (!raw_mode)
460 			vf_pipe = &asd->video_out_vf;
461 		css_capture_pipe_id = IA_CSS_PIPE_ID_CAPTURE;
462 	}
463 
464 #ifdef ISP2401_NEW_INPUT_SYSTEM
465 	if (asd->copy_mode) {
466 		css_capture_pipe_id = IA_CSS_PIPE_ID_COPY;
467 		css_preview_pipe_id = IA_CSS_PIPE_ID_COPY;
468 		css_video_pipe_id = IA_CSS_PIPE_ID_COPY;
469 	}
470 #endif
471 
472 	if (asd->yuvpp_mode) {
473 		capture_pipe = &asd->video_out_capture;
474 		video_pipe   = &asd->video_out_video_capture;
475 		preview_pipe = &asd->video_out_preview;
476 		css_capture_pipe_id = IA_CSS_PIPE_ID_COPY;
477 		css_video_pipe_id   = IA_CSS_PIPE_ID_YUVPP;
478 		css_preview_pipe_id = IA_CSS_PIPE_ID_YUVPP;
479 	}
480 
481 	if (capture_pipe) {
482 		buf_type = atomisp_get_css_buf_type(
483 			       asd, css_capture_pipe_id,
484 			       atomisp_subdev_source_pad(&capture_pipe->vdev));
485 		input_stream_id = ATOMISP_INPUT_STREAM_GENERAL;
486 
487 		/*
488 		 * use yuvpp pipe for SOC camera.
489 		 */
490 		if (ATOMISP_USE_YUVPP(asd))
491 			css_capture_pipe_id = IA_CSS_PIPE_ID_YUVPP;
492 
493 		atomisp_q_video_buffers_to_css(asd, capture_pipe,
494 					       input_stream_id,
495 					       buf_type, css_capture_pipe_id);
496 	}
497 
498 	if (vf_pipe) {
499 		buf_type = atomisp_get_css_buf_type(
500 			       asd, css_capture_pipe_id,
501 			       atomisp_subdev_source_pad(&vf_pipe->vdev));
502 		if (asd->stream_env[ATOMISP_INPUT_STREAM_POSTVIEW].stream)
503 			input_stream_id = ATOMISP_INPUT_STREAM_POSTVIEW;
504 		else
505 			input_stream_id = ATOMISP_INPUT_STREAM_GENERAL;
506 
507 		/*
508 		 * use yuvpp pipe for SOC camera.
509 		 */
510 		if (ATOMISP_USE_YUVPP(asd))
511 			css_capture_pipe_id = IA_CSS_PIPE_ID_YUVPP;
512 		atomisp_q_video_buffers_to_css(asd, vf_pipe,
513 					       input_stream_id,
514 					       buf_type, css_capture_pipe_id);
515 	}
516 
517 	if (preview_pipe) {
518 		buf_type = atomisp_get_css_buf_type(
519 			       asd, css_preview_pipe_id,
520 			       atomisp_subdev_source_pad(&preview_pipe->vdev));
521 		if (ATOMISP_SOC_CAMERA(asd) && css_preview_pipe_id == IA_CSS_PIPE_ID_YUVPP)
522 			input_stream_id = ATOMISP_INPUT_STREAM_GENERAL;
523 		/* else for ext isp use case */
524 		else if (css_preview_pipe_id == IA_CSS_PIPE_ID_YUVPP)
525 			input_stream_id = ATOMISP_INPUT_STREAM_VIDEO;
526 		else if (asd->stream_env[ATOMISP_INPUT_STREAM_PREVIEW].stream)
527 			input_stream_id = ATOMISP_INPUT_STREAM_PREVIEW;
528 		else
529 			input_stream_id = ATOMISP_INPUT_STREAM_GENERAL;
530 
531 		/*
532 		 * use yuvpp pipe for SOC camera.
533 		 */
534 		if (ATOMISP_USE_YUVPP(asd))
535 			css_preview_pipe_id = IA_CSS_PIPE_ID_YUVPP;
536 
537 		atomisp_q_video_buffers_to_css(asd, preview_pipe,
538 					       input_stream_id,
539 					       buf_type, css_preview_pipe_id);
540 	}
541 
542 	if (video_pipe) {
543 		buf_type = atomisp_get_css_buf_type(
544 			       asd, css_video_pipe_id,
545 			       atomisp_subdev_source_pad(&video_pipe->vdev));
546 		if (asd->stream_env[ATOMISP_INPUT_STREAM_VIDEO].stream)
547 			input_stream_id = ATOMISP_INPUT_STREAM_VIDEO;
548 		else
549 			input_stream_id = ATOMISP_INPUT_STREAM_GENERAL;
550 
551 		/*
552 		 * use yuvpp pipe for SOC camera.
553 		 */
554 		if (ATOMISP_USE_YUVPP(asd))
555 			css_video_pipe_id = IA_CSS_PIPE_ID_YUVPP;
556 
557 		atomisp_q_video_buffers_to_css(asd, video_pipe,
558 					       input_stream_id,
559 					       buf_type, css_video_pipe_id);
560 	}
561 
562 	return 0;
563 }
564 
565 static void atomisp_buf_queue(struct videobuf_queue *vq,
566 			      struct videobuf_buffer *vb)
567 {
568 	struct atomisp_video_pipe *pipe = vq->priv_data;
569 
570 	/*
571 	 * when a frame buffer meets following conditions, it should be put into
572 	 * the waiting list:
573 	 * 1.  It is not a main output frame, and it has a per-frame parameter
574 	 *     to go with it.
575 	 * 2.  It is not a main output frame, and the waiting buffer list is not
576 	 *     empty, to keep the FIFO sequence of frame buffer processing, it
577 	 *     is put to waiting list until previous per-frame parameter buffers
578 	 *     get enqueued.
579 	 */
580 	if (!atomisp_is_vf_pipe(pipe) &&
581 	    (pipe->frame_request_config_id[vb->i] ||
582 	     !list_empty(&pipe->buffers_waiting_for_param)))
583 		list_add_tail(&vb->queue, &pipe->buffers_waiting_for_param);
584 	else
585 		list_add_tail(&vb->queue, &pipe->activeq);
586 
587 	vb->state = VIDEOBUF_QUEUED;
588 }
589 
590 static void atomisp_buf_release(struct videobuf_queue *vq,
591 				struct videobuf_buffer *vb)
592 {
593 	vb->state = VIDEOBUF_NEEDS_INIT;
594 	atomisp_videobuf_free_buf(vb);
595 }
596 
597 static int atomisp_buf_setup_output(struct videobuf_queue *vq,
598 				    unsigned int *count, unsigned int *size)
599 {
600 	struct atomisp_video_pipe *pipe = vq->priv_data;
601 
602 	*size = pipe->pix.sizeimage;
603 
604 	return 0;
605 }
606 
607 static int atomisp_buf_prepare_output(struct videobuf_queue *vq,
608 				      struct videobuf_buffer *vb,
609 				      enum v4l2_field field)
610 {
611 	struct atomisp_video_pipe *pipe = vq->priv_data;
612 
613 	vb->size = pipe->pix.sizeimage;
614 	vb->width = pipe->pix.width;
615 	vb->height = pipe->pix.height;
616 	vb->field = field;
617 	vb->state = VIDEOBUF_PREPARED;
618 
619 	return 0;
620 }
621 
622 static void atomisp_buf_queue_output(struct videobuf_queue *vq,
623 				     struct videobuf_buffer *vb)
624 {
625 	struct atomisp_video_pipe *pipe = vq->priv_data;
626 
627 	list_add_tail(&vb->queue, &pipe->activeq_out);
628 	vb->state = VIDEOBUF_QUEUED;
629 }
630 
631 static void atomisp_buf_release_output(struct videobuf_queue *vq,
632 				       struct videobuf_buffer *vb)
633 {
634 	videobuf_vmalloc_free(vb);
635 	vb->state = VIDEOBUF_NEEDS_INIT;
636 }
637 
638 static const struct videobuf_queue_ops videobuf_qops = {
639 	.buf_setup	= atomisp_buf_setup,
640 	.buf_prepare	= atomisp_buf_prepare,
641 	.buf_queue	= atomisp_buf_queue,
642 	.buf_release	= atomisp_buf_release,
643 };
644 
645 static const struct videobuf_queue_ops videobuf_qops_output = {
646 	.buf_setup	= atomisp_buf_setup_output,
647 	.buf_prepare	= atomisp_buf_prepare_output,
648 	.buf_queue	= atomisp_buf_queue_output,
649 	.buf_release	= atomisp_buf_release_output,
650 };
651 
652 static int atomisp_init_pipe(struct atomisp_video_pipe *pipe)
653 {
654 	/* init locks */
655 	spin_lock_init(&pipe->irq_lock);
656 
657 	videobuf_queue_vmalloc_init(&pipe->capq, &videobuf_qops, NULL,
658 				    &pipe->irq_lock,
659 				    V4L2_BUF_TYPE_VIDEO_CAPTURE,
660 				    V4L2_FIELD_NONE,
661 				    sizeof(struct atomisp_buffer), pipe,
662 				    NULL);	/* ext_lock: NULL */
663 
664 	videobuf_queue_vmalloc_init(&pipe->outq, &videobuf_qops_output, NULL,
665 				    &pipe->irq_lock,
666 				    V4L2_BUF_TYPE_VIDEO_OUTPUT,
667 				    V4L2_FIELD_NONE,
668 				    sizeof(struct atomisp_buffer), pipe,
669 				    NULL);	/* ext_lock: NULL */
670 
671 	INIT_LIST_HEAD(&pipe->activeq);
672 	INIT_LIST_HEAD(&pipe->activeq_out);
673 	INIT_LIST_HEAD(&pipe->buffers_waiting_for_param);
674 	INIT_LIST_HEAD(&pipe->per_frame_params);
675 	memset(pipe->frame_request_config_id, 0,
676 	       VIDEO_MAX_FRAME * sizeof(unsigned int));
677 	memset(pipe->frame_params, 0,
678 	       VIDEO_MAX_FRAME *
679 	       sizeof(struct atomisp_css_params_with_list *));
680 
681 	return 0;
682 }
683 
684 static void atomisp_dev_init_struct(struct atomisp_device *isp)
685 {
686 	unsigned int i;
687 
688 	isp->sw_contex.file_input = false;
689 	isp->need_gfx_throttle = true;
690 	isp->isp_fatal_error = false;
691 	isp->mipi_frame_size = 0;
692 
693 	for (i = 0; i < isp->input_cnt; i++)
694 		isp->inputs[i].asd = NULL;
695 	/*
696 	 * For Merrifield, frequency is scalable.
697 	 * After boot-up, the default frequency is 200MHz.
698 	 */
699 	isp->sw_contex.running_freq = ISP_FREQ_200MHZ;
700 }
701 
702 static void atomisp_subdev_init_struct(struct atomisp_sub_device *asd)
703 {
704 	v4l2_ctrl_s_ctrl(asd->run_mode, ATOMISP_RUN_MODE_STILL_CAPTURE);
705 	memset(&asd->params.css_param, 0, sizeof(asd->params.css_param));
706 	asd->params.color_effect = V4L2_COLORFX_NONE;
707 	asd->params.bad_pixel_en = true;
708 	asd->params.gdc_cac_en = false;
709 	asd->params.video_dis_en = false;
710 	asd->params.sc_en = false;
711 	asd->params.fpn_en = false;
712 	asd->params.xnr_en = false;
713 	asd->params.false_color = 0;
714 	asd->params.online_process = 1;
715 	asd->params.yuv_ds_en = 0;
716 	/* s3a grid not enabled for any pipe */
717 	asd->params.s3a_enabled_pipe = IA_CSS_PIPE_ID_NUM;
718 
719 	asd->params.offline_parm.num_captures = 1;
720 	asd->params.offline_parm.skip_frames = 0;
721 	asd->params.offline_parm.offset = 0;
722 	asd->delayed_init = ATOMISP_DELAYED_INIT_NOT_QUEUED;
723 	/* Add for channel */
724 	asd->input_curr = 0;
725 
726 	asd->mipi_frame_size = 0;
727 	asd->copy_mode = false;
728 	asd->yuvpp_mode = false;
729 
730 	asd->stream_prepared = false;
731 	asd->high_speed_mode = false;
732 	asd->sensor_array_res.height = 0;
733 	asd->sensor_array_res.width = 0;
734 	atomisp_css_init_struct(asd);
735 }
736 
737 /*
738  * file operation functions
739  */
740 static unsigned int atomisp_subdev_users(struct atomisp_sub_device *asd)
741 {
742 	return asd->video_out_preview.users +
743 	       asd->video_out_vf.users +
744 	       asd->video_out_capture.users +
745 	       asd->video_out_video_capture.users +
746 	       asd->video_acc.users +
747 	       asd->video_in.users;
748 }
749 
750 unsigned int atomisp_dev_users(struct atomisp_device *isp)
751 {
752 	unsigned int i, sum;
753 
754 	for (i = 0, sum = 0; i < isp->num_of_streams; i++)
755 		sum += atomisp_subdev_users(&isp->asd[i]);
756 
757 	return sum;
758 }
759 
760 static int atomisp_open(struct file *file)
761 {
762 	struct video_device *vdev = video_devdata(file);
763 	struct atomisp_device *isp = video_get_drvdata(vdev);
764 	struct atomisp_video_pipe *pipe = NULL;
765 	struct atomisp_acc_pipe *acc_pipe = NULL;
766 	struct atomisp_sub_device *asd;
767 	bool acc_node = false;
768 	int ret;
769 
770 	dev_dbg(isp->dev, "open device %s\n", vdev->name);
771 
772 	rt_mutex_lock(&isp->mutex);
773 
774 	acc_node = !strcmp(vdev->name, "ATOMISP ISP ACC");
775 	if (acc_node) {
776 		acc_pipe = atomisp_to_acc_pipe(vdev);
777 		asd = acc_pipe->asd;
778 	} else {
779 		pipe = atomisp_to_video_pipe(vdev);
780 		asd = pipe->asd;
781 	}
782 	asd->subdev.devnode = vdev;
783 	/* Deferred firmware loading case. */
784 	if (isp->css_env.isp_css_fw.bytes == 0) {
785 		dev_err(isp->dev, "Deferred firmware load.\n");
786 		isp->firmware = atomisp_load_firmware(isp);
787 		if (!isp->firmware) {
788 			dev_err(isp->dev, "Failed to load ISP firmware.\n");
789 			ret = -ENOENT;
790 			goto error;
791 		}
792 		ret = atomisp_css_load_firmware(isp);
793 		if (ret) {
794 			dev_err(isp->dev, "Failed to init css.\n");
795 			goto error;
796 		}
797 		/* No need to keep FW in memory anymore. */
798 		release_firmware(isp->firmware);
799 		isp->firmware = NULL;
800 		isp->css_env.isp_css_fw.data = NULL;
801 	}
802 
803 	if (acc_node && acc_pipe->users) {
804 		dev_dbg(isp->dev, "acc node already opened\n");
805 		rt_mutex_unlock(&isp->mutex);
806 		return -EBUSY;
807 	} else if (acc_node) {
808 		goto dev_init;
809 	}
810 
811 	if (!isp->input_cnt) {
812 		dev_err(isp->dev, "no camera attached\n");
813 		ret = -EINVAL;
814 		goto error;
815 	}
816 
817 	/*
818 	 * atomisp does not allow multiple open
819 	 */
820 	if (pipe->users) {
821 		dev_dbg(isp->dev, "video node already opened\n");
822 		rt_mutex_unlock(&isp->mutex);
823 		return -EBUSY;
824 	}
825 
826 	ret = atomisp_init_pipe(pipe);
827 	if (ret)
828 		goto error;
829 
830 dev_init:
831 	if (atomisp_dev_users(isp)) {
832 		dev_dbg(isp->dev, "skip init isp in open\n");
833 		goto init_subdev;
834 	}
835 
836 	/* runtime power management, turn on ISP */
837 	ret = pm_runtime_get_sync(vdev->v4l2_dev->dev);
838 	if (ret < 0) {
839 		dev_err(isp->dev, "Failed to power on device\n");
840 		goto error;
841 	}
842 
843 	if (dypool_enable) {
844 		ret = hmm_pool_register(dypool_pgnr, HMM_POOL_TYPE_DYNAMIC);
845 		if (ret)
846 			dev_err(isp->dev, "Failed to register dynamic memory pool.\n");
847 	}
848 
849 	/* Init ISP */
850 	if (atomisp_css_init(isp)) {
851 		ret = -EINVAL;
852 		/* Need to clean up CSS init if it fails. */
853 		goto css_error;
854 	}
855 
856 	atomisp_dev_init_struct(isp);
857 
858 	ret = v4l2_subdev_call(isp->flash, core, s_power, 1);
859 	if (ret < 0 && ret != -ENODEV && ret != -ENOIOCTLCMD) {
860 		dev_err(isp->dev, "Failed to power-on flash\n");
861 		goto css_error;
862 	}
863 
864 init_subdev:
865 	if (atomisp_subdev_users(asd))
866 		goto done;
867 
868 	atomisp_subdev_init_struct(asd);
869 
870 done:
871 
872 	if (acc_node)
873 		acc_pipe->users++;
874 	else
875 		pipe->users++;
876 	rt_mutex_unlock(&isp->mutex);
877 	return 0;
878 
879 css_error:
880 	atomisp_css_uninit(isp);
881 error:
882 	hmm_pool_unregister(HMM_POOL_TYPE_DYNAMIC);
883 	pm_runtime_put(vdev->v4l2_dev->dev);
884 	rt_mutex_unlock(&isp->mutex);
885 	return ret;
886 }
887 
888 static int atomisp_release(struct file *file)
889 {
890 	struct video_device *vdev = video_devdata(file);
891 	struct atomisp_device *isp = video_get_drvdata(vdev);
892 	struct atomisp_video_pipe *pipe;
893 	struct atomisp_acc_pipe *acc_pipe;
894 	struct atomisp_sub_device *asd;
895 	bool acc_node;
896 	struct v4l2_requestbuffers req;
897 	struct v4l2_subdev_fh fh;
898 	struct v4l2_rect clear_compose = {0};
899 	int ret = 0;
900 
901 	v4l2_fh_init(&fh.vfh, vdev);
902 
903 	req.count = 0;
904 	if (!isp)
905 		return -EBADF;
906 
907 	mutex_lock(&isp->streamoff_mutex);
908 	rt_mutex_lock(&isp->mutex);
909 
910 	dev_dbg(isp->dev, "release device %s\n", vdev->name);
911 	acc_node = !strcmp(vdev->name, "ATOMISP ISP ACC");
912 	if (acc_node) {
913 		acc_pipe = atomisp_to_acc_pipe(vdev);
914 		asd = acc_pipe->asd;
915 	} else {
916 		pipe = atomisp_to_video_pipe(vdev);
917 		asd = pipe->asd;
918 	}
919 	asd->subdev.devnode = vdev;
920 	if (acc_node) {
921 		acc_pipe->users--;
922 		goto subdev_uninit;
923 	}
924 	pipe->users--;
925 
926 	if (pipe->capq.streaming)
927 		dev_warn(isp->dev,
928 			 "%s: ISP still streaming while closing!",
929 			 __func__);
930 
931 	if (pipe->capq.streaming &&
932 	    __atomisp_streamoff(file, NULL, V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
933 		dev_err(isp->dev,
934 			"atomisp_streamoff failed on release, driver bug");
935 		goto done;
936 	}
937 
938 	if (pipe->users)
939 		goto done;
940 
941 	if (__atomisp_reqbufs(file, NULL, &req)) {
942 		dev_err(isp->dev,
943 			"atomisp_reqbufs failed on release, driver bug");
944 		goto done;
945 	}
946 
947 	if (pipe->outq.bufs[0]) {
948 		mutex_lock(&pipe->outq.vb_lock);
949 		videobuf_queue_cancel(&pipe->outq);
950 		mutex_unlock(&pipe->outq.vb_lock);
951 	}
952 
953 	/*
954 	 * A little trick here:
955 	 * file injection input resolution is recorded in the sink pad,
956 	 * therefore can not be cleared when releaseing one device node.
957 	 * The sink pad setting can only be cleared when all device nodes
958 	 * get released.
959 	 */
960 	if (!isp->sw_contex.file_input && asd->fmt_auto->val) {
961 		struct v4l2_mbus_framefmt isp_sink_fmt = { 0 };
962 
963 		atomisp_subdev_set_ffmt(&asd->subdev, fh.pad,
964 					V4L2_SUBDEV_FORMAT_ACTIVE,
965 					ATOMISP_SUBDEV_PAD_SINK, &isp_sink_fmt);
966 	}
967 subdev_uninit:
968 	if (atomisp_subdev_users(asd))
969 		goto done;
970 
971 	/* clear the sink pad for file input */
972 	if (isp->sw_contex.file_input && asd->fmt_auto->val) {
973 		struct v4l2_mbus_framefmt isp_sink_fmt = { 0 };
974 
975 		atomisp_subdev_set_ffmt(&asd->subdev, fh.pad,
976 					V4L2_SUBDEV_FORMAT_ACTIVE,
977 					ATOMISP_SUBDEV_PAD_SINK, &isp_sink_fmt);
978 	}
979 
980 	atomisp_css_free_stat_buffers(asd);
981 	atomisp_free_internal_buffers(asd);
982 	ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
983 			       core, s_power, 0);
984 	if (ret)
985 		dev_warn(isp->dev, "Failed to power-off sensor\n");
986 
987 	/* clear the asd field to show this camera is not used */
988 	isp->inputs[asd->input_curr].asd = NULL;
989 	asd->streaming = ATOMISP_DEVICE_STREAMING_DISABLED;
990 
991 	if (atomisp_dev_users(isp))
992 		goto done;
993 
994 	atomisp_acc_release(asd);
995 
996 	atomisp_destroy_pipes_stream_force(asd);
997 	atomisp_css_uninit(isp);
998 
999 	if (defer_fw_load) {
1000 		ia_css_unload_firmware();
1001 		isp->css_env.isp_css_fw.data = NULL;
1002 		isp->css_env.isp_css_fw.bytes = 0;
1003 	}
1004 
1005 	hmm_pool_unregister(HMM_POOL_TYPE_DYNAMIC);
1006 
1007 	ret = v4l2_subdev_call(isp->flash, core, s_power, 0);
1008 	if (ret < 0 && ret != -ENODEV && ret != -ENOIOCTLCMD)
1009 		dev_warn(isp->dev, "Failed to power-off flash\n");
1010 
1011 	if (pm_runtime_put_sync(vdev->v4l2_dev->dev) < 0)
1012 		dev_err(isp->dev, "Failed to power off device\n");
1013 
1014 done:
1015 	if (!acc_node) {
1016 		atomisp_subdev_set_selection(&asd->subdev, fh.pad,
1017 					     V4L2_SUBDEV_FORMAT_ACTIVE,
1018 					     atomisp_subdev_source_pad(vdev),
1019 					     V4L2_SEL_TGT_COMPOSE, 0,
1020 					     &clear_compose);
1021 	}
1022 	rt_mutex_unlock(&isp->mutex);
1023 	mutex_unlock(&isp->streamoff_mutex);
1024 
1025 	return 0;
1026 }
1027 
1028 /*
1029  * Memory help functions for image frame and private parameters
1030  */
1031 static int do_isp_mm_remap(struct atomisp_device *isp,
1032 			   struct vm_area_struct *vma,
1033 			   ia_css_ptr isp_virt, u32 host_virt, u32 pgnr)
1034 {
1035 	u32 pfn;
1036 
1037 	while (pgnr) {
1038 		pfn = hmm_virt_to_phys(isp_virt) >> PAGE_SHIFT;
1039 		if (remap_pfn_range(vma, host_virt, pfn,
1040 				    PAGE_SIZE, PAGE_SHARED)) {
1041 			dev_err(isp->dev, "remap_pfn_range err.\n");
1042 			return -EAGAIN;
1043 		}
1044 
1045 		isp_virt += PAGE_SIZE;
1046 		host_virt += PAGE_SIZE;
1047 		pgnr--;
1048 	}
1049 
1050 	return 0;
1051 }
1052 
1053 static int frame_mmap(struct atomisp_device *isp,
1054 		      const struct ia_css_frame *frame, struct vm_area_struct *vma)
1055 {
1056 	ia_css_ptr isp_virt;
1057 	u32 host_virt;
1058 	u32 pgnr;
1059 
1060 	if (!frame) {
1061 		dev_err(isp->dev, "%s: NULL frame pointer.\n", __func__);
1062 		return -EINVAL;
1063 	}
1064 
1065 	host_virt = vma->vm_start;
1066 	isp_virt = frame->data;
1067 	atomisp_get_frame_pgnr(isp, frame, &pgnr);
1068 
1069 	if (do_isp_mm_remap(isp, vma, isp_virt, host_virt, pgnr))
1070 		return -EAGAIN;
1071 
1072 	return 0;
1073 }
1074 
1075 int atomisp_videobuf_mmap_mapper(struct videobuf_queue *q,
1076 				 struct vm_area_struct *vma)
1077 {
1078 	u32 offset = vma->vm_pgoff << PAGE_SHIFT;
1079 	int ret = -EINVAL, i;
1080 	struct atomisp_device *isp =
1081 	    ((struct atomisp_video_pipe *)(q->priv_data))->isp;
1082 	struct videobuf_vmalloc_memory *vm_mem;
1083 	struct videobuf_mapping *map;
1084 
1085 	MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
1086 	if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED)) {
1087 		dev_err(isp->dev, "map appl bug: PROT_WRITE and MAP_SHARED are required\n");
1088 		return -EINVAL;
1089 	}
1090 
1091 	mutex_lock(&q->vb_lock);
1092 	for (i = 0; i < VIDEO_MAX_FRAME; i++) {
1093 		struct videobuf_buffer *buf = q->bufs[i];
1094 
1095 		if (!buf)
1096 			continue;
1097 
1098 		map = kzalloc(sizeof(struct videobuf_mapping), GFP_KERNEL);
1099 		if (!map) {
1100 			mutex_unlock(&q->vb_lock);
1101 			return -ENOMEM;
1102 		}
1103 
1104 		buf->map = map;
1105 		map->q = q;
1106 
1107 		buf->baddr = vma->vm_start;
1108 
1109 		if (buf && buf->memory == V4L2_MEMORY_MMAP &&
1110 		    buf->boff == offset) {
1111 			vm_mem = buf->priv;
1112 			ret = frame_mmap(isp, vm_mem->vaddr, vma);
1113 			vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
1114 			break;
1115 		}
1116 	}
1117 	mutex_unlock(&q->vb_lock);
1118 
1119 	return ret;
1120 }
1121 
1122 /* The input frame contains left and right padding that need to be removed.
1123  * There is always ISP_LEFT_PAD padding on the left side.
1124  * There is also padding on the right (padded_width - width).
1125  */
1126 static int remove_pad_from_frame(struct atomisp_device *isp,
1127 				 struct ia_css_frame *in_frame, __u32 width, __u32 height)
1128 {
1129 	unsigned int i;
1130 	unsigned short *buffer;
1131 	int ret = 0;
1132 	ia_css_ptr load = in_frame->data;
1133 	ia_css_ptr store = load;
1134 
1135 	buffer = kmalloc_array(width, sizeof(load), GFP_KERNEL);
1136 	if (!buffer)
1137 		return -ENOMEM;
1138 
1139 	load += ISP_LEFT_PAD;
1140 	for (i = 0; i < height; i++) {
1141 		ret = hmm_load(load, buffer, width * sizeof(load));
1142 		if (ret < 0)
1143 			goto remove_pad_error;
1144 
1145 		ret = hmm_store(store, buffer, width * sizeof(store));
1146 		if (ret < 0)
1147 			goto remove_pad_error;
1148 
1149 		load  += in_frame->info.padded_width;
1150 		store += width;
1151 	}
1152 
1153 remove_pad_error:
1154 	kfree(buffer);
1155 	return ret;
1156 }
1157 
1158 static int atomisp_mmap(struct file *file, struct vm_area_struct *vma)
1159 {
1160 	struct video_device *vdev = video_devdata(file);
1161 	struct atomisp_device *isp = video_get_drvdata(vdev);
1162 	struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1163 	struct atomisp_sub_device *asd = pipe->asd;
1164 	struct ia_css_frame *raw_virt_addr;
1165 	u32 start = vma->vm_start;
1166 	u32 end = vma->vm_end;
1167 	u32 size = end - start;
1168 	u32 origin_size, new_size;
1169 	int ret;
1170 
1171 	if (!(vma->vm_flags & (VM_WRITE | VM_READ)))
1172 		return -EACCES;
1173 
1174 	rt_mutex_lock(&isp->mutex);
1175 
1176 	if (!(vma->vm_flags & VM_SHARED)) {
1177 		/* Map private buffer.
1178 		 * Set VM_SHARED to the flags since we need
1179 		 * to map the buffer page by page.
1180 		 * Without VM_SHARED, remap_pfn_range() treats
1181 		 * this kind of mapping as invalid.
1182 		 */
1183 		vma->vm_flags |= VM_SHARED;
1184 		ret = hmm_mmap(vma, vma->vm_pgoff << PAGE_SHIFT);
1185 		rt_mutex_unlock(&isp->mutex);
1186 		return ret;
1187 	}
1188 
1189 	/* mmap for ISP offline raw data */
1190 	if (atomisp_subdev_source_pad(vdev)
1191 	    == ATOMISP_SUBDEV_PAD_SOURCE_CAPTURE &&
1192 	    vma->vm_pgoff == (ISP_PARAM_MMAP_OFFSET >> PAGE_SHIFT)) {
1193 		new_size = pipe->pix.width * pipe->pix.height * 2;
1194 		if (asd->params.online_process != 0) {
1195 			ret = -EINVAL;
1196 			goto error;
1197 		}
1198 		raw_virt_addr = asd->raw_output_frame;
1199 		if (!raw_virt_addr) {
1200 			dev_err(isp->dev, "Failed to request RAW frame\n");
1201 			ret = -EINVAL;
1202 			goto error;
1203 		}
1204 
1205 		ret = remove_pad_from_frame(isp, raw_virt_addr,
1206 					    pipe->pix.width, pipe->pix.height);
1207 		if (ret < 0) {
1208 			dev_err(isp->dev, "remove pad failed.\n");
1209 			goto error;
1210 		}
1211 		origin_size = raw_virt_addr->data_bytes;
1212 		raw_virt_addr->data_bytes = new_size;
1213 
1214 		if (size != PAGE_ALIGN(new_size)) {
1215 			dev_err(isp->dev, "incorrect size for mmap ISP  Raw Frame\n");
1216 			ret = -EINVAL;
1217 			goto error;
1218 		}
1219 
1220 		if (frame_mmap(isp, raw_virt_addr, vma)) {
1221 			dev_err(isp->dev, "frame_mmap failed.\n");
1222 			raw_virt_addr->data_bytes = origin_size;
1223 			ret = -EAGAIN;
1224 			goto error;
1225 		}
1226 		raw_virt_addr->data_bytes = origin_size;
1227 		vma->vm_flags |= VM_IO | VM_DONTEXPAND | VM_DONTDUMP;
1228 		rt_mutex_unlock(&isp->mutex);
1229 		return 0;
1230 	}
1231 
1232 	/*
1233 	 * mmap for normal frames
1234 	 */
1235 	if (size != pipe->pix.sizeimage) {
1236 		dev_err(isp->dev, "incorrect size for mmap ISP frames\n");
1237 		ret = -EINVAL;
1238 		goto error;
1239 	}
1240 	rt_mutex_unlock(&isp->mutex);
1241 
1242 	return atomisp_videobuf_mmap_mapper(&pipe->capq, vma);
1243 
1244 error:
1245 	rt_mutex_unlock(&isp->mutex);
1246 
1247 	return ret;
1248 }
1249 
1250 static int atomisp_file_mmap(struct file *file, struct vm_area_struct *vma)
1251 {
1252 	struct video_device *vdev = video_devdata(file);
1253 	struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1254 
1255 	return videobuf_mmap_mapper(&pipe->outq, vma);
1256 }
1257 
1258 static __poll_t atomisp_poll(struct file *file,
1259 			     struct poll_table_struct *pt)
1260 {
1261 	struct video_device *vdev = video_devdata(file);
1262 	struct atomisp_device *isp = video_get_drvdata(vdev);
1263 	struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev);
1264 
1265 	rt_mutex_lock(&isp->mutex);
1266 	if (pipe->capq.streaming != 1) {
1267 		rt_mutex_unlock(&isp->mutex);
1268 		return EPOLLERR;
1269 	}
1270 	rt_mutex_unlock(&isp->mutex);
1271 
1272 	return videobuf_poll_stream(file, &pipe->capq, pt);
1273 }
1274 
1275 const struct v4l2_file_operations atomisp_fops = {
1276 	.owner = THIS_MODULE,
1277 	.open = atomisp_open,
1278 	.release = atomisp_release,
1279 	.mmap = atomisp_mmap,
1280 	.unlocked_ioctl = video_ioctl2,
1281 #ifdef CONFIG_COMPAT
1282 	/*
1283 	 * There are problems with this code. Disable this for now.
1284 	.compat_ioctl32 = atomisp_compat_ioctl32,
1285 	 */
1286 #endif
1287 	.poll = atomisp_poll,
1288 };
1289 
1290 const struct v4l2_file_operations atomisp_file_fops = {
1291 	.owner = THIS_MODULE,
1292 	.open = atomisp_open,
1293 	.release = atomisp_release,
1294 	.mmap = atomisp_file_mmap,
1295 	.unlocked_ioctl = video_ioctl2,
1296 #ifdef CONFIG_COMPAT
1297 	/*
1298 	 * There are problems with this code. Disable this for now.
1299 	.compat_ioctl32 = atomisp_compat_ioctl32,
1300 	 */
1301 #endif
1302 	.poll = atomisp_poll,
1303 };
1304