media: replace strncpy() by strscpy()
[linux-block.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         if (ctx->is_stateless && src_req)
446                 v4l2_ctrl_request_complete(src_req, &ctx->hdl);
447
448         ctx->comp_size = 0;
449         ctx->header_size = 0;
450         ctx->comp_magic_cnt = 0;
451         ctx->comp_has_frame = false;
452         spin_unlock(ctx->lock);
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         if (q_data->visible_width > q_data->coded_width)
1036                 q_data->visible_width = q_data->coded_width;
1037         if (q_data->visible_height > q_data->coded_height)
1038                 q_data->visible_height = q_data->coded_height;
1039
1040
1041         dprintk(ctx->dev,
1042                 "Setting format for type %d, coded wxh: %dx%d, visible wxh: %dx%d, fourcc: %08x\n",
1043                 f->type, q_data->coded_width, q_data->coded_height,
1044                 q_data->visible_width, q_data->visible_height,
1045                 q_data->info->id);
1046
1047         return 0;
1048 }
1049
1050 static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
1051                                 struct v4l2_format *f)
1052 {
1053         int ret;
1054
1055         ret = vidioc_try_fmt_vid_cap(file, priv, f);
1056         if (ret)
1057                 return ret;
1058
1059         return vidioc_s_fmt(file2ctx(file), f);
1060 }
1061
1062 static int vidioc_s_fmt_vid_out(struct file *file, void *priv,
1063                                 struct v4l2_format *f)
1064 {
1065         struct vicodec_ctx *ctx = file2ctx(file);
1066         struct v4l2_pix_format_mplane *pix_mp;
1067         struct v4l2_pix_format *pix;
1068         int ret;
1069
1070         ret = vidioc_try_fmt_vid_out(file, priv, f);
1071         if (ret)
1072                 return ret;
1073
1074         ret = vidioc_s_fmt(file2ctx(file), f);
1075         if (!ret) {
1076                 switch (f->type) {
1077                 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1078                 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1079                         pix = &f->fmt.pix;
1080                         ctx->state.colorspace = pix->colorspace;
1081                         ctx->state.xfer_func = pix->xfer_func;
1082                         ctx->state.ycbcr_enc = pix->ycbcr_enc;
1083                         ctx->state.quantization = pix->quantization;
1084                         break;
1085                 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
1086                 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1087                         pix_mp = &f->fmt.pix_mp;
1088                         ctx->state.colorspace = pix_mp->colorspace;
1089                         ctx->state.xfer_func = pix_mp->xfer_func;
1090                         ctx->state.ycbcr_enc = pix_mp->ycbcr_enc;
1091                         ctx->state.quantization = pix_mp->quantization;
1092                         break;
1093                 default:
1094                         break;
1095                 }
1096         }
1097         return ret;
1098 }
1099
1100 static int vidioc_g_selection(struct file *file, void *priv,
1101                               struct v4l2_selection *s)
1102 {
1103         struct vicodec_ctx *ctx = file2ctx(file);
1104         struct vicodec_q_data *q_data;
1105
1106         q_data = get_q_data(ctx, s->type);
1107         if (!q_data)
1108                 return -EINVAL;
1109         /*
1110          * encoder supports only cropping on the OUTPUT buffer
1111          * decoder supports only composing on the CAPTURE buffer
1112          */
1113         if (ctx->is_enc && s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1114                 switch (s->target) {
1115                 case V4L2_SEL_TGT_CROP:
1116                         s->r.left = 0;
1117                         s->r.top = 0;
1118                         s->r.width = q_data->visible_width;
1119                         s->r.height = q_data->visible_height;
1120                         return 0;
1121                 case V4L2_SEL_TGT_CROP_DEFAULT:
1122                 case V4L2_SEL_TGT_CROP_BOUNDS:
1123                         s->r.left = 0;
1124                         s->r.top = 0;
1125                         s->r.width = q_data->coded_width;
1126                         s->r.height = q_data->coded_height;
1127                         return 0;
1128                 }
1129         } else if (!ctx->is_enc && s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1130                 switch (s->target) {
1131                 case V4L2_SEL_TGT_COMPOSE:
1132                         s->r.left = 0;
1133                         s->r.top = 0;
1134                         s->r.width = q_data->visible_width;
1135                         s->r.height = q_data->visible_height;
1136                         return 0;
1137                 case V4L2_SEL_TGT_COMPOSE_DEFAULT:
1138                 case V4L2_SEL_TGT_COMPOSE_BOUNDS:
1139                         s->r.left = 0;
1140                         s->r.top = 0;
1141                         s->r.width = q_data->coded_width;
1142                         s->r.height = q_data->coded_height;
1143                         return 0;
1144                 }
1145         }
1146         return -EINVAL;
1147 }
1148
1149 static int vidioc_s_selection(struct file *file, void *priv,
1150                               struct v4l2_selection *s)
1151 {
1152         struct vicodec_ctx *ctx = file2ctx(file);
1153         struct vicodec_q_data *q_data;
1154
1155         if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1156                 return -EINVAL;
1157
1158         q_data = get_q_data(ctx, s->type);
1159         if (!q_data)
1160                 return -EINVAL;
1161
1162         if (!ctx->is_enc || s->target != V4L2_SEL_TGT_CROP)
1163                 return -EINVAL;
1164
1165         s->r.left = 0;
1166         s->r.top = 0;
1167         q_data->visible_width = clamp(s->r.width, MIN_WIDTH,
1168                                       q_data->coded_width);
1169         s->r.width = q_data->visible_width;
1170         q_data->visible_height = clamp(s->r.height, MIN_HEIGHT,
1171                                        q_data->coded_height);
1172         s->r.height = q_data->visible_height;
1173         return 0;
1174 }
1175
1176 static void vicodec_mark_last_buf(struct vicodec_ctx *ctx)
1177 {
1178         static const struct v4l2_event eos_event = {
1179                 .type = V4L2_EVENT_EOS
1180         };
1181
1182         spin_lock(ctx->lock);
1183         ctx->last_src_buf = v4l2_m2m_last_src_buf(ctx->fh.m2m_ctx);
1184         if (!ctx->last_src_buf && ctx->last_dst_buf) {
1185                 ctx->last_dst_buf->flags |= V4L2_BUF_FLAG_LAST;
1186                 v4l2_event_queue_fh(&ctx->fh, &eos_event);
1187         }
1188         spin_unlock(ctx->lock);
1189 }
1190
1191 static int vicodec_try_encoder_cmd(struct file *file, void *fh,
1192                                 struct v4l2_encoder_cmd *ec)
1193 {
1194         if (ec->cmd != V4L2_ENC_CMD_STOP)
1195                 return -EINVAL;
1196
1197         if (ec->flags & V4L2_ENC_CMD_STOP_AT_GOP_END)
1198                 return -EINVAL;
1199
1200         return 0;
1201 }
1202
1203 static int vicodec_encoder_cmd(struct file *file, void *fh,
1204                             struct v4l2_encoder_cmd *ec)
1205 {
1206         struct vicodec_ctx *ctx = file2ctx(file);
1207         int ret;
1208
1209         ret = vicodec_try_encoder_cmd(file, fh, ec);
1210         if (ret < 0)
1211                 return ret;
1212
1213         vicodec_mark_last_buf(ctx);
1214         return 0;
1215 }
1216
1217 static int vicodec_try_decoder_cmd(struct file *file, void *fh,
1218                                 struct v4l2_decoder_cmd *dc)
1219 {
1220         if (dc->cmd != V4L2_DEC_CMD_STOP)
1221                 return -EINVAL;
1222
1223         if (dc->flags & V4L2_DEC_CMD_STOP_TO_BLACK)
1224                 return -EINVAL;
1225
1226         if (!(dc->flags & V4L2_DEC_CMD_STOP_IMMEDIATELY) && (dc->stop.pts != 0))
1227                 return -EINVAL;
1228
1229         return 0;
1230 }
1231
1232 static int vicodec_decoder_cmd(struct file *file, void *fh,
1233                             struct v4l2_decoder_cmd *dc)
1234 {
1235         struct vicodec_ctx *ctx = file2ctx(file);
1236         int ret;
1237
1238         ret = vicodec_try_decoder_cmd(file, fh, dc);
1239         if (ret < 0)
1240                 return ret;
1241
1242         vicodec_mark_last_buf(ctx);
1243         return 0;
1244 }
1245
1246 static int vicodec_enum_framesizes(struct file *file, void *fh,
1247                                    struct v4l2_frmsizeenum *fsize)
1248 {
1249         switch (fsize->pixel_format) {
1250         case V4L2_PIX_FMT_FWHT_STATELESS:
1251                 break;
1252         case V4L2_PIX_FMT_FWHT:
1253                 break;
1254         default:
1255                 if (find_fmt(fsize->pixel_format)->id == fsize->pixel_format)
1256                         break;
1257                 return -EINVAL;
1258         }
1259
1260         if (fsize->index)
1261                 return -EINVAL;
1262
1263         fsize->type = V4L2_FRMSIZE_TYPE_STEPWISE;
1264
1265         fsize->stepwise.min_width = MIN_WIDTH;
1266         fsize->stepwise.max_width = MAX_WIDTH;
1267         fsize->stepwise.step_width = 8;
1268         fsize->stepwise.min_height = MIN_HEIGHT;
1269         fsize->stepwise.max_height = MAX_HEIGHT;
1270         fsize->stepwise.step_height = 8;
1271
1272         return 0;
1273 }
1274
1275 static int vicodec_subscribe_event(struct v4l2_fh *fh,
1276                                 const struct v4l2_event_subscription *sub)
1277 {
1278         struct vicodec_ctx *ctx = container_of(fh, struct vicodec_ctx, fh);
1279
1280         switch (sub->type) {
1281         case V4L2_EVENT_SOURCE_CHANGE:
1282                 if (ctx->is_enc)
1283                         return -EINVAL;
1284                 /* fall through */
1285         case V4L2_EVENT_EOS:
1286                 return v4l2_event_subscribe(fh, sub, 0, NULL);
1287         default:
1288                 return v4l2_ctrl_subscribe_event(fh, sub);
1289         }
1290 }
1291
1292 static const struct v4l2_ioctl_ops vicodec_ioctl_ops = {
1293         .vidioc_querycap        = vidioc_querycap,
1294
1295         .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
1296         .vidioc_g_fmt_vid_cap   = vidioc_g_fmt_vid_cap,
1297         .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1298         .vidioc_s_fmt_vid_cap   = vidioc_s_fmt_vid_cap,
1299
1300         .vidioc_enum_fmt_vid_cap_mplane = vidioc_enum_fmt_vid_cap,
1301         .vidioc_g_fmt_vid_cap_mplane    = vidioc_g_fmt_vid_cap,
1302         .vidioc_try_fmt_vid_cap_mplane  = vidioc_try_fmt_vid_cap,
1303         .vidioc_s_fmt_vid_cap_mplane    = vidioc_s_fmt_vid_cap,
1304
1305         .vidioc_enum_fmt_vid_out = vidioc_enum_fmt_vid_out,
1306         .vidioc_g_fmt_vid_out   = vidioc_g_fmt_vid_out,
1307         .vidioc_try_fmt_vid_out = vidioc_try_fmt_vid_out,
1308         .vidioc_s_fmt_vid_out   = vidioc_s_fmt_vid_out,
1309
1310         .vidioc_enum_fmt_vid_out_mplane = vidioc_enum_fmt_vid_out,
1311         .vidioc_g_fmt_vid_out_mplane    = vidioc_g_fmt_vid_out,
1312         .vidioc_try_fmt_vid_out_mplane  = vidioc_try_fmt_vid_out,
1313         .vidioc_s_fmt_vid_out_mplane    = vidioc_s_fmt_vid_out,
1314
1315         .vidioc_reqbufs         = v4l2_m2m_ioctl_reqbufs,
1316         .vidioc_querybuf        = v4l2_m2m_ioctl_querybuf,
1317         .vidioc_qbuf            = v4l2_m2m_ioctl_qbuf,
1318         .vidioc_dqbuf           = v4l2_m2m_ioctl_dqbuf,
1319         .vidioc_prepare_buf     = v4l2_m2m_ioctl_prepare_buf,
1320         .vidioc_create_bufs     = v4l2_m2m_ioctl_create_bufs,
1321         .vidioc_expbuf          = v4l2_m2m_ioctl_expbuf,
1322
1323         .vidioc_streamon        = v4l2_m2m_ioctl_streamon,
1324         .vidioc_streamoff       = v4l2_m2m_ioctl_streamoff,
1325
1326         .vidioc_g_selection     = vidioc_g_selection,
1327         .vidioc_s_selection     = vidioc_s_selection,
1328
1329         .vidioc_try_encoder_cmd = vicodec_try_encoder_cmd,
1330         .vidioc_encoder_cmd     = vicodec_encoder_cmd,
1331         .vidioc_try_decoder_cmd = vicodec_try_decoder_cmd,
1332         .vidioc_decoder_cmd     = vicodec_decoder_cmd,
1333         .vidioc_enum_framesizes = vicodec_enum_framesizes,
1334
1335         .vidioc_subscribe_event = vicodec_subscribe_event,
1336         .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
1337 };
1338
1339
1340 /*
1341  * Queue operations
1342  */
1343
1344 static int vicodec_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
1345                                unsigned int *nplanes, unsigned int sizes[],
1346                                struct device *alloc_devs[])
1347 {
1348         struct vicodec_ctx *ctx = vb2_get_drv_priv(vq);
1349         struct vicodec_q_data *q_data = get_q_data(ctx, vq->type);
1350         unsigned int size = q_data->sizeimage;
1351
1352         if (*nplanes)
1353                 return sizes[0] < size ? -EINVAL : 0;
1354
1355         *nplanes = 1;
1356         sizes[0] = size;
1357         return 0;
1358 }
1359
1360 static int vicodec_buf_out_validate(struct vb2_buffer *vb)
1361 {
1362         struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1363
1364         vbuf->field = V4L2_FIELD_NONE;
1365         return 0;
1366 }
1367
1368 static int vicodec_buf_prepare(struct vb2_buffer *vb)
1369 {
1370         struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1371         struct vicodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1372         struct vicodec_q_data *q_data;
1373
1374         dprintk(ctx->dev, "type: %d\n", vb->vb2_queue->type);
1375
1376         q_data = get_q_data(ctx, vb->vb2_queue->type);
1377         if (V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
1378                 if (vbuf->field == V4L2_FIELD_ANY)
1379                         vbuf->field = V4L2_FIELD_NONE;
1380                 if (vbuf->field != V4L2_FIELD_NONE) {
1381                         dprintk(ctx->dev, "%s field isn't supported\n",
1382                                         __func__);
1383                         return -EINVAL;
1384                 }
1385         }
1386
1387         if (vb2_plane_size(vb, 0) < q_data->sizeimage) {
1388                 dprintk(ctx->dev,
1389                         "%s data will not fit into plane (%lu < %lu)\n",
1390                         __func__, vb2_plane_size(vb, 0),
1391                         (long)q_data->sizeimage);
1392                 return -EINVAL;
1393         }
1394
1395         return 0;
1396 }
1397
1398 static void vicodec_buf_queue(struct vb2_buffer *vb)
1399 {
1400         struct vb2_v4l2_buffer *vbuf = to_vb2_v4l2_buffer(vb);
1401         struct vicodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1402         unsigned int sz = vb2_get_plane_payload(&vbuf->vb2_buf, 0);
1403         u8 *p_src = vb2_plane_vaddr(&vbuf->vb2_buf, 0);
1404         u8 *p = p_src;
1405         struct vb2_queue *vq_out = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
1406                                                    V4L2_BUF_TYPE_VIDEO_OUTPUT);
1407         struct vb2_queue *vq_cap = v4l2_m2m_get_vq(ctx->fh.m2m_ctx,
1408                                                    V4L2_BUF_TYPE_VIDEO_CAPTURE);
1409         bool header_valid = false;
1410         static const struct v4l2_event rs_event = {
1411                 .type = V4L2_EVENT_SOURCE_CHANGE,
1412                 .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION,
1413         };
1414
1415         /* buf_queue handles only the first source change event */
1416         if (ctx->first_source_change_sent) {
1417                 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
1418                 return;
1419         }
1420
1421         /*
1422          * if both queues are streaming, the source change event is
1423          * handled in job_ready
1424          */
1425         if (vb2_is_streaming(vq_cap) && vb2_is_streaming(vq_out)) {
1426                 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
1427                 return;
1428         }
1429
1430         /*
1431          * source change event is relevant only for the stateful decoder
1432          * in the compressed stream
1433          */
1434         if (ctx->is_stateless || ctx->is_enc ||
1435             !V4L2_TYPE_IS_OUTPUT(vb->vb2_queue->type)) {
1436                 v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
1437                 return;
1438         }
1439
1440         do {
1441                 enum vb2_buffer_state state =
1442                         get_next_header(ctx, &p, p_src + sz - p);
1443
1444                 if (ctx->header_size < sizeof(struct fwht_cframe_hdr)) {
1445                         v4l2_m2m_buf_done(vbuf, state);
1446                         return;
1447                 }
1448                 header_valid = is_header_valid(&ctx->state.header);
1449                 /*
1450                  * p points right after the end of the header in the
1451                  * buffer. If the header is invalid we set p to point
1452                  * to the next byte after the start of the header
1453                  */
1454                 if (!header_valid) {
1455                         p = p - sizeof(struct fwht_cframe_hdr) + 1;
1456                         if (p < p_src)
1457                                 p = p_src;
1458                         ctx->header_size = 0;
1459                         ctx->comp_magic_cnt = 0;
1460                 }
1461
1462         } while (!header_valid);
1463
1464         ctx->cur_buf_offset = p - p_src;
1465         update_capture_data_from_header(ctx);
1466         ctx->first_source_change_sent = true;
1467         v4l2_event_queue_fh(&ctx->fh, &rs_event);
1468         v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, vbuf);
1469 }
1470
1471 static void vicodec_return_bufs(struct vb2_queue *q, u32 state)
1472 {
1473         struct vicodec_ctx *ctx = vb2_get_drv_priv(q);
1474         struct vb2_v4l2_buffer *vbuf;
1475
1476         for (;;) {
1477                 if (V4L2_TYPE_IS_OUTPUT(q->type))
1478                         vbuf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx);
1479                 else
1480                         vbuf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx);
1481                 if (vbuf == NULL)
1482                         return;
1483                 v4l2_ctrl_request_complete(vbuf->vb2_buf.req_obj.req,
1484                                            &ctx->hdl);
1485                 spin_lock(ctx->lock);
1486                 v4l2_m2m_buf_done(vbuf, state);
1487                 spin_unlock(ctx->lock);
1488         }
1489 }
1490
1491 static unsigned int total_frame_size(struct vicodec_q_data *q_data)
1492 {
1493         unsigned int size;
1494         unsigned int chroma_div;
1495
1496         if (!q_data->info) {
1497                 WARN_ON(1);
1498                 return 0;
1499         }
1500         size = q_data->coded_width * q_data->coded_height;
1501         chroma_div = q_data->info->width_div * q_data->info->height_div;
1502
1503         if (q_data->info->components_num == 4)
1504                 return 2 * size + 2 * (size / chroma_div);
1505         else if (q_data->info->components_num == 3)
1506                 return size + 2 * (size / chroma_div);
1507         return size;
1508 }
1509
1510 static int vicodec_start_streaming(struct vb2_queue *q,
1511                                    unsigned int count)
1512 {
1513         struct vicodec_ctx *ctx = vb2_get_drv_priv(q);
1514         struct vicodec_q_data *q_data = get_q_data(ctx, q->type);
1515         struct v4l2_fwht_state *state = &ctx->state;
1516         const struct v4l2_fwht_pixfmt_info *info = q_data->info;
1517         unsigned int size = q_data->coded_width * q_data->coded_height;
1518         unsigned int chroma_div;
1519         unsigned int total_planes_size;
1520         u8 *new_comp_frame = NULL;
1521
1522         if (!info)
1523                 return -EINVAL;
1524
1525         chroma_div = info->width_div * info->height_div;
1526         q_data->sequence = 0;
1527
1528         if (V4L2_TYPE_IS_OUTPUT(q->type))
1529                 ctx->last_src_buf = NULL;
1530         else
1531                 ctx->last_dst_buf = NULL;
1532
1533         state->gop_cnt = 0;
1534
1535         if ((V4L2_TYPE_IS_OUTPUT(q->type) && !ctx->is_enc) ||
1536             (!V4L2_TYPE_IS_OUTPUT(q->type) && ctx->is_enc))
1537                 return 0;
1538
1539         if (info->id == V4L2_PIX_FMT_FWHT ||
1540             info->id == V4L2_PIX_FMT_FWHT_STATELESS) {
1541                 vicodec_return_bufs(q, VB2_BUF_STATE_QUEUED);
1542                 return -EINVAL;
1543         }
1544         total_planes_size = total_frame_size(q_data);
1545         ctx->comp_max_size = total_planes_size;
1546
1547         state->visible_width = q_data->visible_width;
1548         state->visible_height = q_data->visible_height;
1549         state->coded_width = q_data->coded_width;
1550         state->coded_height = q_data->coded_height;
1551         state->stride = q_data->coded_width *
1552                                 info->bytesperline_mult;
1553
1554         if (ctx->is_stateless) {
1555                 state->ref_stride = state->stride;
1556                 return 0;
1557         }
1558         state->ref_stride = q_data->coded_width * info->luma_alpha_step;
1559
1560         state->ref_frame.buf = kvmalloc(total_planes_size, GFP_KERNEL);
1561         state->ref_frame.luma = state->ref_frame.buf;
1562         new_comp_frame = kvmalloc(ctx->comp_max_size, GFP_KERNEL);
1563
1564         if (!state->ref_frame.luma || !new_comp_frame) {
1565                 kvfree(state->ref_frame.luma);
1566                 kvfree(new_comp_frame);
1567                 vicodec_return_bufs(q, VB2_BUF_STATE_QUEUED);
1568                 return -ENOMEM;
1569         }
1570         /*
1571          * if state->compressed_frame was already allocated then
1572          * it contain data of the first frame of the new resolution
1573          */
1574         if (state->compressed_frame) {
1575                 if (ctx->comp_size > ctx->comp_max_size)
1576                         ctx->comp_size = ctx->comp_max_size;
1577
1578                 memcpy(new_comp_frame,
1579                        state->compressed_frame, ctx->comp_size);
1580         }
1581
1582         kvfree(state->compressed_frame);
1583         state->compressed_frame = new_comp_frame;
1584
1585         if (info->components_num >= 3) {
1586                 state->ref_frame.cb = state->ref_frame.luma + size;
1587                 state->ref_frame.cr = state->ref_frame.cb + size / chroma_div;
1588         } else {
1589                 state->ref_frame.cb = NULL;
1590                 state->ref_frame.cr = NULL;
1591         }
1592
1593         if (info->components_num == 4)
1594                 state->ref_frame.alpha =
1595                         state->ref_frame.cr + size / chroma_div;
1596         else
1597                 state->ref_frame.alpha = NULL;
1598         return 0;
1599 }
1600
1601 static void vicodec_stop_streaming(struct vb2_queue *q)
1602 {
1603         struct vicodec_ctx *ctx = vb2_get_drv_priv(q);
1604
1605         vicodec_return_bufs(q, VB2_BUF_STATE_ERROR);
1606
1607         if ((!V4L2_TYPE_IS_OUTPUT(q->type) && !ctx->is_enc) ||
1608             (V4L2_TYPE_IS_OUTPUT(q->type) && ctx->is_enc)) {
1609                 if (!ctx->is_stateless)
1610                         kvfree(ctx->state.ref_frame.buf);
1611                 ctx->state.ref_frame.buf = NULL;
1612                 ctx->state.ref_frame.luma = NULL;
1613                 ctx->comp_max_size = 0;
1614                 ctx->source_changed = false;
1615         }
1616         if (V4L2_TYPE_IS_OUTPUT(q->type) && !ctx->is_enc) {
1617                 ctx->cur_buf_offset = 0;
1618                 ctx->comp_size = 0;
1619                 ctx->header_size = 0;
1620                 ctx->comp_magic_cnt = 0;
1621                 ctx->comp_has_frame = 0;
1622                 ctx->comp_has_next_frame = 0;
1623         }
1624 }
1625
1626 static void vicodec_buf_request_complete(struct vb2_buffer *vb)
1627 {
1628         struct vicodec_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
1629
1630         v4l2_ctrl_request_complete(vb->req_obj.req, &ctx->hdl);
1631 }
1632
1633
1634 static const struct vb2_ops vicodec_qops = {
1635         .queue_setup            = vicodec_queue_setup,
1636         .buf_out_validate       = vicodec_buf_out_validate,
1637         .buf_prepare            = vicodec_buf_prepare,
1638         .buf_queue              = vicodec_buf_queue,
1639         .buf_request_complete   = vicodec_buf_request_complete,
1640         .start_streaming        = vicodec_start_streaming,
1641         .stop_streaming         = vicodec_stop_streaming,
1642         .wait_prepare           = vb2_ops_wait_prepare,
1643         .wait_finish            = vb2_ops_wait_finish,
1644 };
1645
1646 static int queue_init(void *priv, struct vb2_queue *src_vq,
1647                       struct vb2_queue *dst_vq)
1648 {
1649         struct vicodec_ctx *ctx = priv;
1650         int ret;
1651
1652         src_vq->type = (multiplanar ?
1653                         V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE :
1654                         V4L2_BUF_TYPE_VIDEO_OUTPUT);
1655         src_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
1656         src_vq->drv_priv = ctx;
1657         src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1658         src_vq->ops = &vicodec_qops;
1659         src_vq->mem_ops = &vb2_vmalloc_memops;
1660         src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1661         if (ctx->is_enc)
1662                 src_vq->lock = &ctx->dev->stateful_enc.mutex;
1663         else if (ctx->is_stateless)
1664                 src_vq->lock = &ctx->dev->stateless_dec.mutex;
1665         else
1666                 src_vq->lock = &ctx->dev->stateful_dec.mutex;
1667         src_vq->supports_requests = ctx->is_stateless;
1668         src_vq->requires_requests = ctx->is_stateless;
1669         ret = vb2_queue_init(src_vq);
1670         if (ret)
1671                 return ret;
1672
1673         dst_vq->type = (multiplanar ?
1674                         V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE :
1675                         V4L2_BUF_TYPE_VIDEO_CAPTURE);
1676         dst_vq->io_modes = VB2_MMAP | VB2_USERPTR | VB2_DMABUF;
1677         dst_vq->drv_priv = ctx;
1678         dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1679         dst_vq->ops = &vicodec_qops;
1680         dst_vq->mem_ops = &vb2_vmalloc_memops;
1681         dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY;
1682         dst_vq->lock = src_vq->lock;
1683
1684         return vb2_queue_init(dst_vq);
1685 }
1686
1687 static int vicodec_try_ctrl(struct v4l2_ctrl *ctrl)
1688 {
1689         struct vicodec_ctx *ctx = container_of(ctrl->handler,
1690                         struct vicodec_ctx, hdl);
1691         const struct v4l2_ctrl_fwht_params *params;
1692         struct vicodec_q_data *q_dst = get_q_data(ctx,
1693                         V4L2_BUF_TYPE_VIDEO_CAPTURE);
1694
1695         switch (ctrl->id) {
1696         case V4L2_CID_MPEG_VIDEO_FWHT_PARAMS:
1697                 if (!q_dst->info)
1698                         return -EINVAL;
1699                 params = ctrl->p_new.p_fwht_params;
1700                 if (params->width > q_dst->coded_width ||
1701                     params->width < MIN_WIDTH ||
1702                     params->height > q_dst->coded_height ||
1703                     params->height < MIN_HEIGHT)
1704                         return -EINVAL;
1705                 if (!validate_by_version(params->flags, params->version))
1706                         return -EINVAL;
1707                 if (!validate_stateless_params_flags(params, q_dst->info))
1708                         return -EINVAL;
1709                 return 0;
1710         default:
1711                 return 0;
1712         }
1713         return 0;
1714 }
1715
1716 static void update_header_from_stateless_params(struct vicodec_ctx *ctx,
1717                                                 const struct v4l2_ctrl_fwht_params *params)
1718 {
1719         struct fwht_cframe_hdr *p_hdr = &ctx->state.header;
1720
1721         p_hdr->magic1 = FWHT_MAGIC1;
1722         p_hdr->magic2 = FWHT_MAGIC2;
1723         p_hdr->version = htonl(params->version);
1724         p_hdr->width = htonl(params->width);
1725         p_hdr->height = htonl(params->height);
1726         p_hdr->flags = htonl(params->flags);
1727         p_hdr->colorspace = htonl(params->colorspace);
1728         p_hdr->xfer_func = htonl(params->xfer_func);
1729         p_hdr->ycbcr_enc = htonl(params->ycbcr_enc);
1730         p_hdr->quantization = htonl(params->quantization);
1731 }
1732
1733 static int vicodec_s_ctrl(struct v4l2_ctrl *ctrl)
1734 {
1735         struct vicodec_ctx *ctx = container_of(ctrl->handler,
1736                                                struct vicodec_ctx, hdl);
1737         const struct v4l2_ctrl_fwht_params *params;
1738
1739         switch (ctrl->id) {
1740         case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
1741                 ctx->state.gop_size = ctrl->val;
1742                 return 0;
1743         case V4L2_CID_FWHT_I_FRAME_QP:
1744                 ctx->state.i_frame_qp = ctrl->val;
1745                 return 0;
1746         case V4L2_CID_FWHT_P_FRAME_QP:
1747                 ctx->state.p_frame_qp = ctrl->val;
1748                 return 0;
1749         case V4L2_CID_MPEG_VIDEO_FWHT_PARAMS:
1750                 params = ctrl->p_new.p_fwht_params;
1751                 update_header_from_stateless_params(ctx, params);
1752                 ctx->state.ref_frame_ts = params->backward_ref_ts;
1753                 return 0;
1754         }
1755         return -EINVAL;
1756 }
1757
1758 static const struct v4l2_ctrl_ops vicodec_ctrl_ops = {
1759         .s_ctrl = vicodec_s_ctrl,
1760         .try_ctrl = vicodec_try_ctrl,
1761 };
1762
1763 static const struct v4l2_ctrl_config vicodec_ctrl_stateless_state = {
1764         .ops            = &vicodec_ctrl_ops,
1765         .id             = V4L2_CID_MPEG_VIDEO_FWHT_PARAMS,
1766         .elem_size      = sizeof(struct v4l2_ctrl_fwht_params),
1767 };
1768
1769 /*
1770  * File operations
1771  */
1772 static int vicodec_open(struct file *file)
1773 {
1774         struct video_device *vfd = video_devdata(file);
1775         struct vicodec_dev *dev = video_drvdata(file);
1776         struct vicodec_ctx *ctx = NULL;
1777         struct v4l2_ctrl_handler *hdl;
1778         unsigned int size;
1779         int rc = 0;
1780
1781         if (mutex_lock_interruptible(vfd->lock))
1782                 return -ERESTARTSYS;
1783         ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
1784         if (!ctx) {
1785                 rc = -ENOMEM;
1786                 goto open_unlock;
1787         }
1788
1789         if (vfd == &dev->stateful_enc.vfd)
1790                 ctx->is_enc = true;
1791         else if (vfd == &dev->stateless_dec.vfd)
1792                 ctx->is_stateless = true;
1793
1794         v4l2_fh_init(&ctx->fh, video_devdata(file));
1795         file->private_data = &ctx->fh;
1796         ctx->dev = dev;
1797         hdl = &ctx->hdl;
1798         v4l2_ctrl_handler_init(hdl, 4);
1799         v4l2_ctrl_new_std(hdl, &vicodec_ctrl_ops, V4L2_CID_MPEG_VIDEO_GOP_SIZE,
1800                           1, 16, 1, 10);
1801         v4l2_ctrl_new_std(hdl, &vicodec_ctrl_ops, V4L2_CID_FWHT_I_FRAME_QP,
1802                           1, 31, 1, 20);
1803         v4l2_ctrl_new_std(hdl, &vicodec_ctrl_ops, V4L2_CID_FWHT_P_FRAME_QP,
1804                           1, 31, 1, 20);
1805         if (ctx->is_stateless)
1806                 v4l2_ctrl_new_custom(hdl, &vicodec_ctrl_stateless_state, NULL);
1807         if (hdl->error) {
1808                 rc = hdl->error;
1809                 v4l2_ctrl_handler_free(hdl);
1810                 kfree(ctx);
1811                 goto open_unlock;
1812         }
1813         ctx->fh.ctrl_handler = hdl;
1814         v4l2_ctrl_handler_setup(hdl);
1815
1816         if (ctx->is_enc)
1817                 ctx->q_data[V4L2_M2M_SRC].info = v4l2_fwht_get_pixfmt(0);
1818         else if (ctx->is_stateless)
1819                 ctx->q_data[V4L2_M2M_SRC].info = &pixfmt_stateless_fwht;
1820         else
1821                 ctx->q_data[V4L2_M2M_SRC].info = &pixfmt_fwht;
1822         ctx->q_data[V4L2_M2M_SRC].coded_width = 1280;
1823         ctx->q_data[V4L2_M2M_SRC].coded_height = 720;
1824         ctx->q_data[V4L2_M2M_SRC].visible_width = 1280;
1825         ctx->q_data[V4L2_M2M_SRC].visible_height = 720;
1826         size = 1280 * 720 * ctx->q_data[V4L2_M2M_SRC].info->sizeimage_mult /
1827                 ctx->q_data[V4L2_M2M_SRC].info->sizeimage_div;
1828         if (ctx->is_enc || ctx->is_stateless)
1829                 ctx->q_data[V4L2_M2M_SRC].sizeimage = size;
1830         else
1831                 ctx->q_data[V4L2_M2M_SRC].sizeimage =
1832                         size + sizeof(struct fwht_cframe_hdr);
1833         if (ctx->is_enc) {
1834                 ctx->q_data[V4L2_M2M_DST] = ctx->q_data[V4L2_M2M_SRC];
1835                 ctx->q_data[V4L2_M2M_DST].info = &pixfmt_fwht;
1836                 ctx->q_data[V4L2_M2M_DST].sizeimage = 1280 * 720 *
1837                         ctx->q_data[V4L2_M2M_DST].info->sizeimage_mult /
1838                         ctx->q_data[V4L2_M2M_DST].info->sizeimage_div +
1839                         sizeof(struct fwht_cframe_hdr);
1840         } else {
1841                 ctx->q_data[V4L2_M2M_DST].info = NULL;
1842         }
1843
1844         ctx->state.colorspace = V4L2_COLORSPACE_REC709;
1845
1846         if (ctx->is_enc) {
1847                 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->stateful_enc.m2m_dev,
1848                                                     ctx, &queue_init);
1849                 ctx->lock = &dev->stateful_enc.lock;
1850         } else if (ctx->is_stateless) {
1851                 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->stateless_dec.m2m_dev,
1852                                                     ctx, &queue_init);
1853                 ctx->lock = &dev->stateless_dec.lock;
1854         } else {
1855                 ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(dev->stateful_dec.m2m_dev,
1856                                                     ctx, &queue_init);
1857                 ctx->lock = &dev->stateful_dec.lock;
1858         }
1859
1860         if (IS_ERR(ctx->fh.m2m_ctx)) {
1861                 rc = PTR_ERR(ctx->fh.m2m_ctx);
1862
1863                 v4l2_ctrl_handler_free(hdl);
1864                 v4l2_fh_exit(&ctx->fh);
1865                 kfree(ctx);
1866                 goto open_unlock;
1867         }
1868
1869         v4l2_fh_add(&ctx->fh);
1870
1871 open_unlock:
1872         mutex_unlock(vfd->lock);
1873         return rc;
1874 }
1875
1876 static int vicodec_release(struct file *file)
1877 {
1878         struct video_device *vfd = video_devdata(file);
1879         struct vicodec_ctx *ctx = file2ctx(file);
1880
1881         mutex_lock(vfd->lock);
1882         v4l2_m2m_ctx_release(ctx->fh.m2m_ctx);
1883         mutex_unlock(vfd->lock);
1884         v4l2_fh_del(&ctx->fh);
1885         v4l2_fh_exit(&ctx->fh);
1886         v4l2_ctrl_handler_free(&ctx->hdl);
1887         kvfree(ctx->state.compressed_frame);
1888         kfree(ctx);
1889
1890         return 0;
1891 }
1892
1893 static int vicodec_request_validate(struct media_request *req)
1894 {
1895         struct media_request_object *obj;
1896         struct v4l2_ctrl_handler *parent_hdl, *hdl;
1897         struct vicodec_ctx *ctx = NULL;
1898         struct v4l2_ctrl *ctrl;
1899         unsigned int count;
1900
1901         list_for_each_entry(obj, &req->objects, list) {
1902                 struct vb2_buffer *vb;
1903
1904                 if (vb2_request_object_is_buffer(obj)) {
1905                         vb = container_of(obj, struct vb2_buffer, req_obj);
1906                         ctx = vb2_get_drv_priv(vb->vb2_queue);
1907
1908                         break;
1909                 }
1910         }
1911
1912         if (!ctx) {
1913                 pr_err("No buffer was provided with the request\n");
1914                 return -ENOENT;
1915         }
1916
1917         count = vb2_request_buffer_cnt(req);
1918         if (!count) {
1919                 v4l2_info(&ctx->dev->v4l2_dev,
1920                           "No buffer was provided with the request\n");
1921                 return -ENOENT;
1922         } else if (count > 1) {
1923                 v4l2_info(&ctx->dev->v4l2_dev,
1924                           "More than one buffer was provided with the request\n");
1925                 return -EINVAL;
1926         }
1927
1928         parent_hdl = &ctx->hdl;
1929
1930         hdl = v4l2_ctrl_request_hdl_find(req, parent_hdl);
1931         if (!hdl) {
1932                 v4l2_info(&ctx->dev->v4l2_dev, "Missing codec control\n");
1933                 return -ENOENT;
1934         }
1935         ctrl = v4l2_ctrl_request_hdl_ctrl_find(hdl,
1936                                                vicodec_ctrl_stateless_state.id);
1937         if (!ctrl) {
1938                 v4l2_info(&ctx->dev->v4l2_dev,
1939                           "Missing required codec control\n");
1940                 return -ENOENT;
1941         }
1942
1943         return vb2_request_validate(req);
1944 }
1945
1946 static const struct v4l2_file_operations vicodec_fops = {
1947         .owner          = THIS_MODULE,
1948         .open           = vicodec_open,
1949         .release        = vicodec_release,
1950         .poll           = v4l2_m2m_fop_poll,
1951         .unlocked_ioctl = video_ioctl2,
1952         .mmap           = v4l2_m2m_fop_mmap,
1953 };
1954
1955 static const struct video_device vicodec_videodev = {
1956         .name           = VICODEC_NAME,
1957         .vfl_dir        = VFL_DIR_M2M,
1958         .fops           = &vicodec_fops,
1959         .ioctl_ops      = &vicodec_ioctl_ops,
1960         .minor          = -1,
1961         .release        = video_device_release_empty,
1962 };
1963
1964 static const struct media_device_ops vicodec_m2m_media_ops = {
1965         .req_validate   = vicodec_request_validate,
1966         .req_queue      = v4l2_m2m_request_queue,
1967 };
1968
1969 static const struct v4l2_m2m_ops m2m_ops = {
1970         .device_run     = device_run,
1971         .job_ready      = job_ready,
1972 };
1973
1974 static int register_instance(struct vicodec_dev *dev,
1975                              struct vicodec_dev_instance *dev_instance,
1976                              const char *name, bool is_enc)
1977 {
1978         struct video_device *vfd;
1979         int ret;
1980
1981         spin_lock_init(&dev_instance->lock);
1982         mutex_init(&dev_instance->mutex);
1983         dev_instance->m2m_dev = v4l2_m2m_init(&m2m_ops);
1984         if (IS_ERR(dev_instance->m2m_dev)) {
1985                 v4l2_err(&dev->v4l2_dev, "Failed to init vicodec enc device\n");
1986                 return PTR_ERR(dev_instance->m2m_dev);
1987         }
1988
1989         dev_instance->vfd = vicodec_videodev;
1990         vfd = &dev_instance->vfd;
1991         vfd->lock = &dev_instance->mutex;
1992         vfd->v4l2_dev = &dev->v4l2_dev;
1993         strscpy(vfd->name, name, sizeof(vfd->name));
1994         vfd->device_caps = V4L2_CAP_STREAMING |
1995                 (multiplanar ? V4L2_CAP_VIDEO_M2M_MPLANE : V4L2_CAP_VIDEO_M2M);
1996         if (is_enc) {
1997                 v4l2_disable_ioctl(vfd, VIDIOC_DECODER_CMD);
1998                 v4l2_disable_ioctl(vfd, VIDIOC_TRY_DECODER_CMD);
1999         } else {
2000                 v4l2_disable_ioctl(vfd, VIDIOC_ENCODER_CMD);
2001                 v4l2_disable_ioctl(vfd, VIDIOC_TRY_ENCODER_CMD);
2002         }
2003         video_set_drvdata(vfd, dev);
2004
2005         ret = video_register_device(vfd, VFL_TYPE_GRABBER, 0);
2006         if (ret) {
2007                 v4l2_err(&dev->v4l2_dev, "Failed to register video device '%s'\n", name);
2008                 v4l2_m2m_release(dev_instance->m2m_dev);
2009                 return ret;
2010         }
2011         v4l2_info(&dev->v4l2_dev, "Device '%s' registered as /dev/video%d\n",
2012                   name, vfd->num);
2013         return 0;
2014 }
2015
2016 static int vicodec_probe(struct platform_device *pdev)
2017 {
2018         struct vicodec_dev *dev;
2019         int ret;
2020
2021         dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL);
2022         if (!dev)
2023                 return -ENOMEM;
2024
2025         ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev);
2026         if (ret)
2027                 return ret;
2028
2029 #ifdef CONFIG_MEDIA_CONTROLLER
2030         dev->mdev.dev = &pdev->dev;
2031         strscpy(dev->mdev.model, "vicodec", sizeof(dev->mdev.model));
2032         strscpy(dev->mdev.bus_info, "platform:vicodec",
2033                 sizeof(dev->mdev.bus_info));
2034         media_device_init(&dev->mdev);
2035         dev->mdev.ops = &vicodec_m2m_media_ops;
2036         dev->v4l2_dev.mdev = &dev->mdev;
2037 #endif
2038
2039         platform_set_drvdata(pdev, dev);
2040
2041         if (register_instance(dev, &dev->stateful_enc,
2042                               "stateful-encoder", true))
2043                 goto unreg_dev;
2044
2045         if (register_instance(dev, &dev->stateful_dec,
2046                               "stateful-decoder", false))
2047                 goto unreg_sf_enc;
2048
2049         if (register_instance(dev, &dev->stateless_dec,
2050                               "stateless-decoder", false))
2051                 goto unreg_sf_dec;
2052
2053 #ifdef CONFIG_MEDIA_CONTROLLER
2054         ret = v4l2_m2m_register_media_controller(dev->stateful_enc.m2m_dev,
2055                                                  &dev->stateful_enc.vfd,
2056                                                  MEDIA_ENT_F_PROC_VIDEO_ENCODER);
2057         if (ret) {
2058                 v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller for enc\n");
2059                 goto unreg_m2m;
2060         }
2061
2062         ret = v4l2_m2m_register_media_controller(dev->stateful_dec.m2m_dev,
2063                                                  &dev->stateful_dec.vfd,
2064                                                  MEDIA_ENT_F_PROC_VIDEO_DECODER);
2065         if (ret) {
2066                 v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller for dec\n");
2067                 goto unreg_m2m_sf_enc_mc;
2068         }
2069
2070         ret = v4l2_m2m_register_media_controller(dev->stateless_dec.m2m_dev,
2071                                                  &dev->stateless_dec.vfd,
2072                                                  MEDIA_ENT_F_PROC_VIDEO_DECODER);
2073         if (ret) {
2074                 v4l2_err(&dev->v4l2_dev, "Failed to init mem2mem media controller for stateless dec\n");
2075                 goto unreg_m2m_sf_dec_mc;
2076         }
2077
2078         ret = media_device_register(&dev->mdev);
2079         if (ret) {
2080                 v4l2_err(&dev->v4l2_dev, "Failed to register mem2mem media device\n");
2081                 goto unreg_m2m_sl_dec_mc;
2082         }
2083 #endif
2084         return 0;
2085
2086 #ifdef CONFIG_MEDIA_CONTROLLER
2087 unreg_m2m_sl_dec_mc:
2088         v4l2_m2m_unregister_media_controller(dev->stateless_dec.m2m_dev);
2089 unreg_m2m_sf_dec_mc:
2090         v4l2_m2m_unregister_media_controller(dev->stateful_dec.m2m_dev);
2091 unreg_m2m_sf_enc_mc:
2092         v4l2_m2m_unregister_media_controller(dev->stateful_enc.m2m_dev);
2093 unreg_m2m:
2094         video_unregister_device(&dev->stateless_dec.vfd);
2095         v4l2_m2m_release(dev->stateless_dec.m2m_dev);
2096 #endif
2097 unreg_sf_dec:
2098         video_unregister_device(&dev->stateful_dec.vfd);
2099         v4l2_m2m_release(dev->stateful_dec.m2m_dev);
2100 unreg_sf_enc:
2101         video_unregister_device(&dev->stateful_enc.vfd);
2102         v4l2_m2m_release(dev->stateful_enc.m2m_dev);
2103 unreg_dev:
2104         v4l2_device_unregister(&dev->v4l2_dev);
2105
2106         return ret;
2107 }
2108
2109 static int vicodec_remove(struct platform_device *pdev)
2110 {
2111         struct vicodec_dev *dev = platform_get_drvdata(pdev);
2112
2113         v4l2_info(&dev->v4l2_dev, "Removing " VICODEC_NAME);
2114
2115 #ifdef CONFIG_MEDIA_CONTROLLER
2116         media_device_unregister(&dev->mdev);
2117         v4l2_m2m_unregister_media_controller(dev->stateful_enc.m2m_dev);
2118         v4l2_m2m_unregister_media_controller(dev->stateful_dec.m2m_dev);
2119         v4l2_m2m_unregister_media_controller(dev->stateless_dec.m2m_dev);
2120         media_device_cleanup(&dev->mdev);
2121 #endif
2122
2123         v4l2_m2m_release(dev->stateful_enc.m2m_dev);
2124         v4l2_m2m_release(dev->stateful_dec.m2m_dev);
2125         video_unregister_device(&dev->stateful_enc.vfd);
2126         video_unregister_device(&dev->stateful_dec.vfd);
2127         video_unregister_device(&dev->stateless_dec.vfd);
2128         v4l2_device_unregister(&dev->v4l2_dev);
2129
2130         return 0;
2131 }
2132
2133 static struct platform_driver vicodec_pdrv = {
2134         .probe          = vicodec_probe,
2135         .remove         = vicodec_remove,
2136         .driver         = {
2137                 .name   = VICODEC_NAME,
2138         },
2139 };
2140
2141 static void __exit vicodec_exit(void)
2142 {
2143         platform_driver_unregister(&vicodec_pdrv);
2144         platform_device_unregister(&vicodec_pdev);
2145 }
2146
2147 static int __init vicodec_init(void)
2148 {
2149         int ret;
2150
2151         ret = platform_device_register(&vicodec_pdev);
2152         if (ret)
2153                 return ret;
2154
2155         ret = platform_driver_register(&vicodec_pdrv);
2156         if (ret)
2157                 platform_device_unregister(&vicodec_pdev);
2158
2159         return ret;
2160 }
2161
2162 module_init(vicodec_init);
2163 module_exit(vicodec_exit);