hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/media/platform/rcar-vin/rcar-core.c
....@@ -243,7 +243,6 @@
243243
244244 static void rvin_group_cleanup(struct rvin_group *group)
245245 {
246
- media_device_unregister(&group->mdev);
247246 media_device_cleanup(&group->mdev);
248247 mutex_destroy(&group->lock);
249248 }
....@@ -253,7 +252,6 @@
253252 struct media_device *mdev = &group->mdev;
254253 const struct of_device_id *match;
255254 struct device_node *np;
256
- int ret;
257255
258256 mutex_init(&group->lock);
259257
....@@ -271,18 +269,14 @@
271269 match = of_match_node(vin->dev->driver->of_match_table,
272270 vin->dev->of_node);
273271
274
- strlcpy(mdev->driver_name, KBUILD_MODNAME, sizeof(mdev->driver_name));
275
- strlcpy(mdev->model, match->compatible, sizeof(mdev->model));
272
+ strscpy(mdev->driver_name, KBUILD_MODNAME, sizeof(mdev->driver_name));
273
+ strscpy(mdev->model, match->compatible, sizeof(mdev->model));
276274 snprintf(mdev->bus_info, sizeof(mdev->bus_info), "platform:%s",
277275 dev_name(mdev->dev));
278276
279277 media_device_init(mdev);
280278
281
- ret = media_device_register(&group->mdev);
282
- if (ret)
283
- rvin_group_cleanup(group);
284
-
285
- return ret;
279
+ return 0;
286280 }
287281
288282 static void rvin_group_release(struct kref *kref)
....@@ -390,6 +384,28 @@
390384 }
391385
392386 /* -----------------------------------------------------------------------------
387
+ * Controls
388
+ */
389
+
390
+static int rvin_s_ctrl(struct v4l2_ctrl *ctrl)
391
+{
392
+ struct rvin_dev *vin =
393
+ container_of(ctrl->handler, struct rvin_dev, ctrl_handler);
394
+
395
+ switch (ctrl->id) {
396
+ case V4L2_CID_ALPHA_COMPONENT:
397
+ rvin_set_alpha(vin, ctrl->val);
398
+ break;
399
+ }
400
+
401
+ return 0;
402
+}
403
+
404
+static const struct v4l2_ctrl_ops rvin_ctrl_ops = {
405
+ .s_ctrl = rvin_s_ctrl,
406
+};
407
+
408
+/* -----------------------------------------------------------------------------
393409 * Async notifier
394410 */
395411
....@@ -478,8 +494,17 @@
478494 if (ret < 0)
479495 return ret;
480496
497
+ v4l2_ctrl_new_std(&vin->ctrl_handler, &rvin_ctrl_ops,
498
+ V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255);
499
+
500
+ if (vin->ctrl_handler.error) {
501
+ ret = vin->ctrl_handler.error;
502
+ v4l2_ctrl_handler_free(&vin->ctrl_handler);
503
+ return ret;
504
+ }
505
+
481506 ret = v4l2_ctrl_add_handler(&vin->ctrl_handler, subdev->ctrl_handler,
482
- NULL);
507
+ NULL, true);
483508 if (ret < 0) {
484509 v4l2_ctrl_handler_free(&vin->ctrl_handler);
485510 return ret;
....@@ -595,12 +620,11 @@
595620
596621 switch (vin->parallel->mbus_type) {
597622 case V4L2_MBUS_PARALLEL:
598
- vin_dbg(vin, "Found PARALLEL media bus\n");
599
- vin->parallel->mbus_flags = vep->bus.parallel.flags;
600
- break;
601623 case V4L2_MBUS_BT656:
602
- vin_dbg(vin, "Found BT656 media bus\n");
603
- vin->parallel->mbus_flags = 0;
624
+ vin_dbg(vin, "Found %s media bus\n",
625
+ vin->parallel->mbus_type == V4L2_MBUS_PARALLEL ?
626
+ "PARALLEL" : "BT656");
627
+ vin->parallel->bus = vep->bus.parallel;
604628 break;
605629 default:
606630 vin_err(vin, "Unknown media bus type\n");
....@@ -613,6 +637,8 @@
613637 static int rvin_parallel_init(struct rvin_dev *vin)
614638 {
615639 int ret;
640
+
641
+ v4l2_async_notifier_init(&vin->notifier);
616642
617643 ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port(
618644 vin->dev, &vin->notifier, sizeof(struct rvin_parallel_entity),
....@@ -648,6 +674,10 @@
648674 const struct rvin_group_route *route;
649675 unsigned int i;
650676 int ret;
677
+
678
+ ret = media_device_register(&vin->group->mdev);
679
+ if (ret)
680
+ return ret;
651681
652682 ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev);
653683 if (ret) {
....@@ -729,6 +759,8 @@
729759 }
730760
731761 mutex_unlock(&vin->group->lock);
762
+
763
+ media_device_unregister(&vin->group->mdev);
732764 }
733765
734766 static int rvin_group_notify_bound(struct v4l2_async_notifier *notifier,
....@@ -764,6 +796,7 @@
764796 struct v4l2_async_subdev *asd)
765797 {
766798 struct rvin_dev *vin = dev_get_drvdata(dev);
799
+ int ret = 0;
767800
768801 if (vep->base.port != 1 || vep->base.id >= RVIN_CSI_MAX)
769802 return -EINVAL;
....@@ -774,37 +807,49 @@
774807 return -ENOTCONN;
775808 }
776809
810
+ mutex_lock(&vin->group->lock);
811
+
777812 if (vin->group->csi[vep->base.id].fwnode) {
778813 vin_dbg(vin, "OF device %pOF already handled\n",
779814 to_of_node(asd->match.fwnode));
780
- return -ENOTCONN;
815
+ ret = -ENOTCONN;
816
+ goto out;
781817 }
782818
783819 vin->group->csi[vep->base.id].fwnode = asd->match.fwnode;
784820
785821 vin_dbg(vin, "Add group OF device %pOF to slot %u\n",
786822 to_of_node(asd->match.fwnode), vep->base.id);
823
+out:
824
+ mutex_unlock(&vin->group->lock);
787825
788
- return 0;
826
+ return ret;
789827 }
790828
791829 static int rvin_mc_parse_of_graph(struct rvin_dev *vin)
792830 {
793
- unsigned int count = 0;
831
+ unsigned int count = 0, vin_mask = 0;
794832 unsigned int i;
795833 int ret;
796834
797835 mutex_lock(&vin->group->lock);
798836
799837 /* If not all VIN's are registered don't register the notifier. */
800
- for (i = 0; i < RCAR_VIN_NUM; i++)
801
- if (vin->group->vin[i])
838
+ for (i = 0; i < RCAR_VIN_NUM; i++) {
839
+ if (vin->group->vin[i]) {
802840 count++;
841
+ vin_mask |= BIT(i);
842
+ }
843
+ }
803844
804845 if (vin->group->count != count) {
805846 mutex_unlock(&vin->group->lock);
806847 return 0;
807848 }
849
+
850
+ mutex_unlock(&vin->group->lock);
851
+
852
+ v4l2_async_notifier_init(&vin->group->notifier);
808853
809854 /*
810855 * Have all VIN's look for CSI-2 subdevices. Some subdevices will
....@@ -812,22 +857,18 @@
812857 * will only be registered once with the group notifier.
813858 */
814859 for (i = 0; i < RCAR_VIN_NUM; i++) {
815
- if (!vin->group->vin[i])
860
+ if (!(vin_mask & BIT(i)))
816861 continue;
817862
818863 ret = v4l2_async_notifier_parse_fwnode_endpoints_by_port(
819864 vin->group->vin[i]->dev, &vin->group->notifier,
820865 sizeof(struct v4l2_async_subdev), 1,
821866 rvin_mc_parse_of_endpoint);
822
- if (ret) {
823
- mutex_unlock(&vin->group->lock);
867
+ if (ret)
824868 return ret;
825
- }
826869 }
827870
828
- mutex_unlock(&vin->group->lock);
829
-
830
- if (!vin->group->notifier.num_subdevs)
871
+ if (list_empty(&vin->group->notifier.asd_list))
831872 return 0;
832873
833874 vin->group->notifier.ops = &rvin_group_notify_ops;
....@@ -859,6 +900,21 @@
859900 if (ret)
860901 rvin_group_put(vin);
861902
903
+ ret = v4l2_ctrl_handler_init(&vin->ctrl_handler, 1);
904
+ if (ret < 0)
905
+ return ret;
906
+
907
+ v4l2_ctrl_new_std(&vin->ctrl_handler, &rvin_ctrl_ops,
908
+ V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255);
909
+
910
+ if (vin->ctrl_handler.error) {
911
+ ret = vin->ctrl_handler.error;
912
+ v4l2_ctrl_handler_free(&vin->ctrl_handler);
913
+ return ret;
914
+ }
915
+
916
+ vin->vdev.ctrl_handler = &vin->ctrl_handler;
917
+
862918 return ret;
863919 }
864920
....@@ -885,6 +941,42 @@
885941 .use_mc = false,
886942 .max_width = 2048,
887943 .max_height = 2048,
944
+};
945
+
946
+static const struct rvin_group_route rcar_info_r8a774e1_routes[] = {
947
+ { .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
948
+ { .csi = RVIN_CSI20, .channel = 0, .vin = 0, .mask = BIT(1) | BIT(4) },
949
+ { .csi = RVIN_CSI40, .channel = 1, .vin = 0, .mask = BIT(2) },
950
+ { .csi = RVIN_CSI20, .channel = 0, .vin = 1, .mask = BIT(0) },
951
+ { .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(1) | BIT(3) },
952
+ { .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
953
+ { .csi = RVIN_CSI20, .channel = 1, .vin = 1, .mask = BIT(4) },
954
+ { .csi = RVIN_CSI20, .channel = 1, .vin = 2, .mask = BIT(0) },
955
+ { .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
956
+ { .csi = RVIN_CSI20, .channel = 0, .vin = 2, .mask = BIT(2) },
957
+ { .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
958
+ { .csi = RVIN_CSI20, .channel = 2, .vin = 2, .mask = BIT(4) },
959
+ { .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
960
+ { .csi = RVIN_CSI20, .channel = 1, .vin = 3, .mask = BIT(1) | BIT(2) },
961
+ { .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
962
+ { .csi = RVIN_CSI20, .channel = 3, .vin = 3, .mask = BIT(4) },
963
+ { .csi = RVIN_CSI20, .channel = 0, .vin = 4, .mask = BIT(1) | BIT(4) },
964
+ { .csi = RVIN_CSI20, .channel = 0, .vin = 5, .mask = BIT(0) },
965
+ { .csi = RVIN_CSI20, .channel = 1, .vin = 5, .mask = BIT(4) },
966
+ { .csi = RVIN_CSI20, .channel = 1, .vin = 6, .mask = BIT(0) },
967
+ { .csi = RVIN_CSI20, .channel = 0, .vin = 6, .mask = BIT(2) },
968
+ { .csi = RVIN_CSI20, .channel = 2, .vin = 6, .mask = BIT(4) },
969
+ { .csi = RVIN_CSI20, .channel = 1, .vin = 7, .mask = BIT(1) | BIT(2) },
970
+ { .csi = RVIN_CSI20, .channel = 3, .vin = 7, .mask = BIT(4) },
971
+ { /* Sentinel */ }
972
+};
973
+
974
+static const struct rvin_info rcar_info_r8a774e1 = {
975
+ .model = RCAR_GEN3,
976
+ .use_mc = true,
977
+ .max_width = 4096,
978
+ .max_height = 4096,
979
+ .routes = rcar_info_r8a774e1_routes,
888980 };
889981
890982 static const struct rvin_group_route rcar_info_r8a7795_routes[] = {
....@@ -926,6 +1018,7 @@
9261018 static const struct rvin_info rcar_info_r8a7795 = {
9271019 .model = RCAR_GEN3,
9281020 .use_mc = true,
1021
+ .nv12 = true,
9291022 .max_width = 4096,
9301023 .max_height = 4096,
9311024 .routes = rcar_info_r8a7795_routes,
....@@ -1020,6 +1113,7 @@
10201113 static const struct rvin_info rcar_info_r8a7796 = {
10211114 .model = RCAR_GEN3,
10221115 .use_mc = true,
1116
+ .nv12 = true,
10231117 .max_width = 4096,
10241118 .max_height = 4096,
10251119 .routes = rcar_info_r8a7796_routes,
....@@ -1064,6 +1158,7 @@
10641158 static const struct rvin_info rcar_info_r8a77965 = {
10651159 .model = RCAR_GEN3,
10661160 .use_mc = true,
1161
+ .nv12 = true,
10671162 .max_width = 4096,
10681163 .max_height = 4096,
10691164 .routes = rcar_info_r8a77965_routes,
....@@ -1088,6 +1183,52 @@
10881183 .routes = rcar_info_r8a77970_routes,
10891184 };
10901185
1186
+static const struct rvin_group_route rcar_info_r8a77980_routes[] = {
1187
+ { .csi = RVIN_CSI40, .channel = 0, .vin = 0, .mask = BIT(0) | BIT(3) },
1188
+ { .csi = RVIN_CSI40, .channel = 1, .vin = 0, .mask = BIT(2) },
1189
+ { .csi = RVIN_CSI40, .channel = 0, .vin = 1, .mask = BIT(2) },
1190
+ { .csi = RVIN_CSI40, .channel = 1, .vin = 1, .mask = BIT(1) | BIT(3) },
1191
+ { .csi = RVIN_CSI40, .channel = 0, .vin = 2, .mask = BIT(1) },
1192
+ { .csi = RVIN_CSI40, .channel = 2, .vin = 2, .mask = BIT(3) },
1193
+ { .csi = RVIN_CSI40, .channel = 1, .vin = 3, .mask = BIT(0) },
1194
+ { .csi = RVIN_CSI40, .channel = 3, .vin = 3, .mask = BIT(3) },
1195
+ { .csi = RVIN_CSI41, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) },
1196
+ { .csi = RVIN_CSI41, .channel = 1, .vin = 4, .mask = BIT(2) },
1197
+ { .csi = RVIN_CSI41, .channel = 0, .vin = 5, .mask = BIT(2) },
1198
+ { .csi = RVIN_CSI41, .channel = 1, .vin = 5, .mask = BIT(1) | BIT(3) },
1199
+ { .csi = RVIN_CSI41, .channel = 0, .vin = 6, .mask = BIT(1) },
1200
+ { .csi = RVIN_CSI41, .channel = 2, .vin = 6, .mask = BIT(3) },
1201
+ { .csi = RVIN_CSI41, .channel = 1, .vin = 7, .mask = BIT(0) },
1202
+ { .csi = RVIN_CSI41, .channel = 3, .vin = 7, .mask = BIT(3) },
1203
+ { /* Sentinel */ }
1204
+};
1205
+
1206
+static const struct rvin_info rcar_info_r8a77980 = {
1207
+ .model = RCAR_GEN3,
1208
+ .use_mc = true,
1209
+ .nv12 = true,
1210
+ .max_width = 4096,
1211
+ .max_height = 4096,
1212
+ .routes = rcar_info_r8a77980_routes,
1213
+};
1214
+
1215
+static const struct rvin_group_route rcar_info_r8a77990_routes[] = {
1216
+ { .csi = RVIN_CSI40, .channel = 0, .vin = 4, .mask = BIT(0) | BIT(3) },
1217
+ { .csi = RVIN_CSI40, .channel = 0, .vin = 5, .mask = BIT(2) },
1218
+ { .csi = RVIN_CSI40, .channel = 1, .vin = 4, .mask = BIT(2) },
1219
+ { .csi = RVIN_CSI40, .channel = 1, .vin = 5, .mask = BIT(1) | BIT(3) },
1220
+ { /* Sentinel */ }
1221
+};
1222
+
1223
+static const struct rvin_info rcar_info_r8a77990 = {
1224
+ .model = RCAR_GEN3,
1225
+ .use_mc = true,
1226
+ .nv12 = true,
1227
+ .max_width = 4096,
1228
+ .max_height = 4096,
1229
+ .routes = rcar_info_r8a77990_routes,
1230
+};
1231
+
10911232 static const struct rvin_group_route rcar_info_r8a77995_routes[] = {
10921233 { /* Sentinel */ }
10931234 };
....@@ -1095,12 +1236,29 @@
10951236 static const struct rvin_info rcar_info_r8a77995 = {
10961237 .model = RCAR_GEN3,
10971238 .use_mc = true,
1239
+ .nv12 = true,
10981240 .max_width = 4096,
10991241 .max_height = 4096,
11001242 .routes = rcar_info_r8a77995_routes,
11011243 };
11021244
11031245 static const struct of_device_id rvin_of_id_table[] = {
1246
+ {
1247
+ .compatible = "renesas,vin-r8a774a1",
1248
+ .data = &rcar_info_r8a7796,
1249
+ },
1250
+ {
1251
+ .compatible = "renesas,vin-r8a774b1",
1252
+ .data = &rcar_info_r8a77965,
1253
+ },
1254
+ {
1255
+ .compatible = "renesas,vin-r8a774c0",
1256
+ .data = &rcar_info_r8a77990,
1257
+ },
1258
+ {
1259
+ .compatible = "renesas,vin-r8a774e1",
1260
+ .data = &rcar_info_r8a774e1,
1261
+ },
11041262 {
11051263 .compatible = "renesas,vin-r8a7778",
11061264 .data = &rcar_info_m1,
....@@ -1146,6 +1304,14 @@
11461304 .data = &rcar_info_r8a77970,
11471305 },
11481306 {
1307
+ .compatible = "renesas,vin-r8a77980",
1308
+ .data = &rcar_info_r8a77980,
1309
+ },
1310
+ {
1311
+ .compatible = "renesas,vin-r8a77990",
1312
+ .data = &rcar_info_r8a77990,
1313
+ },
1314
+ {
11491315 .compatible = "renesas,vin-r8a77995",
11501316 .data = &rcar_info_r8a77995,
11511317 },
....@@ -1165,7 +1331,6 @@
11651331 {
11661332 const struct soc_device_attribute *attr;
11671333 struct rvin_dev *vin;
1168
- struct resource *mem;
11691334 int irq, ret;
11701335
11711336 vin = devm_kzalloc(&pdev->dev, sizeof(*vin), GFP_KERNEL);
....@@ -1174,6 +1339,7 @@
11741339
11751340 vin->dev = &pdev->dev;
11761341 vin->info = of_device_get_match_data(&pdev->dev);
1342
+ vin->alpha = 0xff;
11771343
11781344 /*
11791345 * Special care is needed on r8a7795 ES1.x since it
....@@ -1183,11 +1349,7 @@
11831349 if (attr)
11841350 vin->info = attr->data;
11851351
1186
- mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1187
- if (mem == NULL)
1188
- return -EINVAL;
1189
-
1190
- vin->base = devm_ioremap_resource(vin->dev, mem);
1352
+ vin->base = devm_platform_ioremap_resource(pdev, 0);
11911353 if (IS_ERR(vin->base))
11921354 return PTR_ERR(vin->base);
11931355
....@@ -1217,6 +1379,8 @@
12171379 return 0;
12181380
12191381 error_group_unregister:
1382
+ v4l2_ctrl_handler_free(&vin->ctrl_handler);
1383
+
12201384 if (vin->info->use_mc) {
12211385 mutex_lock(&vin->group->lock);
12221386 if (&vin->v4l2_dev == vin->group->notifier.v4l2_dev) {
....@@ -1245,17 +1409,13 @@
12451409 v4l2_async_notifier_cleanup(&vin->notifier);
12461410
12471411 if (vin->info->use_mc) {
1248
- mutex_lock(&vin->group->lock);
1249
- if (&vin->v4l2_dev == vin->group->notifier.v4l2_dev) {
1250
- v4l2_async_notifier_unregister(&vin->group->notifier);
1251
- v4l2_async_notifier_cleanup(&vin->group->notifier);
1252
- }
1253
- mutex_unlock(&vin->group->lock);
1412
+ v4l2_async_notifier_unregister(&vin->group->notifier);
1413
+ v4l2_async_notifier_cleanup(&vin->group->notifier);
12541414 rvin_group_put(vin);
1255
- } else {
1256
- v4l2_ctrl_handler_free(&vin->ctrl_handler);
12571415 }
12581416
1417
+ v4l2_ctrl_handler_free(&vin->ctrl_handler);
1418
+
12591419 rvin_dma_unregister(vin);
12601420
12611421 return 0;