19 #include <linux/module.h>
23 #include <linux/sched.h>
24 #include <linux/slab.h>
34 #define MEM2MEM_TEST_MODULE_NAME "mem2mem-testdev"
45 #define DIM_ALIGN_MASK 7
48 #define MEM2MEM_CAPTURE (1 << 0)
49 #define MEM2MEM_OUTPUT (1 << 1)
51 #define MEM2MEM_NAME "m2m-testdev"
54 #define MEM2MEM_DEF_NUM_BUFS VIDEO_MAX_FRAME
56 #define MEM2MEM_VID_MEM_LIMIT (16 * 1024 * 1024)
59 #define MEM2MEM_DEF_TRANSTIME 1000
61 #define MEM2MEM_DEF_TRANSLEN 1
62 #define MEM2MEM_COLOR_STEP (0xff >> 4)
63 #define MEM2MEM_NUM_TILES 8
66 #define MEM2MEM_HFLIP (1 << 0)
67 #define MEM2MEM_VFLIP (1 << 1)
69 #define dprintk(dev, fmt, arg...) \
70 v4l2_dbg(1, 1, &dev->v4l2_dev, "%s: " fmt, __func__, ## arg)
73 static void m2mtest_dev_release(
struct device *
dev)
78 .dev.release = m2mtest_dev_release,
91 .name =
"RGB565 (BE)",
98 .name =
"4:2:2, packed, YUYV",
106 #define NUM_FORMATS ARRAY_SIZE(formats)
121 #define V4L2_CID_TRANS_TIME_MSEC (V4L2_CID_USER_BASE + 0x1000)
122 #define V4L2_CID_TRANS_NUM_BUFS (V4L2_CID_USER_BASE + 0x1001)
135 if (k == NUM_FORMATS)
210 int tile_w, bytes_left;
215 width = q_data->
width;
217 bytesperline = (q_data->
width * q_data->
fmt->depth) >> 3;
221 if (!p_in || !p_out) {
223 "Acquiring kernel pointers to buffers failed\n");
227 if (vb2_plane_size(in_vb, 0) > vb2_plane_size(out_vb, 0)) {
239 p_out += bytesperline * height - bytes_left;
243 for (x = 0; x < tile_w; ++
x)
247 for (x = 0; x < tile_w; ++
x)
260 p_out += MEM2MEM_NUM_TILES * tile_w;
263 for (x = 0; x < tile_w; ++
x)
267 for (x = 0; x < tile_w; ++
x)
279 p_out += bytesperline * (height - 1);
283 for (x = 0; x < tile_w; ++
x)
287 for (x = 0; x < tile_w; ++
x)
302 for (x = 0; x < tile_w; ++
x)
306 for (x = 0; x < tile_w; ++
x)
320 static void schedule_irq(
struct m2mtest_dev *dev,
int msec_timeout)
322 dprintk(dev,
"Scheduling a simulated irq\n");
333 static int job_ready(
void *
priv)
339 dprintk(ctx->
dev,
"Not enough buffers available\n");
346 static void job_abort(
void *priv)
354 static void m2mtest_lock(
void *priv)
361 static void m2mtest_unlock(
void *priv)
375 static void device_run(
void *priv)
381 src_buf = v4l2_m2m_next_src_buf(ctx->
m2m_ctx);
382 dst_buf = v4l2_m2m_next_dst_buf(ctx->
m2m_ctx);
384 device_process(ctx, src_buf, dst_buf);
390 static void device_isr(
unsigned long priv)
399 if (
NULL == curr_ctx) {
400 pr_err(
"Instance released before the end of transaction\n");
404 src_vb = v4l2_m2m_src_buf_remove(curr_ctx->
m2m_ctx);
405 dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->
m2m_ctx);
412 spin_unlock_irqrestore(&m2mtest_dev->
irqlock, flags);
416 dprintk(curr_ctx->
dev,
"Finishing transaction\n");
420 device_run(curr_ctx);
427 static int vidioc_querycap(
struct file *
file,
void *priv,
447 if (formats[i].
types & type) {
457 if (i < NUM_FORMATS) {
469 static int vidioc_enum_fmt_vid_cap(
struct file *
file,
void *priv,
475 static int vidioc_enum_fmt_vid_out(
struct file *
file,
void *priv,
490 q_data = get_q_data(ctx, f->
type);
495 f->
fmt.
pix.pixelformat = q_data->
fmt->fourcc;
496 f->
fmt.
pix.bytesperline = (q_data->
width * q_data->
fmt->depth) >> 3;
503 static int vidioc_g_fmt_vid_out(
struct file *
file,
void *priv,
506 return vidioc_g_fmt(file2ctx(file), f);
509 static int vidioc_g_fmt_vid_cap(
struct file *file,
void *priv,
512 return vidioc_g_fmt(file2ctx(file), f);
547 static int vidioc_try_fmt_vid_cap(
struct file *file,
void *priv,
553 fmt = find_format(f);
556 "Fourcc format (0x%08x) invalid.\n",
562 return vidioc_try_fmt(f, fmt);
565 static int vidioc_try_fmt_vid_out(
struct file *file,
void *priv,
571 fmt = find_format(f);
574 "Fourcc format (0x%08x) invalid.\n",
578 if (!f->
fmt.
pix.colorspace)
581 return vidioc_try_fmt(f, fmt);
593 q_data = get_q_data(ctx, f->
type);
597 if (vb2_is_busy(vq)) {
598 v4l2_err(&ctx->
dev->v4l2_dev,
"%s queue busy\n", __func__);
602 q_data->
fmt = find_format(f);
606 * q_data->
fmt->depth >> 3;
609 "Setting format for type %d, wxh: %dx%d, fmt: %d\n",
615 static int vidioc_s_fmt_vid_cap(
struct file *file,
void *priv,
620 ret = vidioc_try_fmt_vid_cap(file, priv, f);
624 return vidioc_s_fmt(file2ctx(file), f);
627 static int vidioc_s_fmt_vid_out(
struct file *file,
void *priv,
633 ret = vidioc_try_fmt_vid_out(file, priv, f);
637 ret = vidioc_s_fmt(file2ctx(file), f);
643 static int vidioc_reqbufs(
struct file *file,
void *priv,
651 static int vidioc_querybuf(
struct file *file,
void *priv,
659 static int vidioc_qbuf(
struct file *file,
void *priv,
struct v4l2_buffer *
buf)
666 static int vidioc_dqbuf(
struct file *file,
void *priv,
struct v4l2_buffer *
buf)
673 static int vidioc_streamon(
struct file *file,
void *priv,
681 static int vidioc_streamoff(
struct file *file,
void *priv,
718 v4l2_err(&ctx->
dev->v4l2_dev,
"Invalid control\n");
726 .s_ctrl = m2mtest_s_ctrl,
760 static int m2mtest_queue_setup(
struct vb2_queue *vq,
762 unsigned int *nbuffers,
unsigned int *nplanes,
763 unsigned int sizes[],
void *alloc_ctxs[])
769 q_data = get_q_data(ctx, vq->
type);
785 dprintk(ctx->
dev,
"get %d buffer(s) of size %d each.\n", count, size);
790 static int m2mtest_buf_prepare(
struct vb2_buffer *vb)
797 q_data = get_q_data(ctx, vb->
vb2_queue->type);
799 if (vb2_plane_size(vb, 0) < q_data->
sizeimage) {
800 dprintk(ctx->
dev,
"%s data will not fit into plane (%lu < %lu)\n",
801 __func__, vb2_plane_size(vb, 0), (
long)q_data->
sizeimage);
805 vb2_set_plane_payload(vb, 0, q_data->
sizeimage);
810 static void m2mtest_buf_queue(
struct vb2_buffer *vb)
816 static void m2mtest_wait_prepare(
struct vb2_queue *
q)
822 static void m2mtest_wait_finish(
struct vb2_queue *
q)
828 static struct vb2_ops m2mtest_qops = {
829 .queue_setup = m2mtest_queue_setup,
830 .buf_prepare = m2mtest_buf_prepare,
831 .buf_queue = m2mtest_buf_queue,
832 .wait_prepare = m2mtest_wait_prepare,
833 .wait_finish = m2mtest_wait_finish,
845 src_vq->
ops = &m2mtest_qops;
856 dst_vq->
ops = &m2mtest_qops;
863 .ops = &m2mtest_ctrl_ops,
865 .name =
"Transaction Time (msec)",
874 .ops = &m2mtest_ctrl_ops,
876 .name =
"Buffers Per Transaction",
887 static int m2mtest_open(
struct file *file)
889 struct m2mtest_dev *dev = video_drvdata(file);
916 ctx->
fh.ctrl_handler = hdl;
942 dprintk(dev,
"Created instance %p, m2m_ctx: %p\n", ctx, ctx->
m2m_ctx);
949 static int m2mtest_release(
struct file *file)
951 struct m2mtest_dev *dev = video_drvdata(file);
954 dprintk(dev,
"Releasing instance %p\n", ctx);
969 static unsigned int m2mtest_poll(
struct file *file,
977 static int m2mtest_mmap(
struct file *file,
struct vm_area_struct *vma)
979 struct m2mtest_dev *dev = video_drvdata(file);
992 .open = m2mtest_open,
993 .release = m2mtest_release,
994 .poll = m2mtest_poll,
996 .mmap = m2mtest_mmap,
1002 .fops = &m2mtest_fops,
1003 .ioctl_ops = &m2mtest_ioctl_ops,
1012 .lock = m2mtest_lock,
1013 .unlock = m2mtest_unlock,
1018 struct m2mtest_dev *
dev;
1042 *vfd = m2mtest_videodev;
1051 video_set_drvdata(vfd, dev);
1055 "Device registered as /dev/video%d\n", vfd->
num);
1058 platform_set_drvdata(pdev, dev);
1082 struct m2mtest_dev *dev =
1083 (
struct m2mtest_dev *)platform_get_drvdata(pdev);
1095 .probe = m2mtest_probe,
1096 .remove = m2mtest_remove,
1103 static void __exit m2mtest_exit(
void)
1109 static int __init m2mtest_init(
void)