1 // SPDX-License-Identifier: GPL-2.0
3 * Imagination E5010 JPEG Encoder driver.
5 * TODO: Add MMU and memory tiling support
7 * Copyright (C) 2023 Texas Instruments Incorporated - https://www.ti.com/
9 * Author: David Huang <d-huang@ti.com>
10 * Author: Devarsh Thakkar <devarsht@ti.com>
13 #include <linux/clk.h>
14 #include <linux/dma-mapping.h>
15 #include <linux/err.h>
16 #include <linux/interrupt.h>
17 #include <linux/ioctl.h>
18 #include <linux/module.h>
19 #include <linux/of_device.h>
20 #include <linux/pm_runtime.h>
21 #include <media/jpeg.h>
22 #include <media/v4l2-common.h>
23 #include <media/v4l2-ctrls.h>
24 #include <media/v4l2-device.h>
25 #include <media/v4l2-event.h>
26 #include <media/v4l2-ioctl.h>
27 #include <media/v4l2-jpeg.h>
28 #include <media/v4l2-rect.h>
29 #include <media/v4l2-mem2mem.h>
30 #include <media/videobuf2-dma-contig.h>
31 #include <media/videobuf2-v4l2.h>
32 #include "e5010-jpeg-enc.h"
33 #include "e5010-jpeg-enc-hw.h"
35 /* forward declarations */
36 static const struct of_device_id e5010_of_match
[];
38 static const struct v4l2_file_operations e5010_fops
;
40 static const struct v4l2_ioctl_ops e5010_ioctl_ops
;
42 static const struct vb2_ops e5010_video_ops
;
44 static const struct v4l2_m2m_ops e5010_m2m_ops
;
46 static struct e5010_fmt e5010_formats
[] = {
48 .fourcc
= V4L2_PIX_FMT_NV12
,
50 .type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
,
51 .subsampling
= V4L2_JPEG_CHROMA_SUBSAMPLING_420
,
52 .chroma_order
= CHROMA_ORDER_CB_CR
,
53 .frmsize
= { MIN_DIMENSION
, MAX_DIMENSION
, 64,
54 MIN_DIMENSION
, MAX_DIMENSION
, 8 },
57 .fourcc
= V4L2_PIX_FMT_NV12M
,
59 .type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
,
60 .subsampling
= V4L2_JPEG_CHROMA_SUBSAMPLING_420
,
61 .chroma_order
= CHROMA_ORDER_CB_CR
,
62 .frmsize
= { MIN_DIMENSION
, MAX_DIMENSION
, 64,
63 MIN_DIMENSION
, MAX_DIMENSION
, 8 },
66 .fourcc
= V4L2_PIX_FMT_NV21
,
68 .type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
,
69 .subsampling
= V4L2_JPEG_CHROMA_SUBSAMPLING_420
,
70 .chroma_order
= CHROMA_ORDER_CR_CB
,
71 .frmsize
= { MIN_DIMENSION
, MAX_DIMENSION
, 64,
72 MIN_DIMENSION
, MAX_DIMENSION
, 8 },
75 .fourcc
= V4L2_PIX_FMT_NV21M
,
77 .type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
,
78 .subsampling
= V4L2_JPEG_CHROMA_SUBSAMPLING_420
,
79 .chroma_order
= CHROMA_ORDER_CR_CB
,
80 .frmsize
= { MIN_DIMENSION
, MAX_DIMENSION
, 64,
81 MIN_DIMENSION
, MAX_DIMENSION
, 8 },
84 .fourcc
= V4L2_PIX_FMT_NV16
,
86 .type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
,
87 .subsampling
= V4L2_JPEG_CHROMA_SUBSAMPLING_422
,
88 .chroma_order
= CHROMA_ORDER_CB_CR
,
89 .frmsize
= { MIN_DIMENSION
, MAX_DIMENSION
, 64,
90 MIN_DIMENSION
, MAX_DIMENSION
, 8 },
93 .fourcc
= V4L2_PIX_FMT_NV16M
,
95 .type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
,
96 .subsampling
= V4L2_JPEG_CHROMA_SUBSAMPLING_422
,
97 .chroma_order
= CHROMA_ORDER_CB_CR
,
98 .frmsize
= { MIN_DIMENSION
, MAX_DIMENSION
, 64,
99 MIN_DIMENSION
, MAX_DIMENSION
, 8 },
103 .fourcc
= V4L2_PIX_FMT_NV61
,
105 .type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
,
106 .subsampling
= V4L2_JPEG_CHROMA_SUBSAMPLING_422
,
107 .chroma_order
= CHROMA_ORDER_CR_CB
,
108 .frmsize
= { MIN_DIMENSION
, MAX_DIMENSION
, 64,
109 MIN_DIMENSION
, MAX_DIMENSION
, 8 },
112 .fourcc
= V4L2_PIX_FMT_NV61M
,
114 .type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
,
115 .subsampling
= V4L2_JPEG_CHROMA_SUBSAMPLING_422
,
116 .chroma_order
= CHROMA_ORDER_CR_CB
,
117 .frmsize
= { MIN_DIMENSION
, MAX_DIMENSION
, 64,
118 MIN_DIMENSION
, MAX_DIMENSION
, 8 },
121 .fourcc
= V4L2_PIX_FMT_JPEG
,
123 .type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
,
126 .frmsize
= { MIN_DIMENSION
, MAX_DIMENSION
, 16,
127 MIN_DIMENSION
, MAX_DIMENSION
, 8 },
131 static unsigned int debug
;
132 module_param(debug
, uint
, 0644);
133 MODULE_PARM_DESC(debug
, "debug level");
135 #define dprintk(dev, lvl, fmt, arg...) \
136 v4l2_dbg(lvl, debug, &(dev)->v4l2_dev, "%s: " fmt, __func__, ## arg)
138 static const struct v4l2_event e5010_eos_event
= {
139 .type
= V4L2_EVENT_EOS
142 static const char *type_name(enum v4l2_buf_type type
)
145 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
:
147 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
:
154 static struct e5010_q_data
*get_queue(struct e5010_context
*ctx
, enum v4l2_buf_type type
)
156 return (type
== V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
) ? &ctx
->out_queue
: &ctx
->cap_queue
;
159 static void calculate_qp_tables(struct e5010_context
*ctx
)
161 long long luminosity
, contrast
;
164 quality
= 50 - ctx
->quality
;
166 luminosity
= LUMINOSITY
* quality
/ 50;
167 contrast
= CONTRAST
* quality
/ 50;
170 luminosity
*= INCREASE
;
171 contrast
*= INCREASE
;
174 for (i
= 0; i
< V4L2_JPEG_PIXELS_IN_BLOCK
; i
++) {
175 long long delta
= v4l2_jpeg_ref_table_chroma_qt
[i
] * contrast
+ luminosity
;
176 int val
= (int)(v4l2_jpeg_ref_table_chroma_qt
[i
] + delta
);
179 ctx
->chroma_qp
[i
] = quality
== -50 ? 1 : val
;
181 delta
= v4l2_jpeg_ref_table_luma_qt
[i
] * contrast
+ luminosity
;
182 val
= (int)(v4l2_jpeg_ref_table_luma_qt
[i
] + delta
);
184 ctx
->luma_qp
[i
] = quality
== -50 ? 1 : val
;
187 ctx
->update_qp
= true;
190 static int update_qp_tables(struct e5010_context
*ctx
)
192 struct e5010_dev
*e5010
= ctx
->e5010
;
199 for (i
= 0; i
< QP_TABLE_SIZE
; i
++) {
200 lvalue
|= ctx
->luma_qp
[i
] << (8 * (i
% 4));
201 cvalue
|= ctx
->chroma_qp
[i
] << (8 * (i
% 4));
203 ret
|= e5010_hw_set_qpvalue(e5010
->core_base
,
204 JASPER_LUMA_QUANTIZATION_TABLE0_OFFSET
205 + QP_TABLE_FIELD_OFFSET
* ((i
- 3) / 4),
207 ret
|= e5010_hw_set_qpvalue(e5010
->core_base
,
208 JASPER_CHROMA_QUANTIZATION_TABLE0_OFFSET
209 + QP_TABLE_FIELD_OFFSET
* ((i
- 3) / 4),
219 static int e5010_set_input_subsampling(void __iomem
*core_base
, int subsampling
)
221 switch (subsampling
) {
222 case V4L2_JPEG_CHROMA_SUBSAMPLING_420
:
223 return e5010_hw_set_input_subsampling(core_base
, SUBSAMPLING_420
);
224 case V4L2_JPEG_CHROMA_SUBSAMPLING_422
:
225 return e5010_hw_set_input_subsampling(core_base
, SUBSAMPLING_422
);
231 static int e5010_querycap(struct file
*file
, void *priv
, struct v4l2_capability
*cap
)
233 strscpy(cap
->driver
, E5010_MODULE_NAME
, sizeof(cap
->driver
));
234 strscpy(cap
->card
, E5010_MODULE_NAME
, sizeof(cap
->card
));
239 static struct e5010_fmt
*find_format(struct v4l2_format
*f
)
243 for (i
= 0; i
< ARRAY_SIZE(e5010_formats
); ++i
) {
244 if (e5010_formats
[i
].fourcc
== f
->fmt
.pix_mp
.pixelformat
&&
245 e5010_formats
[i
].type
== f
->type
)
246 return &e5010_formats
[i
];
252 static int e5010_enum_fmt(struct file
*file
, void *priv
, struct v4l2_fmtdesc
*f
)
255 struct e5010_fmt
*fmt
= NULL
;
256 struct e5010_context
*ctx
= file
->private_data
;
258 if (!V4L2_TYPE_IS_MULTIPLANAR(f
->type
)) {
259 v4l2_err(&ctx
->e5010
->v4l2_dev
, "ENUMFMT with Invalid type: %d\n", f
->type
);
263 for (i
= 0; i
< ARRAY_SIZE(e5010_formats
); ++i
) {
264 if (e5010_formats
[i
].type
== f
->type
) {
265 if (index
== f
->index
) {
266 fmt
= &e5010_formats
[i
];
276 f
->pixelformat
= fmt
->fourcc
;
280 static int e5010_g_fmt(struct file
*file
, void *priv
, struct v4l2_format
*f
)
282 struct e5010_context
*ctx
= file
->private_data
;
283 struct e5010_q_data
*queue
;
285 struct v4l2_pix_format_mplane
*pix_mp
= &f
->fmt
.pix_mp
;
286 struct v4l2_plane_pix_format
*plane_fmt
= pix_mp
->plane_fmt
;
288 queue
= get_queue(ctx
, f
->type
);
291 pix_mp
->field
= V4L2_FIELD_NONE
;
292 pix_mp
->pixelformat
= queue
->fmt
->fourcc
;
293 pix_mp
->width
= queue
->width_adjusted
;
294 pix_mp
->height
= queue
->height_adjusted
;
295 pix_mp
->num_planes
= queue
->fmt
->num_planes
;
297 if (V4L2_TYPE_IS_OUTPUT(f
->type
)) {
298 if (!pix_mp
->colorspace
)
299 pix_mp
->colorspace
= V4L2_COLORSPACE_SRGB
;
301 for (i
= 0; i
< queue
->fmt
->num_planes
; i
++) {
302 plane_fmt
[i
].sizeimage
= queue
->sizeimage
[i
];
303 plane_fmt
[i
].bytesperline
= queue
->bytesperline
[i
];
307 pix_mp
->colorspace
= V4L2_COLORSPACE_JPEG
;
308 plane_fmt
[0].bytesperline
= 0;
309 plane_fmt
[0].sizeimage
= queue
->sizeimage
[0];
311 pix_mp
->ycbcr_enc
= V4L2_YCBCR_ENC_DEFAULT
;
312 pix_mp
->xfer_func
= V4L2_XFER_FUNC_DEFAULT
;
313 pix_mp
->quantization
= V4L2_QUANTIZATION_DEFAULT
;
318 static int e5010_jpeg_try_fmt(struct v4l2_format
*f
, struct e5010_context
*ctx
)
320 struct e5010_fmt
*fmt
;
321 struct v4l2_pix_format_mplane
*pix_mp
= &f
->fmt
.pix_mp
;
322 struct v4l2_plane_pix_format
*plane_fmt
= pix_mp
->plane_fmt
;
324 fmt
= find_format(f
);
326 if (V4L2_TYPE_IS_OUTPUT(f
->type
))
327 pix_mp
->pixelformat
= V4L2_PIX_FMT_NV12
;
329 pix_mp
->pixelformat
= V4L2_PIX_FMT_JPEG
;
330 fmt
= find_format(f
);
335 if (V4L2_TYPE_IS_OUTPUT(f
->type
)) {
336 if (!pix_mp
->colorspace
)
337 pix_mp
->colorspace
= V4L2_COLORSPACE_JPEG
;
338 if (!pix_mp
->ycbcr_enc
)
339 pix_mp
->ycbcr_enc
= V4L2_YCBCR_ENC_DEFAULT
;
340 if (!pix_mp
->quantization
)
341 pix_mp
->quantization
= V4L2_QUANTIZATION_DEFAULT
;
342 if (!pix_mp
->xfer_func
)
343 pix_mp
->xfer_func
= V4L2_XFER_FUNC_DEFAULT
;
345 v4l2_apply_frmsize_constraints(&pix_mp
->width
,
349 v4l2_fill_pixfmt_mp(pix_mp
, pix_mp
->pixelformat
,
350 pix_mp
->width
, pix_mp
->height
);
353 pix_mp
->colorspace
= V4L2_COLORSPACE_JPEG
;
354 pix_mp
->ycbcr_enc
= V4L2_YCBCR_ENC_DEFAULT
;
355 pix_mp
->quantization
= V4L2_QUANTIZATION_DEFAULT
;
356 pix_mp
->xfer_func
= V4L2_XFER_FUNC_DEFAULT
;
357 v4l2_apply_frmsize_constraints(&pix_mp
->width
,
360 plane_fmt
[0].sizeimage
= pix_mp
->width
* pix_mp
->height
* JPEG_MAX_BYTES_PER_PIXEL
;
361 plane_fmt
[0].sizeimage
+= HEADER_SIZE
;
362 plane_fmt
[0].bytesperline
= 0;
363 pix_mp
->pixelformat
= fmt
->fourcc
;
364 pix_mp
->num_planes
= fmt
->num_planes
;
367 pix_mp
->field
= V4L2_FIELD_NONE
;
369 dprintk(ctx
->e5010
, 2,
370 "ctx: 0x%p: format type %s:, wxh: %dx%d (plane0 : %d bytes, plane1 : %d bytes),fmt: %c%c%c%c\n",
371 ctx
, type_name(f
->type
), pix_mp
->width
, pix_mp
->height
,
372 plane_fmt
[0].sizeimage
, plane_fmt
[1].sizeimage
,
373 (fmt
->fourcc
& 0xff),
374 (fmt
->fourcc
>> 8) & 0xff,
375 (fmt
->fourcc
>> 16) & 0xff,
376 (fmt
->fourcc
>> 24) & 0xff);
381 static int e5010_try_fmt(struct file
*file
, void *priv
, struct v4l2_format
*f
)
383 struct e5010_context
*ctx
= file
->private_data
;
385 return e5010_jpeg_try_fmt(f
, ctx
);
388 static int e5010_s_fmt(struct file
*file
, void *priv
, struct v4l2_format
*f
)
390 struct e5010_context
*ctx
= file
->private_data
;
391 struct vb2_queue
*vq
;
393 struct v4l2_pix_format_mplane
*pix_mp
= &f
->fmt
.pix_mp
;
394 struct v4l2_plane_pix_format
*plane_fmt
= pix_mp
->plane_fmt
;
395 struct e5010_q_data
*queue
;
396 struct e5010_fmt
*fmt
;
398 vq
= v4l2_m2m_get_vq(ctx
->fh
.m2m_ctx
, f
->type
);
402 if (vb2_is_busy(vq
)) {
403 v4l2_err(&ctx
->e5010
->v4l2_dev
, "queue busy\n");
407 ret
= e5010_jpeg_try_fmt(f
, ctx
);
411 fmt
= find_format(f
);
412 queue
= get_queue(ctx
, f
->type
);
415 queue
->width
= pix_mp
->width
;
416 queue
->height
= pix_mp
->height
;
418 if (V4L2_TYPE_IS_OUTPUT(f
->type
)) {
419 for (i
= 0; i
< fmt
->num_planes
; i
++) {
420 queue
->bytesperline
[i
] = plane_fmt
[i
].bytesperline
;
421 queue
->sizeimage
[i
] = plane_fmt
[i
].sizeimage
;
423 queue
->crop
.left
= 0;
425 queue
->crop
.width
= queue
->width
;
426 queue
->crop
.height
= queue
->height
;
428 queue
->sizeimage
[0] = plane_fmt
[0].sizeimage
;
429 queue
->sizeimage
[1] = 0;
430 queue
->bytesperline
[0] = 0;
431 queue
->bytesperline
[1] = 0;
437 static int e5010_enum_framesizes(struct file
*file
, void *priv
, struct v4l2_frmsizeenum
*fsize
)
439 struct v4l2_format f
;
440 struct e5010_fmt
*fmt
;
442 if (fsize
->index
!= 0)
445 f
.fmt
.pix_mp
.pixelformat
= fsize
->pixel_format
;
446 if (f
.fmt
.pix_mp
.pixelformat
== V4L2_PIX_FMT_JPEG
)
447 f
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
449 f
.type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
;
451 fmt
= find_format(&f
);
455 fsize
->type
= V4L2_FRMSIZE_TYPE_STEPWISE
;
456 fsize
->stepwise
= fmt
->frmsize
;
457 fsize
->reserved
[0] = 0;
458 fsize
->reserved
[1] = 0;
463 static int e5010_g_selection(struct file
*file
, void *fh
, struct v4l2_selection
*s
)
465 struct e5010_context
*ctx
= file
->private_data
;
466 struct e5010_q_data
*queue
;
468 if (s
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT
)
471 queue
= get_queue(ctx
, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
);
474 case V4L2_SEL_TGT_CROP_DEFAULT
:
475 case V4L2_SEL_TGT_CROP_BOUNDS
:
478 s
->r
.width
= queue
->width
;
479 s
->r
.height
= queue
->height
;
481 case V4L2_SEL_TGT_CROP
:
482 memcpy(&s
->r
, &queue
->crop
, sizeof(s
->r
));
491 static int e5010_s_selection(struct file
*file
, void *fh
, struct v4l2_selection
*s
)
493 struct e5010_context
*ctx
= file
->private_data
;
494 struct e5010_q_data
*queue
;
495 struct vb2_queue
*vq
;
496 struct v4l2_rect base_rect
;
498 vq
= v4l2_m2m_get_vq(ctx
->fh
.m2m_ctx
, s
->type
);
502 if (vb2_is_streaming(vq
))
505 if (s
->target
!= V4L2_SEL_TGT_CROP
||
506 s
->type
!= V4L2_BUF_TYPE_VIDEO_OUTPUT
)
509 queue
= get_queue(ctx
, V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
);
512 base_rect
.width
= queue
->width
;
513 base_rect
.height
= queue
->height
;
517 s
->r
.width
= round_down(s
->r
.width
, queue
->fmt
->frmsize
.step_width
);
518 s
->r
.height
= round_down(s
->r
.height
, queue
->fmt
->frmsize
.step_height
);
519 s
->r
.left
= round_down(s
->r
.left
, queue
->fmt
->frmsize
.step_width
);
520 s
->r
.top
= round_down(s
->r
.top
, 2);
522 if (s
->r
.left
+ s
->r
.width
> queue
->width
)
523 s
->r
.width
= round_down(s
->r
.width
+ s
->r
.left
- queue
->width
,
524 queue
->fmt
->frmsize
.step_width
);
525 if (s
->r
.top
+ s
->r
.height
> queue
->height
)
526 s
->r
.top
= round_down(s
->r
.top
+ s
->r
.height
- queue
->height
, 2);
528 case V4L2_SEL_FLAG_GE
:
529 s
->r
.width
= round_up(s
->r
.width
, queue
->fmt
->frmsize
.step_width
);
530 s
->r
.height
= round_up(s
->r
.height
, queue
->fmt
->frmsize
.step_height
);
531 s
->r
.left
= round_up(s
->r
.left
, queue
->fmt
->frmsize
.step_width
);
532 s
->r
.top
= round_up(s
->r
.top
, 2);
534 case V4L2_SEL_FLAG_LE
:
535 s
->r
.width
= round_down(s
->r
.width
, queue
->fmt
->frmsize
.step_width
);
536 s
->r
.height
= round_down(s
->r
.height
, queue
->fmt
->frmsize
.step_height
);
537 s
->r
.left
= round_down(s
->r
.left
, queue
->fmt
->frmsize
.step_width
);
538 s
->r
.top
= round_down(s
->r
.top
, 2);
540 case V4L2_SEL_FLAG_LE
| V4L2_SEL_FLAG_GE
:
541 if (!IS_ALIGNED(s
->r
.width
, queue
->fmt
->frmsize
.step_width
) ||
542 !IS_ALIGNED(s
->r
.height
, queue
->fmt
->frmsize
.step_height
) ||
543 !IS_ALIGNED(s
->r
.left
, queue
->fmt
->frmsize
.step_width
) ||
544 !IS_ALIGNED(s
->r
.top
, 2))
551 if (!v4l2_rect_enclosed(&s
->r
, &base_rect
))
554 memcpy(&queue
->crop
, &s
->r
, sizeof(s
->r
));
556 if (!v4l2_rect_equal(&s
->r
, &base_rect
))
557 queue
->crop_set
= true;
559 dprintk(ctx
->e5010
, 2, "ctx: 0x%p: crop rectangle: w: %d, h : %d, l : %d, t : %d\n",
560 ctx
, queue
->crop
.width
, queue
->crop
.height
, queue
->crop
.left
, queue
->crop
.top
);
565 static int e5010_subscribe_event(struct v4l2_fh
*fh
, const struct v4l2_event_subscription
*sub
)
569 return v4l2_event_subscribe(fh
, sub
, 0, NULL
);
570 case V4L2_EVENT_CTRL
:
571 return v4l2_ctrl_subscribe_event(fh
, sub
);
579 static int queue_init(void *priv
, struct vb2_queue
*src_vq
, struct vb2_queue
*dst_vq
)
581 struct e5010_context
*ctx
= priv
;
582 struct e5010_dev
*e5010
= ctx
->e5010
;
586 memset(src_vq
, 0, sizeof(*src_vq
));
587 src_vq
->type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
;
588 src_vq
->io_modes
= VB2_MMAP
| VB2_DMABUF
;
589 src_vq
->drv_priv
= ctx
;
590 src_vq
->buf_struct_size
= sizeof(struct e5010_buffer
);
591 src_vq
->ops
= &e5010_video_ops
;
592 src_vq
->mem_ops
= &vb2_dma_contig_memops
;
593 src_vq
->timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_COPY
;
594 src_vq
->lock
= &e5010
->mutex
;
595 src_vq
->dev
= e5010
->v4l2_dev
.dev
;
597 ret
= vb2_queue_init(src_vq
);
602 memset(dst_vq
, 0, sizeof(*dst_vq
));
603 dst_vq
->type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
604 dst_vq
->io_modes
= VB2_MMAP
| VB2_DMABUF
;
605 dst_vq
->drv_priv
= ctx
;
606 dst_vq
->buf_struct_size
= sizeof(struct e5010_buffer
);
607 dst_vq
->ops
= &e5010_video_ops
;
608 dst_vq
->mem_ops
= &vb2_dma_contig_memops
;
609 dst_vq
->timestamp_flags
= V4L2_BUF_FLAG_TIMESTAMP_COPY
;
610 dst_vq
->lock
= &e5010
->mutex
;
611 dst_vq
->dev
= e5010
->v4l2_dev
.dev
;
613 ret
= vb2_queue_init(dst_vq
);
615 vb2_queue_release(src_vq
);
622 static int e5010_s_ctrl(struct v4l2_ctrl
*ctrl
)
624 struct e5010_context
*ctx
=
625 container_of(ctrl
->handler
, struct e5010_context
, ctrl_handler
);
628 case V4L2_CID_JPEG_COMPRESSION_QUALITY
:
629 ctx
->quality
= ctrl
->val
;
630 calculate_qp_tables(ctx
);
631 dprintk(ctx
->e5010
, 2, "ctx: 0x%p compression quality set to : %d\n", ctx
,
641 static const struct v4l2_ctrl_ops e5010_ctrl_ops
= {
642 .s_ctrl
= e5010_s_ctrl
,
645 static void e5010_encode_ctrls(struct e5010_context
*ctx
)
647 v4l2_ctrl_new_std(&ctx
->ctrl_handler
, &e5010_ctrl_ops
,
648 V4L2_CID_JPEG_COMPRESSION_QUALITY
, 1, 100, 1, 75);
651 static int e5010_ctrls_setup(struct e5010_context
*ctx
)
655 v4l2_ctrl_handler_init(&ctx
->ctrl_handler
, 1);
657 e5010_encode_ctrls(ctx
);
659 if (ctx
->ctrl_handler
.error
) {
660 err
= ctx
->ctrl_handler
.error
;
661 v4l2_ctrl_handler_free(&ctx
->ctrl_handler
);
666 err
= v4l2_ctrl_handler_setup(&ctx
->ctrl_handler
);
668 v4l2_ctrl_handler_free(&ctx
->ctrl_handler
);
673 static void e5010_jpeg_set_default_params(struct e5010_context
*ctx
)
675 struct e5010_q_data
*queue
;
676 struct v4l2_format f
;
677 struct e5010_fmt
*fmt
;
678 struct v4l2_pix_format_mplane
*pix_mp
= &f
.fmt
.pix_mp
;
679 struct v4l2_plane_pix_format
*plane_fmt
= pix_mp
->plane_fmt
;
682 f
.type
= V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE
;
683 f
.fmt
.pix_mp
.pixelformat
= V4L2_PIX_FMT_NV12
;
684 fmt
= find_format(&f
);
685 queue
= &ctx
->out_queue
;
687 queue
->width
= DEFAULT_WIDTH
;
688 queue
->height
= DEFAULT_HEIGHT
;
689 pix_mp
->width
= queue
->width
;
690 pix_mp
->height
= queue
->height
;
691 queue
->crop
.left
= 0;
693 queue
->crop
.width
= queue
->width
;
694 queue
->crop
.height
= queue
->height
;
695 v4l2_apply_frmsize_constraints(&pix_mp
->width
,
698 v4l2_fill_pixfmt_mp(pix_mp
, pix_mp
->pixelformat
,
699 pix_mp
->width
, pix_mp
->height
);
700 for (i
= 0; i
< fmt
->num_planes
; i
++) {
701 queue
->bytesperline
[i
] = plane_fmt
[i
].bytesperline
;
702 queue
->sizeimage
[i
] = plane_fmt
[i
].sizeimage
;
704 queue
->width_adjusted
= pix_mp
->width
;
705 queue
->height_adjusted
= pix_mp
->height
;
707 f
.type
= V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
;
708 f
.fmt
.pix_mp
.pixelformat
= V4L2_PIX_FMT_JPEG
;
709 fmt
= find_format(&f
);
710 queue
= &ctx
->cap_queue
;
712 queue
->width
= DEFAULT_WIDTH
;
713 queue
->height
= DEFAULT_HEIGHT
;
714 pix_mp
->width
= queue
->width
;
715 pix_mp
->height
= queue
->height
;
716 v4l2_apply_frmsize_constraints(&pix_mp
->width
,
719 queue
->sizeimage
[0] = pix_mp
->width
* pix_mp
->height
* JPEG_MAX_BYTES_PER_PIXEL
;
720 queue
->sizeimage
[0] += HEADER_SIZE
;
721 queue
->sizeimage
[1] = 0;
722 queue
->bytesperline
[0] = 0;
723 queue
->bytesperline
[1] = 0;
724 queue
->width_adjusted
= pix_mp
->width
;
725 queue
->height_adjusted
= pix_mp
->height
;
728 static int e5010_open(struct file
*file
)
730 struct e5010_dev
*e5010
= video_drvdata(file
);
731 struct video_device
*vdev
= video_devdata(file
);
732 struct e5010_context
*ctx
;
735 ctx
= kzalloc(sizeof(*ctx
), GFP_KERNEL
);
739 if (mutex_lock_interruptible(&e5010
->mutex
)) {
744 v4l2_fh_init(&ctx
->fh
, vdev
);
745 file
->private_data
= ctx
;
746 v4l2_fh_add(&ctx
->fh
);
749 ctx
->fh
.m2m_ctx
= v4l2_m2m_ctx_init(e5010
->m2m_dev
, ctx
, queue_init
);
750 if (IS_ERR(ctx
->fh
.m2m_ctx
)) {
751 v4l2_err(&e5010
->v4l2_dev
, "failed to init m2m ctx\n");
752 ret
= PTR_ERR(ctx
->fh
.m2m_ctx
);
756 ret
= e5010_ctrls_setup(ctx
);
758 v4l2_err(&e5010
->v4l2_dev
, "failed to setup e5010 jpeg controls\n");
759 goto err_ctrls_setup
;
761 ctx
->fh
.ctrl_handler
= &ctx
->ctrl_handler
;
763 e5010_jpeg_set_default_params(ctx
);
765 dprintk(e5010
, 1, "Created instance: 0x%p, m2m_ctx: 0x%p\n", ctx
, ctx
->fh
.m2m_ctx
);
767 mutex_unlock(&e5010
->mutex
);
771 v4l2_m2m_ctx_release(ctx
->fh
.m2m_ctx
);
773 v4l2_fh_del(&ctx
->fh
);
774 v4l2_fh_exit(&ctx
->fh
);
775 mutex_unlock(&e5010
->mutex
);
781 static int e5010_release(struct file
*file
)
783 struct e5010_dev
*e5010
= video_drvdata(file
);
784 struct e5010_context
*ctx
= file
->private_data
;
786 dprintk(e5010
, 1, "Releasing instance: 0x%p, m2m_ctx: 0x%p\n", ctx
, ctx
->fh
.m2m_ctx
);
787 mutex_lock(&e5010
->mutex
);
788 v4l2_ctrl_handler_free(&ctx
->ctrl_handler
);
789 v4l2_m2m_ctx_release(ctx
->fh
.m2m_ctx
);
790 v4l2_fh_del(&ctx
->fh
);
791 v4l2_fh_exit(&ctx
->fh
);
793 mutex_unlock(&e5010
->mutex
);
798 static void header_write(struct e5010_context
*ctx
, u8
*addr
, unsigned int *offset
,
799 unsigned int no_bytes
, unsigned long bits
)
801 u8
*w_addr
= addr
+ *offset
;
804 if ((*offset
+ no_bytes
) > HEADER_SIZE
) {
805 v4l2_warn(&ctx
->e5010
->v4l2_dev
, "%s: %s: %d: Problem writing header. %d > HEADER_SIZE %d\n",
806 __FILE__
, __func__
, __LINE__
, *offset
+ no_bytes
, HEADER_SIZE
);
810 for (i
= no_bytes
- 1; i
>= 0; i
--)
811 *(w_addr
++) = ((u8
*)&bits
)[i
];
816 static void encode_marker_segment(struct e5010_context
*ctx
, void *addr
, unsigned int *offset
)
818 u8
*buffer
= (u8
*)addr
;
821 header_write(ctx
, buffer
, offset
, 2, START_OF_IMAGE
);
822 header_write(ctx
, buffer
, offset
, 2, DQT_MARKER
);
823 header_write(ctx
, buffer
, offset
, 3, LQPQ
<< 4);
824 for (i
= 0; i
< V4L2_JPEG_PIXELS_IN_BLOCK
; i
++)
825 header_write(ctx
, buffer
, offset
, 1, ctx
->luma_qp
[v4l2_jpeg_zigzag_scan_index
[i
]]);
827 header_write(ctx
, buffer
, offset
, 2, DQT_MARKER
);
828 header_write(ctx
, buffer
, offset
, 3, (LQPQ
<< 4) | 1);
829 for (i
= 0; i
< V4L2_JPEG_PIXELS_IN_BLOCK
; i
++)
830 header_write(ctx
, buffer
, offset
, 1,
831 ctx
->chroma_qp
[v4l2_jpeg_zigzag_scan_index
[i
]]);
834 header_write(ctx
, buffer
, offset
, 2, DHT_MARKER
);
835 header_write(ctx
, buffer
, offset
, 2, LH_DC
);
836 header_write(ctx
, buffer
, offset
, 1, V4L2_JPEG_LUM_HT
| V4L2_JPEG_DC_HT
);
837 for (i
= 0 ; i
< V4L2_JPEG_REF_HT_DC_LEN
; i
++)
838 header_write(ctx
, buffer
, offset
, 1, v4l2_jpeg_ref_table_luma_dc_ht
[i
]);
840 header_write(ctx
, buffer
, offset
, 2, DHT_MARKER
);
841 header_write(ctx
, buffer
, offset
, 2, LH_AC
);
842 header_write(ctx
, buffer
, offset
, 1, V4L2_JPEG_LUM_HT
| V4L2_JPEG_AC_HT
);
843 for (i
= 0 ; i
< V4L2_JPEG_REF_HT_AC_LEN
; i
++)
844 header_write(ctx
, buffer
, offset
, 1, v4l2_jpeg_ref_table_luma_ac_ht
[i
]);
846 header_write(ctx
, buffer
, offset
, 2, DHT_MARKER
);
847 header_write(ctx
, buffer
, offset
, 2, LH_DC
);
848 header_write(ctx
, buffer
, offset
, 1, V4L2_JPEG_CHR_HT
| V4L2_JPEG_DC_HT
);
849 for (i
= 0 ; i
< V4L2_JPEG_REF_HT_DC_LEN
; i
++)
850 header_write(ctx
, buffer
, offset
, 1, v4l2_jpeg_ref_table_chroma_dc_ht
[i
]);
852 header_write(ctx
, buffer
, offset
, 2, DHT_MARKER
);
853 header_write(ctx
, buffer
, offset
, 2, LH_AC
);
854 header_write(ctx
, buffer
, offset
, 1, V4L2_JPEG_CHR_HT
| V4L2_JPEG_AC_HT
);
855 for (i
= 0 ; i
< V4L2_JPEG_REF_HT_AC_LEN
; i
++)
856 header_write(ctx
, buffer
, offset
, 1, v4l2_jpeg_ref_table_chroma_ac_ht
[i
]);
859 static void encode_frame_header(struct e5010_context
*ctx
, void *addr
, unsigned int *offset
)
861 u8
*buffer
= (u8
*)addr
;
863 header_write(ctx
, buffer
, offset
, 2, SOF_BASELINE_DCT
);
864 header_write(ctx
, buffer
, offset
, 2, 8 + (3 * UC_NUM_COMP
));
865 header_write(ctx
, buffer
, offset
, 1, PRECISION
);
866 header_write(ctx
, buffer
, offset
, 2, ctx
->out_queue
.crop
.height
);
867 header_write(ctx
, buffer
, offset
, 2, ctx
->out_queue
.crop
.width
);
868 header_write(ctx
, buffer
, offset
, 1, UC_NUM_COMP
);
871 header_write(ctx
, buffer
, offset
, 1, 1);
872 if (ctx
->out_queue
.fmt
->subsampling
== V4L2_JPEG_CHROMA_SUBSAMPLING_422
)
873 header_write(ctx
, buffer
, offset
, 1,
874 HORZ_SAMPLING_FACTOR
| (VERT_SAMPLING_FACTOR_422
));
876 header_write(ctx
, buffer
, offset
, 1,
877 HORZ_SAMPLING_FACTOR
| (VERT_SAMPLING_FACTOR_420
));
878 header_write(ctx
, buffer
, offset
, 1, 0);
880 header_write(ctx
, buffer
, offset
, 1, 2);
881 header_write(ctx
, buffer
, offset
, 1, (HORZ_SAMPLING_FACTOR
>> 1) | 1);
882 header_write(ctx
, buffer
, offset
, 1, 1);
883 header_write(ctx
, buffer
, offset
, 1, 3);
884 header_write(ctx
, buffer
, offset
, 1, (HORZ_SAMPLING_FACTOR
>> 1) | 1);
885 header_write(ctx
, buffer
, offset
, 1, 1);
888 static void jpg_encode_sos_header(struct e5010_context
*ctx
, void *addr
, unsigned int *offset
)
890 u8
*buffer
= (u8
*)addr
;
893 header_write(ctx
, buffer
, offset
, 2, START_OF_SCAN
);
894 header_write(ctx
, buffer
, offset
, 2, 6 + (COMPONENTS_IN_SCAN
<< 1));
895 header_write(ctx
, buffer
, offset
, 1, COMPONENTS_IN_SCAN
);
897 for (i
= 0; i
< COMPONENTS_IN_SCAN
; i
++) {
898 header_write(ctx
, buffer
, offset
, 1, i
+ 1);
900 header_write(ctx
, buffer
, offset
, 1, 0);
902 header_write(ctx
, buffer
, offset
, 1, 17);
905 header_write(ctx
, buffer
, offset
, 1, 0);
906 header_write(ctx
, buffer
, offset
, 1, 63);
907 header_write(ctx
, buffer
, offset
, 1, 0);
910 static void write_header(struct e5010_context
*ctx
, void *addr
)
912 unsigned int offset
= 0;
914 encode_marker_segment(ctx
, addr
, &offset
);
915 encode_frame_header(ctx
, addr
, &offset
);
916 jpg_encode_sos_header(ctx
, addr
, &offset
);
919 static irqreturn_t
e5010_irq(int irq
, void *data
)
921 struct e5010_dev
*e5010
= data
;
922 struct e5010_context
*ctx
;
924 struct vb2_v4l2_buffer
*src_buf
, *dst_buf
;
925 bool pic_done
, out_addr_err
;
927 spin_lock(&e5010
->hw_lock
);
928 pic_done
= e5010_hw_pic_done_irq(e5010
->core_base
);
929 out_addr_err
= e5010_hw_output_address_irq(e5010
->core_base
);
931 if (!pic_done
&& !out_addr_err
) {
932 spin_unlock(&e5010
->hw_lock
);
936 ctx
= v4l2_m2m_get_curr_priv(e5010
->m2m_dev
);
940 dst_buf
= v4l2_m2m_dst_buf_remove(ctx
->fh
.m2m_ctx
);
941 src_buf
= v4l2_m2m_src_buf_remove(ctx
->fh
.m2m_ctx
);
942 if (!dst_buf
|| !src_buf
) {
943 v4l2_err(&e5010
->v4l2_dev
, "ctx: 0x%p No source or destination buffer\n", ctx
);
948 e5010_hw_clear_output_error(e5010
->core_base
, 1);
949 v4l2_warn(&e5010
->v4l2_dev
,
950 "ctx: 0x%p Output bitstream size exceeded max size\n", ctx
);
951 v4l2_m2m_buf_done(src_buf
, VB2_BUF_STATE_ERROR
);
952 vb2_set_plane_payload(&dst_buf
->vb2_buf
, 0, dst_buf
->planes
[0].length
);
953 v4l2_m2m_buf_done(dst_buf
, VB2_BUF_STATE_ERROR
);
954 if (v4l2_m2m_is_last_draining_src_buf(ctx
->fh
.m2m_ctx
, src_buf
)) {
955 dst_buf
->flags
|= V4L2_BUF_FLAG_LAST
;
956 v4l2_m2m_mark_stopped(ctx
->fh
.m2m_ctx
);
957 v4l2_event_queue_fh(&ctx
->fh
, &e5010_eos_event
);
958 dprintk(e5010
, 2, "ctx: 0x%p Sending EOS\n", ctx
);
963 e5010_hw_clear_picture_done(e5010
->core_base
, 1);
964 dprintk(e5010
, 3, "ctx: 0x%p Got output bitstream of size %d bytes\n",
965 ctx
, readl(e5010
->core_base
+ JASPER_OUTPUT_SIZE_OFFSET
));
967 if (v4l2_m2m_is_last_draining_src_buf(ctx
->fh
.m2m_ctx
, src_buf
)) {
968 dst_buf
->flags
|= V4L2_BUF_FLAG_LAST
;
969 v4l2_m2m_mark_stopped(ctx
->fh
.m2m_ctx
);
970 v4l2_event_queue_fh(&ctx
->fh
, &e5010_eos_event
);
971 dprintk(e5010
, 2, "ctx: 0x%p Sending EOS\n", ctx
);
973 v4l2_m2m_buf_done(src_buf
, VB2_BUF_STATE_DONE
);
974 output_size
= e5010_hw_get_output_size(e5010
->core_base
);
975 vb2_set_plane_payload(&dst_buf
->vb2_buf
, 0, output_size
+ HEADER_SIZE
);
976 v4l2_m2m_buf_done(dst_buf
, VB2_BUF_STATE_DONE
);
978 "ctx: 0x%p frame done for dst_buf->sequence: %d src_buf->sequence: %d\n",
979 ctx
, dst_buf
->sequence
, src_buf
->sequence
);
982 v4l2_m2m_job_finish(e5010
->m2m_dev
, ctx
->fh
.m2m_ctx
);
983 dprintk(e5010
, 3, "ctx: 0x%p Finish job\n", ctx
);
986 spin_unlock(&e5010
->hw_lock
);
990 static int e5010_init_device(struct e5010_dev
*e5010
)
994 /*TODO: Set MMU in bypass mode until support for the same is added in driver*/
995 e5010_hw_bypass_mmu(e5010
->mmu_base
, 1);
997 if (e5010_hw_enable_auto_clock_gating(e5010
->core_base
, 1))
998 v4l2_warn(&e5010
->v4l2_dev
, "failed to enable auto clock gating\n");
1000 if (e5010_hw_enable_manual_clock_gating(e5010
->core_base
, 0))
1001 v4l2_warn(&e5010
->v4l2_dev
, "failed to disable manual clock gating\n");
1003 if (e5010_hw_enable_crc_check(e5010
->core_base
, 0))
1004 v4l2_warn(&e5010
->v4l2_dev
, "failed to disable CRC check\n");
1006 if (e5010_hw_enable_output_address_error_irq(e5010
->core_base
, 1))
1007 v4l2_err(&e5010
->v4l2_dev
, "failed to enable Output Address Error interrupts\n");
1009 ret
= e5010_hw_set_input_source_to_memory(e5010
->core_base
, 1);
1011 v4l2_err(&e5010
->v4l2_dev
, "failed to set input source to memory\n");
1015 ret
= e5010_hw_enable_picture_done_irq(e5010
->core_base
, 1);
1017 v4l2_err(&e5010
->v4l2_dev
, "failed to enable Picture Done interrupts\n");
1022 static int e5010_probe(struct platform_device
*pdev
)
1024 struct e5010_dev
*e5010
;
1026 struct device
*dev
= &pdev
->dev
;
1028 ret
= dma_set_mask(dev
, DMA_BIT_MASK(32));
1030 return dev_err_probe(dev
, ret
, "32-bit consistent DMA enable failed\n");
1032 e5010
= devm_kzalloc(dev
, sizeof(*e5010
), GFP_KERNEL
);
1036 platform_set_drvdata(pdev
, e5010
);
1040 mutex_init(&e5010
->mutex
);
1041 spin_lock_init(&e5010
->hw_lock
);
1043 e5010
->vdev
= video_device_alloc();
1045 dev_err(dev
, "failed to allocate video device\n");
1049 snprintf(e5010
->vdev
->name
, sizeof(e5010
->vdev
->name
), "%s", E5010_MODULE_NAME
);
1050 e5010
->vdev
->fops
= &e5010_fops
;
1051 e5010
->vdev
->ioctl_ops
= &e5010_ioctl_ops
;
1052 e5010
->vdev
->minor
= -1;
1053 e5010
->vdev
->release
= video_device_release
;
1054 e5010
->vdev
->vfl_dir
= VFL_DIR_M2M
;
1055 e5010
->vdev
->device_caps
= V4L2_CAP_VIDEO_M2M_MPLANE
| V4L2_CAP_STREAMING
;
1056 e5010
->vdev
->v4l2_dev
= &e5010
->v4l2_dev
;
1057 e5010
->vdev
->lock
= &e5010
->mutex
;
1059 ret
= v4l2_device_register(dev
, &e5010
->v4l2_dev
);
1061 return dev_err_probe(dev
, ret
, "failed to register v4l2 device\n");
1063 e5010
->m2m_dev
= v4l2_m2m_init(&e5010_m2m_ops
);
1064 if (IS_ERR(e5010
->m2m_dev
)) {
1065 ret
= PTR_ERR(e5010
->m2m_dev
);
1066 e5010
->m2m_dev
= NULL
;
1067 dev_err_probe(dev
, ret
, "failed to init mem2mem device\n");
1068 goto fail_after_v4l2_register
;
1071 video_set_drvdata(e5010
->vdev
, e5010
);
1073 e5010
->core_base
= devm_platform_ioremap_resource_byname(pdev
, "core");
1074 if (IS_ERR(e5010
->core_base
)) {
1075 ret
= PTR_ERR(e5010
->core_base
);
1076 dev_err_probe(dev
, ret
, "Missing 'core' resources area\n");
1077 goto fail_after_v4l2_register
;
1080 e5010
->mmu_base
= devm_platform_ioremap_resource_byname(pdev
, "mmu");
1081 if (IS_ERR(e5010
->mmu_base
)) {
1082 ret
= PTR_ERR(e5010
->mmu_base
);
1083 dev_err_probe(dev
, ret
, "Missing 'mmu' resources area\n");
1084 goto fail_after_v4l2_register
;
1087 e5010
->last_context_run
= NULL
;
1089 irq
= platform_get_irq(pdev
, 0);
1090 ret
= devm_request_irq(dev
, irq
, e5010_irq
, 0,
1091 E5010_MODULE_NAME
, e5010
);
1093 dev_err_probe(dev
, ret
, "failed to register IRQ %d\n", irq
);
1094 goto fail_after_v4l2_register
;
1097 e5010
->clk
= devm_clk_get(dev
, NULL
);
1098 if (IS_ERR(e5010
->clk
)) {
1099 ret
= PTR_ERR(e5010
->clk
);
1100 dev_err_probe(dev
, ret
, "failed to get clock\n");
1101 goto fail_after_v4l2_register
;
1104 pm_runtime_enable(dev
);
1106 ret
= video_register_device(e5010
->vdev
, VFL_TYPE_VIDEO
, 0);
1108 dev_err_probe(dev
, ret
, "failed to register video device\n");
1109 goto fail_after_video_register_device
;
1112 v4l2_info(&e5010
->v4l2_dev
, "Device registered as /dev/video%d\n",
1117 fail_after_video_register_device
:
1118 v4l2_m2m_release(e5010
->m2m_dev
);
1119 fail_after_v4l2_register
:
1120 v4l2_device_unregister(&e5010
->v4l2_dev
);
1124 static void e5010_remove(struct platform_device
*pdev
)
1126 struct e5010_dev
*e5010
= platform_get_drvdata(pdev
);
1128 pm_runtime_disable(e5010
->dev
);
1129 video_unregister_device(e5010
->vdev
);
1130 v4l2_m2m_release(e5010
->m2m_dev
);
1131 v4l2_device_unregister(&e5010
->v4l2_dev
);
1134 static void e5010_vb2_buffers_return(struct vb2_queue
*q
, enum vb2_buffer_state state
)
1136 struct vb2_v4l2_buffer
*vbuf
;
1137 struct e5010_context
*ctx
= vb2_get_drv_priv(q
);
1139 if (V4L2_TYPE_IS_OUTPUT(q
->type
)) {
1140 while ((vbuf
= v4l2_m2m_src_buf_remove(ctx
->fh
.m2m_ctx
))) {
1141 dprintk(ctx
->e5010
, 2, "ctx: 0x%p, buf type %s | index %d\n",
1142 ctx
, type_name(vbuf
->vb2_buf
.type
), vbuf
->vb2_buf
.index
);
1143 v4l2_m2m_buf_done(vbuf
, state
);
1146 while ((vbuf
= v4l2_m2m_dst_buf_remove(ctx
->fh
.m2m_ctx
))) {
1147 dprintk(ctx
->e5010
, 2, "ctx: 0x%p, buf type %s | index %d\n",
1148 ctx
, type_name(vbuf
->vb2_buf
.type
), vbuf
->vb2_buf
.index
);
1149 vb2_set_plane_payload(&vbuf
->vb2_buf
, 0, 0);
1150 v4l2_m2m_buf_done(vbuf
, state
);
1155 static int e5010_queue_setup(struct vb2_queue
*vq
, unsigned int *nbuffers
, unsigned int *nplanes
,
1156 unsigned int sizes
[], struct device
*alloc_devs
[])
1158 struct e5010_context
*ctx
= vb2_get_drv_priv(vq
);
1159 struct e5010_q_data
*queue
;
1162 queue
= get_queue(ctx
, vq
->type
);
1165 if (*nplanes
!= queue
->fmt
->num_planes
)
1167 for (i
= 0; i
< *nplanes
; i
++) {
1168 if (sizes
[i
] < queue
->sizeimage
[i
])
1174 *nplanes
= queue
->fmt
->num_planes
;
1175 for (i
= 0; i
< *nplanes
; i
++)
1176 sizes
[i
] = queue
->sizeimage
[i
];
1178 dprintk(ctx
->e5010
, 2,
1179 "ctx: 0x%p, type %s, buffer(s): %d, planes %d, plane1: bytes %d plane2: %d bytes\n",
1180 ctx
, type_name(vq
->type
), *nbuffers
, *nplanes
, sizes
[0], sizes
[1]);
1185 static void e5010_buf_finish(struct vb2_buffer
*vb
)
1187 struct e5010_context
*ctx
= vb2_get_drv_priv(vb
->vb2_queue
);
1190 if (vb
->state
!= VB2_BUF_STATE_DONE
|| V4L2_TYPE_IS_OUTPUT(vb
->vb2_queue
->type
))
1193 d_addr
= vb2_plane_vaddr(vb
, 0);
1194 write_header(ctx
, d_addr
);
1197 static int e5010_buf_out_validate(struct vb2_buffer
*vb
)
1199 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
1200 struct e5010_context
*ctx
= vb2_get_drv_priv(vb
->vb2_queue
);
1202 if (vbuf
->field
!= V4L2_FIELD_NONE
)
1203 dprintk(ctx
->e5010
, 1, "ctx: 0x%p, field isn't supported\n", ctx
);
1205 vbuf
->field
= V4L2_FIELD_NONE
;
1210 static int e5010_buf_prepare(struct vb2_buffer
*vb
)
1212 struct e5010_context
*ctx
= vb2_get_drv_priv(vb
->vb2_queue
);
1213 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
1214 struct e5010_q_data
*queue
;
1217 vbuf
->field
= V4L2_FIELD_NONE
;
1219 queue
= get_queue(ctx
, vb
->vb2_queue
->type
);
1221 for (i
= 0; i
< queue
->fmt
->num_planes
; i
++) {
1222 if (vb2_plane_size(vb
, i
) < (unsigned long)queue
->sizeimage
[i
]) {
1223 v4l2_err(&ctx
->e5010
->v4l2_dev
, "plane %d too small (%lu < %lu)", i
,
1224 vb2_plane_size(vb
, i
), (unsigned long)queue
->sizeimage
[i
]);
1230 if (V4L2_TYPE_IS_CAPTURE(vb
->vb2_queue
->type
)) {
1231 vb2_set_plane_payload(vb
, 0, 0);
1232 vb2_set_plane_payload(vb
, 1, 0);
1238 static void e5010_buf_queue(struct vb2_buffer
*vb
)
1240 struct e5010_context
*ctx
= vb2_get_drv_priv(vb
->vb2_queue
);
1241 struct vb2_v4l2_buffer
*vbuf
= to_vb2_v4l2_buffer(vb
);
1243 if (V4L2_TYPE_IS_CAPTURE(vb
->vb2_queue
->type
) &&
1244 vb2_is_streaming(vb
->vb2_queue
) &&
1245 v4l2_m2m_dst_buf_is_last(ctx
->fh
.m2m_ctx
)) {
1246 struct e5010_q_data
*queue
= get_queue(ctx
, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
);
1248 vbuf
->sequence
= queue
->sequence
++;
1249 v4l2_m2m_last_buffer_done(ctx
->fh
.m2m_ctx
, vbuf
);
1250 v4l2_event_queue_fh(&ctx
->fh
, &e5010_eos_event
);
1254 v4l2_m2m_buf_queue(ctx
->fh
.m2m_ctx
, vbuf
);
1257 static int e5010_encoder_cmd(struct file
*file
, void *priv
,
1258 struct v4l2_encoder_cmd
*cmd
)
1260 struct e5010_context
*ctx
= file
->private_data
;
1262 struct vb2_queue
*cap_vq
;
1264 cap_vq
= v4l2_m2m_get_vq(ctx
->fh
.m2m_ctx
, V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE
);
1266 ret
= v4l2_m2m_ioctl_try_encoder_cmd(file
, &ctx
->fh
, cmd
);
1270 if (!vb2_is_streaming(v4l2_m2m_get_src_vq(ctx
->fh
.m2m_ctx
)) ||
1271 !vb2_is_streaming(v4l2_m2m_get_dst_vq(ctx
->fh
.m2m_ctx
)))
1274 ret
= v4l2_m2m_ioctl_encoder_cmd(file
, &ctx
->fh
, cmd
);
1278 if (cmd
->cmd
== V4L2_ENC_CMD_STOP
&&
1279 v4l2_m2m_has_stopped(ctx
->fh
.m2m_ctx
))
1280 v4l2_event_queue_fh(&ctx
->fh
, &e5010_eos_event
);
1282 if (cmd
->cmd
== V4L2_ENC_CMD_START
&&
1283 v4l2_m2m_has_stopped(ctx
->fh
.m2m_ctx
))
1284 vb2_clear_last_buffer_dequeued(cap_vq
);
1289 static int e5010_start_streaming(struct vb2_queue
*q
, unsigned int count
)
1291 struct e5010_context
*ctx
= vb2_get_drv_priv(q
);
1294 struct e5010_q_data
*queue
= get_queue(ctx
, q
->type
);
1296 v4l2_m2m_update_start_streaming_state(ctx
->fh
.m2m_ctx
, q
);
1297 queue
->sequence
= 0;
1299 ret
= pm_runtime_resume_and_get(ctx
->e5010
->dev
);
1301 v4l2_err(&ctx
->e5010
->v4l2_dev
, "failed to power up jpeg\n");
1305 ret
= e5010_init_device(ctx
->e5010
);
1307 v4l2_err(&ctx
->e5010
->v4l2_dev
, "failed to Enable e5010 device\n");
1314 e5010_vb2_buffers_return(q
, VB2_BUF_STATE_QUEUED
);
1319 static void e5010_stop_streaming(struct vb2_queue
*q
)
1321 struct e5010_context
*ctx
= vb2_get_drv_priv(q
);
1323 e5010_vb2_buffers_return(q
, VB2_BUF_STATE_ERROR
);
1325 if (V4L2_TYPE_IS_OUTPUT(q
->type
))
1326 v4l2_m2m_update_stop_streaming_state(ctx
->fh
.m2m_ctx
, q
);
1328 if (V4L2_TYPE_IS_OUTPUT(q
->type
) &&
1329 v4l2_m2m_has_stopped(ctx
->fh
.m2m_ctx
)) {
1330 v4l2_event_queue_fh(&ctx
->fh
, &e5010_eos_event
);
1333 pm_runtime_put_sync(ctx
->e5010
->dev
);
1336 static void e5010_device_run(void *priv
)
1338 struct e5010_context
*ctx
= priv
;
1339 struct e5010_dev
*e5010
= ctx
->e5010
;
1340 struct vb2_v4l2_buffer
*s_vb
, *d_vb
;
1342 int ret
= 0, luma_crop_offset
= 0, chroma_crop_offset
= 0;
1343 unsigned long flags
;
1344 int num_planes
= ctx
->out_queue
.fmt
->num_planes
;
1346 spin_lock_irqsave(&e5010
->hw_lock
, flags
);
1347 s_vb
= v4l2_m2m_next_src_buf(ctx
->fh
.m2m_ctx
);
1349 d_vb
= v4l2_m2m_next_dst_buf(ctx
->fh
.m2m_ctx
);
1352 goto no_ready_buf_err
;
1354 s_vb
->sequence
= ctx
->out_queue
.sequence
++;
1355 d_vb
->sequence
= ctx
->cap_queue
.sequence
++;
1357 v4l2_m2m_buf_copy_metadata(s_vb
, d_vb
, false);
1359 if (ctx
!= e5010
->last_context_run
|| ctx
->update_qp
) {
1360 dprintk(e5010
, 1, "ctx updated: 0x%p -> 0x%p, updating qp tables\n",
1361 e5010
->last_context_run
, ctx
);
1362 ret
= update_qp_tables(ctx
);
1366 ctx
->update_qp
= true;
1367 v4l2_err(&e5010
->v4l2_dev
, "failed to update QP tables\n");
1368 goto device_busy_err
;
1370 e5010
->last_context_run
= ctx
;
1371 ctx
->update_qp
= false;
1374 /* Set I/O Buffer addresses */
1375 reg
= (u32
)vb2_dma_contig_plane_dma_addr(&s_vb
->vb2_buf
, 0);
1377 if (ctx
->out_queue
.crop_set
) {
1378 luma_crop_offset
= ctx
->out_queue
.bytesperline
[0] * ctx
->out_queue
.crop
.top
+
1379 ctx
->out_queue
.crop
.left
;
1381 if (ctx
->out_queue
.fmt
->subsampling
== V4L2_JPEG_CHROMA_SUBSAMPLING_422
) {
1382 chroma_crop_offset
=
1383 ctx
->out_queue
.bytesperline
[0] * ctx
->out_queue
.crop
.top
1384 + ctx
->out_queue
.crop
.left
;
1386 chroma_crop_offset
=
1387 ctx
->out_queue
.bytesperline
[0] * ctx
->out_queue
.crop
.top
/ 2
1388 + ctx
->out_queue
.crop
.left
;
1391 dprintk(e5010
, 1, "Luma crop offset : %x, chroma crop offset : %x\n",
1392 luma_crop_offset
, chroma_crop_offset
);
1395 ret
= e5010_hw_set_input_luma_addr(e5010
->core_base
, reg
+ luma_crop_offset
);
1397 v4l2_err(&e5010
->v4l2_dev
, "failed to set input luma address\n");
1398 goto device_busy_err
;
1401 if (num_planes
== 1)
1402 reg
+= (ctx
->out_queue
.bytesperline
[0]) * (ctx
->out_queue
.height
);
1404 reg
= (u32
)vb2_dma_contig_plane_dma_addr(&s_vb
->vb2_buf
, 1);
1407 "ctx: 0x%p, luma_addr: 0x%x, chroma_addr: 0x%x, out_addr: 0x%x\n",
1408 ctx
, (u32
)vb2_dma_contig_plane_dma_addr(&s_vb
->vb2_buf
, 0) + luma_crop_offset
,
1409 reg
+ chroma_crop_offset
, (u32
)vb2_dma_contig_plane_dma_addr(&d_vb
->vb2_buf
, 0));
1412 "ctx: 0x%p, buf indices: src_index: %d, dst_index: %d\n",
1413 ctx
, s_vb
->vb2_buf
.index
, d_vb
->vb2_buf
.index
);
1415 ret
= e5010_hw_set_input_chroma_addr(e5010
->core_base
, reg
+ chroma_crop_offset
);
1417 v4l2_err(&e5010
->v4l2_dev
, "failed to set input chroma address\n");
1418 goto device_busy_err
;
1421 reg
= (u32
)vb2_dma_contig_plane_dma_addr(&d_vb
->vb2_buf
, 0);
1423 ret
= e5010_hw_set_output_base_addr(e5010
->core_base
, reg
);
1425 v4l2_err(&e5010
->v4l2_dev
, "failed to set output base address\n");
1426 goto device_busy_err
;
1429 /* Set input settings */
1430 ret
= e5010_hw_set_horizontal_size(e5010
->core_base
, ctx
->out_queue
.crop
.width
- 1);
1432 v4l2_err(&e5010
->v4l2_dev
, "failed to set input width\n");
1433 goto device_busy_err
;
1436 ret
= e5010_hw_set_vertical_size(e5010
->core_base
, ctx
->out_queue
.crop
.height
- 1);
1438 v4l2_err(&e5010
->v4l2_dev
, "failed to set input width\n");
1439 goto device_busy_err
;
1442 ret
= e5010_hw_set_luma_stride(e5010
->core_base
, ctx
->out_queue
.bytesperline
[0]);
1444 v4l2_err(&e5010
->v4l2_dev
, "failed to set luma stride\n");
1445 goto device_busy_err
;
1448 ret
= e5010_hw_set_chroma_stride(e5010
->core_base
, ctx
->out_queue
.bytesperline
[0]);
1450 v4l2_err(&e5010
->v4l2_dev
, "failed to set chroma stride\n");
1451 goto device_busy_err
;
1454 ret
= e5010_set_input_subsampling(e5010
->core_base
, ctx
->out_queue
.fmt
->subsampling
);
1456 v4l2_err(&e5010
->v4l2_dev
, "failed to set input subsampling\n");
1457 goto device_busy_err
;
1460 ret
= e5010_hw_set_chroma_order(e5010
->core_base
, ctx
->out_queue
.fmt
->chroma_order
);
1462 v4l2_err(&e5010
->v4l2_dev
, "failed to set chroma order\n");
1463 goto device_busy_err
;
1466 e5010_hw_set_output_max_size(e5010
->core_base
, d_vb
->planes
[0].length
);
1467 e5010_hw_encode_start(e5010
->core_base
, 1);
1469 spin_unlock_irqrestore(&e5010
->hw_lock
, flags
);
1474 e5010_reset(e5010
->dev
, e5010
->core_base
, e5010
->mmu_base
);
1478 v4l2_m2m_src_buf_remove_by_buf(ctx
->fh
.m2m_ctx
, s_vb
);
1479 v4l2_m2m_buf_done(s_vb
, VB2_BUF_STATE_ERROR
);
1483 v4l2_m2m_dst_buf_remove_by_buf(ctx
->fh
.m2m_ctx
, d_vb
);
1484 /* Payload set to 1 since 0 payload can trigger EOS */
1485 vb2_set_plane_payload(&d_vb
->vb2_buf
, 0, 1);
1486 v4l2_m2m_buf_done(d_vb
, VB2_BUF_STATE_ERROR
);
1488 v4l2_m2m_job_finish(e5010
->m2m_dev
, ctx
->fh
.m2m_ctx
);
1489 spin_unlock_irqrestore(&e5010
->hw_lock
, flags
);
1493 static int e5010_runtime_resume(struct device
*dev
)
1495 struct e5010_dev
*e5010
= dev_get_drvdata(dev
);
1498 ret
= clk_prepare_enable(e5010
->clk
);
1500 v4l2_err(&e5010
->v4l2_dev
, "failed to enable clock\n");
1507 static int e5010_runtime_suspend(struct device
*dev
)
1509 struct e5010_dev
*e5010
= dev_get_drvdata(dev
);
1511 clk_disable_unprepare(e5010
->clk
);
1517 #ifdef CONFIG_PM_SLEEP
1518 static int e5010_suspend(struct device
*dev
)
1520 struct e5010_dev
*e5010
= dev_get_drvdata(dev
);
1522 v4l2_m2m_suspend(e5010
->m2m_dev
);
1524 return pm_runtime_force_suspend(dev
);
1527 static int e5010_resume(struct device
*dev
)
1529 struct e5010_dev
*e5010
= dev_get_drvdata(dev
);
1532 ret
= pm_runtime_force_resume(dev
);
1536 ret
= e5010_init_device(e5010
);
1538 dev_err(dev
, "Failed to re-enable e5010 device\n");
1542 v4l2_m2m_resume(e5010
->m2m_dev
);
1548 static const struct dev_pm_ops e5010_pm_ops
= {
1549 SET_RUNTIME_PM_OPS(e5010_runtime_suspend
,
1550 e5010_runtime_resume
, NULL
)
1551 SET_SYSTEM_SLEEP_PM_OPS(e5010_suspend
, e5010_resume
)
1554 static const struct v4l2_ioctl_ops e5010_ioctl_ops
= {
1555 .vidioc_querycap
= e5010_querycap
,
1557 .vidioc_enum_fmt_vid_cap
= e5010_enum_fmt
,
1558 .vidioc_g_fmt_vid_cap_mplane
= e5010_g_fmt
,
1559 .vidioc_try_fmt_vid_cap_mplane
= e5010_try_fmt
,
1560 .vidioc_s_fmt_vid_cap_mplane
= e5010_s_fmt
,
1562 .vidioc_enum_fmt_vid_out
= e5010_enum_fmt
,
1563 .vidioc_g_fmt_vid_out_mplane
= e5010_g_fmt
,
1564 .vidioc_try_fmt_vid_out_mplane
= e5010_try_fmt
,
1565 .vidioc_s_fmt_vid_out_mplane
= e5010_s_fmt
,
1567 .vidioc_g_selection
= e5010_g_selection
,
1568 .vidioc_s_selection
= e5010_s_selection
,
1570 .vidioc_reqbufs
= v4l2_m2m_ioctl_reqbufs
,
1571 .vidioc_querybuf
= v4l2_m2m_ioctl_querybuf
,
1572 .vidioc_qbuf
= v4l2_m2m_ioctl_qbuf
,
1573 .vidioc_dqbuf
= v4l2_m2m_ioctl_dqbuf
,
1574 .vidioc_expbuf
= v4l2_m2m_ioctl_expbuf
,
1575 .vidioc_create_bufs
= v4l2_m2m_ioctl_create_bufs
,
1576 .vidioc_prepare_buf
= v4l2_m2m_ioctl_prepare_buf
,
1578 .vidioc_streamon
= v4l2_m2m_ioctl_streamon
,
1579 .vidioc_streamoff
= v4l2_m2m_ioctl_streamoff
,
1580 .vidioc_log_status
= v4l2_ctrl_log_status
,
1582 .vidioc_subscribe_event
= e5010_subscribe_event
,
1583 .vidioc_unsubscribe_event
= v4l2_event_unsubscribe
,
1584 .vidioc_try_encoder_cmd
= v4l2_m2m_ioctl_try_encoder_cmd
,
1585 .vidioc_encoder_cmd
= e5010_encoder_cmd
,
1587 .vidioc_enum_framesizes
= e5010_enum_framesizes
,
1590 static const struct vb2_ops e5010_video_ops
= {
1591 .queue_setup
= e5010_queue_setup
,
1592 .buf_queue
= e5010_buf_queue
,
1593 .buf_finish
= e5010_buf_finish
,
1594 .buf_prepare
= e5010_buf_prepare
,
1595 .buf_out_validate
= e5010_buf_out_validate
,
1596 .start_streaming
= e5010_start_streaming
,
1597 .stop_streaming
= e5010_stop_streaming
,
1600 static const struct v4l2_file_operations e5010_fops
= {
1601 .owner
= THIS_MODULE
,
1603 .release
= e5010_release
,
1604 .poll
= v4l2_m2m_fop_poll
,
1605 .unlocked_ioctl
= video_ioctl2
,
1606 .mmap
= v4l2_m2m_fop_mmap
,
1609 static const struct v4l2_m2m_ops e5010_m2m_ops
= {
1610 .device_run
= e5010_device_run
,
1613 static const struct of_device_id e5010_of_match
[] = {
1614 {.compatible
= "img,e5010-jpeg-enc"}, { /* end */},
1616 MODULE_DEVICE_TABLE(of
, e5010_of_match
);
1618 static struct platform_driver e5010_driver
= {
1619 .probe
= e5010_probe
,
1620 .remove
= e5010_remove
,
1622 .name
= E5010_MODULE_NAME
,
1623 .of_match_table
= e5010_of_match
,
1624 .pm
= &e5010_pm_ops
,
1627 module_platform_driver(e5010_driver
);
1629 MODULE_LICENSE("GPL");
1630 MODULE_DESCRIPTION("Imagination E5010 JPEG encoder driver");