Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dledford/rdma
[sfrench/cifs-2.6.git] / drivers / staging / media / atomisp / pci / atomisp2 / atomisp_fops.c
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 "hrt/hive_isp_css_mm_hrt.h"
38
39 #include "type_support.h"
40 #include "device_access/device_access.h"
41 #include "memory_access/memory_access.h"
42
43 #include "atomisp_acc.h"
44
45 #define ISP_LEFT_PAD                    128     /* equal to 2*NWAY */
46
47 /*
48  * input image data, and current frame resolution for test
49  */
50 #define ISP_PARAM_MMAP_OFFSET   0xfffff000
51
52 #define MAGIC_CHECK(is, should) \
53         do { \
54                 if (unlikely((is) != (should))) { \
55                         pr_err("magic mismatch: %x (expected %x)\n", \
56                                 is, should); \
57                         BUG(); \
58                 } \
59         } while (0)
60
61 /*
62  * Videobuf ops
63  */
64 static int atomisp_buf_setup(struct videobuf_queue *vq, unsigned int *count,
65                              unsigned int *size)
66 {
67         struct atomisp_video_pipe *pipe = vq->priv_data;
68
69         *size = pipe->pix.sizeimage;
70
71         return 0;
72 }
73
74 static int atomisp_buf_prepare(struct videobuf_queue *vq,
75                                struct videobuf_buffer *vb,
76                                enum v4l2_field field)
77 {
78         struct atomisp_video_pipe *pipe = vq->priv_data;
79
80         vb->size = pipe->pix.sizeimage;
81         vb->width = pipe->pix.width;
82         vb->height = pipe->pix.height;
83         vb->field = field;
84         vb->state = VIDEOBUF_PREPARED;
85
86         return 0;
87 }
88
89 static int atomisp_q_one_metadata_buffer(struct atomisp_sub_device *asd,
90                 enum atomisp_input_stream_id stream_id,
91                 enum atomisp_css_pipe_id css_pipe_id)
92 {
93         struct atomisp_metadata_buf *metadata_buf;
94         enum atomisp_metadata_type md_type =
95                         atomisp_get_metadata_type(asd, css_pipe_id);
96         struct list_head *metadata_list;
97
98         if (asd->metadata_bufs_in_css[stream_id][css_pipe_id] >=
99                 ATOMISP_CSS_Q_DEPTH)
100                 return 0; /* we have reached CSS queue depth */
101
102         if (!list_empty(&asd->metadata[md_type])) {
103                 metadata_list = &asd->metadata[md_type];
104         } else if (!list_empty(&asd->metadata_ready[md_type])) {
105                 metadata_list = &asd->metadata_ready[md_type];
106         } else {
107                 dev_warn(asd->isp->dev, "%s: No metadata buffers available for type %d!\n",
108                         __func__, md_type);
109                 return -EINVAL;
110         }
111
112         metadata_buf = list_entry(metadata_list->next,
113                                   struct atomisp_metadata_buf, list);
114         list_del_init(&metadata_buf->list);
115
116         if (atomisp_q_metadata_buffer_to_css(asd, metadata_buf,
117                                 stream_id, css_pipe_id)) {
118                 list_add(&metadata_buf->list, metadata_list);
119                 return -EINVAL;
120         } else {
121                 list_add_tail(&metadata_buf->list,
122                                 &asd->metadata_in_css[md_type]);
123         }
124         asd->metadata_bufs_in_css[stream_id][css_pipe_id]++;
125
126         return 0;
127 }
128
129 static int atomisp_q_one_s3a_buffer(struct atomisp_sub_device *asd,
130                                     enum atomisp_input_stream_id stream_id,
131                                     enum atomisp_css_pipe_id css_pipe_id)
132 {
133         struct atomisp_s3a_buf *s3a_buf;
134         struct list_head *s3a_list;
135         unsigned int exp_id;
136
137         if (asd->s3a_bufs_in_css[css_pipe_id] >= ATOMISP_CSS_Q_DEPTH)
138                 return 0; /* we have reached CSS queue depth */
139
140         if (!list_empty(&asd->s3a_stats)) {
141                 s3a_list = &asd->s3a_stats;
142         } else if (!list_empty(&asd->s3a_stats_ready)) {
143                 s3a_list = &asd->s3a_stats_ready;
144         } else {
145                 dev_warn(asd->isp->dev, "%s: No s3a buffers available!\n",
146                         __func__);
147                 return -EINVAL;
148         }
149
150         s3a_buf = list_entry(s3a_list->next, struct atomisp_s3a_buf, list);
151         list_del_init(&s3a_buf->list);
152         exp_id = s3a_buf->s3a_data->exp_id;
153
154         hmm_flush_vmap(s3a_buf->s3a_data->data_ptr);
155         if (atomisp_q_s3a_buffer_to_css(asd, s3a_buf,
156                                         stream_id, css_pipe_id)) {
157                 /* got from head, so return back to the head */
158                 list_add(&s3a_buf->list, s3a_list);
159                 return -EINVAL;
160         } else {
161                 list_add_tail(&s3a_buf->list, &asd->s3a_stats_in_css);
162                 if (s3a_list == &asd->s3a_stats_ready)
163                         dev_warn(asd->isp->dev, "%s: drop one s3a stat which has exp_id %d!\n",
164                                 __func__, exp_id);
165         }
166
167         asd->s3a_bufs_in_css[css_pipe_id]++;
168         return 0;
169 }
170
171 static int atomisp_q_one_dis_buffer(struct atomisp_sub_device *asd,
172                                     enum atomisp_input_stream_id stream_id,
173                                     enum atomisp_css_pipe_id css_pipe_id)
174 {
175         struct atomisp_dis_buf *dis_buf;
176         unsigned long irqflags;
177
178         if (asd->dis_bufs_in_css >=  ATOMISP_CSS_Q_DEPTH)
179                 return 0; /* we have reached CSS queue depth */
180
181         spin_lock_irqsave(&asd->dis_stats_lock, irqflags);
182         if (list_empty(&asd->dis_stats)) {
183                 spin_unlock_irqrestore(&asd->dis_stats_lock, irqflags);
184                 dev_warn(asd->isp->dev, "%s: No dis buffers available!\n",
185                         __func__);
186                 return -EINVAL;
187         }
188
189         dis_buf = list_entry(asd->dis_stats.prev,
190                         struct atomisp_dis_buf, list);
191         list_del_init(&dis_buf->list);
192         spin_unlock_irqrestore(&asd->dis_stats_lock, irqflags);
193
194         hmm_flush_vmap(dis_buf->dis_data->data_ptr);
195         if (atomisp_q_dis_buffer_to_css(asd, dis_buf,
196                                         stream_id, css_pipe_id)) {
197                 spin_lock_irqsave(&asd->dis_stats_lock, irqflags);
198                 /* got from tail, so return back to the tail */
199                 list_add_tail(&dis_buf->list, &asd->dis_stats);
200                 spin_unlock_irqrestore(&asd->dis_stats_lock, irqflags);
201                 return -EINVAL;
202         } else {
203                 spin_lock_irqsave(&asd->dis_stats_lock, irqflags);
204                 list_add_tail(&dis_buf->list, &asd->dis_stats_in_css);
205                 spin_unlock_irqrestore(&asd->dis_stats_lock, irqflags);
206         }
207
208         asd->dis_bufs_in_css++;
209
210         return 0;
211 }
212
213 int atomisp_q_video_buffers_to_css(struct atomisp_sub_device *asd,
214                              struct atomisp_video_pipe *pipe,
215                              enum atomisp_input_stream_id stream_id,
216                              enum atomisp_css_buffer_type css_buf_type,
217                              enum atomisp_css_pipe_id css_pipe_id)
218 {
219         struct videobuf_vmalloc_memory *vm_mem;
220         struct atomisp_css_params_with_list *param;
221         struct atomisp_css_dvs_grid_info *dvs_grid =
222                  atomisp_css_get_dvs_grid_info(&asd->params.curr_grid_info);
223         unsigned long irqflags;
224         int err = 0;
225
226         while (pipe->buffers_in_css < ATOMISP_CSS_Q_DEPTH) {
227                 struct videobuf_buffer *vb;
228
229                 spin_lock_irqsave(&pipe->irq_lock, irqflags);
230                 if (list_empty(&pipe->activeq)) {
231                         spin_unlock_irqrestore(&pipe->irq_lock, irqflags);
232                         return -EINVAL;
233                 }
234                 vb = list_entry(pipe->activeq.next,
235                                 struct videobuf_buffer, queue);
236                 list_del_init(&vb->queue);
237                 vb->state = VIDEOBUF_ACTIVE;
238                 spin_unlock_irqrestore(&pipe->irq_lock, irqflags);
239
240                 /*
241                  * If there is a per_frame setting to apply on the buffer,
242                  * do it before buffer en-queueing.
243                  */
244                 vm_mem = vb->priv;
245
246                 param = pipe->frame_params[vb->i];
247                 if (param) {
248                         atomisp_makeup_css_parameters(asd,
249                                         &asd->params.css_param.update_flag,
250                                         &param->params);
251                         atomisp_apply_css_parameters(asd, &param->params);
252
253                         if (param->params.update_flag.dz_config &&
254                                 asd->run_mode->val != ATOMISP_RUN_MODE_VIDEO) {
255                                 err = atomisp_calculate_real_zoom_region(asd,
256                                         &param->params.dz_config, css_pipe_id);
257                                 if (!err)
258                                         atomisp_css_set_dz_config(asd,
259                                                 &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 atomisp_css_dvs_6axis *)
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 inculde
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 == 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 == 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 == CSS_PIPE_ID_VIDEO &&
317                         css_buf_type == 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 atomisp_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 CSS_BUFFER_TYPE_OUTPUT_FRAME;
335                         else if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW)
336                                 return CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME;
337                         else
338                                 return 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 CSS_BUFFER_TYPE_OUTPUT_FRAME;
346                         else if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_PREVIEW)
347                                 return CSS_BUFFER_TYPE_SEC_VF_OUTPUT_FRAME;
348                         else if (source_pad == ATOMISP_SUBDEV_PAD_SOURCE_VIDEO)
349                                 return CSS_BUFFER_TYPE_SEC_OUTPUT_FRAME;
350                         else
351                                 return 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 CSS_BUFFER_TYPE_OUTPUT_FRAME;
360                 else
361                         return CSS_BUFFER_TYPE_VF_OUTPUT_FRAME;
362         }
363
364         if (pipe_id == 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 CSS_BUFFER_TYPE_OUTPUT_FRAME;
370         else
371                 return 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 atomisp_css_buffer_type buf_type;
377         enum atomisp_css_pipe_id css_capture_pipe_id = CSS_PIPE_ID_COPY;
378         enum atomisp_css_pipe_id css_preview_pipe_id = CSS_PIPE_ID_COPY;
379         enum atomisp_css_pipe_id css_video_pipe_id = 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
414 /* queue all available buffers to css */
415 int atomisp_qbuffers_to_css(struct atomisp_sub_device *asd)
416 {
417         enum atomisp_css_buffer_type buf_type;
418         enum atomisp_css_pipe_id css_capture_pipe_id = CSS_PIPE_ID_NUM;
419         enum atomisp_css_pipe_id css_preview_pipe_id = CSS_PIPE_ID_NUM;
420         enum atomisp_css_pipe_id css_video_pipe_id = CSS_PIPE_ID_NUM;
421         enum atomisp_input_stream_id input_stream_id;
422         struct atomisp_video_pipe *capture_pipe = NULL;
423         struct atomisp_video_pipe *vf_pipe = NULL;
424         struct atomisp_video_pipe *preview_pipe = NULL;
425         struct atomisp_video_pipe *video_pipe = NULL;
426         bool raw_mode = atomisp_is_mbuscode_raw(
427                             asd->fmt[asd->capture_pad].fmt.code);
428
429         if (asd->isp->inputs[asd->input_curr].camera_caps->
430             sensor[asd->sensor_curr].stream_num == 2 &&
431             !asd->yuvpp_mode)
432                 return atomisp_qbuffers_to_css_for_all_pipes(asd);
433
434         if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_SCALER) {
435                 video_pipe = &asd->video_out_video_capture;
436                 css_video_pipe_id = CSS_PIPE_ID_VIDEO;
437         } else if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_LOWLAT) {
438                 preview_pipe = &asd->video_out_capture;
439                 css_preview_pipe_id = CSS_PIPE_ID_CAPTURE;
440         } else if (asd->run_mode->val == ATOMISP_RUN_MODE_VIDEO) {
441                 if (asd->continuous_mode->val) {
442                         capture_pipe = &asd->video_out_capture;
443                         vf_pipe = &asd->video_out_vf;
444                         css_capture_pipe_id = CSS_PIPE_ID_CAPTURE;
445                 }
446                 video_pipe = &asd->video_out_video_capture;
447                 preview_pipe = &asd->video_out_preview;
448                 css_video_pipe_id = CSS_PIPE_ID_VIDEO;
449                 css_preview_pipe_id = CSS_PIPE_ID_VIDEO;
450         } else if (asd->continuous_mode->val) {
451                 capture_pipe = &asd->video_out_capture;
452                 vf_pipe = &asd->video_out_vf;
453                 preview_pipe = &asd->video_out_preview;
454
455                 css_preview_pipe_id = CSS_PIPE_ID_PREVIEW;
456                 css_capture_pipe_id = CSS_PIPE_ID_CAPTURE;
457         } else if (asd->run_mode->val == ATOMISP_RUN_MODE_PREVIEW) {
458                 preview_pipe = &asd->video_out_preview;
459                 css_preview_pipe_id = CSS_PIPE_ID_PREVIEW;
460         } else {
461                 /* ATOMISP_RUN_MODE_STILL_CAPTURE */
462                 capture_pipe = &asd->video_out_capture;
463                 if (!raw_mode)
464                         vf_pipe = &asd->video_out_vf;
465                 css_capture_pipe_id = CSS_PIPE_ID_CAPTURE;
466         }
467
468 #ifdef ISP2401_NEW_INPUT_SYSTEM
469         if (asd->copy_mode) {
470                 css_capture_pipe_id = CSS_PIPE_ID_COPY;
471                 css_preview_pipe_id = CSS_PIPE_ID_COPY;
472                 css_video_pipe_id = CSS_PIPE_ID_COPY;
473         }
474 #endif
475
476         if (asd->yuvpp_mode) {
477                 capture_pipe = &asd->video_out_capture;
478                 video_pipe   = &asd->video_out_video_capture;
479                 preview_pipe = &asd->video_out_preview;
480                 css_capture_pipe_id = CSS_PIPE_ID_COPY;
481                 css_video_pipe_id   = CSS_PIPE_ID_YUVPP;
482                 css_preview_pipe_id = CSS_PIPE_ID_YUVPP;
483         }
484
485         if (capture_pipe) {
486                 buf_type = atomisp_get_css_buf_type(
487                         asd, css_capture_pipe_id,
488                         atomisp_subdev_source_pad(&capture_pipe->vdev));
489                 input_stream_id = ATOMISP_INPUT_STREAM_GENERAL;
490
491                 /*
492                  * use yuvpp pipe for SOC camera.
493                  */
494                 if (ATOMISP_USE_YUVPP(asd))
495                         css_capture_pipe_id = CSS_PIPE_ID_YUVPP;
496
497                 atomisp_q_video_buffers_to_css(asd, capture_pipe,
498                                                input_stream_id,
499                                                buf_type, css_capture_pipe_id);
500         }
501
502         if (vf_pipe) {
503                 buf_type = atomisp_get_css_buf_type(
504                         asd, css_capture_pipe_id,
505                         atomisp_subdev_source_pad(&vf_pipe->vdev));
506                 if (asd->stream_env[ATOMISP_INPUT_STREAM_POSTVIEW].stream)
507                         input_stream_id = ATOMISP_INPUT_STREAM_POSTVIEW;
508                 else
509                         input_stream_id = ATOMISP_INPUT_STREAM_GENERAL;
510
511                 /*
512                  * use yuvpp pipe for SOC camera.
513                  */
514                 if (ATOMISP_USE_YUVPP(asd))
515                         css_capture_pipe_id = CSS_PIPE_ID_YUVPP;
516                 atomisp_q_video_buffers_to_css(asd, vf_pipe,
517                                                input_stream_id,
518                                                buf_type, css_capture_pipe_id);
519         }
520
521         if (preview_pipe) {
522                 buf_type = atomisp_get_css_buf_type(
523                         asd, css_preview_pipe_id,
524                         atomisp_subdev_source_pad(&preview_pipe->vdev));
525                 if (ATOMISP_SOC_CAMERA(asd) && css_preview_pipe_id == CSS_PIPE_ID_YUVPP)
526                         input_stream_id = ATOMISP_INPUT_STREAM_GENERAL;
527                  /* else for ext isp use case */
528                 else if (css_preview_pipe_id == CSS_PIPE_ID_YUVPP)
529                         input_stream_id = ATOMISP_INPUT_STREAM_VIDEO;
530                 else if (asd->stream_env[ATOMISP_INPUT_STREAM_PREVIEW].stream)
531                         input_stream_id = ATOMISP_INPUT_STREAM_PREVIEW;
532                 else
533                         input_stream_id = ATOMISP_INPUT_STREAM_GENERAL;
534
535                 /*
536                  * use yuvpp pipe for SOC camera.
537                  */
538                 if (ATOMISP_USE_YUVPP(asd))
539                         css_preview_pipe_id = CSS_PIPE_ID_YUVPP;
540
541                 atomisp_q_video_buffers_to_css(asd, preview_pipe,
542                                                input_stream_id,
543                                                buf_type, css_preview_pipe_id);
544         }
545
546         if (video_pipe) {
547                 buf_type = atomisp_get_css_buf_type(
548                         asd, css_video_pipe_id,
549                         atomisp_subdev_source_pad(&video_pipe->vdev));
550                 if (asd->stream_env[ATOMISP_INPUT_STREAM_VIDEO].stream)
551                         input_stream_id = ATOMISP_INPUT_STREAM_VIDEO;
552                 else
553                         input_stream_id = ATOMISP_INPUT_STREAM_GENERAL;
554
555                 /*
556                  * use yuvpp pipe for SOC camera.
557                  */
558                 if (ATOMISP_USE_YUVPP(asd))
559                         css_video_pipe_id = CSS_PIPE_ID_YUVPP;
560
561                 atomisp_q_video_buffers_to_css(asd, video_pipe,
562                                                input_stream_id,
563                                                buf_type, css_video_pipe_id);
564         }
565
566         return 0;
567 }
568
569 static void atomisp_buf_queue(struct videobuf_queue *vq,
570                               struct videobuf_buffer *vb)
571 {
572         struct atomisp_video_pipe *pipe = vq->priv_data;
573
574         /*
575          * when a frame buffer meets following conditions, it should be put into
576          * the waiting list:
577          * 1.  It is not a main output frame, and it has a per-frame parameter
578          *     to go with it.
579          * 2.  It is not a main output frame, and the waiting buffer list is not
580          *     empty, to keep the FIFO sequence of frame buffer processing, it
581          *     is put to waiting list until previous per-frame parameter buffers
582          *     get enqueued.
583          */
584         if (!atomisp_is_vf_pipe(pipe) &&
585             (pipe->frame_request_config_id[vb->i] ||
586              !list_empty(&pipe->buffers_waiting_for_param)))
587                 list_add_tail(&vb->queue, &pipe->buffers_waiting_for_param);
588         else
589                 list_add_tail(&vb->queue, &pipe->activeq);
590
591         vb->state = VIDEOBUF_QUEUED;
592 }
593
594 static void atomisp_buf_release(struct videobuf_queue *vq,
595                                 struct videobuf_buffer *vb)
596 {
597         vb->state = VIDEOBUF_NEEDS_INIT;
598         atomisp_videobuf_free_buf(vb);
599 }
600
601 static int atomisp_buf_setup_output(struct videobuf_queue *vq,
602                                     unsigned int *count, unsigned int *size)
603 {
604         struct atomisp_video_pipe *pipe = vq->priv_data;
605
606         *size = pipe->pix.sizeimage;
607
608         return 0;
609 }
610
611 static int atomisp_buf_prepare_output(struct videobuf_queue *vq,
612                                       struct videobuf_buffer *vb,
613                                       enum v4l2_field field)
614 {
615         struct atomisp_video_pipe *pipe = vq->priv_data;
616
617         vb->size = pipe->pix.sizeimage;
618         vb->width = pipe->pix.width;
619         vb->height = pipe->pix.height;
620         vb->field = field;
621         vb->state = VIDEOBUF_PREPARED;
622
623         return 0;
624 }
625
626 static void atomisp_buf_queue_output(struct videobuf_queue *vq,
627                                      struct videobuf_buffer *vb)
628 {
629         struct atomisp_video_pipe *pipe = vq->priv_data;
630
631         list_add_tail(&vb->queue, &pipe->activeq_out);
632         vb->state = VIDEOBUF_QUEUED;
633 }
634
635 static void atomisp_buf_release_output(struct videobuf_queue *vq,
636                                        struct videobuf_buffer *vb)
637 {
638         videobuf_vmalloc_free(vb);
639         vb->state = VIDEOBUF_NEEDS_INIT;
640 }
641
642 static const struct videobuf_queue_ops videobuf_qops = {
643         .buf_setup      = atomisp_buf_setup,
644         .buf_prepare    = atomisp_buf_prepare,
645         .buf_queue      = atomisp_buf_queue,
646         .buf_release    = atomisp_buf_release,
647 };
648
649 static const struct videobuf_queue_ops videobuf_qops_output = {
650         .buf_setup      = atomisp_buf_setup_output,
651         .buf_prepare    = atomisp_buf_prepare_output,
652         .buf_queue      = atomisp_buf_queue_output,
653         .buf_release    = atomisp_buf_release_output,
654 };
655
656 static int atomisp_init_pipe(struct atomisp_video_pipe *pipe)
657 {
658         /* init locks */
659         spin_lock_init(&pipe->irq_lock);
660
661         videobuf_queue_vmalloc_init(&pipe->capq, &videobuf_qops, NULL,
662                                     &pipe->irq_lock,
663                                     V4L2_BUF_TYPE_VIDEO_CAPTURE,
664                                     V4L2_FIELD_NONE,
665                                     sizeof(struct atomisp_buffer), pipe,
666                                     NULL);      /* ext_lock: NULL */
667
668         videobuf_queue_vmalloc_init(&pipe->outq, &videobuf_qops_output, NULL,
669                                     &pipe->irq_lock,
670                                     V4L2_BUF_TYPE_VIDEO_OUTPUT,
671                                     V4L2_FIELD_NONE,
672                                     sizeof(struct atomisp_buffer), pipe,
673                                     NULL);      /* ext_lock: NULL */
674
675         INIT_LIST_HEAD(&pipe->activeq);
676         INIT_LIST_HEAD(&pipe->activeq_out);
677         INIT_LIST_HEAD(&pipe->buffers_waiting_for_param);
678         INIT_LIST_HEAD(&pipe->per_frame_params);
679         memset(pipe->frame_request_config_id, 0,
680                 VIDEO_MAX_FRAME * sizeof(unsigned int));
681         memset(pipe->frame_params, 0,
682                 VIDEO_MAX_FRAME *
683                 sizeof(struct atomisp_css_params_with_list *));
684
685         return 0;
686 }
687
688 static void atomisp_dev_init_struct(struct atomisp_device *isp)
689 {
690         unsigned int i;
691
692         isp->sw_contex.file_input = 0;
693         isp->need_gfx_throttle = true;
694         isp->isp_fatal_error = false;
695         isp->mipi_frame_size = 0;
696
697         for (i = 0; i < isp->input_cnt; i++)
698                 isp->inputs[i].asd = NULL;
699         /*
700          * For Merrifield, frequency is scalable.
701          * After boot-up, the default frequency is 200MHz.
702          */
703         isp->sw_contex.running_freq = ISP_FREQ_200MHZ;
704 }
705
706 static void atomisp_subdev_init_struct(struct atomisp_sub_device *asd)
707 {
708         v4l2_ctrl_s_ctrl(asd->run_mode, ATOMISP_RUN_MODE_STILL_CAPTURE);
709         memset(&asd->params.css_param, 0, sizeof(asd->params.css_param));
710         asd->params.color_effect = V4L2_COLORFX_NONE;
711         asd->params.bad_pixel_en = 1;
712         asd->params.gdc_cac_en = 0;
713         asd->params.video_dis_en = 0;
714         asd->params.sc_en = 0;
715         asd->params.fpn_en = 0;
716         asd->params.xnr_en = 0;
717         asd->params.false_color = 0;
718         asd->params.online_process = 1;
719         asd->params.yuv_ds_en = 0;
720         /* s3a grid not enabled for any pipe */
721         asd->params.s3a_enabled_pipe = CSS_PIPE_ID_NUM;
722
723         asd->params.offline_parm.num_captures = 1;
724         asd->params.offline_parm.skip_frames = 0;
725         asd->params.offline_parm.offset = 0;
726         asd->delayed_init = ATOMISP_DELAYED_INIT_NOT_QUEUED;
727         /* Add for channel */
728         asd->input_curr = 0;
729
730         asd->mipi_frame_size = 0;
731         asd->copy_mode = false;
732         asd->yuvpp_mode = false;
733
734         asd->stream_prepared = false;
735         asd->high_speed_mode = false;
736         asd->sensor_array_res.height = 0;
737         asd->sensor_array_res.width = 0;
738         atomisp_css_init_struct(asd);
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         for (i = 0, sum = 0; i < isp->num_of_streams; i++)
757                 sum += atomisp_subdev_users(&isp->asd[i]);
758
759         return sum;
760 }
761
762 static int atomisp_open(struct file *file)
763 {
764         struct video_device *vdev = video_devdata(file);
765         struct atomisp_device *isp = video_get_drvdata(vdev);
766         struct atomisp_video_pipe *pipe = NULL;
767         struct atomisp_acc_pipe *acc_pipe = NULL;
768         struct atomisp_sub_device *asd;
769         bool acc_node = false;
770         int ret;
771
772         dev_dbg(isp->dev, "open device %s\n", vdev->name);
773
774         rt_mutex_lock(&isp->mutex);
775
776         acc_node = !strncmp(vdev->name, "ATOMISP ISP ACC",
777                         sizeof(vdev->name));
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                 isp->firmware = atomisp_load_firmware(isp);
789                 if (!isp->firmware) {
790                         dev_err(isp->dev, "Failed to load ISP firmware.\n");
791                         ret = -ENOENT;
792                         goto error;
793                 }
794                 ret = atomisp_css_load_firmware(isp);
795                 if (ret) {
796                         dev_err(isp->dev, "Failed to init css.\n");
797                         goto error;
798                 }
799                 /* No need to keep FW in memory anymore. */
800                 release_firmware(isp->firmware);
801                 isp->firmware = NULL;
802                 isp->css_env.isp_css_fw.data = NULL;
803         }
804
805         if (acc_node && acc_pipe->users) {
806                 dev_dbg(isp->dev, "acc node already opened\n");
807                 rt_mutex_unlock(&isp->mutex);
808                 return -EBUSY;
809         } else if (acc_node) {
810                 goto dev_init;
811         }
812
813         if (!isp->input_cnt) {
814                 dev_err(isp->dev, "no camera attached\n");
815                 ret = -EINVAL;
816                 goto error;
817         }
818
819         /*
820          * atomisp does not allow multiple open
821          */
822         if (pipe->users) {
823                 dev_dbg(isp->dev, "video node already opened\n");
824                 rt_mutex_unlock(&isp->mutex);
825                 return -EBUSY;
826         }
827
828         ret = atomisp_init_pipe(pipe);
829         if (ret)
830                 goto error;
831
832 dev_init:
833         if (atomisp_dev_users(isp)) {
834                 dev_dbg(isp->dev, "skip init isp in open\n");
835                 goto init_subdev;
836         }
837
838         /* runtime power management, turn on ISP */
839         ret = pm_runtime_get_sync(vdev->v4l2_dev->dev);
840         if (ret < 0) {
841                 dev_err(isp->dev, "Failed to power on device\n");
842                 goto error;
843         }
844
845         if (dypool_enable) {
846                 ret = hmm_pool_register(dypool_pgnr, HMM_POOL_TYPE_DYNAMIC);
847                 if (ret)
848                         dev_err(isp->dev, "Failed to register dynamic memory pool.\n");
849         }
850
851         /* Init ISP */
852         if (atomisp_css_init(isp)) {
853                 ret = -EINVAL;
854                 /* Need to clean up CSS init if it fails. */
855                 goto css_error;
856         }
857
858         atomisp_dev_init_struct(isp);
859
860         ret = v4l2_subdev_call(isp->flash, core, s_power, 1);
861         if (ret < 0 && ret != -ENODEV && ret != -ENOIOCTLCMD) {
862                 dev_err(isp->dev, "Failed to power-on flash\n");
863                 goto css_error;
864         }
865
866 init_subdev:
867         if (atomisp_subdev_users(asd))
868                 goto done;
869
870         atomisp_subdev_init_struct(asd);
871
872 done:
873
874         if (acc_node)
875                 acc_pipe->users++;
876         else
877                 pipe->users++;
878         rt_mutex_unlock(&isp->mutex);
879         return 0;
880
881 css_error:
882         atomisp_css_uninit(isp);
883 error:
884         hmm_pool_unregister(HMM_POOL_TYPE_DYNAMIC);
885         pm_runtime_put(vdev->v4l2_dev->dev);
886         rt_mutex_unlock(&isp->mutex);
887         return ret;
888 }
889
890 static int atomisp_release(struct file *file)
891 {
892         struct video_device *vdev = video_devdata(file);
893         struct atomisp_device *isp = video_get_drvdata(vdev);
894         struct atomisp_video_pipe *pipe;
895         struct atomisp_acc_pipe *acc_pipe;
896         struct atomisp_sub_device *asd;
897         bool acc_node;
898         struct v4l2_requestbuffers req;
899         struct v4l2_subdev_fh fh;
900         struct v4l2_rect clear_compose = {0};
901         int ret = 0;
902
903         v4l2_fh_init(&fh.vfh, vdev);
904
905         req.count = 0;
906         if (isp == NULL)
907                 return -EBADF;
908
909         mutex_lock(&isp->streamoff_mutex);
910         rt_mutex_lock(&isp->mutex);
911
912         dev_dbg(isp->dev, "release device %s\n", vdev->name);
913         acc_node = !strncmp(vdev->name, "ATOMISP ISP ACC",
914                         sizeof(vdev->name));
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                 atomisp_subdev_set_ffmt(&asd->subdev, fh.pad,
966                                         V4L2_SUBDEV_FORMAT_ACTIVE,
967                                         ATOMISP_SUBDEV_PAD_SINK, &isp_sink_fmt);
968         }
969 subdev_uninit:
970         if (atomisp_subdev_users(asd))
971                 goto done;
972
973         /* clear the sink pad for file input */
974         if (isp->sw_contex.file_input && asd->fmt_auto->val) {
975                 struct v4l2_mbus_framefmt isp_sink_fmt = { 0 };
976                 atomisp_subdev_set_ffmt(&asd->subdev, fh.pad,
977                                         V4L2_SUBDEV_FORMAT_ACTIVE,
978                                         ATOMISP_SUBDEV_PAD_SINK, &isp_sink_fmt);
979         }
980
981         atomisp_css_free_stat_buffers(asd);
982         atomisp_free_internal_buffers(asd);
983         ret = v4l2_subdev_call(isp->inputs[asd->input_curr].camera,
984                                        core, s_power, 0);
985         if (ret)
986                 dev_warn(isp->dev, "Failed to power-off sensor\n");
987
988         /* clear the asd field to show this camera is not used */
989         isp->inputs[asd->input_curr].asd = NULL;
990         asd->streaming = ATOMISP_DEVICE_STREAMING_DISABLED;
991
992         if (atomisp_dev_users(isp))
993                 goto done;
994
995         atomisp_acc_release(asd);
996
997         atomisp_destroy_pipes_stream_force(asd);
998         atomisp_css_uninit(isp);
999
1000         if (defer_fw_load) {
1001                 atomisp_css_unload_firmware(isp);
1002                 isp->css_env.isp_css_fw.data = NULL;
1003                 isp->css_env.isp_css_fw.bytes = 0;
1004         }
1005
1006         hmm_pool_unregister(HMM_POOL_TYPE_DYNAMIC);
1007
1008         ret = v4l2_subdev_call(isp->flash, core, s_power, 0);
1009         if (ret < 0 && ret != -ENODEV && ret != -ENOIOCTLCMD)
1010                 dev_warn(isp->dev, "Failed to power-off flash\n");
1011
1012         if (pm_runtime_put_sync(vdev->v4l2_dev->dev) < 0)
1013                 dev_err(isp->dev, "Failed to power off device\n");
1014
1015 done:
1016         if (!acc_node) {
1017                 atomisp_subdev_set_selection(&asd->subdev, fh.pad,
1018                                 V4L2_SUBDEV_FORMAT_ACTIVE,
1019                                 atomisp_subdev_source_pad(vdev),
1020                                 V4L2_SEL_TGT_COMPOSE, 0,
1021                                 &clear_compose);
1022         }
1023         rt_mutex_unlock(&isp->mutex);
1024         mutex_unlock(&isp->streamoff_mutex);
1025
1026         return 0;
1027 }
1028
1029 /*
1030  * Memory help functions for image frame and private parameters
1031  */
1032 static int do_isp_mm_remap(struct atomisp_device *isp,
1033                            struct vm_area_struct *vma,
1034                            ia_css_ptr isp_virt, u32 host_virt, u32 pgnr)
1035 {
1036         u32 pfn;
1037
1038         while (pgnr) {
1039                 pfn = hmm_virt_to_phys(isp_virt) >> PAGE_SHIFT;
1040                 if (remap_pfn_range(vma, host_virt, pfn,
1041                                     PAGE_SIZE, PAGE_SHARED)) {
1042                         dev_err(isp->dev, "remap_pfn_range err.\n");
1043                         return -EAGAIN;
1044                 }
1045
1046                 isp_virt += PAGE_SIZE;
1047                 host_virt += PAGE_SIZE;
1048                 pgnr--;
1049         }
1050
1051         return 0;
1052 }
1053
1054 static int frame_mmap(struct atomisp_device *isp,
1055         const struct atomisp_css_frame *frame, struct vm_area_struct *vma)
1056 {
1057         ia_css_ptr isp_virt;
1058         u32 host_virt;
1059         u32 pgnr;
1060
1061         if (!frame) {
1062                 dev_err(isp->dev, "%s: NULL frame pointer.\n", __func__);
1063                 return -EINVAL;
1064         }
1065
1066         host_virt = vma->vm_start;
1067         isp_virt = frame->data;
1068         atomisp_get_frame_pgnr(isp, frame, &pgnr);
1069
1070         if (do_isp_mm_remap(isp, vma, isp_virt, host_virt, pgnr))
1071                 return -EAGAIN;
1072
1073         return 0;
1074 }
1075
1076 int atomisp_videobuf_mmap_mapper(struct videobuf_queue *q,
1077         struct vm_area_struct *vma)
1078 {
1079         u32 offset = vma->vm_pgoff << PAGE_SHIFT;
1080         int ret = -EINVAL, i;
1081         struct atomisp_device *isp =
1082                 ((struct atomisp_video_pipe *)(q->priv_data))->isp;
1083         struct videobuf_vmalloc_memory *vm_mem;
1084         struct videobuf_mapping *map;
1085
1086         MAGIC_CHECK(q->int_ops->magic, MAGIC_QTYPE_OPS);
1087         if (!(vma->vm_flags & VM_WRITE) || !(vma->vm_flags & VM_SHARED)) {
1088                 dev_err(isp->dev, "map appl bug: PROT_WRITE and MAP_SHARED are required\n");
1089                 return -EINVAL;
1090         }
1091
1092         mutex_lock(&q->vb_lock);
1093         for (i = 0; i < VIDEO_MAX_FRAME; i++) {
1094                 struct videobuf_buffer *buf = q->bufs[i];
1095                 if (buf == NULL)
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 atomisp_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(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 atomisp_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 == NULL) {
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 unsigned int 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 POLLERR;
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         .compat_ioctl32 = atomisp_compat_ioctl32,
1283 #endif
1284         .poll = atomisp_poll,
1285 };
1286
1287 const struct v4l2_file_operations atomisp_file_fops = {
1288         .owner = THIS_MODULE,
1289         .open = atomisp_open,
1290         .release = atomisp_release,
1291         .mmap = atomisp_file_mmap,
1292         .unlocked_ioctl = video_ioctl2,
1293 #ifdef CONFIG_COMPAT
1294         .compat_ioctl32 = atomisp_compat_ioctl32,
1295 #endif
1296         .poll = atomisp_poll,
1297 };
1298