rcar-core.c (35054B)
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Driver for Renesas R-Car VIN 4 * 5 * Copyright (C) 2016 Renesas Electronics Corp. 6 * Copyright (C) 2011-2013 Renesas Solutions Corp. 7 * Copyright (C) 2013 Cogent Embedded, Inc., <source@cogentembedded.com> 8 * Copyright (C) 2008 Magnus Damm 9 * 10 * Based on the soc-camera rcar_vin driver 11 */ 12 13#include <linux/module.h> 14#include <linux/of.h> 15#include <linux/of_device.h> 16#include <linux/of_graph.h> 17#include <linux/platform_device.h> 18#include <linux/pm_runtime.h> 19#include <linux/slab.h> 20#include <linux/sys_soc.h> 21 22#include <media/v4l2-async.h> 23#include <media/v4l2-fwnode.h> 24#include <media/v4l2-mc.h> 25 26#include "rcar-vin.h" 27 28/* 29 * The companion CSI-2 receiver driver (rcar-csi2) is known 30 * and we know it has one source pad (pad 0) and four sink 31 * pads (pad 1-4). So to translate a pad on the remote 32 * CSI-2 receiver to/from the VIN internal channel number simply 33 * subtract/add one from the pad/channel number. 34 */ 35#define rvin_group_csi_pad_to_channel(pad) ((pad) - 1) 36#define rvin_group_csi_channel_to_pad(channel) ((channel) + 1) 37 38/* 39 * Not all VINs are created equal, master VINs control the 40 * routing for other VIN's. We can figure out which VIN is 41 * master by looking at a VINs id. 42 */ 43#define rvin_group_id_to_master(vin) ((vin) < 4 ? 0 : 4) 44 45#define v4l2_dev_to_vin(d) container_of(d, struct rvin_dev, v4l2_dev) 46 47/* ----------------------------------------------------------------------------- 48 * Gen3 Group Allocator 49 */ 50 51/* FIXME: This should if we find a system that supports more 52 * than one group for the whole system be replaced with a linked 53 * list of groups. And eventually all of this should be replaced 54 * with a global device allocator API. 55 * 56 * But for now this works as on all supported systems there will 57 * be only one group for all instances. 58 */ 59 60static DEFINE_MUTEX(rvin_group_lock); 61static struct rvin_group *rvin_group_data; 62 63static void rvin_group_cleanup(struct rvin_group *group) 64{ 65 media_device_cleanup(&group->mdev); 66 mutex_destroy(&group->lock); 67} 68 69static int rvin_group_init(struct rvin_group *group, struct rvin_dev *vin, 70 int (*link_setup)(struct rvin_dev *), 71 const struct media_device_ops *ops) 72{ 73 struct media_device *mdev = &group->mdev; 74 const struct of_device_id *match; 75 struct device_node *np; 76 77 mutex_init(&group->lock); 78 79 /* Count number of VINs in the system */ 80 group->count = 0; 81 for_each_matching_node(np, vin->dev->driver->of_match_table) 82 if (of_device_is_available(np)) 83 group->count++; 84 85 vin_dbg(vin, "found %u enabled VIN's in DT", group->count); 86 87 group->link_setup = link_setup; 88 89 mdev->dev = vin->dev; 90 mdev->ops = ops; 91 92 match = of_match_node(vin->dev->driver->of_match_table, 93 vin->dev->of_node); 94 95 strscpy(mdev->driver_name, KBUILD_MODNAME, sizeof(mdev->driver_name)); 96 strscpy(mdev->model, match->compatible, sizeof(mdev->model)); 97 98 media_device_init(mdev); 99 100 return 0; 101} 102 103static void rvin_group_release(struct kref *kref) 104{ 105 struct rvin_group *group = 106 container_of(kref, struct rvin_group, refcount); 107 108 mutex_lock(&rvin_group_lock); 109 110 rvin_group_data = NULL; 111 112 rvin_group_cleanup(group); 113 114 kfree(group); 115 116 mutex_unlock(&rvin_group_lock); 117} 118 119static int rvin_group_get(struct rvin_dev *vin, 120 int (*link_setup)(struct rvin_dev *), 121 const struct media_device_ops *ops) 122{ 123 struct rvin_group *group; 124 u32 id; 125 int ret; 126 127 /* Make sure VIN id is present and sane */ 128 ret = of_property_read_u32(vin->dev->of_node, "renesas,id", &id); 129 if (ret) { 130 vin_err(vin, "%pOF: No renesas,id property found\n", 131 vin->dev->of_node); 132 return -EINVAL; 133 } 134 135 if (id >= RCAR_VIN_NUM) { 136 vin_err(vin, "%pOF: Invalid renesas,id '%u'\n", 137 vin->dev->of_node, id); 138 return -EINVAL; 139 } 140 141 /* Join or create a VIN group */ 142 mutex_lock(&rvin_group_lock); 143 if (rvin_group_data) { 144 group = rvin_group_data; 145 kref_get(&group->refcount); 146 } else { 147 group = kzalloc(sizeof(*group), GFP_KERNEL); 148 if (!group) { 149 ret = -ENOMEM; 150 goto err_group; 151 } 152 153 ret = rvin_group_init(group, vin, link_setup, ops); 154 if (ret) { 155 kfree(group); 156 vin_err(vin, "Failed to initialize group\n"); 157 goto err_group; 158 } 159 160 kref_init(&group->refcount); 161 162 rvin_group_data = group; 163 } 164 mutex_unlock(&rvin_group_lock); 165 166 /* Add VIN to group */ 167 mutex_lock(&group->lock); 168 169 if (group->vin[id]) { 170 vin_err(vin, "Duplicate renesas,id property value %u\n", id); 171 mutex_unlock(&group->lock); 172 kref_put(&group->refcount, rvin_group_release); 173 return -EINVAL; 174 } 175 176 group->vin[id] = vin; 177 178 vin->id = id; 179 vin->group = group; 180 vin->v4l2_dev.mdev = &group->mdev; 181 182 mutex_unlock(&group->lock); 183 184 return 0; 185err_group: 186 mutex_unlock(&rvin_group_lock); 187 return ret; 188} 189 190static void rvin_group_put(struct rvin_dev *vin) 191{ 192 struct rvin_group *group = vin->group; 193 194 mutex_lock(&group->lock); 195 196 vin->group = NULL; 197 vin->v4l2_dev.mdev = NULL; 198 199 if (WARN_ON(group->vin[vin->id] != vin)) 200 goto out; 201 202 group->vin[vin->id] = NULL; 203out: 204 mutex_unlock(&group->lock); 205 206 kref_put(&group->refcount, rvin_group_release); 207} 208 209/* group lock should be held when calling this function. */ 210static int rvin_group_entity_to_remote_id(struct rvin_group *group, 211 struct media_entity *entity) 212{ 213 struct v4l2_subdev *sd; 214 unsigned int i; 215 216 sd = media_entity_to_v4l2_subdev(entity); 217 218 for (i = 0; i < RVIN_REMOTES_MAX; i++) 219 if (group->remotes[i].subdev == sd) 220 return i; 221 222 return -ENODEV; 223} 224 225static int rvin_group_notify_complete(struct v4l2_async_notifier *notifier) 226{ 227 struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev); 228 unsigned int i; 229 int ret; 230 231 ret = media_device_register(&vin->group->mdev); 232 if (ret) 233 return ret; 234 235 ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev); 236 if (ret) { 237 vin_err(vin, "Failed to register subdev nodes\n"); 238 return ret; 239 } 240 241 /* Register all video nodes for the group. */ 242 for (i = 0; i < RCAR_VIN_NUM; i++) { 243 if (vin->group->vin[i] && 244 !video_is_registered(&vin->group->vin[i]->vdev)) { 245 ret = rvin_v4l2_register(vin->group->vin[i]); 246 if (ret) 247 return ret; 248 } 249 } 250 251 return vin->group->link_setup(vin); 252} 253 254static void rvin_group_notify_unbind(struct v4l2_async_notifier *notifier, 255 struct v4l2_subdev *subdev, 256 struct v4l2_async_subdev *asd) 257{ 258 struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev); 259 unsigned int i; 260 261 for (i = 0; i < RCAR_VIN_NUM; i++) 262 if (vin->group->vin[i]) 263 rvin_v4l2_unregister(vin->group->vin[i]); 264 265 mutex_lock(&vin->group->lock); 266 267 for (i = 0; i < RVIN_CSI_MAX; i++) { 268 if (vin->group->remotes[i].asd != asd) 269 continue; 270 vin->group->remotes[i].subdev = NULL; 271 vin_dbg(vin, "Unbind %s from slot %u\n", subdev->name, i); 272 break; 273 } 274 275 mutex_unlock(&vin->group->lock); 276 277 media_device_unregister(&vin->group->mdev); 278} 279 280static int rvin_group_notify_bound(struct v4l2_async_notifier *notifier, 281 struct v4l2_subdev *subdev, 282 struct v4l2_async_subdev *asd) 283{ 284 struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev); 285 unsigned int i; 286 287 mutex_lock(&vin->group->lock); 288 289 for (i = 0; i < RVIN_CSI_MAX; i++) { 290 if (vin->group->remotes[i].asd != asd) 291 continue; 292 vin->group->remotes[i].subdev = subdev; 293 vin_dbg(vin, "Bound %s to slot %u\n", subdev->name, i); 294 break; 295 } 296 297 mutex_unlock(&vin->group->lock); 298 299 return 0; 300} 301 302static const struct v4l2_async_notifier_operations rvin_group_notify_ops = { 303 .bound = rvin_group_notify_bound, 304 .unbind = rvin_group_notify_unbind, 305 .complete = rvin_group_notify_complete, 306}; 307 308static int rvin_group_parse_of(struct rvin_dev *vin, unsigned int port, 309 unsigned int id) 310{ 311 struct fwnode_handle *ep, *fwnode; 312 struct v4l2_fwnode_endpoint vep = { 313 .bus_type = V4L2_MBUS_CSI2_DPHY, 314 }; 315 struct v4l2_async_subdev *asd; 316 int ret; 317 318 ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(vin->dev), port, id, 0); 319 if (!ep) 320 return 0; 321 322 fwnode = fwnode_graph_get_remote_endpoint(ep); 323 ret = v4l2_fwnode_endpoint_parse(ep, &vep); 324 fwnode_handle_put(ep); 325 if (ret) { 326 vin_err(vin, "Failed to parse %pOF\n", to_of_node(fwnode)); 327 ret = -EINVAL; 328 goto out; 329 } 330 331 asd = v4l2_async_nf_add_fwnode(&vin->group->notifier, fwnode, 332 struct v4l2_async_subdev); 333 if (IS_ERR(asd)) { 334 ret = PTR_ERR(asd); 335 goto out; 336 } 337 338 vin->group->remotes[vep.base.id].asd = asd; 339 340 vin_dbg(vin, "Add group OF device %pOF to slot %u\n", 341 to_of_node(fwnode), vep.base.id); 342out: 343 fwnode_handle_put(fwnode); 344 345 return ret; 346} 347 348static void rvin_group_notifier_cleanup(struct rvin_dev *vin) 349{ 350 if (&vin->v4l2_dev == vin->group->notifier.v4l2_dev) { 351 v4l2_async_nf_unregister(&vin->group->notifier); 352 v4l2_async_nf_cleanup(&vin->group->notifier); 353 } 354} 355 356static int rvin_group_notifier_init(struct rvin_dev *vin, unsigned int port, 357 unsigned int max_id) 358{ 359 unsigned int count = 0, vin_mask = 0; 360 unsigned int i, id; 361 int ret; 362 363 mutex_lock(&vin->group->lock); 364 365 /* If not all VIN's are registered don't register the notifier. */ 366 for (i = 0; i < RCAR_VIN_NUM; i++) { 367 if (vin->group->vin[i]) { 368 count++; 369 vin_mask |= BIT(i); 370 } 371 } 372 373 if (vin->group->count != count) { 374 mutex_unlock(&vin->group->lock); 375 return 0; 376 } 377 378 mutex_unlock(&vin->group->lock); 379 380 v4l2_async_nf_init(&vin->group->notifier); 381 382 /* 383 * Some subdevices may overlap but the parser function can handle it and 384 * each subdevice will only be registered once with the group notifier. 385 */ 386 for (i = 0; i < RCAR_VIN_NUM; i++) { 387 if (!(vin_mask & BIT(i))) 388 continue; 389 390 for (id = 0; id < max_id; id++) { 391 if (vin->group->remotes[id].asd) 392 continue; 393 394 ret = rvin_group_parse_of(vin->group->vin[i], port, id); 395 if (ret) 396 return ret; 397 } 398 } 399 400 if (list_empty(&vin->group->notifier.asd_list)) 401 return 0; 402 403 vin->group->notifier.ops = &rvin_group_notify_ops; 404 ret = v4l2_async_nf_register(&vin->v4l2_dev, &vin->group->notifier); 405 if (ret < 0) { 406 vin_err(vin, "Notifier registration failed\n"); 407 v4l2_async_nf_cleanup(&vin->group->notifier); 408 return ret; 409 } 410 411 return 0; 412} 413 414/* ----------------------------------------------------------------------------- 415 * Controls 416 */ 417 418static int rvin_s_ctrl(struct v4l2_ctrl *ctrl) 419{ 420 struct rvin_dev *vin = 421 container_of(ctrl->handler, struct rvin_dev, ctrl_handler); 422 423 switch (ctrl->id) { 424 case V4L2_CID_ALPHA_COMPONENT: 425 rvin_set_alpha(vin, ctrl->val); 426 break; 427 } 428 429 return 0; 430} 431 432static const struct v4l2_ctrl_ops rvin_ctrl_ops = { 433 .s_ctrl = rvin_s_ctrl, 434}; 435 436static void rvin_free_controls(struct rvin_dev *vin) 437{ 438 v4l2_ctrl_handler_free(&vin->ctrl_handler); 439 vin->vdev.ctrl_handler = NULL; 440} 441 442static int rvin_create_controls(struct rvin_dev *vin, struct v4l2_subdev *subdev) 443{ 444 int ret; 445 446 ret = v4l2_ctrl_handler_init(&vin->ctrl_handler, 16); 447 if (ret < 0) 448 return ret; 449 450 /* The VIN directly deals with alpha component. */ 451 v4l2_ctrl_new_std(&vin->ctrl_handler, &rvin_ctrl_ops, 452 V4L2_CID_ALPHA_COMPONENT, 0, 255, 1, 255); 453 454 if (vin->ctrl_handler.error) { 455 ret = vin->ctrl_handler.error; 456 rvin_free_controls(vin); 457 return ret; 458 } 459 460 /* For the non-MC mode add controls from the subdevice. */ 461 if (subdev) { 462 ret = v4l2_ctrl_add_handler(&vin->ctrl_handler, 463 subdev->ctrl_handler, NULL, true); 464 if (ret < 0) { 465 rvin_free_controls(vin); 466 return ret; 467 } 468 } 469 470 vin->vdev.ctrl_handler = &vin->ctrl_handler; 471 472 return 0; 473} 474 475/* ----------------------------------------------------------------------------- 476 * Async notifier 477 */ 478 479static int rvin_find_pad(struct v4l2_subdev *sd, int direction) 480{ 481 unsigned int pad; 482 483 if (sd->entity.num_pads <= 1) 484 return 0; 485 486 for (pad = 0; pad < sd->entity.num_pads; pad++) 487 if (sd->entity.pads[pad].flags & direction) 488 return pad; 489 490 return -EINVAL; 491} 492 493/* ----------------------------------------------------------------------------- 494 * Parallel async notifier 495 */ 496 497/* The vin lock should be held when calling the subdevice attach and detach */ 498static int rvin_parallel_subdevice_attach(struct rvin_dev *vin, 499 struct v4l2_subdev *subdev) 500{ 501 struct v4l2_subdev_mbus_code_enum code = { 502 .which = V4L2_SUBDEV_FORMAT_ACTIVE, 503 }; 504 int ret; 505 506 /* Find source and sink pad of remote subdevice */ 507 ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SOURCE); 508 if (ret < 0) 509 return ret; 510 vin->parallel.source_pad = ret; 511 512 ret = rvin_find_pad(subdev, MEDIA_PAD_FL_SINK); 513 vin->parallel.sink_pad = ret < 0 ? 0 : ret; 514 515 if (vin->info->use_mc) { 516 vin->parallel.subdev = subdev; 517 return 0; 518 } 519 520 /* Find compatible subdevices mbus format */ 521 vin->mbus_code = 0; 522 code.index = 0; 523 code.pad = vin->parallel.source_pad; 524 while (!vin->mbus_code && 525 !v4l2_subdev_call(subdev, pad, enum_mbus_code, NULL, &code)) { 526 code.index++; 527 switch (code.code) { 528 case MEDIA_BUS_FMT_YUYV8_1X16: 529 case MEDIA_BUS_FMT_UYVY8_1X16: 530 case MEDIA_BUS_FMT_UYVY8_2X8: 531 case MEDIA_BUS_FMT_UYVY10_2X10: 532 case MEDIA_BUS_FMT_RGB888_1X24: 533 vin->mbus_code = code.code; 534 vin_dbg(vin, "Found media bus format for %s: %d\n", 535 subdev->name, vin->mbus_code); 536 break; 537 default: 538 break; 539 } 540 } 541 542 if (!vin->mbus_code) { 543 vin_err(vin, "Unsupported media bus format for %s\n", 544 subdev->name); 545 return -EINVAL; 546 } 547 548 /* Read tvnorms */ 549 ret = v4l2_subdev_call(subdev, video, g_tvnorms, &vin->vdev.tvnorms); 550 if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) 551 return ret; 552 553 /* Read standard */ 554 vin->std = V4L2_STD_UNKNOWN; 555 ret = v4l2_subdev_call(subdev, video, g_std, &vin->std); 556 if (ret < 0 && ret != -ENOIOCTLCMD) 557 return ret; 558 559 /* Add the controls */ 560 ret = rvin_create_controls(vin, subdev); 561 if (ret < 0) 562 return ret; 563 564 vin->parallel.subdev = subdev; 565 566 return 0; 567} 568 569static void rvin_parallel_subdevice_detach(struct rvin_dev *vin) 570{ 571 rvin_v4l2_unregister(vin); 572 vin->parallel.subdev = NULL; 573 574 if (!vin->info->use_mc) 575 rvin_free_controls(vin); 576} 577 578static int rvin_parallel_notify_complete(struct v4l2_async_notifier *notifier) 579{ 580 struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev); 581 struct media_entity *source; 582 struct media_entity *sink; 583 int ret; 584 585 ret = v4l2_device_register_subdev_nodes(&vin->v4l2_dev); 586 if (ret < 0) { 587 vin_err(vin, "Failed to register subdev nodes\n"); 588 return ret; 589 } 590 591 if (!video_is_registered(&vin->vdev)) { 592 ret = rvin_v4l2_register(vin); 593 if (ret < 0) 594 return ret; 595 } 596 597 if (!vin->info->use_mc) 598 return 0; 599 600 /* If we're running with media-controller, link the subdevs. */ 601 source = &vin->parallel.subdev->entity; 602 sink = &vin->vdev.entity; 603 604 ret = media_create_pad_link(source, vin->parallel.source_pad, 605 sink, vin->parallel.sink_pad, 0); 606 if (ret) 607 vin_err(vin, "Error adding link from %s to %s: %d\n", 608 source->name, sink->name, ret); 609 610 return ret; 611} 612 613static void rvin_parallel_notify_unbind(struct v4l2_async_notifier *notifier, 614 struct v4l2_subdev *subdev, 615 struct v4l2_async_subdev *asd) 616{ 617 struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev); 618 619 vin_dbg(vin, "unbind parallel subdev %s\n", subdev->name); 620 621 mutex_lock(&vin->lock); 622 rvin_parallel_subdevice_detach(vin); 623 mutex_unlock(&vin->lock); 624} 625 626static int rvin_parallel_notify_bound(struct v4l2_async_notifier *notifier, 627 struct v4l2_subdev *subdev, 628 struct v4l2_async_subdev *asd) 629{ 630 struct rvin_dev *vin = v4l2_dev_to_vin(notifier->v4l2_dev); 631 int ret; 632 633 mutex_lock(&vin->lock); 634 ret = rvin_parallel_subdevice_attach(vin, subdev); 635 mutex_unlock(&vin->lock); 636 if (ret) 637 return ret; 638 639 v4l2_set_subdev_hostdata(subdev, vin); 640 641 vin_dbg(vin, "bound subdev %s source pad: %u sink pad: %u\n", 642 subdev->name, vin->parallel.source_pad, 643 vin->parallel.sink_pad); 644 645 return 0; 646} 647 648static const struct v4l2_async_notifier_operations rvin_parallel_notify_ops = { 649 .bound = rvin_parallel_notify_bound, 650 .unbind = rvin_parallel_notify_unbind, 651 .complete = rvin_parallel_notify_complete, 652}; 653 654static int rvin_parallel_parse_of(struct rvin_dev *vin) 655{ 656 struct fwnode_handle *ep, *fwnode; 657 struct v4l2_fwnode_endpoint vep = { 658 .bus_type = V4L2_MBUS_UNKNOWN, 659 }; 660 struct v4l2_async_subdev *asd; 661 int ret; 662 663 ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(vin->dev), 0, 0, 0); 664 if (!ep) 665 return 0; 666 667 fwnode = fwnode_graph_get_remote_endpoint(ep); 668 ret = v4l2_fwnode_endpoint_parse(ep, &vep); 669 fwnode_handle_put(ep); 670 if (ret) { 671 vin_err(vin, "Failed to parse %pOF\n", to_of_node(fwnode)); 672 ret = -EINVAL; 673 goto out; 674 } 675 676 switch (vep.bus_type) { 677 case V4L2_MBUS_PARALLEL: 678 case V4L2_MBUS_BT656: 679 vin_dbg(vin, "Found %s media bus\n", 680 vep.bus_type == V4L2_MBUS_PARALLEL ? 681 "PARALLEL" : "BT656"); 682 vin->parallel.mbus_type = vep.bus_type; 683 vin->parallel.bus = vep.bus.parallel; 684 break; 685 default: 686 vin_err(vin, "Unknown media bus type\n"); 687 ret = -EINVAL; 688 goto out; 689 } 690 691 asd = v4l2_async_nf_add_fwnode(&vin->notifier, fwnode, 692 struct v4l2_async_subdev); 693 if (IS_ERR(asd)) { 694 ret = PTR_ERR(asd); 695 goto out; 696 } 697 698 vin->parallel.asd = asd; 699 700 vin_dbg(vin, "Add parallel OF device %pOF\n", to_of_node(fwnode)); 701out: 702 fwnode_handle_put(fwnode); 703 704 return ret; 705} 706 707static void rvin_parallel_cleanup(struct rvin_dev *vin) 708{ 709 v4l2_async_nf_unregister(&vin->notifier); 710 v4l2_async_nf_cleanup(&vin->notifier); 711} 712 713static int rvin_parallel_init(struct rvin_dev *vin) 714{ 715 int ret; 716 717 v4l2_async_nf_init(&vin->notifier); 718 719 ret = rvin_parallel_parse_of(vin); 720 if (ret) 721 return ret; 722 723 if (!vin->parallel.asd) 724 return -ENODEV; 725 726 vin_dbg(vin, "Found parallel subdevice %pOF\n", 727 to_of_node(vin->parallel.asd->match.fwnode)); 728 729 vin->notifier.ops = &rvin_parallel_notify_ops; 730 ret = v4l2_async_nf_register(&vin->v4l2_dev, &vin->notifier); 731 if (ret < 0) { 732 vin_err(vin, "Notifier registration failed\n"); 733 v4l2_async_nf_cleanup(&vin->notifier); 734 return ret; 735 } 736 737 return 0; 738} 739 740/* ----------------------------------------------------------------------------- 741 * CSI-2 742 */ 743 744/* 745 * Link setup for the links between a VIN and a CSI-2 receiver is a bit 746 * complex. The reason for this is that the register controlling routing 747 * is not present in each VIN instance. There are special VINs which 748 * control routing for themselves and other VINs. There are not many 749 * different possible links combinations that can be enabled at the same 750 * time, therefor all already enabled links which are controlled by a 751 * master VIN need to be taken into account when making the decision 752 * if a new link can be enabled or not. 753 * 754 * 1. Find out which VIN the link the user tries to enable is connected to. 755 * 2. Lookup which master VIN controls the links for this VIN. 756 * 3. Start with a bitmask with all bits set. 757 * 4. For each previously enabled link from the master VIN bitwise AND its 758 * route mask (see documentation for mask in struct rvin_group_route) 759 * with the bitmask. 760 * 5. Bitwise AND the mask for the link the user tries to enable to the bitmask. 761 * 6. If the bitmask is not empty at this point the new link can be enabled 762 * while keeping all previous links enabled. Update the CHSEL value of the 763 * master VIN and inform the user that the link could be enabled. 764 * 765 * Please note that no link can be enabled if any VIN in the group is 766 * currently open. 767 */ 768static int rvin_csi2_link_notify(struct media_link *link, u32 flags, 769 unsigned int notification) 770{ 771 struct rvin_group *group = container_of(link->graph_obj.mdev, 772 struct rvin_group, mdev); 773 struct media_entity *entity; 774 struct video_device *vdev; 775 struct rvin_dev *vin; 776 unsigned int i; 777 int csi_id, ret; 778 779 ret = v4l2_pipeline_link_notify(link, flags, notification); 780 if (ret) 781 return ret; 782 783 /* Only care about link enablement for VIN nodes. */ 784 if (!(flags & MEDIA_LNK_FL_ENABLED) || 785 !is_media_entity_v4l2_video_device(link->sink->entity)) 786 return 0; 787 788 /* 789 * Don't allow link changes if any entity in the graph is 790 * streaming, modifying the CHSEL register fields can disrupt 791 * running streams. 792 */ 793 media_device_for_each_entity(entity, &group->mdev) 794 if (media_entity_is_streaming(entity)) 795 return -EBUSY; 796 797 /* Find the master VIN that controls the routes. */ 798 vdev = media_entity_to_video_device(link->sink->entity); 799 vin = container_of(vdev, struct rvin_dev, vdev); 800 801 mutex_lock(&group->lock); 802 803 csi_id = rvin_group_entity_to_remote_id(group, link->source->entity); 804 if (csi_id == -ENODEV) { 805 struct v4l2_subdev *sd; 806 807 /* 808 * Make sure the source entity subdevice is registered as 809 * a parallel input of one of the enabled VINs if it is not 810 * one of the CSI-2 subdevices. 811 * 812 * No hardware configuration required for parallel inputs, 813 * we can return here. 814 */ 815 sd = media_entity_to_v4l2_subdev(link->source->entity); 816 for (i = 0; i < RCAR_VIN_NUM; i++) { 817 if (group->vin[i] && 818 group->vin[i]->parallel.subdev == sd) { 819 group->vin[i]->is_csi = false; 820 ret = 0; 821 goto out; 822 } 823 } 824 825 vin_err(vin, "Subdevice %s not registered to any VIN\n", 826 link->source->entity->name); 827 ret = -ENODEV; 828 } else { 829 const struct rvin_group_route *route; 830 unsigned int chsel = UINT_MAX; 831 unsigned int master_id; 832 833 master_id = rvin_group_id_to_master(vin->id); 834 835 if (WARN_ON(!group->vin[master_id])) { 836 ret = -ENODEV; 837 goto out; 838 } 839 840 /* Make sure group is connected to same CSI-2 */ 841 for (i = master_id; i < master_id + 4; i++) { 842 struct media_pad *csi_pad; 843 844 if (!group->vin[i]) 845 continue; 846 847 /* Get remote CSI-2, if any. */ 848 csi_pad = media_entity_remote_pad( 849 &group->vin[i]->vdev.entity.pads[0]); 850 if (!csi_pad) 851 continue; 852 853 if (csi_pad->entity != link->source->entity) { 854 vin_dbg(vin, "Already attached to %s\n", 855 csi_pad->entity->name); 856 ret = -EBUSY; 857 goto out; 858 } 859 } 860 861 for (route = vin->info->routes; route->chsel; route++) { 862 if (route->master == master_id && route->csi == csi_id) { 863 chsel = route->chsel; 864 break; 865 } 866 } 867 868 if (chsel == UINT_MAX) { 869 vin_err(vin, "No CHSEL value found\n"); 870 ret = -EINVAL; 871 goto out; 872 } 873 874 ret = rvin_set_channel_routing(group->vin[master_id], chsel); 875 if (ret) 876 goto out; 877 878 vin->is_csi = true; 879 } 880out: 881 mutex_unlock(&group->lock); 882 883 return ret; 884} 885 886static const struct media_device_ops rvin_csi2_media_ops = { 887 .link_notify = rvin_csi2_link_notify, 888}; 889 890static int rvin_csi2_create_link(struct rvin_group *group, unsigned int id, 891 const struct rvin_group_route *route) 892{ 893 struct media_entity *source = &group->remotes[route->csi].subdev->entity; 894 struct media_entity *sink = &group->vin[id]->vdev.entity; 895 struct media_pad *sink_pad = &sink->pads[0]; 896 unsigned int channel; 897 int ret; 898 899 for (channel = 0; channel < 4; channel++) { 900 unsigned int source_idx = rvin_group_csi_channel_to_pad(channel); 901 struct media_pad *source_pad = &source->pads[source_idx]; 902 903 /* Skip if link already exists. */ 904 if (media_entity_find_link(source_pad, sink_pad)) 905 continue; 906 907 ret = media_create_pad_link(source, source_idx, sink, 0, 0); 908 if (ret) 909 return ret; 910 } 911 912 return 0; 913} 914 915static int rvin_csi2_setup_links(struct rvin_dev *vin) 916{ 917 const struct rvin_group_route *route; 918 unsigned int id; 919 int ret = -EINVAL; 920 921 /* Create all media device links between VINs and CSI-2's. */ 922 mutex_lock(&vin->group->lock); 923 for (route = vin->info->routes; route->chsel; route++) { 924 /* Check that VIN' master is part of the group. */ 925 if (!vin->group->vin[route->master]) 926 continue; 927 928 /* Check that CSI-2 is part of the group. */ 929 if (!vin->group->remotes[route->csi].subdev) 930 continue; 931 932 for (id = route->master; id < route->master + 4; id++) { 933 /* Check that VIN is part of the group. */ 934 if (!vin->group->vin[id]) 935 continue; 936 937 ret = rvin_csi2_create_link(vin->group, id, route); 938 if (ret) 939 goto out; 940 } 941 } 942out: 943 mutex_unlock(&vin->group->lock); 944 945 return ret; 946} 947 948static void rvin_csi2_cleanup(struct rvin_dev *vin) 949{ 950 rvin_parallel_cleanup(vin); 951 rvin_group_notifier_cleanup(vin); 952 rvin_group_put(vin); 953 rvin_free_controls(vin); 954} 955 956static int rvin_csi2_init(struct rvin_dev *vin) 957{ 958 int ret; 959 960 vin->pad.flags = MEDIA_PAD_FL_SINK; 961 ret = media_entity_pads_init(&vin->vdev.entity, 1, &vin->pad); 962 if (ret) 963 return ret; 964 965 ret = rvin_create_controls(vin, NULL); 966 if (ret < 0) 967 return ret; 968 969 ret = rvin_group_get(vin, rvin_csi2_setup_links, &rvin_csi2_media_ops); 970 if (ret) 971 goto err_controls; 972 973 /* It's OK to not have a parallel subdevice. */ 974 ret = rvin_parallel_init(vin); 975 if (ret && ret != -ENODEV) 976 goto err_group; 977 978 ret = rvin_group_notifier_init(vin, 1, RVIN_CSI_MAX); 979 if (ret) 980 goto err_parallel; 981 982 return 0; 983err_parallel: 984 rvin_parallel_cleanup(vin); 985err_group: 986 rvin_group_put(vin); 987err_controls: 988 rvin_free_controls(vin); 989 990 return ret; 991} 992 993/* ----------------------------------------------------------------------------- 994 * ISP 995 */ 996 997static int rvin_isp_setup_links(struct rvin_dev *vin) 998{ 999 unsigned int i; 1000 int ret = -EINVAL; 1001 1002 /* Create all media device links between VINs and ISP's. */ 1003 mutex_lock(&vin->group->lock); 1004 for (i = 0; i < RCAR_VIN_NUM; i++) { 1005 struct media_pad *source_pad, *sink_pad; 1006 struct media_entity *source, *sink; 1007 unsigned int source_slot = i / 8; 1008 unsigned int source_idx = i % 8 + 1; 1009 1010 if (!vin->group->vin[i]) 1011 continue; 1012 1013 /* Check that ISP is part of the group. */ 1014 if (!vin->group->remotes[source_slot].subdev) 1015 continue; 1016 1017 source = &vin->group->remotes[source_slot].subdev->entity; 1018 source_pad = &source->pads[source_idx]; 1019 1020 sink = &vin->group->vin[i]->vdev.entity; 1021 sink_pad = &sink->pads[0]; 1022 1023 /* Skip if link already exists. */ 1024 if (media_entity_find_link(source_pad, sink_pad)) 1025 continue; 1026 1027 ret = media_create_pad_link(source, source_idx, sink, 0, 1028 MEDIA_LNK_FL_ENABLED | 1029 MEDIA_LNK_FL_IMMUTABLE); 1030 if (ret) { 1031 vin_err(vin, "Error adding link from %s to %s\n", 1032 source->name, sink->name); 1033 break; 1034 } 1035 } 1036 mutex_unlock(&vin->group->lock); 1037 1038 return ret; 1039} 1040 1041static void rvin_isp_cleanup(struct rvin_dev *vin) 1042{ 1043 rvin_group_notifier_cleanup(vin); 1044 rvin_group_put(vin); 1045 rvin_free_controls(vin); 1046} 1047 1048static int rvin_isp_init(struct rvin_dev *vin) 1049{ 1050 int ret; 1051 1052 vin->pad.flags = MEDIA_PAD_FL_SINK; 1053 ret = media_entity_pads_init(&vin->vdev.entity, 1, &vin->pad); 1054 if (ret) 1055 return ret; 1056 1057 ret = rvin_create_controls(vin, NULL); 1058 if (ret < 0) 1059 return ret; 1060 1061 ret = rvin_group_get(vin, rvin_isp_setup_links, NULL); 1062 if (ret) 1063 goto err_controls; 1064 1065 ret = rvin_group_notifier_init(vin, 2, RVIN_ISP_MAX); 1066 if (ret) 1067 goto err_group; 1068 1069 return 0; 1070err_group: 1071 rvin_group_put(vin); 1072err_controls: 1073 rvin_free_controls(vin); 1074 1075 return ret; 1076} 1077 1078/* ----------------------------------------------------------------------------- 1079 * Suspend / Resume 1080 */ 1081 1082static int __maybe_unused rvin_suspend(struct device *dev) 1083{ 1084 struct rvin_dev *vin = dev_get_drvdata(dev); 1085 1086 if (vin->state != RUNNING) 1087 return 0; 1088 1089 rvin_stop_streaming(vin); 1090 1091 vin->state = SUSPENDED; 1092 1093 return 0; 1094} 1095 1096static int __maybe_unused rvin_resume(struct device *dev) 1097{ 1098 struct rvin_dev *vin = dev_get_drvdata(dev); 1099 1100 if (vin->state != SUSPENDED) 1101 return 0; 1102 1103 /* 1104 * Restore group master CHSEL setting. 1105 * 1106 * This needs to be done by every VIN resuming not only the master 1107 * as we don't know if and in which order the master VINs will 1108 * be resumed. 1109 */ 1110 if (vin->info->use_mc) { 1111 unsigned int master_id = rvin_group_id_to_master(vin->id); 1112 struct rvin_dev *master = vin->group->vin[master_id]; 1113 int ret; 1114 1115 if (WARN_ON(!master)) 1116 return -ENODEV; 1117 1118 ret = rvin_set_channel_routing(master, master->chsel); 1119 if (ret) 1120 return ret; 1121 } 1122 1123 return rvin_start_streaming(vin); 1124} 1125 1126/* ----------------------------------------------------------------------------- 1127 * Platform Device Driver 1128 */ 1129 1130static const struct rvin_info rcar_info_h1 = { 1131 .model = RCAR_H1, 1132 .use_mc = false, 1133 .max_width = 2048, 1134 .max_height = 2048, 1135}; 1136 1137static const struct rvin_info rcar_info_m1 = { 1138 .model = RCAR_M1, 1139 .use_mc = false, 1140 .max_width = 2048, 1141 .max_height = 2048, 1142}; 1143 1144static const struct rvin_info rcar_info_gen2 = { 1145 .model = RCAR_GEN2, 1146 .use_mc = false, 1147 .max_width = 2048, 1148 .max_height = 2048, 1149}; 1150 1151static const struct rvin_group_route rcar_info_r8a774e1_routes[] = { 1152 { .master = 0, .csi = RVIN_CSI20, .chsel = 0x04 }, 1153 { .master = 0, .csi = RVIN_CSI40, .chsel = 0x03 }, 1154 { .master = 4, .csi = RVIN_CSI20, .chsel = 0x04 }, 1155 { /* Sentinel */ } 1156}; 1157 1158static const struct rvin_info rcar_info_r8a774e1 = { 1159 .model = RCAR_GEN3, 1160 .use_mc = true, 1161 .max_width = 4096, 1162 .max_height = 4096, 1163 .routes = rcar_info_r8a774e1_routes, 1164}; 1165 1166static const struct rvin_group_route rcar_info_r8a7795_routes[] = { 1167 { .master = 0, .csi = RVIN_CSI20, .chsel = 0x04 }, 1168 { .master = 0, .csi = RVIN_CSI40, .chsel = 0x03 }, 1169 { .master = 4, .csi = RVIN_CSI20, .chsel = 0x04 }, 1170 { .master = 4, .csi = RVIN_CSI41, .chsel = 0x03 }, 1171 { /* Sentinel */ } 1172}; 1173 1174static const struct rvin_info rcar_info_r8a7795 = { 1175 .model = RCAR_GEN3, 1176 .use_mc = true, 1177 .nv12 = true, 1178 .max_width = 4096, 1179 .max_height = 4096, 1180 .routes = rcar_info_r8a7795_routes, 1181}; 1182 1183static const struct rvin_group_route rcar_info_r8a7795es1_routes[] = { 1184 { .master = 0, .csi = RVIN_CSI20, .chsel = 0x04 }, 1185 { .master = 0, .csi = RVIN_CSI21, .chsel = 0x05 }, 1186 { .master = 0, .csi = RVIN_CSI40, .chsel = 0x03 }, 1187 { .master = 4, .csi = RVIN_CSI20, .chsel = 0x04 }, 1188 { .master = 4, .csi = RVIN_CSI21, .chsel = 0x05 }, 1189 { .master = 4, .csi = RVIN_CSI41, .chsel = 0x03 }, 1190 { /* Sentinel */ } 1191}; 1192 1193static const struct rvin_info rcar_info_r8a7795es1 = { 1194 .model = RCAR_GEN3, 1195 .use_mc = true, 1196 .max_width = 4096, 1197 .max_height = 4096, 1198 .routes = rcar_info_r8a7795es1_routes, 1199}; 1200 1201static const struct rvin_group_route rcar_info_r8a7796_routes[] = { 1202 { .master = 0, .csi = RVIN_CSI20, .chsel = 0x04 }, 1203 { .master = 0, .csi = RVIN_CSI40, .chsel = 0x03 }, 1204 { .master = 4, .csi = RVIN_CSI20, .chsel = 0x04 }, 1205 { .master = 4, .csi = RVIN_CSI40, .chsel = 0x03 }, 1206 { /* Sentinel */ } 1207}; 1208 1209static const struct rvin_info rcar_info_r8a7796 = { 1210 .model = RCAR_GEN3, 1211 .use_mc = true, 1212 .nv12 = true, 1213 .max_width = 4096, 1214 .max_height = 4096, 1215 .routes = rcar_info_r8a7796_routes, 1216}; 1217 1218static const struct rvin_group_route rcar_info_r8a77965_routes[] = { 1219 { .master = 0, .csi = RVIN_CSI20, .chsel = 0x04 }, 1220 { .master = 0, .csi = RVIN_CSI40, .chsel = 0x03 }, 1221 { .master = 4, .csi = RVIN_CSI20, .chsel = 0x04 }, 1222 { .master = 4, .csi = RVIN_CSI40, .chsel = 0x03 }, 1223 { /* Sentinel */ } 1224}; 1225 1226static const struct rvin_info rcar_info_r8a77965 = { 1227 .model = RCAR_GEN3, 1228 .use_mc = true, 1229 .nv12 = true, 1230 .max_width = 4096, 1231 .max_height = 4096, 1232 .routes = rcar_info_r8a77965_routes, 1233}; 1234 1235static const struct rvin_group_route rcar_info_r8a77970_routes[] = { 1236 { .master = 0, .csi = RVIN_CSI40, .chsel = 0x03 }, 1237 { /* Sentinel */ } 1238}; 1239 1240static const struct rvin_info rcar_info_r8a77970 = { 1241 .model = RCAR_GEN3, 1242 .use_mc = true, 1243 .max_width = 4096, 1244 .max_height = 4096, 1245 .routes = rcar_info_r8a77970_routes, 1246}; 1247 1248static const struct rvin_group_route rcar_info_r8a77980_routes[] = { 1249 { .master = 0, .csi = RVIN_CSI40, .chsel = 0x03 }, 1250 { .master = 4, .csi = RVIN_CSI41, .chsel = 0x03 }, 1251 { /* Sentinel */ } 1252}; 1253 1254static const struct rvin_info rcar_info_r8a77980 = { 1255 .model = RCAR_GEN3, 1256 .use_mc = true, 1257 .nv12 = true, 1258 .max_width = 4096, 1259 .max_height = 4096, 1260 .routes = rcar_info_r8a77980_routes, 1261}; 1262 1263static const struct rvin_group_route rcar_info_r8a77990_routes[] = { 1264 { .master = 0, .csi = RVIN_CSI40, .chsel = 0x03 }, 1265 { /* Sentinel */ } 1266}; 1267 1268static const struct rvin_info rcar_info_r8a77990 = { 1269 .model = RCAR_GEN3, 1270 .use_mc = true, 1271 .nv12 = true, 1272 .max_width = 4096, 1273 .max_height = 4096, 1274 .routes = rcar_info_r8a77990_routes, 1275}; 1276 1277static const struct rvin_group_route rcar_info_r8a77995_routes[] = { 1278 { /* Sentinel */ } 1279}; 1280 1281static const struct rvin_info rcar_info_r8a77995 = { 1282 .model = RCAR_GEN3, 1283 .use_mc = true, 1284 .nv12 = true, 1285 .max_width = 4096, 1286 .max_height = 4096, 1287 .routes = rcar_info_r8a77995_routes, 1288}; 1289 1290static const struct rvin_info rcar_info_r8a779a0 = { 1291 .model = RCAR_GEN3, 1292 .use_mc = true, 1293 .use_isp = true, 1294 .nv12 = true, 1295 .max_width = 4096, 1296 .max_height = 4096, 1297}; 1298 1299static const struct of_device_id rvin_of_id_table[] = { 1300 { 1301 .compatible = "renesas,vin-r8a774a1", 1302 .data = &rcar_info_r8a7796, 1303 }, 1304 { 1305 .compatible = "renesas,vin-r8a774b1", 1306 .data = &rcar_info_r8a77965, 1307 }, 1308 { 1309 .compatible = "renesas,vin-r8a774c0", 1310 .data = &rcar_info_r8a77990, 1311 }, 1312 { 1313 .compatible = "renesas,vin-r8a774e1", 1314 .data = &rcar_info_r8a774e1, 1315 }, 1316 { 1317 .compatible = "renesas,vin-r8a7778", 1318 .data = &rcar_info_m1, 1319 }, 1320 { 1321 .compatible = "renesas,vin-r8a7779", 1322 .data = &rcar_info_h1, 1323 }, 1324 { 1325 .compatible = "renesas,rcar-gen2-vin", 1326 .data = &rcar_info_gen2, 1327 }, 1328 { 1329 .compatible = "renesas,vin-r8a7795", 1330 .data = &rcar_info_r8a7795, 1331 }, 1332 { 1333 .compatible = "renesas,vin-r8a7796", 1334 .data = &rcar_info_r8a7796, 1335 }, 1336 { 1337 .compatible = "renesas,vin-r8a77961", 1338 .data = &rcar_info_r8a7796, 1339 }, 1340 { 1341 .compatible = "renesas,vin-r8a77965", 1342 .data = &rcar_info_r8a77965, 1343 }, 1344 { 1345 .compatible = "renesas,vin-r8a77970", 1346 .data = &rcar_info_r8a77970, 1347 }, 1348 { 1349 .compatible = "renesas,vin-r8a77980", 1350 .data = &rcar_info_r8a77980, 1351 }, 1352 { 1353 .compatible = "renesas,vin-r8a77990", 1354 .data = &rcar_info_r8a77990, 1355 }, 1356 { 1357 .compatible = "renesas,vin-r8a77995", 1358 .data = &rcar_info_r8a77995, 1359 }, 1360 { 1361 .compatible = "renesas,vin-r8a779a0", 1362 .data = &rcar_info_r8a779a0, 1363 }, 1364 { /* Sentinel */ }, 1365}; 1366MODULE_DEVICE_TABLE(of, rvin_of_id_table); 1367 1368static const struct soc_device_attribute r8a7795es1[] = { 1369 { 1370 .soc_id = "r8a7795", .revision = "ES1.*", 1371 .data = &rcar_info_r8a7795es1, 1372 }, 1373 { /* Sentinel */ } 1374}; 1375 1376static int rcar_vin_probe(struct platform_device *pdev) 1377{ 1378 const struct soc_device_attribute *attr; 1379 struct rvin_dev *vin; 1380 int irq, ret; 1381 1382 vin = devm_kzalloc(&pdev->dev, sizeof(*vin), GFP_KERNEL); 1383 if (!vin) 1384 return -ENOMEM; 1385 1386 vin->dev = &pdev->dev; 1387 vin->info = of_device_get_match_data(&pdev->dev); 1388 vin->alpha = 0xff; 1389 1390 /* 1391 * Special care is needed on r8a7795 ES1.x since it 1392 * uses different routing than r8a7795 ES2.0. 1393 */ 1394 attr = soc_device_match(r8a7795es1); 1395 if (attr) 1396 vin->info = attr->data; 1397 1398 vin->base = devm_platform_ioremap_resource(pdev, 0); 1399 if (IS_ERR(vin->base)) 1400 return PTR_ERR(vin->base); 1401 1402 irq = platform_get_irq(pdev, 0); 1403 if (irq < 0) 1404 return irq; 1405 1406 ret = rvin_dma_register(vin, irq); 1407 if (ret) 1408 return ret; 1409 1410 platform_set_drvdata(pdev, vin); 1411 1412 if (vin->info->use_isp) 1413 ret = rvin_isp_init(vin); 1414 else if (vin->info->use_mc) 1415 ret = rvin_csi2_init(vin); 1416 else 1417 ret = rvin_parallel_init(vin); 1418 1419 if (ret) { 1420 rvin_dma_unregister(vin); 1421 return ret; 1422 } 1423 1424 pm_suspend_ignore_children(&pdev->dev, true); 1425 pm_runtime_enable(&pdev->dev); 1426 1427 return 0; 1428} 1429 1430static int rcar_vin_remove(struct platform_device *pdev) 1431{ 1432 struct rvin_dev *vin = platform_get_drvdata(pdev); 1433 1434 pm_runtime_disable(&pdev->dev); 1435 1436 rvin_v4l2_unregister(vin); 1437 1438 if (vin->info->use_isp) 1439 rvin_isp_cleanup(vin); 1440 else if (vin->info->use_mc) 1441 rvin_csi2_cleanup(vin); 1442 else 1443 rvin_parallel_cleanup(vin); 1444 1445 rvin_dma_unregister(vin); 1446 1447 return 0; 1448} 1449 1450static SIMPLE_DEV_PM_OPS(rvin_pm_ops, rvin_suspend, rvin_resume); 1451 1452static struct platform_driver rcar_vin_driver = { 1453 .driver = { 1454 .name = "rcar-vin", 1455 .suppress_bind_attrs = true, 1456 .pm = &rvin_pm_ops, 1457 .of_match_table = rvin_of_id_table, 1458 }, 1459 .probe = rcar_vin_probe, 1460 .remove = rcar_vin_remove, 1461}; 1462 1463module_platform_driver(rcar_vin_driver); 1464 1465MODULE_AUTHOR("Niklas Söderlund <niklas.soderlund@ragnatech.se>"); 1466MODULE_DESCRIPTION("Renesas R-Car VIN camera host driver"); 1467MODULE_LICENSE("GPL");