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