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