forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/drivers/media/platform/exynos4-is/fimc-m2m.c
....@@ -1,13 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Samsung S5P/EXYNOS4 SoC series FIMC (video postprocessor) driver
34 *
45 * Copyright (C) 2012 - 2013 Samsung Electronics Co., Ltd.
56 * Sylwester Nawrocki <s.nawrocki@samsung.com>
6
- *
7
- * This program is free software; you can redistribute it and/or modify
8
- * it under the terms of the GNU General Public License as published
9
- * by the Free Software Foundation, either version 2 of the License,
10
- * or (at your option) any later version.
117 */
128
139 #include <linux/module.h>
....@@ -77,16 +73,13 @@
7773 static int start_streaming(struct vb2_queue *q, unsigned int count)
7874 {
7975 struct fimc_ctx *ctx = q->drv_priv;
80
- int ret;
8176
82
- ret = pm_runtime_get_sync(&ctx->fimc_dev->pdev->dev);
83
- return ret > 0 ? 0 : ret;
77
+ return pm_runtime_resume_and_get(&ctx->fimc_dev->pdev->dev);
8478 }
8579
8680 static void stop_streaming(struct vb2_queue *q)
8781 {
8882 struct fimc_ctx *ctx = q->drv_priv;
89
-
9083
9184 fimc_m2m_shutdown(ctx);
9285 fimc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR);
....@@ -236,14 +229,13 @@
236229 struct v4l2_capability *cap)
237230 {
238231 struct fimc_dev *fimc = video_drvdata(file);
239
- unsigned int caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE;
240232
241
- __fimc_vidioc_querycap(&fimc->pdev->dev, cap, caps);
233
+ __fimc_vidioc_querycap(&fimc->pdev->dev, cap);
242234 return 0;
243235 }
244236
245
-static int fimc_m2m_enum_fmt_mplane(struct file *file, void *priv,
246
- struct v4l2_fmtdesc *f)
237
+static int fimc_m2m_enum_fmt(struct file *file, void *priv,
238
+ struct v4l2_fmtdesc *f)
247239 {
248240 struct fimc_fmt *fmt;
249241
....@@ -252,7 +244,6 @@
252244 if (!fmt)
253245 return -EINVAL;
254246
255
- strncpy(f->description, fmt->name, sizeof(f->description) - 1);
256247 f->pixelformat = fmt->fourcc;
257248 return 0;
258249 }
....@@ -383,60 +374,80 @@
383374 return 0;
384375 }
385376
386
-static int fimc_m2m_cropcap(struct file *file, void *fh,
387
- struct v4l2_cropcap *cr)
377
+static int fimc_m2m_g_selection(struct file *file, void *fh,
378
+ struct v4l2_selection *s)
388379 {
389380 struct fimc_ctx *ctx = fh_to_ctx(fh);
390381 struct fimc_frame *frame;
391382
392
- frame = ctx_get_frame(ctx, cr->type);
383
+ frame = ctx_get_frame(ctx, s->type);
393384 if (IS_ERR(frame))
394385 return PTR_ERR(frame);
395386
396
- cr->bounds.left = 0;
397
- cr->bounds.top = 0;
398
- cr->bounds.width = frame->o_width;
399
- cr->bounds.height = frame->o_height;
400
- cr->defrect = cr->bounds;
387
+ switch (s->target) {
388
+ case V4L2_SEL_TGT_CROP:
389
+ case V4L2_SEL_TGT_CROP_DEFAULT:
390
+ case V4L2_SEL_TGT_CROP_BOUNDS:
391
+ if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
392
+ return -EINVAL;
393
+ break;
394
+ case V4L2_SEL_TGT_COMPOSE:
395
+ case V4L2_SEL_TGT_COMPOSE_DEFAULT:
396
+ case V4L2_SEL_TGT_COMPOSE_BOUNDS:
397
+ if (s->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
398
+ return -EINVAL;
399
+ break;
400
+ default:
401
+ return -EINVAL;
402
+ }
401403
404
+ switch (s->target) {
405
+ case V4L2_SEL_TGT_CROP:
406
+ case V4L2_SEL_TGT_COMPOSE:
407
+ s->r.left = frame->offs_h;
408
+ s->r.top = frame->offs_v;
409
+ s->r.width = frame->width;
410
+ s->r.height = frame->height;
411
+ break;
412
+ case V4L2_SEL_TGT_CROP_DEFAULT:
413
+ case V4L2_SEL_TGT_CROP_BOUNDS:
414
+ case V4L2_SEL_TGT_COMPOSE_DEFAULT:
415
+ case V4L2_SEL_TGT_COMPOSE_BOUNDS:
416
+ s->r.left = 0;
417
+ s->r.top = 0;
418
+ s->r.width = frame->o_width;
419
+ s->r.height = frame->o_height;
420
+ break;
421
+ default:
422
+ return -EINVAL;
423
+ }
402424 return 0;
403425 }
404426
405
-static int fimc_m2m_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
406
-{
407
- struct fimc_ctx *ctx = fh_to_ctx(fh);
408
- struct fimc_frame *frame;
409
-
410
- frame = ctx_get_frame(ctx, cr->type);
411
- if (IS_ERR(frame))
412
- return PTR_ERR(frame);
413
-
414
- cr->c.left = frame->offs_h;
415
- cr->c.top = frame->offs_v;
416
- cr->c.width = frame->width;
417
- cr->c.height = frame->height;
418
-
419
- return 0;
420
-}
421
-
422
-static int fimc_m2m_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr)
427
+static int fimc_m2m_try_selection(struct fimc_ctx *ctx,
428
+ struct v4l2_selection *s)
423429 {
424430 struct fimc_dev *fimc = ctx->fimc_dev;
425431 struct fimc_frame *f;
426432 u32 min_size, halign, depth = 0;
427433 int i;
428434
429
- if (cr->c.top < 0 || cr->c.left < 0) {
435
+ if (s->r.top < 0 || s->r.left < 0) {
430436 v4l2_err(&fimc->m2m.vfd,
431437 "doesn't support negative values for top & left\n");
432438 return -EINVAL;
433439 }
434
- if (cr->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
440
+ if (s->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
435441 f = &ctx->d_frame;
436
- else if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
442
+ if (s->target != V4L2_SEL_TGT_COMPOSE)
443
+ return -EINVAL;
444
+ } else if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
437445 f = &ctx->s_frame;
438
- else
446
+ if (s->target != V4L2_SEL_TGT_CROP)
447
+ return -EINVAL;
448
+ } else {
439449 return -EINVAL;
450
+ }
440451
441452 min_size = (f == &ctx->s_frame) ?
442453 fimc->variant->min_inp_pixsize : fimc->variant->min_out_pixsize;
....@@ -450,61 +461,61 @@
450461 for (i = 0; i < f->fmt->memplanes; i++)
451462 depth += f->fmt->depth[i];
452463
453
- v4l_bound_align_image(&cr->c.width, min_size, f->o_width,
464
+ v4l_bound_align_image(&s->r.width, min_size, f->o_width,
454465 ffs(min_size) - 1,
455
- &cr->c.height, min_size, f->o_height,
466
+ &s->r.height, min_size, f->o_height,
456467 halign, 64/(ALIGN(depth, 8)));
457468
458469 /* adjust left/top if cropping rectangle is out of bounds */
459
- if (cr->c.left + cr->c.width > f->o_width)
460
- cr->c.left = f->o_width - cr->c.width;
461
- if (cr->c.top + cr->c.height > f->o_height)
462
- cr->c.top = f->o_height - cr->c.height;
470
+ if (s->r.left + s->r.width > f->o_width)
471
+ s->r.left = f->o_width - s->r.width;
472
+ if (s->r.top + s->r.height > f->o_height)
473
+ s->r.top = f->o_height - s->r.height;
463474
464
- cr->c.left = round_down(cr->c.left, min_size);
465
- cr->c.top = round_down(cr->c.top, fimc->variant->hor_offs_align);
475
+ s->r.left = round_down(s->r.left, min_size);
476
+ s->r.top = round_down(s->r.top, fimc->variant->hor_offs_align);
466477
467478 dbg("l:%d, t:%d, w:%d, h:%d, f_w: %d, f_h: %d",
468
- cr->c.left, cr->c.top, cr->c.width, cr->c.height,
479
+ s->r.left, s->r.top, s->r.width, s->r.height,
469480 f->f_width, f->f_height);
470481
471482 return 0;
472483 }
473484
474
-static int fimc_m2m_s_crop(struct file *file, void *fh, const struct v4l2_crop *crop)
485
+static int fimc_m2m_s_selection(struct file *file, void *fh,
486
+ struct v4l2_selection *s)
475487 {
476488 struct fimc_ctx *ctx = fh_to_ctx(fh);
477489 struct fimc_dev *fimc = ctx->fimc_dev;
478
- struct v4l2_crop cr = *crop;
479490 struct fimc_frame *f;
480491 int ret;
481492
482
- ret = fimc_m2m_try_crop(ctx, &cr);
493
+ ret = fimc_m2m_try_selection(ctx, s);
483494 if (ret)
484495 return ret;
485496
486
- f = (cr.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ?
497
+ f = (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ?
487498 &ctx->s_frame : &ctx->d_frame;
488499
489500 /* Check to see if scaling ratio is within supported range */
490
- if (cr.type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
491
- ret = fimc_check_scaler_ratio(ctx, cr.c.width,
492
- cr.c.height, ctx->d_frame.width,
501
+ if (s->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
502
+ ret = fimc_check_scaler_ratio(ctx, s->r.width,
503
+ s->r.height, ctx->d_frame.width,
493504 ctx->d_frame.height, ctx->rotation);
494505 } else {
495506 ret = fimc_check_scaler_ratio(ctx, ctx->s_frame.width,
496
- ctx->s_frame.height, cr.c.width,
497
- cr.c.height, ctx->rotation);
507
+ ctx->s_frame.height, s->r.width,
508
+ s->r.height, ctx->rotation);
498509 }
499510 if (ret) {
500511 v4l2_err(&fimc->m2m.vfd, "Out of scaler range\n");
501512 return -EINVAL;
502513 }
503514
504
- f->offs_h = cr.c.left;
505
- f->offs_v = cr.c.top;
506
- f->width = cr.c.width;
507
- f->height = cr.c.height;
515
+ f->offs_h = s->r.left;
516
+ f->offs_v = s->r.top;
517
+ f->width = s->r.width;
518
+ f->height = s->r.height;
508519
509520 fimc_ctx_state_set(FIMC_PARAMS, ctx);
510521
....@@ -513,8 +524,8 @@
513524
514525 static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = {
515526 .vidioc_querycap = fimc_m2m_querycap,
516
- .vidioc_enum_fmt_vid_cap_mplane = fimc_m2m_enum_fmt_mplane,
517
- .vidioc_enum_fmt_vid_out_mplane = fimc_m2m_enum_fmt_mplane,
527
+ .vidioc_enum_fmt_vid_cap = fimc_m2m_enum_fmt,
528
+ .vidioc_enum_fmt_vid_out = fimc_m2m_enum_fmt,
518529 .vidioc_g_fmt_vid_cap_mplane = fimc_m2m_g_fmt_mplane,
519530 .vidioc_g_fmt_vid_out_mplane = fimc_m2m_g_fmt_mplane,
520531 .vidioc_try_fmt_vid_cap_mplane = fimc_m2m_try_fmt_mplane,
....@@ -528,9 +539,8 @@
528539 .vidioc_expbuf = v4l2_m2m_ioctl_expbuf,
529540 .vidioc_streamon = v4l2_m2m_ioctl_streamon,
530541 .vidioc_streamoff = v4l2_m2m_ioctl_streamoff,
531
- .vidioc_g_crop = fimc_m2m_g_crop,
532
- .vidioc_s_crop = fimc_m2m_s_crop,
533
- .vidioc_cropcap = fimc_m2m_cropcap
542
+ .vidioc_g_selection = fimc_m2m_g_selection,
543
+ .vidioc_s_selection = fimc_m2m_s_selection,
534544
535545 };
536546
....@@ -717,6 +727,8 @@
717727 vfd->release = video_device_release_empty;
718728 vfd->lock = &fimc->lock;
719729 vfd->vfl_dir = VFL_DIR_M2M;
730
+ vfd->device_caps = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_M2M_MPLANE;
731
+ set_bit(V4L2_FL_QUIRK_INVERTED_CROP, &vfd->flags);
720732
721733 snprintf(vfd->name, sizeof(vfd->name), "fimc.%d.m2m", fimc->id);
722734 video_set_drvdata(vfd, fimc);
....@@ -731,7 +743,7 @@
731743 if (ret)
732744 goto err_me;
733745
734
- ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
746
+ ret = video_register_device(vfd, VFL_TYPE_VIDEO, -1);
735747 if (ret)
736748 goto err_vd;
737749