7a78d044072d22ccf9a76aeb67aff153f35bba49
[linux-2.6-microblaze.git] / drivers / media / platform / vicodec / vicodec-core.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * A virtual codec example device.
4  *
5  * Copyright 2018 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
6  *
7  * This is a virtual codec device driver for testing the codec framework.
8  * It simulates a device that uses memory buffers for both source and
9  * destination and encodes or decodes the data.
10  */
11
12 #include <linux/module.h>
13 #include <linux/delay.h>
14 #include <linux/fs.h>
15 #include <linux/sched.h>
16 #include <linux/slab.h>
17
18 #include <linux/platform_device.h>
19 #include <media/v4l2-mem2mem.h>
20 #include <media/v4l2-device.h>
21 #include <media/v4l2-ioctl.h>
22 #include <media/v4l2-ctrls.h>
23 #include <media/v4l2-event.h>
24 #include <media/videobuf2-vmalloc.h>
25
26 #include "codec-v4l2-fwht.h"
27
28 MODULE_DESCRIPTION("Virtual codec device");
29 MODULE_AUTHOR("Hans Verkuil <hans.verkuil@cisco.com>");
30 MODULE_LICENSE("GPL v2");
31
32 static bool multiplanar;
33 module_param(multiplanar, bool, 0444);
34 MODULE_PARM_DESC(multiplanar,
35                  " use multi-planar API instead of single-planar API");
36
37 static unsigned int debug;
38 module_param(debug, uint, 0644);
39 MODULE_PARM_DESC(debug, " activates debug info");
40
41 #define VICODEC_NAME            "vicodec"
42 #define MAX_WIDTH               4096U
43 #define MIN_WIDTH               640U
44 #define MAX_HEIGHT              2160U
45 #define MIN_HEIGHT              360U
46
47 #define dprintk(dev, fmt, arg...) \
48         v4l2_dbg(1, debug, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg)
49
50
51 struct pixfmt_info {
52         u32 id;
53         unsigned int bytesperline_mult;
54         unsigned int sizeimage_mult;
55         unsigned int sizeimage_div;
56         unsigned int luma_step;
57         unsigned int chroma_step;
58         /* Chroma plane subsampling */
59         unsigned int width_div;
60         unsigned int height_div;
61 };
62
63 static const struct v4l2_fwht_pixfmt_info pixfmt_fwht = {
64         V4L2_PIX_FMT_FWHT, 0, 3, 1, 1, 1, 1, 1, 0, 1
65 };
66
67 static const struct v4l2_fwht_pixfmt_info pixfmt_stateless_fwht = {
68         V4L2_PIX_FMT_FWHT_STATELESS, 0, 3, 1, 1, 1, 1, 1, 0, 1
69 };
70
71 static void vicodec_dev_release(struct device *dev)
72 {
73 }
74
75 static struct platform_device vicodec_pdev = {
76         .name           = VICODEC_NAME,
77         .dev.release    = vicodec_dev_release,
78 };
79
80 /* Per-queue, driver-specific private data */
81 struct vicodec_q_data {
82         unsigned int            coded_width;
83         unsigned int            coded_height;
84         unsigned int            visible_width;
85         unsigned int            visible_height;
86         unsigned int            sizeimage;
87         unsigned int            sequence;
88         const struct v4l2_fwht_pixfmt_info *info;
89 };
90
91 enum {
92         V4L2_M2M_SRC = 0,
93         V4L2_M2M_DST = 1,
94 };
95
96 struct vicodec_dev_instance {
97         struct video_device     vfd;
98         struct mutex            mutex;
99         spinlock_t              lock;
100         struct v4l2_m2m_dev     *m2m_dev;
101 };
102
103 struct vicodec_dev {
104         struct v4l2_device      v4l2_dev;
105         struct vicodec_dev_instance stateful_enc;
106         struct vicodec_dev_instance stateful_dec;
107         struct vicodec_dev_instance stateless_dec;
108 #ifdef CONFIG_MEDIA_CONTROLLER
109         struct media_device     mdev;
110 #endif
111
112 };
113
114 struct vicodec_ctx {
115         struct v4l2_fh          fh;
116         struct vicodec_dev      *dev;
117         bool                    is_enc;
118         bool                    is_stateless;
119         spinlock_t              *lock;
120
121         struct v4l2_ctrl_handler hdl;
122
123         struct vb2_v4l2_buffer *last_src_buf;
124         struct vb2_v4l2_buffer *last_dst_buf;
125
126         /* Source and destination queue data */
127         struct vicodec_q_data   q_data[2];
128         struct v4l2_fwht_state  state;
129
130         u32                     cur_buf_offset;
131         u32                     comp_max_size;
132         u32                     comp_size;
133         u32                     header_size;
134         u32                     comp_magic_cnt;
135         bool                    comp_has_frame;
136         bool                    comp_has_next_frame;
137         bool                    first_source_change_sent;
138         bool                    source_changed;
139 };
140
141 static inline struct vicodec_ctx *file2ctx(struct file *file)
142 {
143         return container_of(file->private_data, struct vicodec_ctx, fh);
144 }
145
146 static struct vicodec_q_data *get_q_data(struct vicodec_ctx *ctx,
147                                          enum v4l2_buf_type type)
148 {
149         switch (type) {
150         case V4L2_BUF_TYPE_VIDEO_OUTPUT:
151         case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
152                 return &ctx->q_data[V4L2_M2M_SRC];
153         case V4L2_BUF_TYPE_VIDEO_CAPTURE:
154         case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
155                 return &ctx->q_data[V4L2_M2M_DST];
156         default:
157                 break;
158         }
159         return NULL;
160 }
161
162 static void copy_cap_to_ref(const u8 *cap, const struct v4l2_fwht_pixfmt_info *info,
163                 struct v4l2_fwht_state *state)
164 {
165         int plane_idx;
166         u8 *p_ref = state->ref_frame.buf;
167         unsigned int cap_stride = state->stride;
168         unsigned int ref_stride = state->ref_stride;
169
170         for (plane_idx = 0; plane_idx < info->planes_num; plane_idx++) {
171                 int i;
172                 unsigned int h_div = (plane_idx == 1 || plane_idx == 2) ?
173                         info->height_div : 1;
174                 const u8 *row_cap = cap;
175                 u8 *row_ref = p_ref;
176
177                 if (info->planes_num == 3 && plane_idx == 1) {
178                         cap_stride /= 2;
179                         ref_stride /= 2;
180                 }
181
182                 if (plane_idx == 1 &&
183                     (info->id == V4L2_PIX_FMT_NV24 ||
184                      info->id == V4L2_PIX_FMT_NV42)) {
185                         cap_stride *= 2;
186                         ref_stride *= 2;
187                 }
188
189                 for (i = 0; i < state->visible_height / h_div; i++) {
190                         memcpy(row_ref, row_cap, ref_stride);
191                         row_ref += ref_stride;
192                         row_cap += cap_stride;
193                 }
194                 cap += cap_stride * (state->coded_height / h_div);
195                 p_ref += ref_stride * (state->coded_height / h_div);
196         }
197 }
198
199 static bool validate_by_version(unsigned int flags, unsigned int version)
200 {
201         if (!version || version > FWHT_VERSION)
202                 return false;
203
204         if (version >= 2) {
205                 unsigned int components_num = 1 +
206                         ((flags & FWHT_FL_COMPONENTS_NUM_MSK) >>
207                          FWHT_FL_COMPONENTS_NUM_OFFSET);
208                 unsigned int pixenc = flags & FWHT_FL_PIXENC_MSK;
209
210                 if (components_num == 0 || components_num > 4 || !pixenc)
211                         return false;
212         }
213         return true;
214 }
215
216 static bool validate_stateless_params_flags(const struct v4l2_ctrl_fwht_params *params,
217                                             const struct v4l2_fwht_pixfmt_info *cur_info)
218 {
219         unsigned int width_div =
220                 (params->flags & FWHT_FL_CHROMA_FULL_WIDTH) ? 1 : 2;
221         unsigned int height_div =
222                 (params->flags & FWHT_FL_CHROMA_FULL_HEIGHT) ? 1 : 2;
223         unsigned int components_num = 3;
224         unsigned int pixenc = 0;
225
226         if (params->version < 3)
227                 return false;
228
229         components_num = 1 + ((params->flags & FWHT_FL_COMPONENTS_NUM_MSK) >>
230                               FWHT_FL_COMPONENTS_NUM_OFFSET);
231         pixenc = (params->flags & FWHT_FL_PIXENC_MSK);
232         if (v4l2_fwht_validate_fmt(cur_info, width_div, height_div,
233                                     components_num, pixenc))
234                 return true;
235         return false;
236 }
237
238
239 static void update_state_from_header(struct vicodec_ctx *ctx)
240 {
241         const struct fwht_cframe_hdr *p_hdr = &ctx->state.header;
242
243         ctx->state.visible_width = ntohl(p_hdr->width);
244         ctx->state.visible_height = ntohl(p_hdr->height);
245         ctx->state.colorspace = ntohl(p_hdr->colorspace);
246         ctx->state.xfer_func = ntohl(p_hdr->xfer_func);
247         ctx->state.ycbcr_enc = ntohl(p_hdr->ycbcr_enc);
248         ctx->state.quantization = ntohl(p_hdr->quantization);
249 }
250
251 static int device_process(struct vicodec_ctx *ctx,
252                           struct vb2_v4l2_buffer *src_vb,
253                           struct vb2_v4l2_buffer *dst_vb)
254 {
255         struct vicodec_dev *dev = ctx->dev;
256         struct v4l2_fwht_state *state = &ctx->state;
257         u8 *p_src, *p_dst;
258         int ret = 0;
259
260         if (ctx->is_enc || ctx->is_stateless)
261                 p_src = vb2_plane_vaddr(&src_vb->vb2_buf, 0);
262         else
263                 p_src = state->compressed_frame;
264
265         if (ctx->is_stateless) {
266                 struct media_request *src_req = src_vb->vb2_buf.req_obj.req;
267
268                 ret = v4l2_ctrl_request_setup(src_req, &ctx->hdl);
269                 if (ret)
270                         return ret;
271                 update_state_from_header(ctx);
272
273                 ctx->state.header.size =
274                         htonl(vb2_get_plane_payload(&src_vb->vb2_buf, 0));
275                 /*
276                  * set the reference buffer from the reference timestamp
277                  * only if this is a P-frame
278                  */
279                 if (!(ntohl(ctx->state.header.flags) & FWHT_FL_I_FRAME)) {
280                         struct vb2_buffer *ref_vb2_buf;
281                         int ref_buf_idx;
282                         struct vb2_queue *vq_cap =
283                                 v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
284                                                 V4L2_BUF_TYPE_VIDEO_CAPTURE);
285
286                         ref_buf_idx = vb2_find_timestamp(vq_cap,
287                                                          ctx->state.ref_frame_ts, 0);
288                         if (ref_buf_idx < 0)
289                                 return -EINVAL;
290
291                         ref_vb2_buf = vq_cap->bufs[ref_buf_idx];
292                         if (ref_vb2_buf->state == VB2_BUF_STATE_ERROR)
293                                 ret = -EINVAL;
294                         ctx->state.ref_frame.buf =
295                                 vb2_plane_vaddr(ref_vb2_buf, 0);
296                 } else {
297                         ctx->state.ref_frame.buf = NULL;
298                 }
299         }
300         p_dst = vb2_plane_vaddr(&dst_vb->vb2_buf, 0);
301         if (!p_src || !p_dst) {
302                 v4l2_err(&dev->v4l2_dev,
303                          "Acquiring kernel pointers to buffers failed\n");
304                 return -EFAULT;
305         }
306
307         if (ctx->is_enc) {
308                 struct vicodec_q_data *q_src;
309                 int comp_sz_or_errcode;
310
311                 q_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
312                 state->info = q_src->info;
313                 comp_sz_or_errcode = v4l2_fwht_encode(state, p_src, p_dst);
314                 if (comp_sz_or_errcode < 0)
315                         return comp_sz_or_errcode;
316                 vb2_set_plane_payload(&dst_vb->vb2_buf, 0, comp_sz_or_errcode);
317         } else {
318                 struct vicodec_q_data *q_dst;
319                 unsigned int comp_frame_size = ntohl(ctx->state.header.size);
320
321                 q_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
322                 if (comp_frame_size > ctx->comp_max_size)
323                         return -EINVAL;
324                 state->info = q_dst->info;
325                 ret = v4l2_fwht_decode(state, p_src, p_dst);
326                 if (ret < 0)
327                         return ret;
328                 if (!ctx->is_stateless)
329                         copy_cap_to_ref(p_dst, ctx->state.info, &ctx->state);
330
331                 vb2_set_plane_payload(&dst_vb->vb2_buf, 0, q_dst->sizeimage);
332         }
333         return ret;
334 }
335
336 /*
337  * mem2mem callbacks
338  */
339 static enum vb2_buffer_state get_next_header(struct vicodec_ctx *ctx,
340                                              u8 **pp, u32 sz)
341 {
342         static const u8 magic[] = {
343                 0x4f, 0x4f, 0x4f, 0x4f, 0xff, 0xff, 0xff, 0xff
344         };
345         u8 *p = *pp;
346         u32 state;
347         u8 *header = (u8 *)&ctx->state.header;
348
349         state = VB2_BUF_STATE_DONE;
350
351         if (!ctx->header_size) {
352                 state = VB2_BUF_STATE_ERROR;
353                 for (; p < *pp + sz; p++) {
354                         u32 copy;
355
356                         p = memchr(p, magic[ctx->comp_magic_cnt],
357                                    *pp + sz - p);
358                         if (!p) {
359                                 ctx->comp_magic_cnt = 0;
360                                 p = *pp + sz;
361                                 break;
362                         }
363                         copy = sizeof(magic) - ctx->comp_magic_cnt;
364                         if (*pp + sz - p < copy)
365                                 copy = *pp + sz - p;
366
367                         memcpy(header + ctx->comp_magic_cnt, p, copy);
368                         ctx->comp_magic_cnt += copy;
369                         if (!memcmp(header, magic, ctx->comp_magic_cnt)) {
370                                 p += copy;
371                                 state = VB2_BUF_STATE_DONE;
372                                 break;
373                         }
374                         ctx->comp_magic_cnt = 0;
375                 }
376                 if (ctx->comp_magic_cnt < sizeof(magic)) {
377                         *pp = p;
378                         return state;
379                 }
380                 ctx->header_size = sizeof(magic);
381         }
382
383         if (ctx->header_size < sizeof(struct fwht_cframe_hdr)) {
384                 u32 copy = sizeof(struct fwht_cframe_hdr) - ctx->header_size;
385
386                 if (*pp + sz - p < copy)
387                         copy = *pp + sz - p;
388
389                 memcpy(header + ctx->header_size, p, copy);
390                 p += copy;
391                 ctx->header_size += copy;
392         }
393         *pp = p;
394         return state;
395 }
396
397 /* device_run() - prepares and starts the device */
398 static void device_run(void *priv)
399 {
400         static const struct v4l2_event eos_event = {
401                 .type = V4L2_EVENT_EOS
402         };
403         struct vicodec_ctx *ctx = priv;
404         struct vicodec_dev *dev = ctx->dev;
405         struct vb2_v4l2_buffer *src_buf, *dst_buf;
406         struct vicodec_q_data *q_src, *q_dst;
407         u32 state;
408         struct media_request *src_req;
409
410
411         src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
412         dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
413         src_req = src_buf->vb2_buf.req_obj.req;
414
415         q_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
416         q_dst = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
417
418         state = VB2_BUF_STATE_DONE;
419         if (device_process(ctx, src_buf, dst_buf))
420                 state = VB2_BUF_STATE_ERROR;
421         else
422                 dst_buf->sequence = q_dst->sequence++;
423         dst_buf->flags &= ~V4L2_BUF_FLAG_LAST;
424         v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, !ctx->is_enc);
425
426         ctx->last_dst_buf = dst_buf;
427
428         spin_lock(ctx->lock);
429         if (!ctx->comp_has_next_frame && src_buf == ctx->last_src_buf) {
430                 dst_buf->flags |= V4L2_BUF_FLAG_LAST;
431                 v4l2_event_queue_fh(&ctx->fh, &eos_event);
432         }
433         if (ctx->is_enc || ctx->is_stateless) {
434                 src_buf->sequence = q_src->sequence++;
435                 src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
436                 v4l2_m2m_buf_done(src_buf, state);
437         } else if (vb2_get_plane_payload(&src_buf->vb2_buf, 0) == ctx->cur_buf_offset) {
438                 src_buf->sequence = q_src->sequence++;
439                 src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
440                 v4l2_m2m_buf_done(src_buf, state);
441                 ctx->cur_buf_offset = 0;
442                 ctx->comp_has_next_frame = false;
443         }
444         v4l2_m2m_buf_done(dst_buf, state);
445
446         ctx->comp_size = 0;
447         ctx->header_size = 0;
448         ctx->comp_magic_cnt = 0;
449         ctx->comp_has_frame = false;
450         spin_unlock(ctx->lock);
451         if (ctx->is_stateless && src_req)
452                 v4l2_ctrl_request_complete(src_req, &ctx->hdl);
453
454         if (ctx->is_enc)
455                 v4l2_m2m_job_finish(dev->stateful_enc.m2m_dev, ctx->fh.m2m_ctx);
456         else if (ctx->is_stateless)
457                 v4l2_m2m_job_finish(dev->stateless_dec.m2m_dev,
458                                     ctx->fh.m2m_ctx);
459         else
460                 v4l2_m2m_job_finish(dev->stateful_dec.m2m_dev, ctx->fh.m2m_ctx);
461 }
462
463 static void job_remove_src_buf(struct vicodec_ctx *ctx, u32 state)
464 {
465         struct vb2_v4l2_buffer *src_buf;
466         struct vicodec_q_data *q_src;
467
468         q_src = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT);
469         spin_lock(ctx->lock);
470         src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
471         src_buf->sequence = q_src->sequence++;
472         v4l2_m2m_buf_done(src_buf, state);
473         ctx->cur_buf_offset = 0;
474         spin_unlock(ctx->lock);
475 }
476
477 static const struct v4l2_fwht_pixfmt_info *
478 info_from_header(const struct fwht_cframe_hdr *p_hdr)
479 {
480         unsigned int flags = ntohl(p_hdr->flags);
481         unsigned int width_div = (flags & FWHT_FL_CHROMA_FULL_WIDTH) ? 1 : 2;
482         unsigned int height_div = (flags & FWHT_FL_CHROMA_FULL_HEIGHT) ? 1 : 2;
483         unsigned int components_num = 3;
484         unsigned int pixenc = 0;
485         unsigned int version = ntohl(p_hdr->version);
486
487         if (version >= 2) {
488                 components_num = 1 + ((flags & FWHT_FL_COMPONENTS_NUM_MSK) >>
489                                 FWHT_FL_COMPONENTS_NUM_OFFSET);
490                 pixenc = (flags & FWHT_FL_PIXENC_MSK);
491         }
492         return v4l2_fwht_find_nth_fmt(width_div, height_div,
493                                      components_num, pixenc, 0);
494 }
495
496 static bool is_header_valid(const struct fwht_cframe_hdr *p_hdr)
497 {
498         const struct v4l2_fwht_pixfmt_info *info;
499         unsigned int w = ntohl(p_hdr->width);
500         unsigned int h = ntohl(p_hdr->height);
501         unsigned int version = ntohl(p_hdr->version);
502         unsigned int flags = ntohl(p_hdr->flags);
503
504         if (w < MIN_WIDTH || w > MAX_WIDTH || h < MIN_HEIGHT || h > MAX_HEIGHT)
505                 return false;
506
507         if (!validate_by_version(flags, version))
508                 return false;
509
510         info = info_from_header(p_hdr);
511         if (!info)
512                 return false;
513         return true;
514 }
515
516 static void update_capture_data_from_header(struct vicodec_ctx *ctx)
517 {
518         struct vicodec_q_data *q_dst = get_q_data(ctx,
519                                                   V4L2_BUF_TYPE_VIDEO_CAPTURE);
520         const struct fwht_cframe_hdr *p_hdr = &ctx->state.header;
521         const struct v4l2_fwht_pixfmt_info *info = info_from_header(p_hdr);
522         unsigned int flags = ntohl(p_hdr->flags);
523         unsigned int hdr_width_div = (flags & FWHT_FL_CHROMA_FULL_WIDTH) ? 1 : 2;
524         unsigned int hdr_height_div = (flags & FWHT_FL_CHROMA_FULL_HEIGHT) ? 1 : 2;
525
526         /*
527          * This function should not be used by a stateless codec since
528          * it changes values in q_data that are not request specific
529          */
530         WARN_ON(ctx->is_stateless);
531
532         q_dst->info = info;
533         q_dst->visible_width = ntohl(p_hdr->width);
534         q_dst->visible_height = ntohl(p_hdr->height);
535         q_dst->coded_width = vic_round_dim(q_dst->visible_width, hdr_width_div);
536         q_dst->coded_height = vic_round_dim(q_dst->visible_height,
537                                             hdr_height_div);
538
539         q_dst->sizeimage = q_dst->coded_width * q_dst->coded_height *
540                 q_dst->info->sizeimage_mult / q_dst->info->sizeimage_div;
541         ctx->state.colorspace = ntohl(p_hdr->colorspace);
542
543         ctx->state.xfer_func = ntohl(p_hdr->xfer_func);
544         ctx->state.ycbcr_enc = ntohl(p_hdr->ycbcr_enc);
545         ctx->state.quantization = ntohl(p_hdr->quantization);
546 }
547
548 static void set_last_buffer(struct vb2_v4l2_buffer *dst_buf,
549                             const struct vb2_v4l2_buffer *src_buf,
550                             struct vicodec_ctx *ctx)
551 {
552         struct vicodec_q_data *q_dst = get_q_data(ctx,
553                                                   V4L2_BUF_TYPE_VIDEO_CAPTURE);
554
555         vb2_set_plane_payload(&dst_buf->vb2_buf, 0, 0);
556         dst_buf->sequence = q_dst->sequence++;
557
558         v4l2_m2m_buf_copy_metadata(src_buf, dst_buf, !ctx->is_enc);
559         dst_buf->flags |= V4L2_BUF_FLAG_LAST;
560         v4l2_m2m_buf_done(dst_buf, VB2_BUF_STATE_DONE);
561 }
562
563 static int job_ready(void *priv)
564 {
565         static const u8 magic[] = {
566                 0x4f, 0x4f, 0x4f, 0x4f, 0xff, 0xff, 0xff, 0xff
567         };
568         struct vicodec_ctx *ctx = priv;
569         struct vb2_v4l2_buffer *src_buf;
570         u8 *p_src;
571         u8 *p;
572         u32 sz;
573         u32 state;
574         struct vicodec_q_data *q_dst = get_q_data(ctx,
575                                                   V4L2_BUF_TYPE_VIDEO_CAPTURE);
576         unsigned int flags;
577         unsigned int hdr_width_div;
578         unsigned int hdr_height_div;
579         unsigned int max_to_copy;
580         unsigned int comp_frame_size;
581
582         if (ctx->source_changed)
583                 return 0;
584         if (ctx->is_stateless || ctx->is_enc || ctx->comp_has_frame)
585                 return 1;
586
587 restart:
588         ctx->comp_has_next_frame = false;
589         src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx);
590         if (!src_buf)
591                 return 0;
592         p_src = vb2_plane_vaddr(&src_buf->vb2_buf, 0);
593         sz = vb2_get_plane_payload(&src_buf->vb2_buf, 0);
594         p = p_src + ctx->cur_buf_offset;
595
596         state = VB2_BUF_STATE_DONE;
597
598         if (ctx->header_size < sizeof(struct fwht_cframe_hdr)) {
599                 state = get_next_header(ctx, &p, p_src + sz - p);
600                 if (ctx->header_size < sizeof(struct fwht_cframe_hdr)) {
601                         job_remove_src_buf(ctx, state);
602                         goto restart;
603                 }
604         }
605
606         comp_frame_size = ntohl(ctx->state.header.size);
607
608         /*
609          * The current scanned frame might be the first frame of a new
610          * resolution so its size might be larger than ctx->comp_max_size.
611          * In that case it is copied up to the current buffer capacity and
612          * the copy will continue after allocating new large enough buffer
613          * when restreaming
614          */
615         max_to_copy = min(comp_frame_size, ctx->comp_max_size);
616
617         if (ctx->comp_size < max_to_copy) {
618                 u32 copy = max_to_copy - ctx->comp_size;
619
620                 if (copy > p_src + sz - p)
621                         copy = p_src + sz - p;
622
623                 memcpy(ctx->state.compressed_frame + ctx->comp_size,
624                        p, copy);
625                 p += copy;
626                 ctx->comp_size += copy;
627                 if (ctx->comp_size < max_to_copy) {
628                         job_remove_src_buf(ctx, state);
629                         goto restart;
630                 }
631         }
632         ctx->cur_buf_offset = p - p_src;
633         if (ctx->comp_size == comp_frame_size)
634                 ctx->comp_has_frame = true;
635         ctx->comp_has_next_frame = false;
636         if (ctx->comp_has_frame && sz - ctx->cur_buf_offset >=
637                         sizeof(struct fwht_cframe_hdr)) {
638                 struct fwht_cframe_hdr *p_hdr = (struct fwht_cframe_hdr *)p;
639                 u32 frame_size = ntohl(p_hdr->size);
640                 u32 remaining = sz - ctx->cur_buf_offset - sizeof(*p_hdr);
641
642                 if (!memcmp(p, magic, sizeof(magic)))
643                         ctx->comp_has_next_frame = remaining >= frame_size;
644         }
645         /*
646          * if the header is invalid the device_run will just drop the frame
647          * with an error
648          */
649         if (!is_header_valid(&ctx->state.header) && ctx->comp_has_frame)
650                 return 1;
651         flags = ntohl(ctx->state.header.flags);
652         hdr_width_div = (flags & FWHT_FL_CHROMA_FULL_WIDTH) ? 1 : 2;
653         hdr_height_div = (flags & FWHT_FL_CHROMA_FULL_HEIGHT) ? 1 : 2;
654
655         if (ntohl(ctx->state.header.width) != q_dst->visible_width ||
656             ntohl(ctx->state.header.height) != q_dst->visible_height ||
657             !q_dst->info ||
658             hdr_width_div != q_dst->info->width_div ||
659             hdr_height_div != q_dst->info->height_div) {
660                 static const struct v4l2_event rs_event = {
661                         .type = V4L2_EVENT_SOURCE_CHANGE,
662                         .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
663                 };
664
665                 struct vb2_v4l2_buffer *dst_buf =
666                         v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
667
668                 update_capture_data_from_header(ctx);
669                 ctx->first_source_change_sent = true;
670                 v4l2_event_queue_fh(&ctx->fh, &rs_event);
671                 set_last_buffer(dst_buf, src_buf, ctx);
672                 ctx->source_changed = true;
673                 return 0;
674         }
675         return 1;
676 }
677
678 /*
679  * video ioctls
680  */
681
682 static const struct v4l2_fwht_pixfmt_info *find_fmt(u32 fmt)
683 {
684         const struct v4l2_fwht_pixfmt_info *info =
685                 v4l2_fwht_find_pixfmt(fmt);
686
687         if (!info)
688                 info = v4l2_fwht_get_pixfmt(0);
689         return info;
690 }
691
692 static int vidioc_querycap(struct file *file, void *priv,
693                            struct v4l2_capability *cap)
694 {
695         strscpy(cap->driver, VICODEC_NAME, sizeof(cap->driver));
696         strscpy(cap->card, VICODEC_NAME, sizeof(cap->card));
697         snprintf(cap->bus_info, sizeof(cap->bus_info),
698                         "platform:%s", VICODEC_NAME);
699         return 0;
700 }
701
702 static int enum_fmt(struct v4l2_fmtdesc *f, struct vicodec_ctx *ctx,
703                     bool is_out)
704 {
705         bool is_uncomp = (ctx->is_enc && is_out) || (!ctx->is_enc && !is_out);
706
707         if (V4L2_TYPE_IS_MULTIPLANAR(f->type) && !multiplanar)
708                 return -EINVAL;
709         if (!V4L2_TYPE_IS_MULTIPLANAR(f->type) && multiplanar)
710                 return -EINVAL;
711
712         if (is_uncomp) {
713                 const struct v4l2_fwht_pixfmt_info *info =
714                                         get_q_data(ctx, f->type)->info;
715
716                 if (!info || ctx->is_enc)
717                         info = v4l2_fwht_get_pixfmt(f->index);
718                 else
719                         info = v4l2_fwht_find_nth_fmt(info->width_div,
720                                                      info->height_div,
721                                                      info->components_num,
722                                                      info->pixenc,
723                                                      f->index);
724                 if (!info)
725                         return -EINVAL;
726                 f->pixelformat = info->id;
727         } else {
728                 if (f->index)
729                         return -EINVAL;
730                 f->pixelformat = ctx->is_stateless ?
731                         V4L2_PIX_FMT_FWHT_STATELESS : V4L2_PIX_FMT_FWHT;
732         }
733         return 0;
734 }
735
736 static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
737                                    struct v4l2_fmtdesc *f)
738 {
739         struct vicodec_ctx *ctx = file2ctx(file);
740
741         return enum_fmt(f, ctx, false);
742 }
743
744 static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
745                                    struct v4l2_fmtdesc *f)
746 {
747         struct vicodec_ctx *ctx = file2ctx(file);
748
749         return enum_fmt(f, ctx, true);
750 }
751
752 static int vidioc_g_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f)
753 {
754         struct vb2_queue *vq;
755         struct vicodec_q_data *q_data;
756         struct v4l2_pix_format_mplane *pix_mp;
757         struct v4l2_pix_format *pix;
758         const struct v4l2_fwht_pixfmt_info *info;
759
760         vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
761         if (!vq)
762                 return -EINVAL;
763
764         q_data = get_q_data(ctx, f->type);
765         info = q_data->info;
766
767         if (!info)
768                 info = v4l2_fwht_get_pixfmt(0);
769
770         switch (f->type) {
771         case V4L2_BUF_TYPE_VIDEO_CAPTURE:
772         case V4L2_BUF_TYPE_VIDEO_OUTPUT:
773                 if (multiplanar)
774                         return -EINVAL;
775                 pix = &f->fmt.pix;
776                 pix->width = q_data->coded_width;
777                 pix->height = q_data->coded_height;
778                 pix->field = V4L2_FIELD_NONE;
779                 pix->pixelformat = info->id;
780                 pix->bytesperline = q_data->coded_width *
781                                         info->bytesperline_mult;
782                 pix->sizeimage = q_data->sizeimage;
783                 pix->colorspace = ctx->state.colorspace;
784                 pix->xfer_func = ctx->state.xfer_func;
785                 pix->ycbcr_enc = ctx->state.ycbcr_enc;
786                 pix->quantization = ctx->state.quantization;
787                 break;
788
789         case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
790         case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
791                 if (!multiplanar)
792                         return -EINVAL;
793                 pix_mp = &f->fmt.pix_mp;
794                 pix_mp->width = q_data->coded_width;
795                 pix_mp->height = q_data->coded_height;
796                 pix_mp->field = V4L2_FIELD_NONE;
797                 pix_mp->pixelformat = info->id;
798                 pix_mp->num_planes = 1;
799                 pix_mp->plane_fmt[0].bytesperline =
800                                 q_data->coded_width * info->bytesperline_mult;
801                 pix_mp->plane_fmt[0].sizeimage = q_data->sizeimage;
802                 pix_mp->colorspace = ctx->state.colorspace;
803                 pix_mp->xfer_func = ctx->state.xfer_func;
804                 pix_mp->ycbcr_enc = ctx->state.ycbcr_enc;
805                 pix_mp->quantization = ctx->state.quantization;
806                 memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved));
807                 memset(pix_mp->plane_fmt[0].reserved, 0,
808                        sizeof(pix_mp->plane_fmt[0].reserved));
809                 break;
810         default:
811                 return -EINVAL;
812         }
813         return 0;
814 }
815
816 static int vidioc_g_fmt_vid_out(struct file *file, void *priv,
817                                 struct v4l2_format *f)
818 {
819         return vidioc_g_fmt(file2ctx(file), f);
820 }
821
822 static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
823                                 struct v4l2_format *f)
824 {
825         return vidioc_g_fmt(file2ctx(file), f);
826 }
827
828 static int vidioc_try_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f)
829 {
830         struct v4l2_pix_format_mplane *pix_mp;
831         struct v4l2_pix_format *pix;
832         struct v4l2_plane_pix_format *plane;
833         const struct v4l2_fwht_pixfmt_info *info = ctx->is_stateless ?
834                 &pixfmt_stateless_fwht : &pixfmt_fwht;
835
836         switch (f->type) {
837         case V4L2_BUF_TYPE_VIDEO_CAPTURE:
838         case V4L2_BUF_TYPE_VIDEO_OUTPUT:
839                 pix = &f->fmt.pix;
840                 if (pix->pixelformat != V4L2_PIX_FMT_FWHT &&
841                     pix->pixelformat != V4L2_PIX_FMT_FWHT_STATELESS)
842                         info = find_fmt(pix->pixelformat);
843
844                 pix->width = clamp(pix->width, MIN_WIDTH, MAX_WIDTH);
845                 pix->width = vic_round_dim(pix->width, info->width_div);
846
847                 pix->height = clamp(pix->height, MIN_HEIGHT, MAX_HEIGHT);
848                 pix->height = vic_round_dim(pix->height, info->height_div);
849
850                 pix->field = V4L2_FIELD_NONE;
851                 pix->bytesperline =
852                         pix->width * info->bytesperline_mult;
853                 pix->sizeimage = pix->width * pix->height *
854                         info->sizeimage_mult / info->sizeimage_div;
855                 if (pix->pixelformat == V4L2_PIX_FMT_FWHT)
856                         pix->sizeimage += sizeof(struct fwht_cframe_hdr);
857                 break;
858         case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
859         case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
860                 pix_mp = &f->fmt.pix_mp;
861                 plane = pix_mp->plane_fmt;
862                 if (pix_mp->pixelformat != V4L2_PIX_FMT_FWHT &&
863                     pix_mp->pixelformat != V4L2_PIX_FMT_FWHT_STATELESS)
864                         info = find_fmt(pix_mp->pixelformat);
865                 pix_mp->num_planes = 1;
866
867                 pix_mp->width = clamp(pix_mp->width, MIN_WIDTH, MAX_WIDTH);
868                 pix_mp->width = vic_round_dim(pix_mp->width, info->width_div);
869
870                 pix_mp->height = clamp(pix_mp->height, MIN_HEIGHT, MAX_HEIGHT);
871                 pix_mp->height = vic_round_dim(pix_mp->height,
872                                                info->height_div);
873
874                 pix_mp->field = V4L2_FIELD_NONE;
875                 plane->bytesperline =
876                         pix_mp->width * info->bytesperline_mult;
877                 plane->sizeimage = pix_mp->width * pix_mp->height *
878                         info->sizeimage_mult / info->sizeimage_div;
879                 if (pix_mp->pixelformat == V4L2_PIX_FMT_FWHT)
880                         plane->sizeimage += sizeof(struct fwht_cframe_hdr);
881                 memset(pix_mp->reserved, 0, sizeof(pix_mp->reserved));
882                 memset(plane->reserved, 0, sizeof(plane->reserved));
883                 break;
884         default:
885                 return -EINVAL;
886         }
887
888         return 0;
889 }
890
891 static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
892                                   struct v4l2_format *f)
893 {
894         struct vicodec_ctx *ctx = file2ctx(file);
895         struct v4l2_pix_format_mplane *pix_mp;
896         struct v4l2_pix_format *pix;
897
898         switch (f->type) {
899         case V4L2_BUF_TYPE_VIDEO_CAPTURE:
900                 if (multiplanar)
901                         return -EINVAL;
902                 pix = &f->fmt.pix;
903                 pix->pixelformat = ctx->is_enc ? V4L2_PIX_FMT_FWHT :
904                                    find_fmt(f->fmt.pix.pixelformat)->id;
905                 pix->colorspace = ctx->state.colorspace;
906                 pix->xfer_func = ctx->state.xfer_func;
907                 pix->ycbcr_enc = ctx->state.ycbcr_enc;
908                 pix->quantization = ctx->state.quantization;
909                 break;
910         case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
911                 if (!multiplanar)
912                         return -EINVAL;
913                 pix_mp = &f->fmt.pix_mp;
914                 pix_mp->pixelformat = ctx->is_enc ? V4L2_PIX_FMT_FWHT :
915                                       find_fmt(pix_mp->pixelformat)->id;
916                 pix_mp->colorspace = ctx->state.colorspace;
917                 pix_mp->xfer_func = ctx->state.xfer_func;
918                 pix_mp->ycbcr_enc = ctx->state.ycbcr_enc;
919                 pix_mp->quantization = ctx->state.quantization;
920                 break;
921         default:
922                 return -EINVAL;
923         }
924
925         return vidioc_try_fmt(ctx, f);
926 }
927
928 static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
929                                   struct v4l2_format *f)
930 {
931         struct vicodec_ctx *ctx = file2ctx(file);
932         struct v4l2_pix_format_mplane *pix_mp;
933         struct v4l2_pix_format *pix;
934
935         switch (f->type) {
936         case V4L2_BUF_TYPE_VIDEO_OUTPUT:
937                 if (multiplanar)
938                         return -EINVAL;
939                 pix = &f->fmt.pix;
940                 if (ctx->is_enc)
941                         pix->pixelformat = find_fmt(pix->pixelformat)->id;
942                 else if (ctx->is_stateless)
943                         pix->pixelformat = V4L2_PIX_FMT_FWHT_STATELESS;
944                 else
945                         pix->pixelformat = V4L2_PIX_FMT_FWHT;
946                 if (!pix->colorspace)
947                         pix->colorspace = V4L2_COLORSPACE_REC709;
948                 break;
949         case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
950                 if (!multiplanar)
951                         return -EINVAL;
952                 pix_mp = &f->fmt.pix_mp;
953                 if (ctx->is_enc)
954                         pix_mp->pixelformat = find_fmt(pix_mp->pixelformat)->id;
955                 else if (ctx->is_stateless)
956                         pix_mp->pixelformat = V4L2_PIX_FMT_FWHT_STATELESS;
957                 else
958                         pix_mp->pixelformat = V4L2_PIX_FMT_FWHT;
959                 if (!pix_mp->colorspace)
960                         pix_mp->colorspace = V4L2_COLORSPACE_REC709;
961                 break;
962         default:
963                 return -EINVAL;
964         }
965
966         return vidioc_try_fmt(ctx, f);
967 }
968
969 static int vidioc_s_fmt(struct vicodec_ctx *ctx, struct v4l2_format *f)
970 {
971         struct vicodec_q_data *q_data;
972         struct vb2_queue *vq;
973         bool fmt_changed = true;
974         struct v4l2_pix_format_mplane *pix_mp;
975         struct v4l2_pix_format *pix;
976
977         vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
978         if (!vq)
979                 return -EINVAL;
980
981         q_data = get_q_data(ctx, f->type);
982         if (!q_data)
983                 return -EINVAL;
984
985         switch (f->type) {
986         case V4L2_BUF_TYPE_VIDEO_CAPTURE:
987         case V4L2_BUF_TYPE_VIDEO_OUTPUT:
988                 pix = &f->fmt.pix;
989                 if (ctx->is_enc && V4L2_TYPE_IS_OUTPUT(f->type))
990                         fmt_changed =
991                                 !q_data->info ||
992                                 q_data->info->id != pix->pixelformat ||
993                                 q_data->coded_width != pix->width ||
994                                 q_data->coded_height != pix->height;
995
996                 if (vb2_is_busy(vq) && fmt_changed)
997                         return -EBUSY;
998
999                 if (pix->pixelformat == V4L2_PIX_FMT_FWHT)
1000                         q_data->info = &pixfmt_fwht;
1001                 else if (pix->pixelformat == V4L2_PIX_FMT_FWHT_STATELESS)
1002                         q_data->info = &pixfmt_stateless_fwht;
1003                 else
1004                         q_data->info = find_fmt(pix->pixelformat);
1005                 q_data->coded_width = pix->width;
1006                 q_data->coded_height = pix->height;
1007                 q_data->sizeimage = pix->sizeimage;
1008                 break;
1009         case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1010         case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1011                 pix_mp = &f->fmt.pix_mp;
1012                 if (ctx->is_enc && V4L2_TYPE_IS_OUTPUT(f->type))
1013                         fmt_changed =
1014                                 !q_data->info ||
1015                                 q_data->info->id != pix_mp->pixelformat ||
1016                                 q_data->coded_width != pix_mp->width ||
1017                                 q_data->coded_height != pix_mp->height;
1018
1019                 if (vb2_is_busy(vq) && fmt_changed)
1020                         return -EBUSY;
1021
1022                 if (pix_mp->pixelformat == V4L2_PIX_FMT_FWHT)
1023                         q_data->info = &pixfmt_fwht;
1024                 else if (pix_mp->pixelformat == V4L2_PIX_FMT_FWHT_STATELESS)
1025                         q_data->info = &pixfmt_stateless_fwht;
1026                 else
1027                         q_data->info = find_fmt(pix_mp->pixelformat);
1028                 q_data->coded_width = pix_mp->width;
1029                 q_data->coded_height = pix_mp->height;
1030                 q_data->sizeimage = pix_mp->plane_fmt[0].sizeimage;
1031                 break;
1032         default:
1033                 return -EINVAL;
1034         }
1035
1036         dprintk(ctx->dev,
1037                 "Setting format for type %d, coded wxh: %dx%d, fourcc: 0x%08x\n",
1038                 f->type, q_data->coded_width, q_data->coded_height,
1039                 q_data->info->id);
1040
1041         return 0;
1042 }
1043
1044 static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
1045                                 struct v4l2_format *f)
1046 {
1047         int ret;
1048
1049         ret = vidioc_try_fmt_vid_cap(file, priv, f);
1050         if (ret)
1051                 return ret;
1052
1053         return vidioc_s_fmt(file2ctx(file), f);
1054 }
1055
1056 static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
1057                                 struct v4l2_format *f)
1058 {
1059         struct vicodec_ctx *ctx = file2ctx(file);
1060         struct vicodec_q_data *q_data;
1061         struct vicodec_q_data *q_data_cap;
1062         struct v4l2_pix_format *pix;
1063         struct v4l2_pix_format_mplane *pix_mp;
1064         u32 coded_w = 0, coded_h = 0;
1065         unsigned int size = 0;
1066         int ret;
1067
1068         q_data = get_q_data(ctx, f->type);
1069         q_data_cap = get_q_data(ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE);
1070
1071         ret = vidioc_try_fmt_vid_out(file, priv, f);
1072         if (ret)
1073                 return ret;
1074
1075         if (ctx->is_enc) {
1076                 struct vb2_queue *vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type);
1077                 struct vb2_queue *vq_cap = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
1078                                                            V4L2_BUF_TYPE_VIDEO_CAPTURE);
1079                 const struct v4l2_fwht_pixfmt_info *info = ctx->is_stateless ?
1080                         &pixfmt_stateless_fwht : &pixfmt_fwht;
1081
1082                 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1083                         coded_w = f->fmt.pix.width;
1084                         coded_h = f->fmt.pix.height;
1085                 } else {
1086                         coded_w = f->fmt.pix_mp.width;
1087                         coded_h = f->fmt.pix_mp.height;
1088                 }
1089                 if (vb2_is_busy(vq) && (coded_w != q_data->coded_width ||
1090                                         coded_h != q_data->coded_height))
1091                         return -EBUSY;
1092                 size = coded_w * coded_h *
1093                         info->sizeimage_mult / info->sizeimage_div;
1094                 if (!ctx->is_stateless)
1095                         size += sizeof(struct fwht_cframe_hdr);
1096
1097                 if (vb2_is_busy(vq_cap) && size > q_data_cap->sizeimage)
1098                         return -EBUSY;
1099         }
1100
1101         ret = vidioc_s_fmt(file2ctx(file), f);
1102         if (!ret) {
1103                 if (ctx->is_enc) {
1104                         q_data->visible_width = coded_w;
1105                         q_data->visible_height = coded_h;
1106                         q_data_cap->coded_width = coded_w;
1107                         q_data_cap->coded_height = coded_h;
1108                         q_data_cap->sizeimage = size;
1109                 }
1110
1111                 switch (f->type) {
1112                 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1113                         pix = &f->fmt.pix;
1114                         ctx->state.colorspace = pix->colorspace;
1115                         ctx->state.xfer_func = pix->xfer_func;
1116                         ctx->state.ycbcr_enc = pix->ycbcr_enc;
1117                         ctx->state.quantization = pix->quantization;
1118                         break;
1119                 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1120                         pix_mp = &f->fmt.pix_mp;
1121                         ctx->state.colorspace = pix_mp->colorspace;
1122                         ctx->state.xfer_func = pix_mp->xfer_func;
1123                         ctx->state.ycbcr_enc = pix_mp->ycbcr_enc;
1124                         ctx->state.quantization = pix_mp->quantization;
1125                         break;
1126                 default:
1127                         break;
1128                 }
1129         }
1130         return ret;
1131 }
1132
1133 static int vidioc_g_selection(struct file *file, void *priv,
1134                               struct v4l2_selection *s)
1135 {
1136         struct vicodec_ctx *ctx = file2ctx(file);
1137         struct vicodec_q_data *q_data;
1138
1139         q_data = get_q_data(ctx, s->type);
1140         if (!q_data)
1141                 return -EINVAL;
1142         /*
1143          * encoder supports only cropping on the OUTPUT buffer
1144          * decoder supports only composing on the CAPTURE buffer
1145          */
1146         if (ctx->is_enc && s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1147                 switch (s->target) {
1148                 case V4L2_SEL_TGT_CROP:
1149                         s->r.left = 0;
1150                         s->r.top = 0;
1151                         s->r.width = q_data->visible_width;
1152                         s->r.height = q_data->visible_height;
1153                         return 0;
1154                 case V4L2_SEL_TGT_CROP_DEFAULT:
1155                 case V4L2_SEL_TGT_CROP_BOUNDS:
1156                         s->r.left = 0;
1157                         s->r.top = 0;
1158                         s->r.width = q_data->coded_width;
1159                         s->r.height = q_data->coded_height;
1160                         return 0;
1161                 }
1162         } else if (!ctx->is_enc && s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1163                 switch (s->target) {
1164                 case V4L2_SEL_TGT_COMPOSE:
1165                         s->r.left = 0;
1166                         s->r.top = 0;
1167                         s->r.width = q_data->visible_width;
1168                         s->r.height = q_data->visible_height;
1169                         return 0;
1170                 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1171                 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1172                         s->r.left = 0;
1173                         s->r.top = 0;
1174                         s->r.width = q_data->coded_width;
1175                         s->r.height = q_data->coded_height;
1176                         return 0;
1177                 }
1178         }
1179         return -EINVAL;
1180 }
1181
1182 static int vidioc_s_selection(struct file *file, void *priv,
1183                               struct v4l2_selection *s)
1184 {
1185         struct vicodec_ctx *ctx = file2ctx(file);
1186         struct vicodec_q_data *q_data;
1187
1188         if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1189                 return -EINVAL;
1190
1191         q_data = get_q_data(ctx, s->type);
1192         if (!q_data)
1193                 return -EINVAL;
1194
1195         if (!ctx->is_enc || s->target != V4L2_SEL_TGT_CROP)
1196                 return -EINVAL;
1197
1198         s->r.left = 0;
1199         s->r.top = 0;
1200         q_data->visible_width = clamp(s->r.width, MIN_WIDTH,
1201                                       q_data->coded_width);
1202         s->r.width = q_data->visible_width;
1203         q_data->visible_height = clamp(s->r.height, MIN_HEIGHT,
1204                                        q_data->coded_height);
1205         s->r.height = q_data->visible_height;
1206         return 0;
1207 }
1208
1209 static void vicodec_mark_last_buf(struct vicodec_ctx *ctx)
1210 {
1211         static const struct v4l2_event eos_event = {
1212                 .type = V4L2_EVENT_EOS
1213         };
1214
1215         spin_lock(ctx->lock);
1216         ctx->last_src_buf = v4l2_m2m_last_src_buf(ctx->fh.m2m_ctx);
1217         if (!ctx->last_src_buf && ctx->last_dst_buf) {
1218                 ctx->last_dst_buf->flags |= V4L2_BUF_FLAG_LAST;
1219                 v4l2_event_queue_fh(&ctx->fh, &eos_event);
1220         }
1221         spin_unlock(ctx->lock);
1222 }
1223
1224 static int vicodec_encoder_cmd(struct file *file, void *fh,
1225                             struct v4l2_encoder_cmd *ec)
1226 {
1227         struct vicodec_ctx *ctx = file2ctx(file);
1228         int ret;
1229
1230         ret = v4l2_m2m_ioctl_try_encoder_cmd(file, fh, ec);
1231         if (ret < 0)
1232                 return ret;
1233
1234         vicodec_mark_last_buf(ctx);
1235         return 0;
1236 }
1237
1238 static int vicodec_decoder_cmd(struct file *file, void *fh,
1239                             struct v4l2_decoder_cmd *dc)
1240 {
1241         struct vicodec_ctx *ctx = file2ctx(file);
1242         int ret;
1243
1244         ret = v4l2_m2m_ioctl_try_decoder_cmd(file, fh, dc);
1245         if (ret < 0)
1246                 return ret;
1247
1248         vicodec_mark_last_buf(ctx);
1249         return 0;
1250 }
1251
1252 static int vicodec_enum_framesizes(struct file *file, void *fh,
1253                                    struct v4l2_frmsizeenum *fsize)
1254 {
1255         switch (fsize->pixel_format) {
1256         case V4L2_PIX_FMT_FWHT_STATELESS:
1257                 break;
1258         case V4L2_PIX_FMT_FWHT:
1259                 break;
1260         default:
1261                 if (find_fmt(fsize->pixel_format)->id == fsize->pixel_format)
1262                         break;
1263                 return -EINVAL;
1264         }
1265
1266         if (fsize->index)
1267                 return -EINVAL;
1268
1269         fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
1270
1271         fsize->stepwise.min_width = MIN_WIDTH;
1272         fsize->stepwise.max_width = MAX_WIDTH;
1273         fsize->stepwise.step_width = 8;
1274         fsize->stepwise.min_height = MIN_HEIGHT;
1275         fsize->stepwise.max_height = MAX_HEIGHT;
1276         fsize->stepwise.step_height = 8;
1277
1278         return 0;
1279 }
1280
1281 static int vicodec_subscribe_event(struct v4l2_fh *fh,
1282                                 const struct v4l2_event_subscription *sub)
1283 {
1284         struct vicodec_ctx *ctx = container_of(fh, struct vicodec_ctx, fh);
1285
1286         switch (sub->type) {
1287         case V4L2_EVENT_SOURCE_CHANGE:
1288                 if (ctx->is_enc)
1289                         return -EINVAL;
1290                 /* fall through */
1291         case V4L2_EVENT_EOS:
1292                 return v4l2_event_subscribe(fh, sub, 0, NULL);
1293         default:
1294                 return v4l2_ctrl_subscribe_event(fh, sub);
1295         }
1296 }
1297
1298 static const struct v4l2_ioctl_ops vicodec_ioctl_ops = {
1299         .vidioc_querycap        = vidioc_querycap,
1300
1301         .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1302         .vidioc_g_fmt_vid_cap   = vidioc_g_fmt_vid_cap,
1303         .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1304         .vidioc_s_fmt_vid_cap   = vidioc_s_fmt_vid_cap,
1305
1306         .vidioc_g_fmt_vid_cap_mplane    = vidioc_g_fmt_vid_cap,
1307         .vidioc_try_fmt_vid_cap_mplane  = vidioc_try_fmt_vid_cap,
1308         .vidioc_s_fmt_vid_cap_mplane    = vidioc_s_fmt_vid_cap,
1309
1310         .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
1311         .vidioc_g_fmt_vid_out   = vidioc_g_fmt_vid_out,
1312         .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out,
1313         .vidioc_s_fmt_vid_out   = vidioc_s_fmt_vid_out,
1314
1315         .vidioc_g_fmt_vid_out_mplane    = vidioc_g_fmt_vid_out,
1316         .vidioc_try_fmt_vid_out_mplane  = vidioc_try_fmt_vid_out,
1317         .vidioc_s_fmt_vid_out_mplane    = vidioc_s_fmt_vid_out,
1318
1319         .vidioc_reqbufs         = v4l2_m2m_ioctl_reqbufs,
1320         .vidioc_querybuf        = v4l2_m2m_ioctl_querybuf,
1321         .vidioc_qbuf            = v4l2_m2m_ioctl_qbuf,
1322         .vidioc_dqbuf           = v4l2_m2m_ioctl_dqbuf,
1323         .vidioc_prepare_buf     = v4l2_m2m_ioctl_prepare_buf,
1324         .vidioc_create_bufs     = v4l2_m2m_ioctl_create_bufs,
1325         .vidioc_expbuf          = v4l2_m2m_ioctl_expbuf,
1326
1327         .vidioc_streamon        = v4l2_m2m_ioctl_streamon,
1328         .vidioc_streamoff       = v4l2_m2m_ioctl_streamoff,
1329
1330         .vidioc_g_selection     = vidioc_g_selection,
1331         .vidioc_s_selection     = vidioc_s_selection,
1332
1333         .vidioc_try_encoder_cmd = v4l2_m2m_ioctl_try_encoder_cmd,
1334         .vidioc_encoder_cmd     = vicodec_encoder_cmd,
1335         .vidioc_try_decoder_cmd = v4l2_m2m_ioctl_try_decoder_cmd,
1336         .vidioc_decoder_cmd     = vicodec_decoder_cmd,
1337         .vidioc_enum_framesizes = vicodec_enum_framesizes,
1338
1339         .vidioc_subscribe_event = vicodec_subscribe_event,
1340         .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1341 };
1342
1343
1344 /*
1345  * Queue operations
1346  */
1347
1348 static int vicodec_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
1349                                unsigned int *nplanes, unsigned int sizes[],
1350                                struct device *alloc_devs[])
1351 {
1352         struct vicodec_ctx *ctx = vb2_get_drv_priv(vq);
1353         struct vicodec_q_data *q_data = get_q_data(ctx, vq->type);
1354         unsigned int size = q_data->sizeimage;
1355
1356         if (*nplanes)
1357                 return sizes[0] < size ? -EINVAL : 0;
1358
1359         *nplanes = 1;
1360         sizes[0] = size;
1361         return 0;
1362 }
1363
1364 static int vicodec_buf_out_validate(struct vb2_buffer *vb)
1365 {
1366         struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1367
1368         vbuf->field = V4L2_FIELD_NONE;
1369         return 0;
1370 }
1371
1372 static int vicodec_buf_prepare(struct vb2_buffer *vb)
1373 {
1374         struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1375         struct vicodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1376         struct vicodec_q_data *q_data;
1377
1378         dprintk(ctx->dev, "type: %d\n", vb->vb2_queue->type);
1379
1380         q_data = get_q_data(ctx, vb->vb2_queue->type);
1381         if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
1382                 if (vbuf->field == V4L2_FIELD_ANY)
1383                         vbuf->field = V4L2_FIELD_NONE;
1384                 if (vbuf->field != V4L2_FIELD_NONE) {
1385                         dprintk(ctx->dev, "%s field isn't supported\n",
1386                                         __func__);
1387                         return -EINVAL;
1388                 }
1389         }
1390
1391         if (vb2_plane_size(vb, 0) < q_data->sizeimage) {
1392                 dprintk(ctx->dev,
1393                         "%s data will not fit into plane (%lu < %lu)\n",
1394                         __func__, vb2_plane_size(vb, 0),
1395                         (long)q_data->sizeimage);
1396                 return -EINVAL;
1397         }
1398
1399         return 0;
1400 }
1401
1402 static void vicodec_buf_queue(struct vb2_buffer *vb)
1403 {
1404         struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1405         struct vicodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1406         unsigned int sz = vb2_get_plane_payload(&vbuf->vb2_buf, 0);
1407         u8 *p_src = vb2_plane_vaddr(&vbuf->vb2_buf, 0);
1408         u8 *p = p_src;
1409         struct vb2_queue *vq_out = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
1410                                                    V4L2_BUF_TYPE_VIDEO_OUTPUT);
1411         struct vb2_queue *vq_cap = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
1412                                                    V4L2_BUF_TYPE_VIDEO_CAPTURE);
1413         bool header_valid = false;
1414         static const struct v4l2_event rs_event = {
1415                 .type = V4L2_EVENT_SOURCE_CHANGE,
1416                 .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
1417         };
1418
1419         /* buf_queue handles only the first source change event */
1420         if (ctx->first_source_change_sent) {
1421                 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
1422                 return;
1423         }
1424
1425         /*
1426          * if both queues are streaming, the source change event is
1427          * handled in job_ready
1428          */
1429         if (vb2_is_streaming(vq_cap) && vb2_is_streaming(vq_out)) {
1430                 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
1431                 return;
1432         }
1433
1434         /*
1435          * source change event is relevant only for the stateful decoder
1436          * in the compressed stream
1437          */
1438         if (ctx->is_stateless || ctx->is_enc ||
1439             !V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
1440                 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
1441                 return;
1442         }
1443
1444         do {
1445                 enum vb2_buffer_state state =
1446                         get_next_header(ctx, &p, p_src + sz - p);
1447
1448                 if (ctx->header_size < sizeof(struct fwht_cframe_hdr)) {
1449                         v4l2_m2m_buf_done(vbuf, state);
1450                         return;
1451                 }
1452                 header_valid = is_header_valid(&ctx->state.header);
1453                 /*
1454                  * p points right after the end of the header in the
1455                  * buffer. If the header is invalid we set p to point
1456                  * to the next byte after the start of the header
1457                  */
1458                 if (!header_valid) {
1459                         p = p - sizeof(struct fwht_cframe_hdr) + 1;
1460                         if (p < p_src)
1461                                 p = p_src;
1462                         ctx->header_size = 0;
1463                         ctx->comp_magic_cnt = 0;
1464                 }
1465
1466         } while (!header_valid);
1467
1468         ctx->cur_buf_offset = p - p_src;
1469         update_capture_data_from_header(ctx);
1470         ctx->first_source_change_sent = true;
1471         v4l2_event_queue_fh(&ctx->fh, &rs_event);
1472         v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
1473 }
1474
1475 static void vicodec_return_bufs(struct vb2_queue *q, u32 state)
1476 {
1477         struct vicodec_ctx *ctx = vb2_get_drv_priv(q);
1478         struct vb2_v4l2_buffer *vbuf;
1479
1480         for (;;) {
1481                 if (V4L2_TYPE_IS_OUTPUT(q->type))
1482                         vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1483                 else
1484                         vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1485                 if (vbuf == NULL)
1486                         return;
1487                 v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req,
1488                                            &ctx->hdl);
1489                 spin_lock(ctx->lock);
1490                 v4l2_m2m_buf_done(vbuf, state);
1491                 spin_unlock(ctx->lock);
1492         }
1493 }
1494
1495 static unsigned int total_frame_size(struct vicodec_q_data *q_data)
1496 {
1497         unsigned int size;
1498         unsigned int chroma_div;
1499
1500         if (!q_data->info) {
1501                 WARN_ON(1);
1502                 return 0;
1503         }
1504         size = q_data->coded_width * q_data->coded_height;
1505         chroma_div = q_data->info->width_div * q_data->info->height_div;
1506
1507         if (q_data->info->components_num == 4)
1508                 return 2 * size + 2 * (size / chroma_div);
1509         else if (q_data->info->components_num == 3)
1510                 return size + 2 * (size / chroma_div);
1511         return size;
1512 }
1513
1514 static int vicodec_start_streaming(struct vb2_queue *q,
1515                                    unsigned int count)
1516 {
1517         struct vicodec_ctx *ctx = vb2_get_drv_priv(q);
1518         struct vicodec_q_data *q_data = get_q_data(ctx, q->type);
1519         struct v4l2_fwht_state *state = &ctx->state;
1520         const struct v4l2_fwht_pixfmt_info *info = q_data->info;
1521         unsigned int size = q_data->coded_width * q_data->coded_height;
1522         unsigned int chroma_div;
1523         unsigned int total_planes_size;
1524         u8 *new_comp_frame = NULL;
1525
1526         if (!info)
1527                 return -EINVAL;
1528
1529         chroma_div = info->width_div * info->height_div;
1530         q_data->sequence = 0;
1531
1532         if (V4L2_TYPE_IS_OUTPUT(q->type))
1533                 ctx->last_src_buf = NULL;
1534         else
1535                 ctx->last_dst_buf = NULL;
1536
1537         state->gop_cnt = 0;
1538
1539         if ((V4L2_TYPE_IS_OUTPUT(q->type) && !ctx->is_enc) ||
1540             (!V4L2_TYPE_IS_OUTPUT(q->type) && ctx->is_enc))
1541                 return 0;
1542
1543         if (info->id == V4L2_PIX_FMT_FWHT ||
1544             info->id == V4L2_PIX_FMT_FWHT_STATELESS) {
1545                 vicodec_return_bufs(q, VB2_BUF_STATE_QUEUED);
1546                 return -EINVAL;
1547         }
1548         total_planes_size = total_frame_size(q_data);
1549         ctx->comp_max_size = total_planes_size;
1550
1551         state->visible_width = q_data->visible_width;
1552         state->visible_height = q_data->visible_height;
1553         state->coded_width = q_data->coded_width;
1554         state->coded_height = q_data->coded_height;
1555         state->stride = q_data->coded_width *
1556                                 info->bytesperline_mult;
1557
1558         if (ctx->is_stateless) {
1559                 state->ref_stride = state->stride;
1560                 return 0;
1561         }
1562         state->ref_stride = q_data->coded_width * info->luma_alpha_step;
1563
1564         state->ref_frame.buf = kvmalloc(total_planes_size, GFP_KERNEL);
1565         state->ref_frame.luma = state->ref_frame.buf;
1566         new_comp_frame = kvmalloc(ctx->comp_max_size, GFP_KERNEL);
1567
1568         if (!state->ref_frame.luma || !new_comp_frame) {
1569                 kvfree(state->ref_frame.luma);
1570                 kvfree(new_comp_frame);
1571                 vicodec_return_bufs(q, VB2_BUF_STATE_QUEUED);
1572                 return -ENOMEM;
1573         }
1574         /*
1575          * if state->compressed_frame was already allocated then
1576          * it contain data of the first frame of the new resolution
1577          */
1578         if (state->compressed_frame) {
1579                 if (ctx->comp_size > ctx->comp_max_size)
1580                         ctx->comp_size = ctx->comp_max_size;
1581
1582                 memcpy(new_comp_frame,
1583                        state->compressed_frame, ctx->comp_size);
1584         }
1585
1586         kvfree(state->compressed_frame);
1587         state->compressed_frame = new_comp_frame;
1588
1589         if (info->components_num >= 3) {
1590                 state->ref_frame.cb = state->ref_frame.luma + size;
1591                 state->ref_frame.cr = state->ref_frame.cb + size / chroma_div;
1592         } else {
1593                 state->ref_frame.cb = NULL;
1594                 state->ref_frame.cr = NULL;
1595         }
1596
1597         if (info->components_num == 4)
1598                 state->ref_frame.alpha =
1599                         state->ref_frame.cr + size / chroma_div;
1600         else
1601                 state->ref_frame.alpha = NULL;
1602         return 0;
1603 }
1604
1605 static void vicodec_stop_streaming(struct vb2_queue *q)
1606 {
1607         struct vicodec_ctx *ctx = vb2_get_drv_priv(q);
1608
1609         vicodec_return_bufs(q, VB2_BUF_STATE_ERROR);
1610
1611         if ((!V4L2_TYPE_IS_OUTPUT(q->type) && !ctx->is_enc) ||
1612             (V4L2_TYPE_IS_OUTPUT(q->type) && ctx->is_enc)) {
1613                 if (!ctx->is_stateless)
1614                         kvfree(ctx->state.ref_frame.buf);
1615                 ctx->state.ref_frame.buf = NULL;
1616                 ctx->state.ref_frame.luma = NULL;
1617                 ctx->comp_max_size = 0;
1618                 ctx->source_changed = false;
1619         }
1620         if (V4L2_TYPE_IS_OUTPUT(q->type) && !ctx->is_enc) {
1621                 ctx->cur_buf_offset = 0;
1622                 ctx->comp_size = 0;
1623                 ctx->header_size = 0;
1624                 ctx->comp_magic_cnt = 0;
1625                 ctx->comp_has_frame = 0;
1626                 ctx->comp_has_next_frame = 0;
1627         }
1628 }
1629
1630 static void vicodec_buf_request_complete(struct vb2_buffer *vb)
1631 {
1632         struct vicodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1633
1634         v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->hdl);
1635 }
1636
1637
1638 static const struct vb2_ops vicodec_qops = {
1639         .queue_setup            = vicodec_queue_setup,
1640         .buf_out_validate       = vicodec_buf_out_validate,
1641         .buf_prepare            = vicodec_buf_prepare,
1642         .buf_queue              = vicodec_buf_queue,
1643         .buf_request_complete   = vicodec_buf_request_complete,
1644         .start_streaming        = vicodec_start_streaming,
1645         .stop_streaming         = vicodec_stop_streaming,
1646         .wait_prepare           = vb2_ops_wait_prepare,
1647         .wait_finish            = vb2_ops_wait_finish,
1648 };
1649
1650 static int queue_init(void *priv, struct vb2_queue *src_vq,
1651                       struct vb2_queue *dst_vq)
1652 {
1653         struct vicodec_ctx *ctx = priv;
1654         int ret;
1655
1656         src_vq->type = (multiplanar ?
1657                         V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE :
1658                         V4L2_BUF_TYPE_VIDEO_OUTPUT);
1659         src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
1660         src_vq->drv_priv = ctx;
1661         src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1662         src_vq->ops = &vicodec_qops;
1663         src_vq->mem_ops = &vb2_vmalloc_memops;
1664         src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1665         if (ctx->is_enc)
1666                 src_vq->lock = &ctx->dev->stateful_enc.mutex;
1667         else if (ctx->is_stateless)
1668                 src_vq->lock = &ctx->dev->stateless_dec.mutex;
1669         else
1670                 src_vq->lock = &ctx->dev->stateful_dec.mutex;
1671         src_vq->supports_requests = ctx->is_stateless;
1672         src_vq->requires_requests = ctx->is_stateless;
1673         ret = vb2_queue_init(src_vq);
1674         if (ret)
1675                 return ret;
1676
1677         dst_vq->type = (multiplanar ?
1678                         V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
1679                         V4L2_BUF_TYPE_VIDEO_CAPTURE);
1680         dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
1681         dst_vq->drv_priv = ctx;
1682         dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1683         dst_vq->ops = &vicodec_qops;
1684         dst_vq->mem_ops = &vb2_vmalloc_memops;
1685         dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1686         dst_vq->lock = src_vq->lock;
1687
1688         return vb2_queue_init(dst_vq);
1689 }
1690
1691 static int vicodec_try_ctrl(struct v4l2_ctrl *ctrl)
1692 {
1693         struct vicodec_ctx *ctx = container_of(ctrl->handler,
1694                         struct vicodec_ctx, hdl);
1695         const struct v4l2_ctrl_fwht_params *params;
1696         struct vicodec_q_data *q_dst = get_q_data(ctx,
1697                         V4L2_BUF_TYPE_VIDEO_CAPTURE);
1698
1699         switch (ctrl->id) {
1700         case V4L2_CID_MPEG_VIDEO_FWHT_PARAMS:
1701                 if (!q_dst->info)
1702                         return -EINVAL;
1703                 params = ctrl->p_new.p_fwht_params;
1704                 if (params->width > q_dst->coded_width ||
1705                     params->width < MIN_WIDTH ||
1706                     params->height > q_dst->coded_height ||
1707                     params->height < MIN_HEIGHT)
1708                         return -EINVAL;
1709                 if (!validate_by_version(params->flags, params->version))
1710                         return -EINVAL;
1711                 if (!validate_stateless_params_flags(params, q_dst->info))
1712                         return -EINVAL;
1713                 return 0;
1714         default:
1715                 return 0;
1716         }
1717         return 0;
1718 }
1719
1720 static void update_header_from_stateless_params(struct vicodec_ctx *ctx,
1721                                                 const struct v4l2_ctrl_fwht_params *params)
1722 {
1723         struct fwht_cframe_hdr *p_hdr = &ctx->state.header;
1724
1725         p_hdr->magic1 = FWHT_MAGIC1;
1726         p_hdr->magic2 = FWHT_MAGIC2;
1727         p_hdr->version = htonl(params->version);
1728         p_hdr->width = htonl(params->width);
1729         p_hdr->height = htonl(params->height);
1730         p_hdr->flags = htonl(params->flags);
1731         p_hdr->colorspace = htonl(params->colorspace);
1732         p_hdr->xfer_func = htonl(params->xfer_func);
1733         p_hdr->ycbcr_enc = htonl(params->ycbcr_enc);
1734         p_hdr->quantization = htonl(params->quantization);
1735 }
1736
1737 static int vicodec_s_ctrl(struct v4l2_ctrl *ctrl)
1738 {
1739         struct vicodec_ctx *ctx = container_of(ctrl->handler,
1740                                                struct vicodec_ctx, hdl);
1741         const struct v4l2_ctrl_fwht_params *params;
1742
1743         switch (ctrl->id) {
1744         case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
1745                 ctx->state.gop_size = ctrl->val;
1746                 return 0;
1747         case V4L2_CID_FWHT_I_FRAME_QP:
1748                 ctx->state.i_frame_qp = ctrl->val;
1749                 return 0;
1750         case V4L2_CID_FWHT_P_FRAME_QP:
1751                 ctx->state.p_frame_qp = ctrl->val;
1752                 return 0;
1753         case V4L2_CID_MPEG_VIDEO_FWHT_PARAMS:
1754                 params = ctrl->p_new.p_fwht_params;
1755                 update_header_from_stateless_params(ctx, params);
1756                 ctx->state.ref_frame_ts = params->backward_ref_ts;
1757                 return 0;
1758         }
1759         return -EINVAL;
1760 }
1761
1762 static const struct v4l2_ctrl_ops vicodec_ctrl_ops = {
1763         .s_ctrl = vicodec_s_ctrl,
1764         .try_ctrl = vicodec_try_ctrl,
1765 };
1766
1767 static const struct v4l2_ctrl_config vicodec_ctrl_stateless_state = {
1768         .ops            = &vicodec_ctrl_ops,
1769         .id             = V4L2_CID_MPEG_VIDEO_FWHT_PARAMS,
1770         .elem_size      = sizeof(struct v4l2_ctrl_fwht_params),
1771 };
1772
1773 /*
1774  * File operations
1775  */
1776 static int vicodec_open(struct file *file)
1777 {
1778         const struct v4l2_fwht_pixfmt_info *info = v4l2_fwht_get_pixfmt(0);
1779         struct video_device *vfd = video_devdata(file);
1780         struct vicodec_dev *dev = video_drvdata(file);
1781         struct vicodec_ctx *ctx = NULL;
1782         struct v4l2_ctrl_handler *hdl;
1783         unsigned int raw_size;
1784         unsigned int comp_size;
1785         int rc = 0;
1786
1787         if (mutex_lock_interruptible(vfd->lock))
1788                 return -ERESTARTSYS;
1789         ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
1790         if (!ctx) {
1791                 rc = -ENOMEM;
1792                 goto open_unlock;
1793         }
1794
1795         if (vfd == &dev->stateful_enc.vfd)
1796                 ctx->is_enc = true;
1797         else if (vfd == &dev->stateless_dec.vfd)
1798                 ctx->is_stateless = true;
1799
1800         v4l2_fh_init(&ctx->fh, video_devdata(file));
1801         file->private_data = &ctx->fh;
1802         ctx->dev = dev;
1803         hdl = &ctx->hdl;
1804         v4l2_ctrl_handler_init(hdl, 4);
1805         v4l2_ctrl_new_std(hdl, &vicodec_ctrl_ops, V4L2_CID_MPEG_VIDEO_GOP_SIZE,
1806                           1, 16, 1, 10);
1807         v4l2_ctrl_new_std(hdl, &vicodec_ctrl_ops, V4L2_CID_FWHT_I_FRAME_QP,
1808                           1, 31, 1, 20);
1809         v4l2_ctrl_new_std(hdl, &vicodec_ctrl_ops, V4L2_CID_FWHT_P_FRAME_QP,
1810                           1, 31, 1, 20);
1811         if (ctx->is_stateless)
1812                 v4l2_ctrl_new_custom(hdl, &vicodec_ctrl_stateless_state, NULL);
1813         if (hdl->error) {
1814                 rc = hdl->error;
1815                 v4l2_ctrl_handler_free(hdl);
1816                 kfree(ctx);
1817                 goto open_unlock;
1818         }
1819         ctx->fh.ctrl_handler = hdl;
1820         v4l2_ctrl_handler_setup(hdl);
1821
1822         if (ctx->is_enc)
1823                 ctx->q_data[V4L2_M2M_SRC].info = info;
1824         else if (ctx->is_stateless)
1825                 ctx->q_data[V4L2_M2M_SRC].info = &pixfmt_stateless_fwht;
1826         else
1827                 ctx->q_data[V4L2_M2M_SRC].info = &pixfmt_fwht;
1828         ctx->q_data[V4L2_M2M_SRC].coded_width = 1280;
1829         ctx->q_data[V4L2_M2M_SRC].coded_height = 720;
1830         ctx->q_data[V4L2_M2M_SRC].visible_width = 1280;
1831         ctx->q_data[V4L2_M2M_SRC].visible_height = 720;
1832         raw_size = 1280 * 720 * info->sizeimage_mult / info->sizeimage_div;
1833         comp_size = 1280 * 720 * pixfmt_fwht.sizeimage_mult /
1834                                  pixfmt_fwht.sizeimage_div;
1835         if (ctx->is_enc)
1836                 ctx->q_data[V4L2_M2M_SRC].sizeimage = raw_size;
1837         else if (ctx->is_stateless)
1838                 ctx->q_data[V4L2_M2M_SRC].sizeimage = comp_size;
1839         else
1840                 ctx->q_data[V4L2_M2M_SRC].sizeimage =
1841                         comp_size + sizeof(struct fwht_cframe_hdr);
1842         ctx->q_data[V4L2_M2M_DST] = ctx->q_data[V4L2_M2M_SRC];
1843         if (ctx->is_enc) {
1844                 ctx->q_data[V4L2_M2M_DST].info = &pixfmt_fwht;
1845                 ctx->q_data[V4L2_M2M_DST].sizeimage =
1846                         comp_size + sizeof(struct fwht_cframe_hdr);
1847         } else {
1848                 ctx->q_data[V4L2_M2M_DST].info = info;
1849                 ctx->q_data[V4L2_M2M_DST].sizeimage = raw_size;
1850         }
1851
1852         ctx->state.colorspace = V4L2_COLORSPACE_REC709;
1853
1854         if (ctx->is_enc) {
1855                 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->stateful_enc.m2m_dev,
1856                                                     ctx, &queue_init);
1857                 ctx->lock = &dev->stateful_enc.lock;
1858         } else if (ctx->is_stateless) {
1859                 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->stateless_dec.m2m_dev,
1860                                                     ctx, &queue_init);
1861                 ctx->lock = &dev->stateless_dec.lock;
1862         } else {
1863                 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->stateful_dec.m2m_dev,
1864                                                     ctx, &queue_init);
1865                 ctx->lock = &dev->stateful_dec.lock;
1866         }
1867
1868         if (IS_ERR(ctx->fh.m2m_ctx)) {
1869                 rc = PTR_ERR(ctx->fh.m2m_ctx);
1870
1871                 v4l2_ctrl_handler_free(hdl);
1872                 v4l2_fh_exit(&ctx->fh);
1873                 kfree(ctx);
1874                 goto open_unlock;
1875         }
1876
1877         v4l2_fh_add(&ctx->fh);
1878
1879 open_unlock:
1880         mutex_unlock(vfd->lock);
1881         return rc;
1882 }
1883
1884 static int vicodec_release(struct file *file)
1885 {
1886         struct video_device *vfd = video_devdata(file);
1887         struct vicodec_ctx *ctx = file2ctx(file);
1888
1889         mutex_lock(vfd->lock);
1890         v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
1891         mutex_unlock(vfd->lock);
1892         v4l2_fh_del(&ctx->fh);
1893         v4l2_fh_exit(&ctx->fh);
1894         v4l2_ctrl_handler_free(&ctx->hdl);
1895         kvfree(ctx->state.compressed_frame);
1896         kfree(ctx);
1897
1898         return 0;
1899 }
1900
1901 static int vicodec_request_validate(struct media_request *req)
1902 {
1903         struct media_request_object *obj;
1904         struct v4l2_ctrl_handler *parent_hdl, *hdl;
1905         struct vicodec_ctx *ctx = NULL;
1906         struct v4l2_ctrl *ctrl;
1907         unsigned int count;
1908
1909         list_for_each_entry(obj, &req->objects, list) {
1910                 struct vb2_buffer *vb;
1911
1912                 if (vb2_request_object_is_buffer(obj)) {
1913                         vb = container_of(obj, struct vb2_buffer, req_obj);
1914                         ctx = vb2_get_drv_priv(vb->vb2_queue);
1915
1916                         break;
1917                 }
1918         }
1919
1920         if (!ctx) {
1921                 pr_err("No buffer was provided with the request\n");
1922                 return -ENOENT;
1923         }
1924
1925         count = vb2_request_buffer_cnt(req);
1926         if (!count) {
1927                 v4l2_info(&ctx->dev->v4l2_dev,
1928                           "No buffer was provided with the request\n");
1929                 return -ENOENT;
1930         } else if (count > 1) {
1931                 v4l2_info(&ctx->dev->v4l2_dev,
1932                           "More than one buffer was provided with the request\n");
1933                 return -EINVAL;
1934         }
1935
1936         parent_hdl = &ctx->hdl;
1937
1938         hdl = v4l2_ctrl_request_hdl_find(req, parent_hdl);
1939         if (!hdl) {
1940                 v4l2_info(&ctx->dev->v4l2_dev, "Missing codec control\n");
1941                 return -ENOENT;
1942         }
1943         ctrl = v4l2_ctrl_request_hdl_ctrl_find(hdl,
1944                                                vicodec_ctrl_stateless_state.id);
1945         if (!ctrl) {
1946                 v4l2_info(&ctx->dev->v4l2_dev,
1947                           "Missing required codec control\n");
1948                 return -ENOENT;
1949         }
1950
1951         return vb2_request_validate(req);
1952 }
1953
1954 static const struct v4l2_file_operations vicodec_fops = {
1955         .owner          = THIS_MODULE,
1956         .open           = vicodec_open,
1957         .release        = vicodec_release,
1958         .poll           = v4l2_m2m_fop_poll,
1959         .unlocked_ioctl = video_ioctl2,
1960         .mmap           = v4l2_m2m_fop_mmap,
1961 };
1962
1963 static const struct video_device vicodec_videodev = {
1964         .name           = VICODEC_NAME,
1965         .vfl_dir        = VFL_DIR_M2M,
1966         .fops           = &vicodec_fops,
1967         .ioctl_ops      = &vicodec_ioctl_ops,
1968         .minor          = -1,
1969         .release        = video_device_release_empty,
1970 };
1971
1972 static const struct media_device_ops vicodec_m2m_media_ops = {
1973         .req_validate   = vicodec_request_validate,
1974         .req_queue      = v4l2_m2m_request_queue,
1975 };
1976
1977 static const struct v4l2_m2m_ops m2m_ops = {
1978         .device_run     = device_run,
1979         .job_ready      = job_ready,
1980 };
1981
1982 static int register_instance(struct vicodec_dev *dev,
1983                              struct vicodec_dev_instance *dev_instance,
1984                              const char *name, bool is_enc)
1985 {
1986         struct video_device *vfd;
1987         int ret;
1988
1989         spin_lock_init(&dev_instance->lock);
1990         mutex_init(&dev_instance->mutex);
1991         dev_instance->m2m_dev = v4l2_m2m_init(&m2m_ops);
1992         if (IS_ERR(dev_instance->m2m_dev)) {
1993                 v4l2_err(&dev->v4l2_dev, "Failed to init vicodec enc device\n");
1994                 return PTR_ERR(dev_instance->m2m_dev);
1995         }
1996
1997         dev_instance->vfd = vicodec_videodev;
1998         vfd = &dev_instance->vfd;
1999         vfd->lock = &dev_instance->mutex;
2000         vfd->v4l2_dev = &dev->v4l2_dev;
2001         strscpy(vfd->name, name, sizeof(vfd->name));
2002         vfd->device_caps = V4L2_CAP_STREAMING |
2003                 (multiplanar ? V4L2_CAP_VIDEO_M2M_MPLANE : V4L2_CAP_VIDEO_M2M);
2004         if (is_enc) {
2005                 v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD);
2006                 v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD);
2007         } else {
2008                 v4l2_disable_ioctl(vfd, VIDIOC_ENCODER_CMD);
2009                 v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD);
2010         }
2011         video_set_drvdata(vfd, dev);
2012
2013         ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
2014         if (ret) {
2015                 v4l2_err(&dev->v4l2_dev, "Failed to register video device '%s'\n", name);
2016                 v4l2_m2m_release(dev_instance->m2m_dev);
2017                 return ret;
2018         }
2019         v4l2_info(&dev->v4l2_dev, "Device '%s' registered as /dev/video%d\n",
2020                   name, vfd->num);
2021         return 0;
2022 }
2023
2024 static void vicodec_v4l2_dev_release(struct v4l2_device *v4l2_dev)
2025 {
2026         struct vicodec_dev *dev = container_of(v4l2_dev, struct vicodec_dev, v4l2_dev);
2027
2028         v4l2_device_unregister(&dev->v4l2_dev);
2029         v4l2_m2m_release(dev->stateful_enc.m2m_dev);
2030         v4l2_m2m_release(dev->stateful_dec.m2m_dev);
2031         v4l2_m2m_release(dev->stateless_dec.m2m_dev);
2032         kfree(dev);
2033 }
2034
2035 static int vicodec_probe(struct platform_device *pdev)
2036 {
2037         struct vicodec_dev *dev;
2038         int ret;
2039
2040         dev = kzalloc(sizeof(*dev), GFP_KERNEL);
2041         if (!dev)
2042                 return -ENOMEM;
2043
2044         ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
2045         if (ret)
2046                 goto free_dev;
2047
2048         dev->v4l2_dev.release = vicodec_v4l2_dev_release;
2049
2050 #ifdef CONFIG_MEDIA_CONTROLLER
2051         dev->mdev.dev = &pdev->dev;
2052         strscpy(dev->mdev.model, "vicodec", sizeof(dev->mdev.model));
2053         strscpy(dev->mdev.bus_info, "platform:vicodec",
2054                 sizeof(dev->mdev.bus_info));
2055         media_device_init(&dev->mdev);
2056         dev->mdev.ops = &vicodec_m2m_media_ops;
2057         dev->v4l2_dev.mdev = &dev->mdev;
2058 #endif
2059
2060         platform_set_drvdata(pdev, dev);
2061
2062         if (register_instance(dev, &dev->stateful_enc,
2063                               "stateful-encoder", true))
2064                 goto unreg_dev;
2065
2066         if (register_instance(dev, &dev->stateful_dec,
2067                               "stateful-decoder", false))
2068                 goto unreg_sf_enc;
2069
2070         if (register_instance(dev, &dev->stateless_dec,
2071                               "stateless-decoder", false))
2072                 goto unreg_sf_dec;
2073
2074 #ifdef CONFIG_MEDIA_CONTROLLER
2075         ret = v4l2_m2m_register_media_controller(dev->stateful_enc.m2m_dev,
2076                                                  &dev->stateful_enc.vfd,
2077                                                  MEDIA_ENT_F_PROC_VIDEO_ENCODER);
2078         if (ret) {
2079                 v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller for enc\n");
2080                 goto unreg_m2m;
2081         }
2082
2083         ret = v4l2_m2m_register_media_controller(dev->stateful_dec.m2m_dev,
2084                                                  &dev->stateful_dec.vfd,
2085                                                  MEDIA_ENT_F_PROC_VIDEO_DECODER);
2086         if (ret) {
2087                 v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller for dec\n");
2088                 goto unreg_m2m_sf_enc_mc;
2089         }
2090
2091         ret = v4l2_m2m_register_media_controller(dev->stateless_dec.m2m_dev,
2092                                                  &dev->stateless_dec.vfd,
2093                                                  MEDIA_ENT_F_PROC_VIDEO_DECODER);
2094         if (ret) {
2095                 v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller for stateless dec\n");
2096                 goto unreg_m2m_sf_dec_mc;
2097         }
2098
2099         ret = media_device_register(&dev->mdev);
2100         if (ret) {
2101                 v4l2_err(&dev->v4l2_dev, "Failed to register mem2mem media device\n");
2102                 goto unreg_m2m_sl_dec_mc;
2103         }
2104 #endif
2105         return 0;
2106
2107 #ifdef CONFIG_MEDIA_CONTROLLER
2108 unreg_m2m_sl_dec_mc:
2109         v4l2_m2m_unregister_media_controller(dev->stateless_dec.m2m_dev);
2110 unreg_m2m_sf_dec_mc:
2111         v4l2_m2m_unregister_media_controller(dev->stateful_dec.m2m_dev);
2112 unreg_m2m_sf_enc_mc:
2113         v4l2_m2m_unregister_media_controller(dev->stateful_enc.m2m_dev);
2114 unreg_m2m:
2115         video_unregister_device(&dev->stateless_dec.vfd);
2116         v4l2_m2m_release(dev->stateless_dec.m2m_dev);
2117 #endif
2118 unreg_sf_dec:
2119         video_unregister_device(&dev->stateful_dec.vfd);
2120         v4l2_m2m_release(dev->stateful_dec.m2m_dev);
2121 unreg_sf_enc:
2122         video_unregister_device(&dev->stateful_enc.vfd);
2123         v4l2_m2m_release(dev->stateful_enc.m2m_dev);
2124 unreg_dev:
2125         v4l2_device_unregister(&dev->v4l2_dev);
2126 free_dev:
2127         kfree(dev);
2128
2129         return ret;
2130 }
2131
2132 static int vicodec_remove(struct platform_device *pdev)
2133 {
2134         struct vicodec_dev *dev = platform_get_drvdata(pdev);
2135
2136         v4l2_info(&dev->v4l2_dev, "Removing " VICODEC_NAME);
2137
2138 #ifdef CONFIG_MEDIA_CONTROLLER
2139         media_device_unregister(&dev->mdev);
2140         v4l2_m2m_unregister_media_controller(dev->stateful_enc.m2m_dev);
2141         v4l2_m2m_unregister_media_controller(dev->stateful_dec.m2m_dev);
2142         v4l2_m2m_unregister_media_controller(dev->stateless_dec.m2m_dev);
2143         media_device_cleanup(&dev->mdev);
2144 #endif
2145
2146         video_unregister_device(&dev->stateful_enc.vfd);
2147         video_unregister_device(&dev->stateful_dec.vfd);
2148         video_unregister_device(&dev->stateless_dec.vfd);
2149         v4l2_device_put(&dev->v4l2_dev);
2150
2151         return 0;
2152 }
2153
2154 static struct platform_driver vicodec_pdrv = {
2155         .probe          = vicodec_probe,
2156         .remove         = vicodec_remove,
2157         .driver         = {
2158                 .name   = VICODEC_NAME,
2159         },
2160 };
2161
2162 static void __exit vicodec_exit(void)
2163 {
2164         platform_driver_unregister(&vicodec_pdrv);
2165         platform_device_unregister(&vicodec_pdev);
2166 }
2167
2168 static int __init vicodec_init(void)
2169 {
2170         int ret;
2171
2172         ret = platform_device_register(&vicodec_pdev);
2173         if (ret)
2174                 return ret;
2175
2176         ret = platform_driver_register(&vicodec_pdrv);
2177         if (ret)
2178                 platform_device_unregister(&vicodec_pdev);
2179
2180         return ret;
2181 }
2182
2183 module_init(vicodec_init);
2184 module_exit(vicodec_exit);