hc
2024-01-31 f9004dbfff8a3fbbd7e2a88c8a4327c7f2f8e5b2
kernel/drivers/staging/media/imx/imx-media-vdic.c
....@@ -1,20 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0+
12 /*
23 * V4L2 Deinterlacer Subdev for Freescale i.MX5/6 SOC
34 *
45 * Copyright (c) 2017 Mentor Graphics Inc.
5
- *
6
- * This program is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation; either version 2 of the License, or
9
- * (at your option) any later version.
106 */
11
-#include <linux/delay.h>
12
-#include <linux/interrupt.h>
13
-#include <linux/module.h>
14
-#include <linux/platform_device.h>
15
-#include <linux/sched.h>
16
-#include <linux/slab.h>
17
-#include <linux/timer.h>
187 #include <media/v4l2-ctrls.h>
198 #include <media/v4l2-device.h>
209 #include <media/v4l2-ioctl.h>
....@@ -60,8 +49,8 @@
6049 /*
6150 * Min/Max supported width and heights.
6251 */
63
-#define MIN_W 176
64
-#define MIN_H 144
52
+#define MIN_W 32
53
+#define MIN_H 32
6554 #define MAX_W_VDIC 968
6655 #define MAX_H_VDIC 2048
6756 #define W_ALIGN 4 /* multiple of 16 pixels */
....@@ -69,12 +58,11 @@
6958 #define S_ALIGN 1 /* multiple of 2 */
7059
7160 struct vdic_priv {
72
- struct device *dev;
73
- struct ipu_soc *ipu;
74
- struct imx_media_dev *md;
61
+ struct device *ipu_dev;
62
+ struct ipu_soc *ipu;
63
+
7564 struct v4l2_subdev sd;
7665 struct media_pad pad[VDIC_NUM_PADS];
77
- int ipu_id;
7866
7967 /* lock to protect all members below */
8068 struct mutex lock;
....@@ -149,8 +137,6 @@
149137 struct ipuv3_channel *ch;
150138 struct ipu_vdi *vdi;
151139
152
- priv->ipu = priv->md->ipu[priv->ipu_id];
153
-
154140 vdi = ipu_vdi_get(priv->ipu);
155141 if (IS_ERR(vdi)) {
156142 v4l2_err(&priv->sd, "failed to get VDIC\n");
....@@ -219,26 +205,24 @@
219205
220206 switch (priv->fieldtype) {
221207 case V4L2_FIELD_SEQ_TB:
222
- prev_phys = vb2_dma_contig_plane_dma_addr(prev_vb, 0);
223
- curr_phys = vb2_dma_contig_plane_dma_addr(curr_vb, 0) + fs;
224
- next_phys = vb2_dma_contig_plane_dma_addr(curr_vb, 0);
225
- break;
226208 case V4L2_FIELD_SEQ_BT:
227209 prev_phys = vb2_dma_contig_plane_dma_addr(prev_vb, 0) + fs;
228210 curr_phys = vb2_dma_contig_plane_dma_addr(curr_vb, 0);
229211 next_phys = vb2_dma_contig_plane_dma_addr(curr_vb, 0) + fs;
230212 break;
213
+ case V4L2_FIELD_INTERLACED_TB:
231214 case V4L2_FIELD_INTERLACED_BT:
215
+ case V4L2_FIELD_INTERLACED:
232216 prev_phys = vb2_dma_contig_plane_dma_addr(prev_vb, 0) + is;
233217 curr_phys = vb2_dma_contig_plane_dma_addr(curr_vb, 0);
234218 next_phys = vb2_dma_contig_plane_dma_addr(curr_vb, 0) + is;
235219 break;
236220 default:
237
- /* assume V4L2_FIELD_INTERLACED_TB */
238
- prev_phys = vb2_dma_contig_plane_dma_addr(prev_vb, 0);
239
- curr_phys = vb2_dma_contig_plane_dma_addr(curr_vb, 0) + is;
240
- next_phys = vb2_dma_contig_plane_dma_addr(curr_vb, 0);
241
- break;
221
+ /*
222
+ * can't get here, priv->fieldtype can only be one of
223
+ * the above. This is to quiet smatch errors.
224
+ */
225
+ return;
242226 }
243227
244228 ipu_cpmem_set_buffer(priv->vdi_in_ch_p, 0, prev_phys);
....@@ -263,10 +247,10 @@
263247
264248 memset(&image, 0, sizeof(image));
265249 image.pix = vdev->fmt.fmt.pix;
250
+ image.rect = vdev->compose;
266251 /* one field to VDIC channels */
267252 image.pix.height /= 2;
268
- image.rect.width = image.pix.width;
269
- image.rect.height = image.pix.height;
253
+ image.rect.height /= 2;
270254 image.phys0 = phys0;
271255 image.phys1 = phys1;
272256
....@@ -517,7 +501,8 @@
517501 if (priv->stream_count != !enable)
518502 goto update_count;
519503
520
- dev_dbg(priv->dev, "stream %s\n", enable ? "ON" : "OFF");
504
+ dev_dbg(priv->ipu_dev, "%s: stream %s\n", sd->name,
505
+ enable ? "ON" : "OFF");
521506
522507 if (enable)
523508 ret = vdic_start(priv);
....@@ -563,7 +548,8 @@
563548 if (code->pad >= VDIC_NUM_PADS)
564549 return -EINVAL;
565550
566
- return imx_media_enum_ipu_format(&code->code, code->index, CS_SEL_YUV);
551
+ return imx_media_enum_ipu_formats(&code->code, code->index,
552
+ PIXFMT_SEL_YUV);
567553 }
568554
569555 static int vdic_get_fmt(struct v4l2_subdev *sd,
....@@ -598,12 +584,13 @@
598584 {
599585 struct v4l2_mbus_framefmt *infmt;
600586
601
- *cc = imx_media_find_ipu_format(sdformat->format.code, CS_SEL_YUV);
587
+ *cc = imx_media_find_ipu_format(sdformat->format.code,
588
+ PIXFMT_SEL_YUV);
602589 if (!*cc) {
603590 u32 code;
604591
605
- imx_media_enum_ipu_format(&code, 0, CS_SEL_YUV);
606
- *cc = imx_media_find_ipu_format(code, CS_SEL_YUV);
592
+ imx_media_enum_ipu_formats(&code, 0, PIXFMT_SEL_YUV);
593
+ *cc = imx_media_find_ipu_format(code, PIXFMT_SEL_YUV);
607594 sdformat->format.code = (*cc)->codes[0];
608595 }
609596
....@@ -623,14 +610,13 @@
623610 &sdformat->format.height,
624611 MIN_H, MAX_H_VDIC, H_ALIGN, S_ALIGN);
625612
626
- imx_media_fill_default_mbus_fields(&sdformat->format, infmt,
627
- true);
628
-
629613 /* input must be interlaced! Choose SEQ_TB if not */
630614 if (!V4L2_FIELD_HAS_BOTH(sdformat->format.field))
631615 sdformat->format.field = V4L2_FIELD_SEQ_TB;
632616 break;
633617 }
618
+
619
+ imx_media_try_colorimetry(&sdformat->format, true);
634620 }
635621
636622 static int vdic_set_fmt(struct v4l2_subdev *sd,
....@@ -692,8 +678,8 @@
692678 struct v4l2_subdev *remote_sd;
693679 int ret = 0;
694680
695
- dev_dbg(priv->dev, "link setup %s -> %s", remote->entity->name,
696
- local->entity->name);
681
+ dev_dbg(priv->ipu_dev, "%s: link setup %s -> %s",
682
+ sd->name, remote->entity->name, local->entity->name);
697683
698684 mutex_lock(&priv->lock);
699685
....@@ -752,7 +738,7 @@
752738 remote_sd = media_entity_to_v4l2_subdev(remote->entity);
753739
754740 /* direct pad must connect to a CSI */
755
- if (!(remote_sd->grp_id & IMX_MEDIA_GRP_ID_CSI) ||
741
+ if (!(remote_sd->grp_id & IMX_MEDIA_GRP_ID_IPU_CSI) ||
756742 remote->index != CSI_SRC_PAD_DIRECT) {
757743 ret = -EINVAL;
758744 goto out;
....@@ -826,7 +812,10 @@
826812 switch (fi->pad) {
827813 case VDIC_SINK_PAD_DIRECT:
828814 case VDIC_SINK_PAD_IDMAC:
829
- /* No limits on input frame interval */
815
+ /* No limits on valid input frame intervals */
816
+ if (fi->interval.numerator == 0 ||
817
+ fi->interval.denominator == 0)
818
+ fi->interval = priv->frame_interval[fi->pad];
830819 /* Reset output interval */
831820 *output_fi = fi->interval;
832821 if (priv->csi_direct)
....@@ -854,25 +843,16 @@
854843 return ret;
855844 }
856845
857
-/*
858
- * retrieve our pads parsed from the OF graph by the media device
859
- */
860846 static int vdic_registered(struct v4l2_subdev *sd)
861847 {
862848 struct vdic_priv *priv = v4l2_get_subdevdata(sd);
863849 int i, ret;
864850 u32 code;
865851
866
- /* get media device */
867
- priv->md = dev_get_drvdata(sd->v4l2_dev->dev);
868
-
869852 for (i = 0; i < VDIC_NUM_PADS; i++) {
870
- priv->pad[i].flags = (i == VDIC_SRC_PAD_DIRECT) ?
871
- MEDIA_PAD_FL_SOURCE : MEDIA_PAD_FL_SINK;
872
-
873853 code = 0;
874854 if (i != VDIC_SINK_PAD_IDMAC)
875
- imx_media_enum_ipu_format(&code, 0, CS_SEL_YUV);
855
+ imx_media_enum_ipu_formats(&code, 0, PIXFMT_SEL_YUV);
876856
877857 /* set a default mbus format */
878858 ret = imx_media_init_mbus_fmt(&priv->format_mbus[i],
....@@ -890,15 +870,7 @@
890870
891871 priv->active_input_pad = VDIC_SINK_PAD_DIRECT;
892872
893
- ret = vdic_init_controls(priv);
894
- if (ret)
895
- return ret;
896
-
897
- ret = media_entity_pads_init(&sd->entity, VDIC_NUM_PADS, priv->pad);
898
- if (ret)
899
- v4l2_ctrl_handler_free(&priv->ctrl_hdlr);
900
-
901
- return ret;
873
+ return vdic_init_controls(priv);
902874 }
903875
904876 static void vdic_unregistered(struct v4l2_subdev *sd)
....@@ -937,77 +909,62 @@
937909 .unregistered = vdic_unregistered,
938910 };
939911
940
-static int imx_vdic_probe(struct platform_device *pdev)
912
+struct v4l2_subdev *imx_media_vdic_register(struct v4l2_device *v4l2_dev,
913
+ struct device *ipu_dev,
914
+ struct ipu_soc *ipu,
915
+ u32 grp_id)
941916 {
942
- struct imx_media_internal_sd_platformdata *pdata;
943917 struct vdic_priv *priv;
944
- int ret;
918
+ int i, ret;
945919
946
- priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
920
+ priv = devm_kzalloc(ipu_dev, sizeof(*priv), GFP_KERNEL);
947921 if (!priv)
948
- return -ENOMEM;
922
+ return ERR_PTR(-ENOMEM);
949923
950
- platform_set_drvdata(pdev, &priv->sd);
951
- priv->dev = &pdev->dev;
952
-
953
- pdata = priv->dev->platform_data;
954
- priv->ipu_id = pdata->ipu_id;
924
+ priv->ipu_dev = ipu_dev;
925
+ priv->ipu = ipu;
955926
956927 v4l2_subdev_init(&priv->sd, &vdic_subdev_ops);
957928 v4l2_set_subdevdata(&priv->sd, priv);
958929 priv->sd.internal_ops = &vdic_internal_ops;
959930 priv->sd.entity.ops = &vdic_entity_ops;
960931 priv->sd.entity.function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
961
- priv->sd.dev = &pdev->dev;
962
- priv->sd.owner = THIS_MODULE;
932
+ priv->sd.owner = ipu_dev->driver->owner;
963933 priv->sd.flags = V4L2_SUBDEV_FL_HAS_DEVNODE;
964
- /* get our group id */
965
- priv->sd.grp_id = pdata->grp_id;
966
- strncpy(priv->sd.name, pdata->sd_name, sizeof(priv->sd.name));
934
+ priv->sd.grp_id = grp_id;
935
+ imx_media_grp_id_to_sd_name(priv->sd.name, sizeof(priv->sd.name),
936
+ priv->sd.grp_id, ipu_get_num(ipu));
967937
968938 mutex_init(&priv->lock);
969939
970
- ret = v4l2_async_register_subdev(&priv->sd);
940
+ for (i = 0; i < VDIC_NUM_PADS; i++)
941
+ priv->pad[i].flags = (i == VDIC_SRC_PAD_DIRECT) ?
942
+ MEDIA_PAD_FL_SOURCE : MEDIA_PAD_FL_SINK;
943
+
944
+ ret = media_entity_pads_init(&priv->sd.entity, VDIC_NUM_PADS,
945
+ priv->pad);
971946 if (ret)
972947 goto free;
973948
974
- return 0;
949
+ ret = v4l2_device_register_subdev(v4l2_dev, &priv->sd);
950
+ if (ret)
951
+ goto free;
952
+
953
+ return &priv->sd;
975954 free:
976955 mutex_destroy(&priv->lock);
977
- return ret;
956
+ return ERR_PTR(ret);
978957 }
979958
980
-static int imx_vdic_remove(struct platform_device *pdev)
959
+int imx_media_vdic_unregister(struct v4l2_subdev *sd)
981960 {
982
- struct v4l2_subdev *sd = platform_get_drvdata(pdev);
983961 struct vdic_priv *priv = v4l2_get_subdevdata(sd);
984962
985963 v4l2_info(sd, "Removing\n");
986964
987
- v4l2_async_unregister_subdev(sd);
965
+ v4l2_device_unregister_subdev(sd);
988966 mutex_destroy(&priv->lock);
989967 media_entity_cleanup(&sd->entity);
990968
991969 return 0;
992970 }
993
-
994
-static const struct platform_device_id imx_vdic_ids[] = {
995
- { .name = "imx-ipuv3-vdic" },
996
- { },
997
-};
998
-MODULE_DEVICE_TABLE(platform, imx_vdic_ids);
999
-
1000
-static struct platform_driver imx_vdic_driver = {
1001
- .probe = imx_vdic_probe,
1002
- .remove = imx_vdic_remove,
1003
- .id_table = imx_vdic_ids,
1004
- .driver = {
1005
- .name = "imx-ipuv3-vdic",
1006
- },
1007
-};
1008
-module_platform_driver(imx_vdic_driver);
1009
-
1010
-MODULE_DESCRIPTION("i.MX VDIC subdev driver");
1011
-MODULE_AUTHOR("Steve Longerbeam <steve_longerbeam@mentor.com>");
1012
-MODULE_LICENSE("GPL");
1013
-MODULE_ALIAS("platform:imx-ipuv3-vdic");