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