13 #include <linux/module.h>
14 #include <linux/kernel.h>
15 #include <linux/types.h>
16 #include <linux/errno.h>
19 #include <linux/device.h>
22 #include <linux/list.h>
24 #include <linux/slab.h>
35 static unsigned int get_m2m_fmt_flags(
unsigned int stream_type)
50 src_vb = v4l2_m2m_src_buf_remove(ctx->
m2m_ctx);
51 dst_vb = v4l2_m2m_dst_buf_remove(ctx->
m2m_ctx);
53 if (src_vb && dst_vb) {
54 v4l2_m2m_buf_done(src_vb, vb_state);
55 v4l2_m2m_buf_done(dst_vb, vb_state);
84 ret = pm_runtime_get_sync(&ctx->
fimc_dev->pdev->dev);
85 return ret > 0 ? 0 :
ret;
93 ret = fimc_m2m_shutdown(ctx);
97 pm_runtime_put(&ctx->
fimc_dev->pdev->dev);
101 static void fimc_device_run(
void *
priv)
110 if (
WARN(!ctx,
"Null context\n"))
126 vb = v4l2_m2m_next_src_buf(ctx->
m2m_ctx);
131 vb = v4l2_m2m_next_dst_buf(ctx->
m2m_ctx);
137 if (fimc->
m2m.ctx != ctx) {
168 spin_unlock_irqrestore(&fimc->
slock, flags);
171 static void fimc_job_abort(
void *priv)
173 fimc_m2m_shutdown(priv);
177 unsigned int *num_buffers,
unsigned int *
num_planes,
178 unsigned int sizes[],
void *allocators[])
180 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
184 f = ctx_get_frame(ctx, vq->
type);
194 *num_planes = f->
fmt->memplanes;
195 for (i = 0; i < f->
fmt->memplanes; i++) {
197 allocators[
i] = ctx->
fimc_dev->alloc_ctx;
202 static int fimc_buf_prepare(
struct vb2_buffer *vb)
208 frame = ctx_get_frame(ctx, vb->
vb2_queue->type);
210 return PTR_ERR(frame);
212 for (i = 0; i < frame->
fmt->memplanes; i++)
213 vb2_set_plane_payload(vb, i, frame->
payload[i]);
218 static void fimc_buf_queue(
struct vb2_buffer *vb)
222 dbg(
"ctx: %p, ctx->state: 0x%x", ctx, ctx->
state);
228 static void fimc_lock(
struct vb2_queue *vq)
230 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
234 static void fimc_unlock(
struct vb2_queue *vq)
236 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
240 static struct vb2_ops fimc_qops = {
241 .queue_setup = fimc_queue_setup,
242 .buf_prepare = fimc_buf_prepare,
243 .buf_queue = fimc_buf_queue,
244 .wait_prepare = fimc_unlock,
245 .wait_finish = fimc_lock,
253 static int fimc_m2m_querycap(
struct file *
file,
void *fh,
273 static int fimc_m2m_enum_fmt_mplane(
struct file *
file,
void *priv,
288 static int fimc_m2m_g_fmt_mplane(
struct file *file,
void *fh,
295 return PTR_ERR(frame);
306 u32 max_w, mod_x, mod_y;
314 get_m2m_fmt_flags(f->
type), 0);
315 if (
WARN(fmt ==
NULL,
"Pixel format lookup failed"))
324 max_w = variant->
pix_limit->scaler_dis_w;
327 max_w = variant->
pix_limit->out_rot_dis_w;
331 if (tiled_fmt(fmt)) {
348 static int fimc_m2m_try_fmt_mplane(
struct file *file,
void *fh,
353 return fimc_try_fmt_mplane(ctx, f);
356 static int fimc_m2m_s_fmt_mplane(
struct file *file,
void *fh,
366 ret = fimc_try_fmt_mplane(ctx, f);
372 if (vb2_is_busy(vq)) {
384 get_m2m_fmt_flags(f->
type), 0);
391 for (i = 0; i < frame->
fmt->colplanes; i++) {
410 static int fimc_m2m_reqbufs(
struct file *file,
void *fh,
418 static int fimc_m2m_querybuf(
struct file *file,
void *fh,
426 static int fimc_m2m_qbuf(
struct file *file,
void *fh,
434 static int fimc_m2m_dqbuf(
struct file *file,
void *fh,
442 static int fimc_m2m_streamon(
struct file *file,
void *fh,
458 static int fimc_m2m_streamoff(
struct file *file,
void *fh,
466 static int fimc_m2m_cropcap(
struct file *file,
void *fh,
472 frame = ctx_get_frame(ctx, cr->
type);
474 return PTR_ERR(frame);
485 static int fimc_m2m_g_crop(
struct file *file,
void *fh,
struct v4l2_crop *cr)
490 frame = ctx_get_frame(ctx, cr->
type);
492 return PTR_ERR(frame);
496 cr->
c.width = frame->
width;
509 if (cr->
c.top < 0 || cr->
c.left < 0) {
511 "doesn't support negative values for top & left\n");
521 min_size = (f == &ctx->
s_frame) ?
528 halign =
ffs(fimc->
variant->min_vsize_align) - 1;
530 for (i = 0; i < f->
fmt->colplanes; i++)
531 depth += f->
fmt->depth[i];
536 halign, 64/(
ALIGN(depth, 8)));
539 if (cr->
c.left + cr->
c.width > f->
o_width)
547 dbg(
"l:%d, t:%d, w:%d, h:%d, f_w: %d, f_h: %d",
548 cr->
c.left, cr->
c.top, cr->
c.width, cr->
c.height,
554 static int fimc_m2m_s_crop(
struct file *file,
void *fh,
const struct v4l2_crop *crop)
562 ret = fimc_m2m_try_crop(ctx, &cr);
597 .vidioc_querycap = fimc_m2m_querycap,
598 .vidioc_enum_fmt_vid_cap_mplane = fimc_m2m_enum_fmt_mplane,
599 .vidioc_enum_fmt_vid_out_mplane = fimc_m2m_enum_fmt_mplane,
600 .vidioc_g_fmt_vid_cap_mplane = fimc_m2m_g_fmt_mplane,
601 .vidioc_g_fmt_vid_out_mplane = fimc_m2m_g_fmt_mplane,
602 .vidioc_try_fmt_vid_cap_mplane = fimc_m2m_try_fmt_mplane,
603 .vidioc_try_fmt_vid_out_mplane = fimc_m2m_try_fmt_mplane,
604 .vidioc_s_fmt_vid_cap_mplane = fimc_m2m_s_fmt_mplane,
605 .vidioc_s_fmt_vid_out_mplane = fimc_m2m_s_fmt_mplane,
606 .vidioc_reqbufs = fimc_m2m_reqbufs,
607 .vidioc_querybuf = fimc_m2m_querybuf,
608 .vidioc_qbuf = fimc_m2m_qbuf,
609 .vidioc_dqbuf = fimc_m2m_dqbuf,
610 .vidioc_streamon = fimc_m2m_streamon,
611 .vidioc_streamoff = fimc_m2m_streamoff,
612 .vidioc_g_crop = fimc_m2m_g_crop,
613 .vidioc_s_crop = fimc_m2m_s_crop,
614 .vidioc_cropcap = fimc_m2m_cropcap
618 static int queue_init(
void *priv,
struct vb2_queue *src_vq,
627 src_vq->
ops = &fimc_qops;
638 dst_vq->
ops = &fimc_qops;
645 static int fimc_m2m_open(
struct file *file)
647 struct fimc_dev *fimc = video_drvdata(file);
651 dbg(
"pid: %d, state: 0x%lx, refcnt: %d",
680 ctx->
fh.ctrl_handler = &ctx->
ctrls.handler;
696 if (fimc->
m2m.refcnt++ == 0)
713 static int fimc_m2m_release(
struct file *file)
718 dbg(
"pid: %d, state: 0x%lx, refcnt= %d",
728 if (--fimc->
m2m.refcnt <= 0)
736 static unsigned int fimc_m2m_poll(
struct file *file,
753 static int fimc_m2m_mmap(
struct file *file,
struct vm_area_struct *vma)
770 .open = fimc_m2m_open,
771 .release = fimc_m2m_release,
772 .poll = fimc_m2m_poll,
774 .mmap = fimc_m2m_mmap,
778 .device_run = fimc_device_run,
779 .job_abort = fimc_job_abort,
790 memset(vfd, 0,
sizeof(*vfd));
791 vfd->
fops = &fimc_m2m_fops;
800 video_set_drvdata(vfd, fimc);
803 if (IS_ERR(fimc->
m2m.m2m_dev)) {
804 v4l2_err(v4l2_dev,
"failed to initialize v4l2-m2m device\n");
805 return PTR_ERR(fimc->
m2m.m2m_dev);
816 v4l2_info(v4l2_dev,
"Registered %s as /dev/%s\n",
817 vfd->
name, video_device_node_name(vfd));
832 if (fimc->
m2m.m2m_dev)
835 if (video_is_registered(&fimc->
m2m.vfd)) {